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);
}