groonga 0.0.7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/NEWS.ja.rdoc +56 -0
  2. data/NEWS.rdoc +58 -0
  3. data/Rakefile +2 -3
  4. data/benchmark/read-write-many-small-items.rb +16 -32
  5. data/benchmark/write-many-small-items.rb +14 -28
  6. data/example/bookmark.rb +19 -17
  7. data/example/index-html.rb +11 -1
  8. data/example/search/config.ru +14 -9
  9. data/ext/rb-grn-array.c +6 -6
  10. data/ext/rb-grn-column.c +348 -18
  11. data/ext/rb-grn-context.c +8 -4
  12. data/ext/rb-grn-database.c +6 -7
  13. data/ext/rb-grn-exception.c +101 -5
  14. data/ext/rb-grn-expression.c +206 -23
  15. data/ext/rb-grn-fix-size-column.c +6 -39
  16. data/ext/rb-grn-hash.c +24 -24
  17. data/ext/rb-grn-index-column.c +74 -19
  18. data/ext/rb-grn-logger.c +48 -0
  19. data/ext/rb-grn-object.c +281 -67
  20. data/ext/rb-grn-operation.c +1 -1
  21. data/ext/rb-grn-patricia-trie-cursor.c +10 -1
  22. data/ext/rb-grn-patricia-trie.c +268 -7
  23. data/ext/rb-grn-query.c +52 -1
  24. data/ext/rb-grn-record.c +8 -2
  25. data/ext/rb-grn-snippet.c +63 -1
  26. data/ext/rb-grn-table-cursor-key-support.c +15 -1
  27. data/ext/rb-grn-table-cursor.c +57 -0
  28. data/ext/rb-grn-table-key-support.c +382 -46
  29. data/ext/rb-grn-table.c +729 -192
  30. data/ext/rb-grn-type.c +63 -12
  31. data/ext/rb-grn-utils.c +156 -158
  32. data/ext/rb-grn-variable.c +18 -0
  33. data/ext/rb-grn.h +85 -21
  34. data/ext/rb-groonga.c +13 -3
  35. data/extconf.rb +19 -4
  36. data/html/developer.html +1 -1
  37. data/html/header.html.erb +1 -1
  38. data/html/index.html +4 -4
  39. data/lib/groonga.rb +10 -0
  40. data/lib/groonga/expression-builder.rb +81 -42
  41. data/lib/groonga/patricia-trie.rb +13 -0
  42. data/lib/groonga/record.rb +158 -13
  43. data/lib/groonga/schema.rb +339 -33
  44. data/pkg-config.rb +6 -1
  45. data/test-unit/lib/test/unit.rb +23 -42
  46. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  47. data/test-unit/lib/test/unit/assertions.rb +87 -9
  48. data/test-unit/lib/test/unit/autorunner.rb +20 -11
  49. data/test-unit/lib/test/unit/collector.rb +1 -8
  50. data/test-unit/lib/test/unit/collector/load.rb +2 -3
  51. data/test-unit/lib/test/unit/color-scheme.rb +13 -1
  52. data/test-unit/lib/test/unit/diff.rb +223 -37
  53. data/test-unit/lib/test/unit/error.rb +4 -0
  54. data/test-unit/lib/test/unit/failure.rb +31 -5
  55. data/test-unit/lib/test/unit/notification.rb +8 -4
  56. data/test-unit/lib/test/unit/omission.rb +51 -3
  57. data/test-unit/lib/test/unit/pending.rb +4 -0
  58. data/test-unit/lib/test/unit/testcase.rb +55 -4
  59. data/test-unit/lib/test/unit/ui/console/testrunner.rb +190 -4
  60. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  61. data/test-unit/lib/test/unit/ui/testrunner.rb +8 -0
  62. data/test-unit/lib/test/unit/version.rb +1 -1
  63. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  64. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  65. data/test-unit/sample/test_user.rb +1 -0
  66. data/test-unit/test/collector/test-descendant.rb +2 -4
  67. data/test-unit/test/collector/test_objectspace.rb +7 -5
  68. data/test-unit/test/run-test.rb +2 -0
  69. data/test-unit/test/test-color-scheme.rb +7 -0
  70. data/test-unit/test/test-diff.rb +48 -7
  71. data/test-unit/test/test-omission.rb +1 -1
  72. data/test-unit/test/test-testcase.rb +47 -0
  73. data/test-unit/test/test_assertions.rb +79 -10
  74. data/test/groonga-test-utils.rb +6 -1
  75. data/test/test-array.rb +29 -14
  76. data/test/test-column.rb +107 -55
  77. data/test/test-context.rb +5 -0
  78. data/test/test-database.rb +2 -37
  79. data/test/test-exception.rb +9 -1
  80. data/test/test-expression-builder.rb +23 -5
  81. data/test/test-expression.rb +44 -8
  82. data/test/test-fix-size-column.rb +16 -5
  83. data/test/test-gqtp.rb +70 -0
  84. data/test/test-hash.rb +142 -43
  85. data/test/test-index-column.rb +9 -9
  86. data/test/test-patricia-trie.rb +79 -20
  87. data/test/test-procedure.rb +4 -2
  88. data/test/test-record.rb +32 -20
  89. data/test/test-remote.rb +3 -2
  90. data/test/test-schema.rb +226 -92
  91. data/test/test-table-cursor.rb +103 -1
  92. data/test/test-table-offset-and-limit.rb +102 -0
  93. data/test/test-table-select-normalize.rb +4 -4
  94. data/test/test-table-select.rb +52 -8
  95. data/test/test-table.rb +235 -116
  96. data/test/test-type.rb +2 -2
  97. data/test/test-variable-size-column.rb +21 -5
  98. data/test/test-vector-column.rb +76 -0
  99. data/{TUTORIAL.ja.rdoc → text/TUTORIAL.ja.rdoc} +52 -52
  100. data/text/expression.rdoc +284 -0
  101. metadata +11 -7
  102. data/test-unit/sample/ts_examples.rb +0 -7
