groonga 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/NEWS.ja.rdoc +11 -0
  2. data/NEWS.rdoc +11 -0
  3. data/README.ja.rdoc +4 -3
  4. data/README.rdoc +4 -3
  5. data/Rakefile +1 -1
  6. data/TUTORIAL.ja.rdoc +168 -44
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-small-many-items.rb +156 -0
  9. data/benchmark/write-small-many-items.rb +145 -0
  10. data/example/bookmark.rb +68 -20
  11. data/ext/rb-grn-array-cursor.c +8 -0
  12. data/ext/rb-grn-array.c +40 -11
  13. data/ext/rb-grn-column.c +38 -209
  14. data/ext/rb-grn-context.c +203 -56
  15. data/ext/rb-grn-database.c +119 -5
  16. data/ext/rb-grn-encoding-support.c +64 -0
  17. data/ext/rb-grn-encoding.c +58 -1
  18. data/ext/rb-grn-fix-size-column.c +220 -0
  19. data/ext/rb-grn-hash-cursor.c +8 -0
  20. data/ext/rb-grn-hash.c +244 -2
  21. data/ext/rb-grn-index-column.c +474 -0
  22. data/ext/rb-grn-object.c +143 -265
  23. data/ext/rb-grn-patricia-trie.c +148 -2
  24. data/ext/rb-grn-query.c +5 -3
  25. data/ext/rb-grn-record.c +3 -2
  26. data/ext/rb-grn-snippet.c +5 -3
  27. data/ext/rb-grn-table-cursor-key-support.c +3 -3
  28. data/ext/rb-grn-table-cursor.c +106 -112
  29. data/ext/rb-grn-table-key-support.c +220 -118
  30. data/ext/rb-grn-table.c +336 -80
  31. data/ext/rb-grn-type.c +5 -4
  32. data/ext/rb-grn-utils.c +62 -63
  33. data/ext/rb-grn.h +215 -14
  34. data/ext/rb-groonga.c +7 -16
  35. data/extconf.rb +3 -1
  36. data/html/favicon.ico +0 -0
  37. data/html/favicon.xcf +0 -0
  38. data/html/index.html +1 -7
  39. data/lib/groonga/record.rb +6 -1
  40. data/test/groonga-test-utils.rb +1 -0
  41. data/test/test-array.rb +81 -0
  42. data/test/test-column.rb +22 -12
  43. data/test/test-context.rb +1 -29
  44. data/test/test-database.rb +30 -0
  45. data/test/test-hash.rb +194 -0
  46. data/test/test-index-column.rb +57 -0
  47. data/test/test-patricia-trie.rb +82 -0
  48. data/test/test-record.rb +10 -10
  49. data/test/test-table.rb +37 -130
  50. data/test/test-type.rb +4 -3
  51. metadata +15 -4
  52. data/benchmark/small-many-items.rb +0 -175
@@ -18,14 +18,156 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object) (RVAL2GRNTABLE(object))
21
+ #define SELF(object) ((RbGrnTableKeySupport *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_cGrnPatriciaTrie;
24
24
 
25
25
  static VALUE
26
26
  rb_grn_patricia_trie_s_create (int argc, VALUE *argv, VALUE self)
