groongaを非対話モードでload --tableするときにエスケープしないで済む方法を考えている

訂正

件名があべこべだったので修正 2011-01-08 13:00

s/対話モードで/非対話モードで/

記事の概要

DB操作でいうところのinsertに相当するloadの処理でちょっと悩み中。

Groonga::Clientっていうgroongaを使ったPerlのサンプルスクリプトをたくさん用意しておいて、いざとなった時に備えるという自分用プロジェクトを作ってます。

https://github.com/okamuuu/Groonga-Client

ちなみにCPAN化する予定ないです。それっぽい名前にしたのはひょっとしてもしかするとCPAN化するかもしれないと思ったからですが、すでにp5-Groongaを作っている人がいるのでとても心待ちしているところです。

でもまだまだ時間がかかると思うので、それまで簡易、最小限なモジュールをつくって勉強している人の、以下一人言です。

対話モードの場合

対話モードでgroongaを操作する場合はエスケープする必要はないです。

% mkdir db
% groonga -n db/hoge.db 
> table_create --name Type --flags TABLE_HASH_KEY --key_type ShortText
column_create --table Type --name number --type Int32
column_create --table Type --name float --type Float
column_create --table Type --name string --type ShortText
column_create --table Type --name time --type Time
load --table Type
[{"_key":"sample","number":12345,"float":42.195,"string":"GROONGA","time":1234567890.12}]
shutdown
[[0,1294419945.29487,0.001085],true]
> [[0,1294419945.29613,0.000485],true]
> [[0,1294419945.29671,0.000529],true]
> [[0,1294419945.29734,0.002947],true]
> [[0,1294419945.3004,0.000536],true]
> [[0,1294419945.301,0.001315],1]
> [[0,1294419945.30244,2.1e-05],true]

これをPerlで実装したいんですが、Perlでどうやって書けばいいのかわからないのでそうじゃない形式で実装しようと思いました。

対話モードでない形式

ただし、対話モードでない形式*1だとエスケープが必要です。
これはgroonga document version1.0.6 の4.1.1.5. 引数 の項目にそれっぽい事が書いてあります。

標準入力からコマンド文字列を与える場合は、コマンド名と引数名と値は、空白( )で区切ります。空白や、記号「”’()」のうちいずれかを含む値を指定したい場合は、シングルクォート(‘)かダブルクォート(“)で値を囲みます。

こんな感じになるです

% groonga -n db/fuga.db 
>table_create --name Type --flags TABLE_HASH_KEY --key_type ShortText
>column_create --table Type --name number --type Int32
>column_create --table Type --name float --type Float
>column_create --table Type --name string --type ShortText
>column_create --table Type --name time --type Time
>shutdown
% groonga -d db/fuga.db
% groonga -c localhost 'load --table Type [{\"_key\":\"sample\",\"number\":12345,\"float\":42.19,\"string\":\"GROONGA\",\"time\":1234567890.12}]'

このエスケープ処理がなんかいやだ。
で、いろいろ試行錯誤した


こうなった

% groonga -n db/fuga.db 
table_create --name Type --flags TABLE_HASH_KEY --key_type ShortText
column_create --table Type --name number --type Int32
column_create --table Type --name float --type Float
column_create --table Type --name string --type ShortText
column_create --table Type --name time --type Time
shutdown
% groonga -d db/fuga.db
% /bin/echo 'load --table Type \
[{"_key":"sample","number":12345,"float":42.195,"string":"GROONGA","time":1234567890.12}]'  | groonga -c localhost
[[0,1294423618.38197,0.000296],1]

うーん。\がなんかいやなんだけど、これがないとだめらしい

% /bin/echo 'load --table Type [{"_key":"sample","number":12345,"float":42.195,"string":"GROONGA","time":1234567890.12}]'  | groonga -c localhost
[[-22,1294423803.15155,0.000979,"",[["","",0]]]]
  • 22,エラー

なんだろう。これでも行ける気がしないでもないけど。

うーん。対話モードでやればいいのかなー

なんとなくNet::SSHとかCache::Memcache::Fastとか参考になる気がしつつ、もっと読みやすいモジュールないかなー


まあ自分しか使わないし、素直に改行いれておけばいいかな。なんかgroongaにもrubyでのテストコードあったけど改行してあったし。

なんであそこで改行すればうまくいったのか、ということと対話形式をうまく記述する方法はどこだろう、という一人言でした。

*1:えっと、なんていうんですかね