@@ -1,6 +1,7 @@
1
1
  /* -*- c-file-style: "ruby" -*- */
2
+ /* vim: set sts=4 sw=4 ts=8 noet: */
2
3
  /*
3
- Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
4
+ Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
4
5
 
5
6
  This library is free software; you can redistribute it and/or
6
7
  modify it under the terms of the GNU Lesser General Public
@@ -71,7 +72,7 @@ rb_grn_column_bind (RbGrnColumn *rb_column,
71
72
  RbGrnObject *rb_grn_object;
72
73
 
73
74
  rb_grn_object = RB_GRN_OBJECT(rb_column);
74
-
75
+ rb_grn_named_object_bind(RB_GRN_NAMED_OBJECT(rb_column), context, column);
75
76
  rb_column->value = grn_obj_open(context, GRN_BULK, 0,
76
77
  rb_grn_object->range_id);
77
78
  }
@@ -80,6 +81,8 @@ void
80
81
  rb_grn_column_finalizer (grn_ctx *context, grn_obj *grn_object,
81
82
  RbGrnColumn *rb_column)
82
83
  {
84
+ rb_grn_named_object_finalizer(context, grn_object,
85
+ RB_GRN_NAMED_OBJECT(rb_column));
83
86
  if (context && rb_column->value)
84
87
  grn_obj_close(context, rb_column->value);
85
88
  rb_column->value = NULL;
@@ -106,7 +109,6 @@ rb_grn_column_deconstruct (RbGrnColumn *rb_column,
106
109
  *value = rb_column->value;
107
110
  }
108
111
 
109
-
110
112
  /*
111
113
  * call-seq:
112
114
  * column.table -> Groonga::Table
@@ -135,20 +137,22 @@ rb_grn_column_get_table (VALUE self)
135
137
  *
136
138
  * テーブル名を除いたカラム名を返す。
137
139
  *
138
- * items = Groonga::Array.create(:name => "<items>")
139
- * title = items.define_column("title", "<shorttext>")
140
- * title.name # => "<items>.title"
140
+ * items = Groonga::Array.create(:name => "Items")
141
+ * title = items.define_column("title", "ShortText")
142
+ * title.name # => "Items.title"
141
143
  * title.local_name # => "title"
142
144
  */
143
145
  static VALUE
144
146
  rb_grn_column_get_local_name (VALUE self)
