SQLite3におけるREGEXP演算子 - anon_193の日記sqlite3_mod_regexp.cxx
SQLite では、load_extension 関数を用いて、外部の拡張モジュールをロードすることが出来る。拡張モジュールは、いわばユーザ関数ライブラリで、SQLite3 ODBC Driver には標準で BLOB二次元マッピング拡張(sqlite3_mod_blobtoxy.dll)、外部データ取込・出力拡張(sqlite3_mod_impexp.dll)、全文検索拡張(sqlite3_mod_fts3.dll) が付属している。これらと同様にして、正規表現マッチングを行う regexp ユーザ関数を持つ拡張モジュールを制作し、ロードすれば、お目当ての REGEXP 演算子が使えるわけだ。
http://d.hatena.ne.jp/anon_193/20090114/1231935112
#include <boost/regex.hpp>
#include <sqlite3ext.h>
extern "C" {
SQLITE_EXTENSION_INIT1
static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) {
if (argc >= 2) {
const char *target = (const char *)sqlite3_value_text(argv[1]);
const char *pattern = (const char *)sqlite3_value_text(argv[0]);
try {
boost::regex ereg(pattern, boost::regex_constants::perl);
sqlite3_result_int(context, boost::regex_search(target, ereg));
} catch (boost::regex_error &e) {
sqlite3_result_error(context, e.what(), 0);
}
}
}
__declspec(dllexport) int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) {
SQLITE_EXTENSION_INIT2(api);
return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, (void*)db, regexp_func, NULL, NULL);
}
}
VCでコンパイルしました。
# cl /EHsc -Isrc -I. -I "c:\boost_1_35_0" sqlite3_mod_regexp.cxx /LD "C:\boost_1_35_0\libs\regex\build\vc80\libboost_regex-vc80-mt-s-1_35.lib"
サンプルデータfoo.sql
CREATE TABLE foo(id integer primary key, value text);
INSERT INTO "foo" VALUES(1,'abc');
INSERT INTO "foo" VALUES(2,'def');
INSERT INTO "foo" VALUES(3,'あいうえお');
INSERT INTO "foo" VALUES(4,'かきくけこ');
INSERT INTO "foo" VALUES(5,'さしすせそ');
utf-8で保存して下さい
# cat foo.sql | sqlite3 foo.db
そしてPerlのコード
use strict;
use warnings;
use utf8;
use YAML;
use DBIx::Simple;
my $db = DBIx::Simple->connect("dbi:SQLite:dbname=c:/foo.db", "", "")
or die DBIx::Simple->error;
$db->func(1, "enable_load_extension");
my $result = $db->query("select load_extension('/sqlite3_mod_regexp.dll')")
or die DBIx::Simple->error;
warn Dump $db->query("select * from foo where value regexp '^[あか]'")->hashes;
dbのパスとdllのパスは指定して下さい実行すると...
---
id: 3
value: あいうえお
---
id: 4
value: かきくけこ
スゲーーーー便利!