27
27
  {
28
- return rb_grn_table_s_create(argc, argv, self, GRN_TABLE_PAT_KEY);
28
+ grn_ctx *context;
29
+ grn_obj *key_type = NULL, *table;
30
+ const char *name = NULL, *path = NULL;
31
+ unsigned name_size = 0, value_size = 0;
32
+ grn_obj_flags flags = GRN_TABLE_PAT_KEY;
33
+ VALUE rb_table;
34
+ VALUE options, rb_context, rb_name, rb_path, rb_persistent;
35
+ VALUE rb_key_normalize, rb_key_with_sis, rb_key_type, rb_value_size;
36
+ VALUE rb_default_tokenizer;
37
+
38
+ rb_scan_args(argc, argv, "01", &options);
39
+
40
+ rb_grn_scan_options(options,
41
+ "context", &rb_context,
42
+ "name", &rb_name,
43
+ "path", &rb_path,
44
+ "persistent", &rb_persistent,
45
+ "key_normalize", &rb_key_normalize,
46
+ "key_with_sis", &rb_key_with_sis,
47
+ "key_type", &rb_key_type,
48
+ "value_size", &rb_value_size,
49
+ "default_tokenizer", &rb_default_tokenizer,
50
+ NULL);
51
+
52
+ context = rb_grn_context_ensure(&rb_context);
53
+
54
+ if (!NIL_P(rb_name)) {
55
+ name = StringValuePtr(rb_name);
56
+ name_size = RSTRING_LEN(rb_name);
57
+ }
58
+
59
+ if (!NIL_P(rb_path)) {
60
+ path = StringValueCStr(rb_path);
61
+ flags |= GRN_OBJ_PERSISTENT;
62
+ }
63
+
64
+ if (RVAL2CBOOL(rb_persistent))
65
+ flags |= GRN_OBJ_PERSISTENT;
66
+
67
+ if (RVAL2CBOOL(rb_key_normalize))
68
+ flags |= GRN_OBJ_KEY_NORMALIZE;
69
+
70
+ if (RVAL2CBOOL(rb_key_with_sis))
71
+ flags |= GRN_OBJ_KEY_WITH_SIS;
72
+
73
+ if (NIL_P(rb_key_type)) {
74
+ flags |= GRN_OBJ_KEY_VAR_SIZE;
75
+ } else {
76
+ key_type = RVAL2GRNOBJECT(rb_key_type, &context);
77
+ }
78
+
79
+ if (!NIL_P(rb_value_size))
80
+ value_size = NUM2UINT(rb_value_size);
81
+
82
+ table = grn_table_create(context, name, name_size, path,
83
+ flags, key_type, value_size);
84
+ if (!table)
85
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
86
+ rb_table = rb_grn_table_key_support_alloc(self);
87
+ rb_grn_table_key_support_assign(rb_table, rb_context, context, table,
88
+ RB_GRN_TRUE);
89
+ rb_grn_context_check(context, rb_table);
90
+
91
+ if (!NIL_P(rb_default_tokenizer))
92
+ rb_funcall(rb_table, rb_intern("default_tokenizer="), 1,
93
+ rb_default_tokenizer);
94
+
95
+ if (rb_block_given_p())
96
+ return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
97
+ else
98
+ return rb_table;
99
+ }
100
+
101
+ static VALUE
102
+ rb_grn_patricia_trie_search (int argc, VALUE *argv, VALUE self)
103
+ {
104
+ grn_rc rc;
105
+ grn_ctx *context;
106
+ grn_obj *table;
107
+ grn_id domain_id;
108
+ grn_obj *key, *domain, *result;
109
+ grn_sel_operator operator;
110
+ grn_search_optarg search_options;
111
+ rb_grn_boolean search_options_is_set = RB_GRN_TRUE;
112
+ VALUE rb_key, options, rb_result, rb_operator, rb_type;
113
+
114
+ rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
115
+ &key, &domain_id, &domain,
116
+ NULL, NULL, NULL);
117
+
118
+ rb_scan_args(argc, argv, "11", &rb_key, &options);
119
+
120
+ RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);
121
+
122
+ rb_grn_scan_options(options,
123
+ "result", &rb_result,
124
+ "operator", &rb_operator,
125
+ "type", &rb_type,
126
+ NULL);
127
+
128
+ if (NIL_P(rb_result)) {
129
+ result = grn_table_create(context, NULL, 0, NULL,
130
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
131
+ table, 0);
132
+ rb_grn_context_check(context, self);
133
+ rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
134
+ } else {
135
+ result = RVAL2GRNOBJECT(rb_result, &context);
136
+ }
137
+
138
+ operator = RVAL2GRNSELECTOPERATOR(rb_operator);
139
+
140
+ search_options.flags = 0;
141
+ if (NIL_P(rb_type)) {
142
+ search_options_is_set = RB_GRN_FALSE;
143
+ } else if (rb_grn_equal_option(rb_type, "exact")) {
144
+ search_options.flags |= GRN_SEARCH_EXACT;
145
+ } else if (rb_grn_equal_option(rb_type, "longest_common_prefix") ||
146
+ rb_grn_equal_option(rb_type, "longest-common-prefix")) {
147
+ search_options.flags |= GRN_SEARCH_LCP;
148
+ } else if (rb_grn_equal_option(rb_type, "suffix")) {
149
+ search_options.flags |= GRN_SEARCH_SUFFIX;
150
+ } else if (rb_grn_equal_option(rb_type, "prefix")) {
151
+ search_options.flags |= GRN_SEARCH_PREFIX;
152
+ } else if (rb_grn_equal_option(rb_type, "term_extract") ||
153
+ rb_grn_equal_option(rb_type, "term-extract")) {
154
+ search_options.flags |= GRN_SEARCH_TERM_EXTRACT;
155
+ } else if (rb_grn_equal_option(rb_type, "suffix")) {
156
+ search_options.flags |= GRN_SEARCH_SUFFIX;
157
+ } else {
158
+ rb_raise(rb_eArgError,
159
+ "search type should be one of "
160
+ "[nil, :exact, :longest_common_prefix, :suffix, "
161
+ ":prefix, :term_extract]: %s",
162
+ rb_grn_inspect(rb_type));
163
+ }
164
+
165
+ rc = grn_obj_search(context, table, key,
166
+ result, operator,
167
+ search_options_is_set ? &search_options : NULL);
168
+ rb_grn_rc_check(rc, self);
169
+
170
+ return rb_result;
29
171
  }
