LoginSignup
3
4

More than 5 years have passed since last update.

Groonga Cライブラリ grn_objの操作

Last updated at Posted at 2014-09-26

grn_obj とは・・・

Groonga における汎用オブジェクトです。
型を指定してあげることで、その型に応じたデータを持たせることができます。
v4.0.5 時点で数値型、文字列型、時間型、地理情報型が用意されており、
主にデータベースに値を渡す際の仲介バッファとして用います。

操作関数の概要

型ごとに使う関数は異なりますが、似通ったインタフェイスを持ちます。

初期化

grn_obj オブジェクトを使うには、初期化が必要になります。

GRN_*_INIT(obj,flags)

obj パラメータに、初期化したい grn_obj オブジェクトを指定します。
flags パラメータは、基本的には指定不要ですので、 0 を指定しましょう。

値のセット

GRN_*_SET(ctx,obj,val)

ctx パラメータに、grn_ctx_open()などで取得したコンテキストオブジェクトを指定します。
obj パラメータに、値をセットしたい grn_obj オブジェクトを指定します。
val パラメータに、セットしたい値を指定します。

値の参照

GRN_*_VALUE(obj)

obj パラメータに、値を参照したい grn_obj オブジェクトを指定します。

解放処理

grn_objオブジェクトを使い終わったら、解放してあげましょう。

void grn_obj_unlink(grn_ctx *ctx, grn_obj *obj);

ctx パラメータに、grn_ctx_open()などで取得したコンテキストオブジェクトを指定します。
obj パラメータに、解放したい grn_obj オブジェクトを指定します。

数値型、真偽値型

  • INT8
  • UINT8
  • INT16
  • UINT16
  • INT32
  • UINT32
  • INT64
  • UINT64
  • BOOL

それでは grn_obj を使ってみましょう!
数値型は最もシンプルです。
数値型は v4.0.5 時点で9種類ありますが、 UINT32 型を使って、
初期化、値のセット、値の参照、解放までを行います。

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <groonga/groonga.h>

int main (int argc, char **argv) {
  // ライブラリを初期化
  assert(grn_init() == GRN_SUCCESS);

  // コンテキストを取得
  grn_ctx *ctx;
  ctx = grn_ctx_open(0);
  assert(ctx != NULL);

  // 数値型を操作
  grn_obj intobj;
  GRN_UINT32_INIT(&intobj, 0);
  GRN_UINT32_SET(ctx, &intobj, 100);
  assert(GRN_UINT32_VALUE(&intobj) == 100);
  grn_obj_unlink(ctx, &intobj);

文字列型

  • SHORT_TEXT
  • TEXT
  • LONG_TEXT

最も使う機会の多いであろう文字列型です。
文字列型は v4.0.5 時点で3種類ありますが、ここでは SHORT_TEXT 型を使います。
数値型との違いですが、SET 系の関数を使うことで文字列をセットできます。

  • GRN_TEXT_SET(ctx,obj,str,len)
  • GRN_TEXT_SETS(ctx,obj,str)

GRN_TEXT_VALUE(obj)で文字列の参照、GRN_TEXT_LEN(obj)で文字列長を取得できます。

  // 文字列型を操作
  grn_obj textobj;
  GRN_SHORT_TEXT_INIT(&textobj, 0);
  GRN_TEXT_SETS(ctx, &textobj, "qiita");
  assert(strncmp(GRN_TEXT_VALUE(&textobj), "qiita", GRN_TEXT_LEN(&textobj)) == 0);

PUT系の関数を使うことで、文字列を逐次的に足していくことも可能です。

  • GRN_TEXT_PUT(ctx,obj,str,len)
  • GRN_TEXT_PUTC(ctx,obj,c)
  • GRN_TEXT_PUTS(ctx,obj,str)

追加されたサイズに応じて内部バッファは伸長されるので、ストリームのように文字長を意識せずに使うことができます。

  GRN_BULK_REWIND(&textobj);
  for (int i = 0; i < 5; ++i) {
    GRN_TEXT_PUTC(ctx, &textobj, 'a');
  }
  assert(strncmp(GRN_TEXT_VALUE(&textobj), "aaaaa", GRN_TEXT_LEN(&textobj)) == 0);
  grn_obj_unlink(ctx, &textobj);

さらに、参照渡しも可能です。

  • GRN_TEXT_SET_REF(obj,str,len)

但し GRN_OBJ_DO_SHALLOW_COPY フラグを指定して、grn_objオブジェクトを初期化する必要があります。

  GRN_SHORT_TEXT_INIT(&textobj, GRN_OBJ_DO_SHALLOW_COPY);
  static const char title[] = "qiita";
  GRN_TEXT_SET_REF(&textobj, title, strlen(title));
  assert(strncmp(GRN_TEXT_VALUE(&textobj), "qiita", GRN_TEXT_LEN(&textobj)) == 0);
  grn_obj_unlink(ctx, &textobj);

時間型

  • TIME

時間型は、内部的には数値型の INT64 と同じですが、
パッキング用のユーティリティ関数が用意されています。

  • GRN_TIME_PACK(sec, usec)
  • GRN_TIME_UNPACK(time_value, sec, usec)
  // 時間型を操作
  grn_obj timeobj;
  GRN_TIME_INIT(&timeobj, 0);
  GRN_TIME_SET(ctx, &timeobj, GRN_TIME_PACK(30, 5000));
  int sec, usec;
  GRN_TIME_UNPACK(GRN_TIME_VALUE(&timeobj), sec, usec);
  assert(sec == 30);
  assert(usec == 5000);
  grn_obj_unlink(ctx, &timeobj);

地理情報型

  • TOKYO_GEO_POINT
  • WGS84_GEO_POINT

最後に地理情報型です。
地理情報検索の操作に用います。

  // 地理情報型を操作
  grn_obj geoobj;
  GRN_TOKYO_GEO_POINT_INIT(&geoobj, 0);
  GRN_GEO_POINT_SET(ctx, &geoobj, 128487316, 502920929);
  int latitude;
  int longitude;
  GRN_GEO_POINT_VALUE(geoobj, latitude, longitude);
  assert(latitude == 128487316);
  assert(longitude == 502920929);
  grn_obj_unlink(ctx, &geoobj);

  // コンテキストを破棄
  assert(grn_ctx_close(ctx) == GRN_SUCCESS);

  // ライブラリの終了処理
  assert(grn_fin() == GRN_SUCCESS);
}
3
4
5

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