Groongaプラグイン自作入門 - コマンド詳細編 - 2016-01-15 - ククログ

ククログ

株式会社クリアコード > ククログ > Groongaプラグイン自作入門 - コマンド詳細編

Groongaプラグイン自作入門 - コマンド詳細編

はじめに

Groongaのプラグイン自作入門では、プラグインの雛形を作成できるgrnplumというgemを使って実際に「hi」と出力するだけのgreetコマンドを作成しました。 今回は、このgreetコマンドを拡張しながら、コマンドについてもう少しだけ詳しくみていきます。 具体的には次の2つのことについてどうやったらいいのか、というのを説明します。

  • パラメータを受けとるには

  • 結果を返すには

パラメータを受けとるには

コマンドでは、通常何らかのパラメータを受け取ってその挙動をカスタマイズできるようにします。

これを実現するには、GRN_PLUGIN_REGISTERで、greetコマンドが受けつけるパラメータを宣言します。 例えば、foobarbazという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_opengrn_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_opengrn_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の機能拡張に興味がある人は参考にしてみてください。