30
172
 
31
173
  void
@@ -33,8 +175,12 @@ rb_grn_init_patricia_trie (VALUE mGrn)
33
175
  {
34
176
  rb_cGrnPatriciaTrie =
35
177
  rb_define_class_under(mGrn, "PatriciaTrie", rb_cGrnTable);
178
+ rb_define_alloc_func(rb_cGrnPatriciaTrie, rb_grn_table_key_support_alloc);
36
179
 
37
180
  rb_include_module(rb_cGrnPatriciaTrie, rb_mGrnTableKeySupport);
38
181
  rb_define_singleton_method(rb_cGrnPatriciaTrie, "create",
39
182
  rb_grn_patricia_trie_s_create, -1);
183
+
184
+ rb_define_method(rb_cGrnPatriciaTrie, "search",
185
+ rb_grn_patricia_trie_search, -1);
40
186
  }
data/ext/rb-grn-query.c CHANGED
@@ -60,8 +60,8 @@ rb_rb_grn_query_free (void *object)
60
60
  {
61
61
  RbGrnQuery *rb_grn_query = object;
62
62
 
63
- if (rb_grn_query->context && rb_grn_query->query && rb_grn_query->owner)
64
- /* grn_query_close(rb_grn_query->context, rb_grn_query->query) */;
63
+ if (rb_grn_query->owner && rb_grn_query->context && rb_grn_query->query)
64
+ grn_query_close(rb_grn_query->context, rb_grn_query->query);
65
65
 
66
66
  xfree(object);
67
67
  }
@@ -143,7 +143,7 @@ rb_grn_query_initialize (int argc, VALUE *argv, VALUE self)
143
143
  "max_expressions", &rb_max_expressions,
144
144
  NULL);
145
145
 
146
- context = rb_grn_context_ensure(rb_context);
146
+ context = rb_grn_context_ensure(&rb_context);
147
147
 
148
148
  default_operator = RVAL2GRNSELECTOPERATOR(rb_default_operator);
149
149
 
@@ -160,6 +160,8 @@ rb_grn_query_initialize (int argc, VALUE *argv, VALUE self)
160
160
  rb_grn_query->query = query;
161
161
  rb_grn_query->owner = RB_GRN_TRUE;
162
162
 
163
+ rb_iv_set(self, "context", rb_context);
164
+
163
165
  return Qnil;
164
166
  }
165
167
 
data/ext/rb-grn-record.c CHANGED
@@ -21,9 +21,10 @@
21
21
  VALUE rb_cGrnRecord;
22
22
 
23
23
  VALUE
