mrubyでPostgres.appを使って、LOBも扱ってみた
こんばんは、次男がようやく、トイレで大を出すようになってきたと思いっていたら、またここ数日次男がウンチをしてません。kjunichiです。
背景
Qiitaで
という記事を見かけて、Postgres.appでも、同様にライブラリのパスを指定しないと ビルドでこけるだろうなぁと思った。
そんな訳で、アイコンがなんともエキゾチックでお気に入りのPostgres.appを思い出した。
mruby-pgをPostgres.appでビルドする
mruby-pgをcloneしてリンクのパスを以下の様に指定。
spec.linker.library_paths << `pg_config --libdir`.chomp
Postgres.appのpg_configを以下の様にパスに追加
export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/latest/bin
他のPostgresに浮気している場合は、パスの先頭に追加する。
mruby-pgの応用編
折角、Postgres.appを使ってmruby-pgが出来たので、何かやらねばということで、 応用編にチャレンジした。
先日、顔検出や、笑顔検出に対応して、一気に機能強化したmruby-webcamで 検出した画像をネット越しに転送できないものかとあれこれ考えていたところ、 PostgreSQLのDBに格納してしまえば良いのでは?とハタと気づいた!
PostgreSQLにJPEG画像を保存する
幸いmruby-webcamの画像フォーマットは現在JPEGなので、PostgreSQLに格納しても 他の画像形式よりかさばらない気がする。
まずは、PostgreSQLでバイナリを扱う方法を軽く調べた。
PostgreSQLでのLOBはbytea型らしい
俺調べで、PostgreSQLはbytea型を使う事で、バイナリデータを保存出来ることが判明。
以下の様に試しに画像を格納するテーブルを作成した。
CREATE TABLE image_test ( id serial, data bytea, lastupdate timestamp without time zone )
mruby-pgってLOBに対応してるのか
以下の様なコードで出来た。
# Establish connectoin @conn = PG::Connection.new(port: 5432, dbname: "junichi") # # sugoi.jpgがmruby-webcamで取得した画像と仮定 data = `cat $HOME/work/sugoi.jpg` # 画像データの保存 @conn.exec("INSERT INTO image_test(data) VALUES($1::bytea)", [{:value => data, :format => 1}]) def hex2bin(hhh) # 初めの2文字(00)を飛ばす。 hhh.slice!(0,2) [hhh].pack "H*" #hhh.scan(/../).map{ |b| b.to_i(16) }.pack('C*') #hhh.chars.each_slice(2).map { |x| x.join.to_i(16).chr }.join end @conn.exec( "SELECT data::bytea FROM image_test LIMIT 1") do |res| # 取得したレコードは16進数の文字列で格納されている模様。 img= hex2bin(res['data']) File.open("from_psql.jpg","wb") { |f| f.write img } end
学んだこと
pg_configコマンドを知る
pkg-configのPostgreSQLの特化版といったところ。インクルードファイルのディレクトリや、 今回使ったライブラリディレクトリ等を取得できる。
cmpコマンドでバイナリファイルの比較ができる
hex2bin内の処理で先頭の2バイトを削除して対応できたのは、このコマンドのお蔭。
当初は、なぜか、DBからのレコード取得した内容をファイルに落とすと、元の画像より、1バイトサイズが 大きく、fileコマンドでは、dataファイル扱いとなってしまう謎の現象に見舞われたのですが、 このcmpコマンドと、od -cやheadコマンドで、無事、この問題を解決できました。
mrbgemでライブラリのパスを指定する方法
spec.linker.library_pathsにパスを追加すれば、こちらのパスを優先的にリンクしてくれる模様。
関連記事
- OSXで最速でOCamlでPostgresqlに接続するには
- npm install pgだけでは済まない件
- 64ビット版のVistaでPostgreSQLをODBC経由で使うには
- PostgreSQLのVACUUME
- PostgreSQL on Mac OS X(Intel)
- PostgreSQLの困ったエラー
- PostgreSQLの謎
- PostgreSQL 8.4への移行で苦戦中
- PostgreSQL 9.0への移行~失敗編~
- 結局今回も