145
147
  {
148
+ RbGrnColumn *rb_grn_column;
146
149
  grn_ctx *context = NULL;
147
150
  grn_obj *column;
148
151
  int name_size;
149
152
  VALUE rb_name;
150
153
 
151
- rb_grn_object_deconstruct((RbGrnObject *)(SELF(self)), &column, &context,
154
+ rb_grn_column = SELF(self);
155
+ rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
152
156
  NULL, NULL,
153
157
  NULL, NULL);
154
158
  name_size = grn_column_name(context, column, NULL, 0);
@@ -161,6 +165,116 @@ rb_grn_column_get_local_name (VALUE self)
161
165
  return rb_name;
162
166
  }
163
167
 
168
+ /*
169
+ * call-seq:
170
+ * column.select(options) {|record| ...} -> Groonga::Hash
171
+ * column.select(query, options) -> Groonga::Hash
172
+ * column.select(expression, options) -> Groonga::Hash
173
+ *
174
+ * カラムが所属するテーブルからブロックまたは文字列で指定し
175
+ * た条件にマッチするレコードを返す。返されたテーブルには
176
+ * +expression+という特異メソッドがあり、指定した条件を表し
177
+ * ているGroonga::Expressionを取得できる。
178
+ * Groonga::Expression#snippetを使うことにより、指定した条件
179
+ * 用のスニペットを簡単に生成できる。
180
+ *
181
+ * results = description_column.select do |column|
182
+ * column =~ "groonga"
183
+ * end
184
+ * snippet = results.expression.snippet([["<em>", "</em>"]])
185
+ * results.each do |record|
186
+ * puts "#{record['name']}の説明文の中で「groonga」が含まれる部分"
187
+ * snippet.execute(record["description"].each do |snippet|
188
+ * puts "---"
189
+ * puts "#{snippet}..."
190
+ * puts "---"
191
+ * end
192
+ * end
193
+ *
194
+ * 出力例
195
+ * Ruby/groongaの説明文の中で「groonga」が含まれる部分
196
+ * ---
197
+ * Ruby/<em>groonga</em>は<em>groonga</em>のいわゆるDB-APIの層の...
198
+ * ---
199
+ *
200
+ * _query_には「[カラム名]:[演算子][値]」という書式で条件を
201
+ * 指定する。演算子は以下の通り。
202
+ *
203
+ * [なし]
204
+ * [カラム値] == [値]
205
+ * [<tt>!</tt>]
206
+ * [カラム値] != [値]
207
+ * [<tt><</tt>]
208
+ * [カラム値] < [値]
209
+ * [<tt>></tt>]
210
+ * [カラム値] > [値]
211
+ * [<tt><=</tt>]
212
+ * [カラム値] <= [値]
213
+ * [<tt>>=</tt>]
214
+ * [カラム値] >= [値]
215
+ * [<tt>@</tt>]
216
+ * [カラム値]が[値]を含んでいるかどうか
217
+ *
218
+ * 例:
219
+ * "groonga" # _column_カラムの値が"groonga"のレコードにマッチ
220
+ * "name:daijiro" # _column_カラムが属しているテーブルの
221
+ * # "name"カラムの値が"daijiro"のレコードにマッチ
222
+ * "description:@groonga" # _column_カラムが属しているテーブルの
223
+ * # "description"カラムが
224
+ * # "groonga"を含んでいるレコードにマッチ
225
+ *
226
+ * _expression_には既に作成済みのGroonga::Expressionを渡す
227
+ *
228
+ * ブロックで条件を指定する場合は
229
+ * Groonga::ColumnExpressionBuilderを参照。
230
+ *
231
+ * _options_に指定可能な値は以下の通り。
232
+ *
233
+ * [+:operator+]
234
+ * マッチしたレコードをどのように扱うか。指定可能な値は以
235
+ * 下の通り。省略した場合はGroonga::Operation::OR。
236
+ *
237
+ * [Groonga::Operation::OR]
238
+ * マッチしたレコードを追加。すでにレコードが追加され
239
+ * ている場合は何もしない。
240
+ * [Groonga::Operation::AND]
241
+ * マッチしたレコードのスコアを増加。マッチしなかった
242
+ * レコードを削除。
243
+ * [Groonga::Operation::BUT]
244
+ * マッチしたレコードを削除。
245
+ * [Groonga::Operation::ADJUST]
246
+ * マッチしたレコードのスコアを増加。
247
+ *
248
+ * [+:result+]
249
+ * 検索結果を格納するテーブル。マッチしたレコードが追加さ
250
+ * れていく。省略した場合は新しくテーブルを作成して返す。
251
+ *
252
+ * [+:name+]
253
+ * 条件の名前。省略した場合は名前を付けない。
254
+ *
255
+ * [+:syntax+]
256
+ * _query_の構文。省略した場合は+:query+。
257
+ *
258
+ * 参考: Groonga::Expression#parse.
259
+ *
260
+ * [+:allow_pragma+]
261
+ * query構文時にプラグマを利用するかどうか。省略した場合は
262
+ * 利用する。
263
+ *
264
+ * 参考: Groonga::Expression#parse.
265
+ *
266
+ * [+:allow_column+]
267
+ * query構文時にカラム指定を利用するかどうか。省略した場合
268
+ * は利用する。
269
+ *
270
+ * 参考: Groonga::Expression#parse.
271
+ *
272
+ * [+:allow_update+]
273
+ * script構文時に更新操作を利用するかどうか。省略した場合
274
+ * は利用する。
275
+ *
276
+ * 参考: Groonga::Expression#parse.
277
+ */
164
278
  static VALUE