24
- rb_grn_record_new (VALUE table, grn_id id)
24
+ rb_grn_record_new (VALUE table, grn_id id, VALUE values)
25
25
  {
26
- return rb_funcall(rb_cGrnRecord, rb_intern("new"), 2, table, UINT2NUM(id));
26
+ return rb_funcall(rb_cGrnRecord, rb_intern("new"), 3,
27
+ table, UINT2NUM(id), values);
27
28
  }
28
29
 
29
30
  void
data/ext/rb-grn-snippet.c CHANGED
@@ -64,8 +64,8 @@ rb_rb_grn_snippet_free (void *object)
64
64
  {
65
65
  RbGrnSnippet *rb_grn_snippet = object;
66
66
 
67
- if (rb_grn_snippet->context && rb_grn_snippet->snippet &&
68
- rb_grn_snippet->owner)
67
+ if (rb_grn_snippet->owner &&
68
+ rb_grn_snippet->context && rb_grn_snippet->snippet)
69
69
  grn_snip_close(rb_grn_snippet->context,
70
70
  rb_grn_snippet->snippet);
71
71
 
@@ -127,7 +127,7 @@ rb_grn_snippet_initialize (int argc, VALUE *argv, VALUE self)
127
127
  "html_escape", &rb_html_escape,
128
128
  NULL);
129
129
 
130
- context = rb_grn_context_ensure(rb_context);
130
+ context = rb_grn_context_ensure(&rb_context);
131
131
 
132
132
  if (RVAL2CBOOL(rb_normalize))
133
133
  flags |= GRN_SNIP_NORMALIZE;
@@ -165,6 +165,8 @@ rb_grn_snippet_initialize (int argc, VALUE *argv, VALUE self)
165
165
  rb_grn_snippet->snippet = snippet;
166
166
  rb_grn_snippet->owner = RB_GRN_TRUE;
167
167
 
168
+ rb_iv_set(self, "context", rb_context);
169
+
168
170
  return Qnil;
169
171
  }
170
172
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object) (RVAL2GRNTABLECURSOR(object))
21
+ #define SELF(object) ((RbGrnTableCursor *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_mGrnTableCursorKeySupport;
24
24
 
@@ -29,8 +29,8 @@ rb_grn_table_cursor_get_key (VALUE self)
29
29
  grn_ctx *context;
30
30
  grn_table_cursor *cursor;
31
31
 
32
- context = rb_grn_table_cursor_ensure_context(self, Qnil);
33
- cursor = SELF(self);
32
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
33
+ NULL, NULL, NULL, NULL);
34
34
  if (context && cursor) {
35
35
  void *key;
36
36
  int key_size;
@@ -18,53 +18,18 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object) (rb_rb_grn_table_cursor_from_ruby_object(object))
22
-
23
- typedef struct _RbGrnTableCursor RbGrnTableCursor;
24
- struct _RbGrnTableCursor
25
- {
26
- grn_ctx *context;
27
- grn_table_cursor *cursor;
28
- rb_grn_boolean owner;
29
- };
21
+ #define SELF(object) ((RbGrnTableCursor *)DATA_PTR(object))
30
22
 
31
23
  VALUE rb_cGrnTableCursor;
32
24
 
33
- static RbGrnTableCursor *
34
- rb_rb_grn_table_cursor_from_ruby_object (VALUE object)
25
+ grn_table_cursor *
26
+ rb_grn_table_cursor_from_ruby_object (VALUE object, grn_ctx **context)
35
27
  {
36
- RbGrnTableCursor *rb_grn_table_cursor;
37
-
38
28
  if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnTableCursor))) {
39
29
  rb_raise(rb_eTypeError, "not a groonga table cursor");
40
30
  }
41
31
 
