SQLiteを使ったデータの統計処理なんかをしているとSQL側で処理できてしまうと楽なのになー、と思うケースがあったりする。
そういう時はSQLiteで使えるユーザ定義関数を作ってしまおう。
PHPやPythonで書く手段もあるようだけど、SQLite自体の仕組みを知るためにもCで書いてみよう。
まずは自分で作った関数ではなく、以下で公開されている数値計算用の拡張ライブラリを組み込んでみよう。
SQLite Contributed Files
これを使うと、三角関数やらがSQLから使えるようになる。
最初はSQLite本体のソースコードを以下からダウンロードする。
SQLite Download Page
現時点での最新版は3150000だったので、sqlite-amalgamation-3150000.zipをダウンロード
※環境はOpenSUSE Linux 13.1
既存のSQLite3を使いたい場合はこのままでもいいけど、バージョンを合わせるためにSQLite本体もソースコードからビルドするのであれば、以下の要領で。
拡張ライブラリからリンクするライブラリモジュールを作る時は以下の要領で作成しよう。
次に以下からextension-functions.cをダウンロードしよう。
SQLite Contributed Files
-Iオプションの後ろはsqlite3ext.hが存在するパスを指定しよう。
システムに入っているSQLite3のライブラリではなく、先ほど自分でビルドしたライブラリモジュールを参照したい場合はリンクのパスにライブラリモジュールのパスを追加しよう。
-L../sqlite-amalgamation-3150000 -lsqlite3
これで、LD_LIBRARY_PATHでライブラリの存在するパスを指定してsqlite3を実行する。
拡張モジュールのロードはsqliteプロンプトで.load モジュール名。
そういう時はSQLiteで使えるユーザ定義関数を作ってしまおう。
PHPやPythonで書く手段もあるようだけど、SQLite自体の仕組みを知るためにもCで書いてみよう。
まずは自分で作った関数ではなく、以下で公開されている数値計算用の拡張ライブラリを組み込んでみよう。
SQLite Contributed Files
これを使うと、三角関数やらがSQLから使えるようになる。
最初はSQLite本体のソースコードを以下からダウンロードする。
SQLite Download Page
現時点での最新版は3150000だったので、sqlite-amalgamation-3150000.zipをダウンロード
※環境はOpenSUSE Linux 13.1
$ unzip sqlite-amalgamation-3150000.zip $ cd sqlite-amalgamation-3150000 $ ls shell.c sqlite3.c sqlite3.h sqlite3ext.h
既存のSQLite3を使いたい場合はこのままでもいいけど、バージョンを合わせるためにSQLite本体もソースコードからビルドするのであれば、以下の要領で。
$ gcc shell.c sqlite3.c -DHAVE_READLINE -lpthread -ldl -lreadline -lncurses -Os -o sqlite3 $ # -Osはつけてもつけなくてもいいけど、最適化したい場合はつけておこう。 $ ./sqlite3 SQLite version 3.15.0 2016-10-14 10:20:30 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite>
拡張ライブラリからリンクするライブラリモジュールを作る時は以下の要領で作成しよう。
$ gcc -shared -fPIC -lpthread -ldl -Os sqlite3.c -o libsqlite3.so
次に以下からextension-functions.cをダウンロードしよう。
SQLite Contributed Files
$ mkdir sqlite-extension $ cd sqlite-extension $ gcc -I../sqlite-amalgamation-3150000gcc -I../sqlite-amalgamation-3150000 -L../sqlite-amalgamation-3150000 -fPIC -lm -shared -Os extension-functions.c -o libsqlitefunctions.so -L../sqlite-amalgamation-3150000 -lsqlite3
-Iオプションの後ろはsqlite3ext.hが存在するパスを指定しよう。
システムに入っているSQLite3のライブラリではなく、先ほど自分でビルドしたライブラリモジュールを参照したい場合はリンクのパスにライブラリモジュールのパスを追加しよう。
-L../sqlite-amalgamation-3150000 -lsqlite3
これで、LD_LIBRARY_PATHでライブラリの存在するパスを指定してsqlite3を実行する。
拡張モジュールのロードはsqliteプロンプトで.load モジュール名。
$ LD_LIBRARY_PATH=./../sqlite-amalgamation-3150000/ ../sqlite-amalgamation-3150000/sqlite3 SQLite version 3.15.0 2016-10-14 10:20:30 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> select sin(3.14); Error: no such function: sin sqlite> .load libsqlitefunctions sqlite> select sin(3.14); 0.00159265291648683 sqlite>
pthread必要なんですねぇ
返信削除マルチスレッド対応が必要なければ、以下のマクロ定義を与えることによって、pthreadなしでいけるようです。
削除-DSQLITE_THREADSAFE=0