やったーJavaScriptの動くMySQLできたよー
※ネタです
※UDFです
- 作者: Andrew Hutchings,Sergei Golubchik
- 出版社/メーカー: Packt Publishing
- 発売日: 2010/08/30
- メディア: ペーパーバック
- 購入: 1人 クリック: 45回
- この商品を含むブログ (2件) を見る
しばらく積ん読していたこの本をちょっと眺めてみたら、MySQLのUDFって簡単に作れるんだなー、と思った && そういやV8ってライブラリとして簡単にリンクできるはずだな、と思い出した ので、ついカッとなって作った。
http://github.com/zentooo/mysqludf-jseval
UDFうんぬn
ほとんど↑の本の受け売りになるけど、一応MySQLのUDFについて備忘録代わりに軽く紹介しておくと
- UDFを追加する場合、MySQLの再コンパイルは必要ない (しかるべき所に.soがおいてあればいい)
- UDFにはnormalとaggregateの二種類がある。normalは値をとって値を返す普通の関数、aggregateはgroup byなどと同時に使われる集計関数
だいたいこんな感じ。
例えば文字列っぽいものを返すmyfuncっていうnormal UDFを作りたい場合
my_bool myfunc_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void myfunc_deinit(UDF_INIT *initid); char* myfunc(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
の三つの関数を実装したmyfunc.cっていうコードを用意してあげて
gcc -o myfunc.so myfunc.c `mysql_config --cflags` -shared -fPIC
という風にコンパイルして(これはLinuxの場合)、しかるべき場所(これはSHOW VARIABLES LIKE 'plugin_dir'で分かる)に置いた後、mysqlのシェルで
CREATE FUNCTION myfunc RETURNS STRING SONAME "myfunc.so";
とやればmyfuncが出来上がる。
メモリ領域の確保や引数のチェックなどの前処理をmyfunc_initでやって、後始末をmyfunc_deinitに書き、処理本体はmyfunc、というのがUDFのお作法らしい。mallocで確保したポインタはmyfunc_initでinitid->ptrに代入しておいて、myfuncでそれを使い、myfunc_deinitでfreeする、みたいな。
動かす手順
で、今回作ったのはV8とリンクして、JSの文字列をevalしてくれるjs_evalというUDF。
多分試す人はいないと思うけど、動かすための手順を書くと
V8のビルド
V8を落としてきてビルドする。ただし、MySQLのUDFは-fPICを付けてビルドするものっぽい?ため、V8も-fPICを付けた上でビルドする。具体的には、sconsする前にexport CCFLAGS=-fPIC しておけばおk。
js_eval.cppをコンパイル
V8をビルドしたディレクトリにもっていって
g++ -o js_eval.so js_eval.cpp `mysql_config --cflags` -shared -Iinclude libv8.a -lpthread -fPIC
そうすると、js_eval.soができるので、これをしかるべきディレクトリに置く
キターーーッ
すごい。
全然
役に立つ気がしない。
というかMySQL力が低すぎてどうしたら面白くなるか思いつかない。これを発展させていってTEXTとかに突っ込んだJSONの中身を効率よく検索とか出来たら面白い&実用的なんだけど、道は遠そうだ。