42
- Data_Get_Struct(object, RbGrnTableCursor, rb_grn_table_cursor);
43
- if (!rb_grn_table_cursor)
44
- rb_raise(rb_eGrnError, "groonga table cursor is NULL");
45
-
46
- return rb_grn_table_cursor;
47
- }
48
-
49
- grn_table_cursor *
50
- rb_grn_table_cursor_from_ruby_object (VALUE object)
51
- {
52
- if (NIL_P(object))
53
- return NULL;
54
-
55
- return SELF(object)->cursor;
56
- }
57
-
58
- static void
59
- rb_rb_grn_table_cursor_free (void *object)
60
- {
61
- RbGrnTableCursor *rb_grn_table_cursor = object;
62
-
63
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor &&
64
- rb_grn_table_cursor->owner)
65
- grn_table_cursor_close(rb_grn_table_cursor->context,
66
- rb_grn_table_cursor->cursor);
67
- xfree(object);
32
+ return RVAL2GRNOBJECT(object, context);
68
33
  }
69
34
 
70
35
  VALUE
@@ -94,72 +59,98 @@ rb_grn_table_cursor_to_ruby_class (grn_obj *object)
94
59
 
95
60
  VALUE
96
61
  rb_grn_table_cursor_to_ruby_object (VALUE klass, grn_ctx *context,
97
- grn_table_cursor *cursor)
62
+ grn_table_cursor *cursor,
63
+ rb_grn_boolean owner)
98
64
  {
99
- RbGrnTableCursor *rb_grn_table_cursor;
65
+ if (NIL_P(klass))
66
+ klass = rb_grn_table_cursor_to_ruby_class(cursor);
67
+ return GRNOBJECT2RVAL(klass, context, cursor, owner);
68
+ }
100
69
 
101
- if (!cursor)
102
- return Qnil;
70
+ void
71
+ rb_grn_table_cursor_unbind (RbGrnTableCursor *rb_grn_table_cursor)
72
+ {
73
+ RbGrnObject *rb_grn_object;
103
74
 
104
- rb_grn_table_cursor = ALLOC(RbGrnTableCursor);
105
- rb_grn_table_cursor->context = context;
106
- rb_grn_table_cursor->cursor = cursor;
107
- rb_grn_table_cursor->owner = RB_GRN_TRUE; /* FIXME */
75
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_table_cursor);
76
+ rb_grn_object_unbind(rb_grn_object);
77
+ }
108
78
 
109
- if (NIL_P(klass))
110
- klass = GRNTABLECURSOR2RCLASS(cursor);
79
+ static void
80
+ rb_grn_table_cursor_free (void *object)
81
+ {
82
+ RbGrnTableCursor *rb_grn_table_cursor = object;
111
83
 
112
- return Data_Wrap_Struct(klass, NULL,
113
- rb_rb_grn_table_cursor_free, rb_grn_table_cursor);
84
+ rb_grn_table_cursor_unbind(rb_grn_table_cursor);
85
+ xfree(rb_grn_table_cursor);
114
86
  }
115
87
 
116
- static VALUE
88
+ VALUE
117
89
  rb_grn_table_cursor_alloc (VALUE klass)
118
90
  {
119
- return Data_Wrap_Struct(klass, NULL, rb_rb_grn_table_cursor_free, NULL);
91
+ return Data_Wrap_Struct(klass, NULL, rb_grn_table_cursor_free, NULL);
120
92
  }
121
93
 
122
- grn_ctx *
123
- rb_grn_table_cursor_ensure_context (VALUE cursor, VALUE rb_context)
94
+ void
95
+ rb_grn_table_cursor_bind (RbGrnTableCursor *rb_grn_table_cursor,
96
+ grn_ctx *context, grn_table_cursor *cursor,
97
+ rb_grn_boolean owner)
124
98
  {
125
- if (NIL_P(rb_context)) {
126
- RbGrnTableCursor *rb_grn_table_cursor;
127
-
128
- rb_grn_table_cursor = SELF(cursor);
129
- if (rb_grn_table_cursor && rb_grn_table_cursor->context)
130
- return rb_grn_table_cursor->context;
131
- }
99
+ RbGrnObject *rb_grn_object;
132
100
 
133
- return rb_grn_context_ensure(rb_context);
101
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_table_cursor);
102
+ rb_grn_object_bind(rb_grn_object, context, cursor, owner);
103
+ rb_grn_object->unbind = RB_GRN_UNBIND_FUNCTION(rb_grn_table_cursor_unbind);
134
104
  }