165
279
  rb_grn_column_select (int argc, VALUE *argv, VALUE self)
166
280
  {
@@ -168,34 +282,44 @@ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
168
282
  grn_obj *table, *column, *result, *expression;
169
283
  grn_operator operator = GRN_OP_OR;
170
284
  VALUE options;
171
- VALUE rb_query, rb_query_or_options, rb_name, rb_operator, rb_result;
285
+ VALUE rb_query, condition_or_options;
286
+ VALUE rb_name, rb_operator, rb_result, rb_syntax;
287
+ VALUE rb_allow_pragma, rb_allow_column, rb_allow_update;
172
288
  VALUE builder;
173
- VALUE rb_expression;
174
-
289
+ VALUE rb_expression = Qnil;
290
+
175
291
  rb_query = Qnil;
176
292
 
177
- rb_scan_args(argc, argv, "02", &rb_query_or_options, &options);
293
+ rb_scan_args(argc, argv, "02", &condition_or_options, &options);
178
294
 
179
295
  rb_grn_column_deconstruct(SELF(self), &column, &context,
180
296
  NULL, NULL,
181
297
  NULL, NULL, NULL);
182
298
  table = grn_column_table(context, column);
183
299
 
184
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_query_or_options, rb_cString))) {
185
- rb_query = rb_query_or_options;
300
+ if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options, rb_cString))) {
301
+ rb_query = condition_or_options;
302
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options,
303
+ rb_cGrnExpression))) {
304
+ rb_expression = condition_or_options;
186
305
  } else {
187
306
  if (!NIL_P(options))
188
307
  rb_raise(rb_eArgError,
189
- "should be [query_string, option_hash] "
308
+ "should be [query_string, option_hash], "
309
+ "[expression, opion_hash] "
190
310
  "or [option_hash]: %s",
191
311
  rb_grn_inspect(rb_ary_new4(argc, argv)));
192
- options = rb_query_or_options;
312
+ options = condition_or_options;
193
313
  }
194
-
314
+
195
315
  rb_grn_scan_options(options,
196
316
  "operator", &rb_operator,
197
317
  "result", &rb_result,
198
318
  "name", &rb_name,
319
+ "syntax", &rb_syntax,
320
+ "allow_pragma", &rb_allow_pragma,
321
+ "allow_column", &rb_allow_column,
322
+ "allow_update", &rb_allow_update,
199
323
  NULL);
200
324
 
201
325
  if (!NIL_P(rb_operator))
@@ -211,8 +335,14 @@ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
211
335
  result = RVAL2GRNTABLE(rb_result, &context);
212
336
  }
213
337
 
214
- builder = rb_grn_column_expression_builder_new(self, rb_name, rb_query);
215
- rb_expression = rb_grn_column_expression_builder_build(builder);
338
+ if (NIL_P(rb_expression)) {
339
+ builder = rb_grn_column_expression_builder_new(self, rb_name, rb_query);
340
+ rb_funcall(builder, rb_intern("syntax="), 1, rb_syntax);
341
+ rb_funcall(builder, rb_intern("allow_pragma="), 1, rb_allow_pragma);
342
+ rb_funcall(builder, rb_intern("allow_column="), 1, rb_allow_column);
343
+ rb_funcall(builder, rb_intern("allow_update="), 1, rb_allow_update);
344
+ rb_expression = rb_grn_column_expression_builder_build(builder);
345
+ }
216
346
  rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
