ブログ カレンダー

« « 2020 9月 » »
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3

カテゴリ一覧

アーカイブ

最新のエントリ

最新のコメント

最新のトラックバック

趣味のブログ - Lazarus の SQLite3 絡みのバグでハマった

Lazarus の SQLite3 絡みのバグでハマった

カテゴリ : 
Lazarus
執筆 : 
OhYeah! 2013.11.16 21:46
 本業関係のソフト(ACFinder)を Lazarus に移行しようかということで、最近 Lazarus をいじり始めました。ACFinder には SQLite データベース操作が必須のため、標準の SQLite3 コネクタである TSQLite3Connection をいじってて気づいた点をいくつか。
 まず最初につまづいたのが、TSQLite3Connection の ExecuteDirect メソッドや TSQLite3Connect に接続した TSQLQuery の ExecSQL では、ATTACH DATABASE 文が実行時エラーになってしまうところ。ATTACH DATABASE はトランザクション内では実行できないようで、ExecuteDirect や ExecSQL では必ずトランザクションを発行するため、エラーになるようです。
 これについては、TSQLite3Connect の protected 節にある execsql メソッドがトランザクションを発行しないので、TSQLite3Connect を親クラスとする新しいクラスで public に置いたメソッドから execsql を呼び出すことで解決しました。
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-SQLDB-Can-t-attach-second-SQLite-database-because-transaction-td4028432.html

 ATTACH DATABASE については、ウェブ上に情報もあったのですぐ解決できたんですが、しばらくハマってしまったのが、regexp 演算子の実装がエラーメッセージも出ない原因不明の実行時エラーになってしまうところです。最初は、TRegExpr の使い方が間違っているのかと思ったんだけど、単純なプログラムで動作確認して問題なし。
 デバッガでトレースして、sqlite3_result_cint で真偽の結果を返しているところでエラーが発生していることを確認したものの、相変わらず原因は不明。SQLite3 API を定義している sqlite3.inc (ダイナミックローダ sqlite3dyn.pp、スタティックローダ sqlite3.pp でインクルードしているファイル)を眺めていたら、sqlite3_result_int 関数をリンクしなければならないのに、リンクする関数の名前まで sqlite3_result_cint にしてあるのが問題と判明。元々のライブラリの関数名が sqlite3_result_int なので、関数名をこちらに統一して sqlite3.inc を修正しました。
 が、修正しただけでは sqlite3dyn.pp を使用するユニットをコンパイルしても、sqlite3dyn.pp がリコンパイルされません。sqlite3dyn.pp を保存し直してタイムスタンプを更新してもダメ。結局、コマンドラインから fcp.exe で sqlite3dyn.pp を(ついでに sqlite3.pp も)コンパイルして、 *.o, *.ppu をライブラリ用ディレクトリに移動しました。
 これで解決するかと思ったら、あにはからんや。sqlite3dyn.ppu が更新されると、Lazarus の再構築の際に、今度はそれを使用している sqlite3conn.ppu がリンクできなくなります。で、sqlite3conn.pp もコマンドラインからコンパイルし、sqlite3conn.ppu もライブラリ用ディレクトリに移す必要がありました。

 sqlite3.inc を見ると、コメント中の sqlite3_interrupt なんかも sqlite3_cinterrupt になってたりするので、int を全部 cint に置換して、リンクする関数名だけ int に修正し直したようです。で、sqlite3con 等で使用している API については int に修正したけど、sqlite3_result_int は sqlite3_create_function で SQLite の内部関数を拡張しない限り使用しない API なので、修正漏れになったというところでしょうか…。
 夜3時間くらいしか触っている時間がないのに、このバグのせいで3日無駄にしてしまいました

トラックバック

トラックバックpingアドレス http://www.o-ya.net/modules/d3blog/tb.php/53

コメント一覧

OhYeah!  投稿日時 2015.06.14 23:17
Lazarus 1.4.0 (fpc 2.4.6) でも修正されず(;_;)。う~ん、日本語 ML に報告しておくか…。
OhYeah!  投稿日時 2015.02.16 22:54
Lazarus 1.2.6 でも sqlite3.inc は全く修正されていません。コメントの int... (たとえば interrupt)も全て cint... (たとえば cinterrupt)となったままです。