sqlite3コマンドでblobの出し入れ

SQLite3の専用シェルのsqlite3でバイナリデータを化かさずに 入れる話。sqlite3には拡張モジュールを組み込めて、 バイナリデータを直接やりとりする関数なんかもあることはある。

https://www.sqlite.org/cli.html

https://www.sqlite.org/c3ref/create_function.html

でも、標準で入らないからあまり使いたくない。

そこでxxd。まず、blobを含むtableを作っておこう。

create table image(filename text, data blob);

ここに画像を入れる。sqlite3コマンドラインで16進表記文字列を クォートするための X'...' という表記の間にバイナリファイルの 16進文字列変換値を突っこむ。ここにxxd -pが活躍。

bin=`xxd -p foo.jpg|tr -d '\n'`
echo "insert into image values('foo.jpg', X'$bin');" | sqlite3 foo.sq3

取り出し。0x00がなければそのままselectで出せるのだが、0x00が あると普通のselectではそこで止まってしまう。なので、quote() して出したものをまたxxdに戻してもらう。

sqlite3 foo.sq3 'select quote(data) from image'|xxd -r -p > out.jpg
cmp foo.jpg out.jpg && echo OK
OK

xxdがないとな。vim7に付いて来る。入れたくないとな。 ならperlとかRubyの難解な pack/unpack つかうよろし。 16進ダンプだけなら hexdump -ve '1/1 "%.2x" で行けるのだが。 http://stackoverflow.com/questions/10353467/how-to-insert-binary-data-into-sqlite3-database-in-bash