LoginSignup
3
4

More than 5 years have passed since last update.

Groonga Cライブラリ テーブルのレコード参照

Last updated at Posted at 2014-10-11

前回の投稿で、テーブルの作成やオープン操作を解説しました。
今回は、一歩進んでテーブルに登録されているレコードのアクセス方法を紹介します。
レコードを一意に表す値がレコードIDで、これを取得できれば、
カラムに格納されている特定のデータを参照することが出来ます。

主キー値によるレコードID取得

grn_table_get() 関数を使います。

how_to_use_grn_table_get.c
 assert(grn_table_get(ctx, table, "test_record", strlen("test_record")) == record_id);

ちなみに、キー値がテキスト型以外の場合は char ポインタ型にキャストしましょう。

逆に、レコードIDから主キー値を取得したいときは grn_table_get_key() 関数を使います。

how_to_use_grn_table_get.c
  char keybuf[16];
  int keylen = grn_table_get_key(ctx, table, record_id, keybuf, 16);
  assert(keylen == strlen("test_record"));
  assert(strncmp("test_record", keybuf, keylen) == 0);

grn_table_get_key() 関数ですが、
指定された ID のレコードが見つからない場合は 0 を返します。
レコードが見つかった場合は、パラメータに指定されたバッファに主キー値をコピーして、
主キー値の長さを返却値として返します。(コピーした長さではありません。)
文字列の末尾に NULL を追加するような処理は行いませんので、
返却される文字列長を使って適宜処理してください。

こちらも同様に、キー値がテキスト型以外の場合は char ポインタ型にキャストして受け取りましょう。

テーブルカーソルによる巡回参照

特定のキー値やレコードIDを取得せずに、テーブルに含まれるレコードをなめたい場合には、
テーブルカーソルを使うことで実現可能です。
テーブルカーソルは、特定条件のレコードを特定の順番で参照できる機能です。

ちなみに、テーブルに存在するレコードは ID がすべて連番で揃っているという訳ではないので、
grn_table_size() で存在するレコードの総数を取得して、
レコードIDを 1 から順番になめるというアプローチは、
正しい結果が保障されませんのでご注意下さい。

テーブルカーソルのオープン

how_to_use_grn_table_get.c
  grn_table_cursor *table_cursor = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1,
                                                         GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING);

カーソルのオープンには grn_table_cursor_open() 関数を使います。
grn_table_cursor_open() 関数にはパラメータが複数ありますが、
今回の投稿では単純な巡回で必要になるものに絞って説明します。

groonga.h
GRN_API grn_table_cursor *grn_table_cursor_open(grn_ctx *ctx, grn_obj *table,
const void *min, unsigned int min_size,
const void *max, unsigned int max_size,
int offset, int limit, int flags);

min, min_size, max, max_size パラメータは、単純に巡回するだけであれば不要なので NULL や 0 を指定します。
offset パラメータに、カーソルの開始位置を指定します。
limit パラメータに、レコードの最大取得数を指定します。取得数の制限が不要であれば -1 を指定します。
flags パラメータに、GRN_CURSOR_* をフラグ指定して取り出すレコードを制限します。特に指定がなければ 0 でも構いません。フラグによってはサポートされるテーブルが限定されます。

  • GRN_CURSOR_BY_ID: レコードIDでソートして取り出す
  • GRN_CURSOR_BY_KEY: 主キー値でソートして取り出す(パトリシアトライ、ダブル配列トライでサポート)
  • GRN_CURSOR_ASCENDING: 昇順で取り出す
  • GRN_CURSOR_DESCENDING: 降順で取り出す

テーブルカーソルを進める

how_to_use_grn_table_get.c
  assert(grn_table_cursor_next(ctx, table_cursor) == record_id);
  // レコードの巡回が完了した
  assert(grn_table_cursor_next(ctx, table_cursor) == GRN_ID_NIL);

grn_table_cursor_next() 関数を使ってカーソルを次の位置に進めます。
そして、同時に次の位置のレコードIDを取得します。
ただし、巡回が完了している場合には GRN_ID_NIL が返されます。

注意点として、カーソルをオープン直後は現在位置は何も指しておりません。
現在位置を一つ目のレコードに進めるには、
grn_table_cursor_next() 関数を一度呼び出す必要があります。
grn_table_cursor_get_key() などの現在位置を参照する関数使う場合には、
気を付けましょう。

テーブルカーソルのクローズ

how_to_use_grn_table_get.c
  assert(grn_table_cursor_close(ctx, table_cursor) == GRN_SUCCESS);

grn_table_cursor_close() 関数を使います。
必ずしも巡回が完了している必要はありません。

後書き

以上です。
紹介した機能を利用したプログラムのソースコードを Gist にて公開しております。
投稿内で掲載しているサンプルコードは、このプログラムから切り出したものです。

how_to_use_grn_table_get.c

掲載している情報に関しましては、十分な検証を行っておりますが、
もし誤りがございましたら、コメントにてご指摘ください。

3
4
13

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4