217
347
  &expression, NULL,
218
348
  NULL, NULL, NULL, NULL);
@@ -220,9 +350,205 @@ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
220
350
  grn_table_select(context, table, expression, result, operator);
221
351
  rb_grn_context_check(context, self);
222
352
 
353
+ rb_attr(rb_singleton_class(rb_result),
354
+ rb_intern("expression"),
355
+ RB_GRN_TRUE, RB_GRN_FALSE, RB_GRN_FALSE);
356
+ rb_iv_set(rb_result, "@expression", rb_expression);
357
+
223
358
  return rb_result;
224
359
  }
225
360
 
361
+ /*
362
+ * Document-method: unlock
363
+ *
364
+ * call-seq:
365
+ * column.unlock(options={})
366
+ *
367
+ * _column_のロックを解除する。
368
+ *
369
+ * 利用可能なオプションは以下の通り。
370
+ *
371
+ * [_:id_]
372
+ * _:id_で指定したレコードのロックを解除する。(注:
373
+ * groonga側が未実装のため、現在は無視される)
374
+ */
375
+ static VALUE
376
+ rb_grn_column_unlock (int argc, VALUE *argv, VALUE self)
377
+ {
378
+ grn_id id = GRN_ID_NIL;
379
+ grn_ctx *context;
380
+ grn_obj *column;
381
+ grn_rc rc;
382
+ VALUE options, rb_id;
383
+
384
+ rb_scan_args(argc, argv, "01", &options);
385
+
386
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
387
+ NULL, NULL,
388
+ NULL, NULL, NULL);
389
+
390
+ rb_grn_scan_options(options,
391
+ "id", &rb_id,
392
+ NULL);
393
+
394
+ if (!NIL_P(rb_id))
395
+ id = NUM2UINT(rb_id);
396
+
397
+ rc = grn_obj_unlock(context, column, id);
398
+ rb_grn_context_check(context, self);
399
+ rb_grn_rc_check(rc, self);
400
+
401
+ return Qnil;
402
+ }
403
+
404
+ static VALUE
405
+ rb_grn_column_unlock_ensure (VALUE self)
406
+ {
407
+ return rb_grn_column_unlock(0, NULL, self);
408
+ }
409
+
410
+ /*
411
+ * Document-method: lock
412
+ *
413
+ * call-seq:
414
+ * column.lock(options={})
415
+ * column.lock(options={}) {...}
416
+ *
417
+ * _column_をロックする。ロックに失敗した場合は
418
+ * Groonga::ResourceDeadlockAvoided例外が発生する。
419
+ *
420
+ * ブロックを指定した場合はブロックを抜けたときにunlockする。
421
+ *
422
+ * 利用可能なオプションは以下の通り。
423
+ *
424
+ * [_:timeout_]
425
+ * ロックを獲得できなかった場合は_:timeout_秒間ロックの獲
426
+ * 得を試みる。_:timeout_秒以内にロックを獲得できなかった
427
+ * 場合は例外が発生する。
428
+ * [_:id_]
429
+ * _:id_で指定したレコードをロックする。(注: groonga側が
430
+ * 未実装のため、現在は無視される)
431
+ */
432
+ static VALUE
433
+ rb_grn_column_lock (int argc, VALUE *argv, VALUE self)
434
+ {
435
+ grn_id id = GRN_ID_NIL;
436
+ grn_ctx *context;
437
+ grn_obj *column;
438
+ int timeout = 0;
439
+ grn_rc rc;
440
+ VALUE options, rb_timeout, rb_id;
441
+
442
+ rb_scan_args(argc, argv, "01", &options);
443
+
444
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
445
+ NULL, NULL,
446
+ NULL, NULL, NULL);
447
+
448
+ rb_grn_scan_options(options,
449
+ "timeout", &rb_timeout,
450
+ "id", &rb_id,
451
+ NULL);
452
+
453
+ if (!NIL_P(rb_timeout))
454
+ timeout = NUM2UINT(rb_timeout);
455
+
456
+ if (!NIL_P(rb_id))
457
+ id = NUM2UINT(rb_id);
458
+
459
+ rc = grn_obj_lock(context, column, id, timeout);
460
+ rb_grn_context_check(context, self);
461
+ rb_grn_rc_check(rc, self);
462
+
463
+ if (rb_block_given_p()) {
464
+ return rb_ensure(rb_yield, Qnil, rb_grn_column_unlock_ensure, self);
465
+ } else {
466
+ return Qnil;
467
+ }
468
+ }
469
+
470
+ /*
471
+ * Document-method: clear_lock
472
+ *
473
+ * call-seq:
474
+ * column.clear_lock(options={})
475
+ *
476
+ * _column_のロックを強制的に解除する。
477
+ *
478
+ * 利用可能なオプションは以下の通り。
479
+ *
480
+ * [_:id_]
481
+ * _:id_で指定したレコードのロックを強制的に解除する。
482
+ * (注: groonga側が未実装のため、現在は無視される。実装さ
483
+ * れるのではないかと思っているが、実装されないかもしれな
484
+ * い。)
485
+ */
486
+ static VALUE
487
+ rb_grn_column_clear_lock (int argc, VALUE *argv, VALUE self)
488
+ {
489
+ grn_id id = GRN_ID_NIL;
490
+ grn_ctx *context;
491
+ grn_obj *column;
492
+ VALUE options, rb_id;
493
+
494
+ rb_scan_args(argc, argv, "01", &options);
495
+
496
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
497
+ NULL, NULL,
498
+ NULL, NULL, NULL);
499
+
500
+ rb_grn_scan_options(options,
501
+ "id", &rb_id,
502
+ NULL);
503
+
504
+ if (!NIL_P(rb_id))
505
+ id = NUM2UINT(rb_id);
506
+
507
+ grn_obj_clear_lock(context, column);
508
+
509
+ return Qnil;
510
+ }
511
+
512
+ /*
513
+ * Document-method: locked?
514
+ *
515
+ * call-seq:
516
+ * column.locked?(options={})
517
+ *
518
+ * _column_がロックされていれば+true+を返す。
519
+ *
520
+ * 利用可能なオプションは以下の通り。
521
+ *
522
+ * [_:id_]
523
+ * _:id_で指定したレコードがロックされていれば+true+を返す。
524
+ * (注: groonga側が未実装のため、現在は無視される。実装さ
525
+ * れるのではないかと思っているが、実装されないかもしれな
526
+ * い。)
527
+ */
528
+ static VALUE
529
+ rb_grn_column_is_locked (int argc, VALUE *argv, VALUE self)
530
+ {
531
+ grn_id id = GRN_ID_NIL;
532
+ grn_ctx *context;
533
+ grn_obj *column;
534
+ VALUE options, rb_id;
535
+
536
+ rb_scan_args(argc, argv, "01", &options);
537
+
538
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
539
+ NULL, NULL,
540
+ NULL, NULL, NULL);
541
+
542
+ rb_grn_scan_options(options,
543
+ "id", &rb_id,
544
+ NULL);
545
+
546
+ if (!NIL_P(rb_id))
547
+ id = NUM2UINT(rb_id);
548
+
549
+ return CBOOL2RVAL(grn_obj_is_locked(context, column));
550
+ }
551
+
226
552
  void
227
553
  rb_grn_init_column (VALUE mGrn)
228
554
  {
@@ -233,6 +559,10 @@ rb_grn_init_column (VALUE mGrn)
233
559
  rb_grn_column_get_local_name, 0);
234
560
 
235
561
  rb_define_method(rb_cGrnColumn, "select", rb_grn_column_select, -1);
562
+ rb_define_method(rb_cGrnColumn, "lock", rb_grn_column_lock, -1);
563
+ rb_define_method(rb_cGrnColumn, "unlock", rb_grn_column_unlock, -1);
564
+ rb_define_method(rb_cGrnColumn, "clear_lock", rb_grn_column_clear_lock, -1);
565
+ rb_define_method(rb_cGrnColumn, "locked?", rb_grn_column_is_locked, -1);
236
566
 
237
567
  rb_grn_init_fix_size_column(mGrn);
238
568
  rb_grn_init_variable_size_column(mGrn);