はじめに
Groongaのプラグイン自作入門では、プラグインの雛形を作成できるgrnplumというgemを使って実際に「hi」と出力するだけのgreetコマンドを作成しました。 今回は、このgreetコマンドを拡張しながら、コマンドについてもう少しだけ詳しくみていきます。 具体的には次の2つのことについてどうやったらいいのか、というのを説明します。
-
パラメータを受けとるには
-
結果を返すには
パラメータを受けとるには
コマンドでは、通常何らかのパラメータを受け取ってその挙動をカスタマイズできるようにします。
これを実現するには、GRN_PLUGIN_REGISTER
で、greetコマンドが受けつけるパラメータを宣言します。
例えば、foo
とbar
とbaz
という3つのパラメータを受けとることができるようにするには、次のようにgrn_plugin_expr_var_init
を呼びだして変数vars
を初期化し、grn_plugin_command_create
の引数として渡します。
grn_rc
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
{
grn_expr_var vars[3];
grn_plugin_expr_var_init(ctx, &vars[0], "foo", -1);
grn_plugin_expr_var_init(ctx, &vars[1], "bar", -1);
grn_plugin_expr_var_init(ctx, &vars[2], "baz", -1);
grn_plugin_command_create(ctx, "greet", -1, command_greet, 3, vars);
...
コマンドを実装するcommand_greet
では、grn_plugin_proc_get_var
を使って値を受けとります。
static grn_obj *
command_greet(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
grn_obj *var;
var = grn_plugin_proc_get_var(ctx, user_data, "foo", -1);
if (GRN_TEXT_LEN(var) > 0) {
/* fooが指定されているとき */
}
}
例えば、http://localhost:10041/d/greet?foo=1
というURL経由でGroonga HTTPサーバーへとアクセスしたとき、GRN_TEXT_VALUE
を使って変数var
の値を取りだすと1
が得られます。
結果を返すには
コマンドの目的とする処理が終わったら、何らかの整形した結果を返すことでしょう。
Groongaでは、出力形式にあるように
[HEADER, BODY]
HEADER部分と、BODY部分からなる配列で構成されています。前回の記事では、BODY部分が"hi"だったわけです。
これをもう少し複雑な構造をもった形で出力するにはどうすればいいのでしょうか。
BODY部分では、selectコマンドのようにN件のデータを配列[...]
で表現するものと、statusコマンドのように、ハッシュ{...}
で表現するものとがあります。
それぞれどのようにしたらいいか説明します。
結果を配列で返すには
配列で結果を返すには、次のようにgrn_output_array_open
とgrn_ctx_output_array_close
をペアで使います。
grn_ctx_output_array_open(ctx, "name", 2);
grn_ctx_output_int32(ctx, 1);
grn_ctx_output_int32(ctx, 2);
grn_ctx_output_array_close(ctx);
grn_ctx_output_array_open
の第3引数は何個の要素をもつかというのを指定します。
上記の例では、int32型の値「1」と「2」を出力しているので、BODY部分の結果は[1,2]
となります。
結果をハッシュで返すには
ハッシュで結果を返すには、次のようにgrn_output_map_open
とgrn_output_map_close
をペアで使います。
grn_ctx_output_map_open(ctx, "name", 2);
grn_ctx_output_cstr(ctx, "key1");
grn_ctx_output_int32(ctx, 1);
grn_ctx_output_cstr(ctx, "key2");
grn_ctx_output_int32(ctx, 2);
grn_ctx_output_map_close(ctx);
grn_output_map_open
の第3引数も何個の要素をもつかというのを指定します。
上記の例では、「key1」の値が「1」、「key2」の値が「2」であるハッシュを出力しているので、BODY部分の結果は{"key1":1, "key2":2}
となります。
まとめ
今回は、Groongaプラグイン自作入門として、コマンドの実装をもう少し詳しく紹介してみました。 Groongaの機能拡張に興味がある人は参考にしてみてください。