MathematicaからSQLiteでBLOBとマルチバイト文字列を扱う

ドキュメントにはないものの、MathematicaではSQLiteを扱うことができる。 しかしながら、BLOB型や文字列で日本語などを扱うには少し工夫が必要なので、メモ。

BLOB型

select

直接BLOB型をselectすると$Failedが返ってくるので、hex関数で16進文字列として返す。

db = Database`OpenDatabase[sqlitefilepath];
rs = Database`QueryDatabase[db, "select hex(column_name) from table_name"];

これを16進文字列→数値→バイト列→文字列と変換して、最後にImportStringで読み込むと、Mathematicaで読み込める。

ImportSQLiteBLOB[hex_, format_] :=
 ImportString[
  FromCharacterCode[IntegerDigits[FromDigits[hex, 16], 256]], format];
ImportSQLiteBLOB[rs[[1, 1]], "PNG"]

insert

insertする場合には逆に、データをExportStringで文字列に変換→バイト列→16進文字列と変換し"x’“と”’“で囲う。

ExportSQLiteBLOB[expr_, format_] := 
  StringJoin["x'", IntegerString[ToCharacterCode[ExportString[expr, format]], 16, 2], "'"];
Database`QueryDatabase[db, "insert into table_name values ("
<> ExportSQLiteBLOB[Plot[Sin[x], {x, 0, Pi}], "PNG"]
<> ")"];

マルチバイト文字列

select

日本語などマルチバイト文字列が入っていても適切に変換してくれないので、自前で変換する。

ImportSQLiteString[str_] :=  
  FromCharacterCode[ToCharacterCode[str], "UTF8"];
rs = Database`QueryDatabase[db, "select column_name from table_name"];
ImportSQLiteString[rs[[1, 1]]]

insert

そのまま突っ込むとエラーが出るので、変換してから突っ込む。ついでにシングルクォーテーションをエスケープしておく。

ExportSQLiteString[str_] := 
  "'" <> ExportString[StringReplace[str, "'" -> "''"], "TEXT", 
    CharacterEncoding -> "UTF8"] <> "'";
Database`QueryDatabase[db, "insert into table_name values ("
  <> ExportSQLiteString["あいうえお"]
  <> ")"];