135
105
 
136
- VALUE
137
- rb_grn_table_cursor_close (VALUE self)
106
+ void
107
+ rb_grn_table_cursor_assign (VALUE self, VALUE rb_context,
108
+ grn_ctx *context, grn_table_cursor *cursor,
109
+ rb_grn_boolean owner)
138
110
  {
139
111
  RbGrnTableCursor *rb_grn_table_cursor;
140
112
 
141
- rb_grn_table_cursor = SELF(self);
142
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor) {
143
- grn_rc rc = GRN_SUCCESS;
113
+ rb_grn_table_cursor = ALLOC(RbGrnTableCursor);
114
+ DATA_PTR(self) = rb_grn_table_cursor;
115
+ rb_grn_table_cursor_bind(rb_grn_table_cursor, context, cursor, owner);
144
116
 
145
- if (rb_grn_table_cursor->owner)
146
- rc = grn_table_cursor_close(rb_grn_table_cursor->context,
147
- rb_grn_table_cursor->cursor);
148
- rb_grn_table_cursor->context = NULL;
149
- rb_grn_table_cursor->cursor = NULL;
150
- rb_grn_table_cursor->owner = RB_GRN_FALSE;
151
- rb_grn_rc_check(rc, self);
152
- }
117
+ rb_iv_set(self, "context", rb_context);
118
+ }
119
+
120
+ void
121
+ rb_grn_table_cursor_deconstruct (RbGrnTableCursor *rb_grn_table_cursor,
122
+ grn_table_cursor **cursor,
123
+ grn_ctx **context,
124
+ grn_id *domain_id,
125
+ grn_obj **domain,
126
+ grn_id *range_id,
127
+ grn_obj **range)
128
+ {
129
+ RbGrnObject *rb_grn_object;
130
+
131
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_table_cursor);
132
+ rb_grn_object_deconstruct(rb_grn_object, cursor, context,
133
+ domain_id, domain,
134
+ range_id, range);
135
+ }
136
+
137
+ VALUE
138
+ rb_grn_table_cursor_close (VALUE self)
139
+ {
140
+ rb_grn_table_cursor_unbind(SELF(self));
153
141
  return Qnil;
154
142
  }
155
143
 
156
144
  static VALUE
157
145
  rb_grn_table_cursor_closed_p (VALUE self)
158
146
  {
159
- RbGrnTableCursor *rb_grn_table_cursor;
147
+ grn_table_cursor *cursor;
148
+ grn_ctx *context;
160
149
 
161
- rb_grn_table_cursor = SELF(self);
162
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor)
150
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
151
+ NULL, NULL, NULL, NULL);
152
+
153
+ if (context && cursor)
163
154
  return Qfalse;
164
155
  else
165
156
  return Qtrue;
@@ -168,17 +159,17 @@ rb_grn_table_cursor_closed_p (VALUE self)
168
159
  static VALUE
169
160
  rb_grn_table_cursor_get_value (VALUE self)
170
161
  {
162
+ grn_ctx *context;
163
+ grn_table_cursor *cursor;
171
164
  VALUE rb_value = Qnil;
172
- RbGrnTableCursor *rb_grn_table_cursor;
173
165
 
174
- rb_grn_table_cursor = SELF(self);
175
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor) {
166
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
167
+ NULL, NULL, NULL, NULL);
168
+ if (context && cursor) {
176
169
  int n;
177
170
  void *value;
178
171
 
179
- n = grn_table_cursor_get_value(rb_grn_table_cursor->context,
180
- rb_grn_table_cursor->cursor,
181
- &value);
172
+ n = grn_table_cursor_get_value(context, cursor, &value);
182
173
  rb_value = rb_str_new(value, n);
183
174
  }
184
175
 
@@ -188,15 +179,18 @@ rb_grn_table_cursor_get_value (VALUE self)
188
179
  static VALUE
189
180
  rb_grn_table_cursor_set_value (VALUE self, VALUE value)
190
181
  {
191
- RbGrnTableCursor *rb_grn_table_cursor;
182
+ grn_ctx *context;
183
+ grn_table_cursor *cursor;
192
184
 
193
- rb_grn_table_cursor = SELF(self);
194
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor) {
185
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
186
+ NULL, NULL, NULL, NULL);
187
+ if (context && cursor) {
195
188
  grn_rc rc;
196
189
 
197
- rc = grn_table_cursor_set_value(rb_grn_table_cursor->context,
198
- rb_grn_table_cursor->cursor,
199
- StringValuePtr(value), GRN_OBJ_SET);
190
+ rc = grn_table_cursor_set_value(context,
191
+ cursor,
192
+ StringValuePtr(value),
193
+ GRN_OBJ_SET);
200
194
  rb_grn_rc_check(rc, self);
201
195
  }
202
196
 
@@ -206,14 +200,15 @@ rb_grn_table_cursor_set_value (VALUE self, VALUE value)
206
200
  static VALUE
207
201
  rb_grn_table_cursor_delete (VALUE self)
208
202
  {
209
- RbGrnTableCursor *rb_grn_table_cursor;
203
+ grn_ctx *context;
204
+ grn_table_cursor *cursor;
210
205
 
211
- rb_grn_table_cursor = SELF(self);
212
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor) {
206
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
207
+ NULL, NULL, NULL, NULL);
208
+ if (context && cursor) {
213
209
  grn_rc rc;
214
210
 
215
- rc = grn_table_cursor_delete(rb_grn_table_cursor->context,
216
- rb_grn_table_cursor->cursor);
211
+ rc = grn_table_cursor_delete(context, cursor);
217
212
  rb_grn_rc_check(rc, self);
218
213
  }
219
214
 
@@ -224,16 +219,18 @@ static VALUE
224
219
  rb_grn_table_cursor_next (VALUE self)
225
220
  {
226
221
  VALUE rb_record = Qnil;
227
- RbGrnTableCursor *rb_grn_table_cursor;
222
+ grn_ctx *context;
223
+ grn_table_cursor *cursor;
228
224
 
229
- rb_grn_table_cursor = SELF(self);
230
- if (rb_grn_table_cursor->context && rb_grn_table_cursor->cursor) {
225
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
226
+ NULL, NULL, NULL, NULL);
227
+ if (context && cursor) {
231
228
  grn_id record_id;
232
229
 
233
- record_id = grn_table_cursor_next(rb_grn_table_cursor->context,
234
- rb_grn_table_cursor->cursor);
230
+ record_id = grn_table_cursor_next(context, cursor);
235
231
  if (record_id != GRN_ID_NIL) /* FIXME: use grn_table_cursor_table */
236
- rb_record = rb_grn_record_new(rb_iv_get(self, "@table"), record_id);
232
+ rb_record = rb_grn_record_new(rb_iv_get(self, "@table"),
233
+ record_id, Qnil);
237
234
  }
238
235
 
239
236
  return rb_record;
@@ -243,20 +240,17 @@ static VALUE
243
240
  rb_grn_table_cursor_each (VALUE self)
244
241
  {
245
242
  grn_id record_id;
246
- RbGrnTableCursor *rb_grn_table_cursor;
247
243
  grn_ctx *context;
248
244
  grn_table_cursor *cursor;
249
245
 
250
- rb_grn_table_cursor = SELF(self);
251
- if (!rb_grn_table_cursor->context)
252
- return Qnil;
253
- if (!rb_grn_table_cursor->cursor)
254
- return Qnil;
246
+ rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
247
+ NULL, NULL, NULL, NULL);
255
248
 
256
- context = rb_grn_table_cursor->context;
257
- cursor = rb_grn_table_cursor->cursor;
258
- while ((record_id = grn_table_cursor_next(context, cursor))) {
259
- rb_yield(rb_grn_record_new(rb_iv_get(self, "@table"), record_id));
249
+ if (context && cursor) {
250
+ while ((record_id = grn_table_cursor_next(context, cursor))) {
251
+ rb_yield(rb_grn_record_new(rb_iv_get(self, "@table"),
252
+ record_id, Qnil));
253
+ }
260
254
  }
261
255
 
262
256
  return Qnil;