groonga 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This benchmark is based on Tokyo Cabinet's benchmark at
4
+ # http://alpha.mixi.co.jp/blog/?p=791
5
+ #
6
+ # On my environment at 2009/05/16:
7
+ # % for x in {0..9}; do ruby benchmark/write-small-many-items.rb $x; done
8
+ # user system total real memory
9
+ # Hash 1.090000 0.180000 1.270000 ( 1.565159) 47.090MB
10
+ # groonga: Hash: memory 0.930000 0.140000 1.070000 ( 1.364338) 23.473MB
11
+ # groonga: Trie: memory 1.170000 0.120000 1.290000 ( 1.601229) 15.480MB
12
+ # groonga: Hash: file 0.980000 0.170000 1.150000 ( 1.398126) 23.477MB
13
+ # groonga: Trie: file 1.220000 0.130000 1.350000 ( 1.744243) 15.484MB
14
+ # Localmemcache: file 1.100000 0.210000 1.310000 ( 1.734014) 39.301MB
15
+ # TC: Hash: memory 0.710000 0.130000 0.840000 ( 1.061472) 42.055MB
16
+ # TC: Tree: memory 0.640000 0.150000 0.790000 ( 1.040223) 30.566MB
17
+ # TC: Hash: file 1.310000 2.370000 3.680000 ( 5.028978) 2.133MB
18
+ # TC: Tree: file 1.030000 0.200000 1.230000 ( 1.666725) 6.086MB
19
+ #
20
+ # Ruby: Debian GNU/Linux sid at 2009/05/16:
21
+ # ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]
22
+ # groonga: HEAD at 2009/05/16: ed49074fbc217b97c0b0b8d675f2417f9490c87e
23
+ # Ruby/Groonga: trunk at 2009/05/16: r321
24
+ # Localmemcache: HEAD at 2009/05/16: 6f8cfbd3a103c2be8d54834a65deb096d7cda34f
25
+ # Tokyo Cabinet: 1.4.20
26
+ # Tokyo Cabinet Ruby: 1.23
27
+ #
28
+ # NOTE: All C source codes are built with "-g -O0"
29
+ # option. They will be more faster with "-O2" option.
30
+
31
+ require File.join(File.dirname(__FILE__), "common.rb")
32
+
33
+ n = 500000
34
+
35
+ values = []
36
+ n.times do |i|
37
+ values << "%08d" % i
38
+ end
39
+
40
+ item("Hash") do
41
+ @hash = {}
42
+ values.each do |value|
43
+ @hash[value] = value
44
+ end
45
+ end
46
+
47
+ begin
48
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
49
+ $LOAD_PATH.unshift(File.join(base_dir, "ext"))
50
+ $LOAD_PATH.unshift(File.join(base_dir, "lib"))
51
+
52
+ require 'groonga'
53
+ @database = Groonga::Database.create
54
+
55
+ item("groonga: Hash: memory") do
56
+ @hash = Groonga::Hash.create(:key_type => "<shorttext>",
57
+ :value_size => 8)
58
+ values.each do |value|
59
+ @hash[value] = value
60
+ end
61
+ end
62
+
63
+ item("groonga: Trie: memory") do
64
+ @hash = Groonga::PatriciaTrie.create(:key_type => "<shorttext>",
65
+ :value_size => 8)
66
+ values.each do |value|
67
+ @hash[value] = value
68
+ end
69
+ end
70
+
71
+ @hash_file = Tempfile.new("groonga-hash")
72
+ item("groonga: Hash: file") do
73
+ @hash = Groonga::Hash.create(:key_type => "<shorttext>",
74
+ :value_size => 8,
75
+ :path => @hash_file.path)
76
+ values.each do |value|
77
+ @hash[value] = value
78
+ end
79
+ end
80
+
81
+ trie_file = Tempfile.new("groonga-trie")
82
+ item("groonga: Trie: file") do
83
+ @hash = Groonga::PatriciaTrie.create(:key_type => "<shorttext>",
84
+ :value_size => 8,
85
+ :path => trie_file.path)
86
+ values.each do |value|
87
+ @hash[value] = value
88
+ end
89
+ end
90
+ rescue LoadError
91
+ end
92
+
93
+ begin
94
+ require 'localmemcache'
95
+
96
+ item("Localmemcache: file") do
97
+ LocalMemCache.drop(:namespace => "write-small-many-items", :force => true)
98
+ @db = LocalMemCache.new(:namespace => "write-small-many-items")
99
+ values.each do |value|
100
+ @db[value] = value
101
+ end
102
+ end
103
+ rescue LoadError
104
+ end
105
+
106
+ begin
107
+ require 'tokyocabinet'
108
+
109
+ item("TC: Hash: memory") do
110
+ @db = TokyoCabinet::ADB::new
111
+ @db.open("*#bnum=#{n}#mode=wct#xmsiz=0")
112
+ values.each do |value|
113
+ @db.put(value, value)
114
+ end
115
+ end
116
+
117
+ item("TC: Tree: memory") do
118
+ @db = TokyoCabinet::ADB::new
119
+ @db.open("+#bnum=#{n}#mode=wct#xmsiz=0")
120
+ values.each do |value|
121
+ @db.put(value, value)
122
+ end
123
+ end
124
+
125
+ hash_file = Tempfile.new(["tc-hash", ".tch"])
126
+ item("TC: Hash: file") do
127
+ @db = TokyoCabinet::ADB::new
128
+ @db.open("#{hash_file.path}#bnum=#{n}#mode=wct#xmsiz=0")
129
+ values.each do |value|
130
+ @db.put(value, value)
131
+ end
132
+ end
133
+
134
+ tree_file = Tempfile.new(["tc-tree", ".tcb"])
135
+ item("TC: Tree: file") do
136
+ @db = TokyoCabinet::ADB::new
137
+ @db.open("#{tree_file.path}#bnum=#{n}#mode=wct#xmsiz=0")
138
+ values.each do |value|
139
+ @db.put(value, value)
140
+ end
141
+ end
142
+ rescue LoadError
143
+ end
144
+
145
+ report(Integer(ARGV[0] || 0))
data/example/bookmark.rb CHANGED
@@ -10,29 +10,77 @@ Groonga::Context.default_options = {:encoding => :utf8}
10
10
  path = ARGV[0]
11
11
  persistent = !path.nil?
12
12
 
13
- Groonga::Database.create(:path => path)
13
+ p Groonga::Database.create(:path => path)
14
14
 
15
- items = Groonga::Hash.create(:name => "<items>", :persistent => persistent)
15
+ p(items = Groonga::Hash.create(:name => "<items>", :persistent => persistent))
16
16
 
17
- items.add("http://ja.wikipedia.org/wiki/Ruby")
18
- items.add("http://www.ruby-lang.org/")
17
+ p items.add("http://ja.wikipedia.org/wiki/Ruby")
18
+ p items.add("http://www.ruby-lang.org/")
19
19
 
20
- title_column = items.define_column("title", "<text>",
21
- :persistent => persistent)
20
+ p items.define_column("title", "<text>", :persistent => persistent)
22
21
 
23
- terms = Groonga::Hash.create(:name => "<terms>",
24
- :key_type => "<shorttext>",
25
- :key_normalize => true,
26
- :persistent => persistent)
27
- title_index_column = terms.define_column("item_title", items,
28
- :type => "index",
29
- :with_position => true,
30
- :persistent => persistent)
31
- title_index_column.source = title_column
22
+ p(terms = Groonga::Hash.create(:name => "<terms>",
23
+ :key_type => "<shorttext>",
24
+ :persistent => persistent,
25
+ :default_tokenizer => "<token:bigram>"))
26
+ p terms.define_index_column("item_title", items,
27
+ :persistent => persistent,
28
+ :source => "<items>.title")
32
29
 
33
- items["http://ja.wikipedia.org/wiki/Ruby"]["title"] = "Ruby"
34
- items["http://www.ruby-lang.org/"]["title"] = "オブジェクトスクリプト言語Ruby"
30
+ p items.find("http://ja.wikipedia.org/wiki/Ruby")["title"] = "Ruby"
31
+ p items.find("http://www.ruby-lang.org/")["title"] = "オブジェクトスクリプト言語Ruby"
35
32
 
36
- p terms.collect(&:key)
37
- p title_index_column.search("Ruby").size
38
- p title_index_column.search("ruby").size
33
+ p(users = Groonga::Hash.create(:name => "<users>",
34
+ :key_type => "<shorttext>",
35
+ :persistent => persistent))
36
+ p users.define_column("name", "<text>",
37
+ :persistent => persistent)
38
+
39
+ p(comments = Groonga::Array.create(:name => "<comments>",
40
+ :persistent => persistent))
41
+ p comments.define_column("item", items)
42
+ p comments.define_column("author", users)
43
+ p comments.define_column("content", "<text>")
44
+ p comments.define_column("issued", "<time>")
45
+
46
+ p terms.define_index_column("comment_content", comments,
47
+ :persistent => persistent,
48
+ :source => "<comments>.content")
49
+
50
+ p users.add("moritan", :name => "モリタン")
51
+ p users.add("taporobo", :name => "タポロボ")
52
+
53
+
54
+ p items.find("http://d.hatena.ne.jp/brazil/20050829/1125321936")
55
+
56
+ p items.add("http://d.hatena.ne.jp/brazil/20050829/1125321936",
57
+ :title => "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語")
58
+
59
+ p comments.add(:item => "http://d.hatena.ne.jp/brazil/20050829/1125321936",
60
+ :author => "moritan",
61
+ :content => "JavaScript LISP",
62
+ :issued => 1187430026)
63
+
64
+ @items = items
65
+ @comments = comments
66
+ def add_bookmark(url, title, author, content, issued)
67
+ item = @items.find(url) || @items.add(url, :title => title)
68
+ @comments.add(:item => item,
69
+ :author => author,
70
+ :content => content,
71
+ :issued => issued)
72
+ end
73
+
74
+ p add_bookmark("http://practical-scheme.net/docs/cont-j.html",
75
+ "なんでも継続", "moritan", "継続 LISP Scheme", 1187568692)
76
+ p add_bookmark("http://d.hatena.ne.jp/higepon/20070815/1187192864",
77
+ "末尾再帰", "taporobo", "末尾再帰 Scheme LISP", 1187568793)
78
+ p add_bookmark("http://practical-scheme.net/docs/cont-j.html",
79
+ "なんでも継続", "taporobo", "トランポリン LISP continuation",
80
+ 1187568692)
81
+
82
+ terms.column("comment_content").search("LISP").each do |record|
83
+ record = record.key
84
+ p [record[".issued"], record[".item.title"], record[".author.name"],
85
+ record[".content"]]
86
+ end
@@ -20,6 +20,14 @@
20
20
 
21
21
  VALUE rb_cGrnArrayCursor;
22
22
 
23
+ /*
24
+ * Document-class: Groonga::ArrayCursor < Groonga::TableCursor
25
+ *
26
+ * Groonga::Arrayに登録されているレコードを順番に取り出すため
27
+ * のオブジェクト。利用できるメソッドはGroonga::TableCursorを
28
+ * 参照。
29
+ */
30
+
23
31
  void
24
32
  rb_grn_init_array_cursor (VALUE mGrn)
25
33
  {
data/ext/rb-grn-array.c CHANGED
@@ -25,8 +25,8 @@ VALUE rb_cGrnArray;
25
25
  /*
26
26
  * Document-class: Groonga::Array < Groonga::Table
27
27
  *
28
- * 各レコードにキーが存在しないテーブル。レコードはIDで識別
29
- * する。
28
+ * 各レコードがキーに関連付けられていないテーブル。レコードは
29
+ * IDで識別する。
30
30
  */
31
31
 
32
32
  /*
@@ -51,7 +51,7 @@ VALUE rb_cGrnArray;
51
51
  *
52
52
  * [+:path+]
53
53
  * テーブルを保存するパス。パスを指定すると永続テーブルとな
54
- * り、プロセス終了後もレコードは保持され、次回起動時に
54
+ * り、プロセス終了後もレコードは保持される。次回起動時に
55
55
  * Groonga::Array.openで保存されたレコードを利用することが
56
56
  * できる。省略すると一時テーブルになり、プロセスが終了する
57
57
  * とレコードは破棄される。
@@ -65,6 +65,8 @@ VALUE rb_cGrnArray;
65
65
  * [+:value_size+]
66
66
  * 値の大きさを指定する。省略すると0になる。
67
67
  *
68
+ * 使用例:
69
+ *
68
70
  * 無名一時テーブルを生成する。
69
71
  * Groonga::Array.create
70
72
  *
@@ -102,7 +104,7 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
102
104
  "value_size", &rb_value_size,
103
105
  NULL);
104
106
 
105
- context = rb_grn_context_ensure(rb_context);
107
+ context = rb_grn_context_ensure(&rb_context);
106
108
 
107
109
  if (!NIL_P(rb_name)) {
108
110
  name = StringValuePtr(rb_name);
@@ -122,8 +124,11 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
122
124
 
123
125
  table = grn_table_create(context, name, name_size, path,
124
126
  flags, NULL, value_size);
127
+ if (!table)
128
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
125
129
  rb_table = GRNOBJECT2RVAL(klass, context, table, RB_GRN_TRUE);
126
130
  rb_grn_context_check(context, rb_table);
131
+ rb_iv_set(rb_table, "context", rb_context);
127
132
 
128
133
  if (rb_block_given_p())
129
134
  return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
@@ -133,27 +138,51 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
133
138
 
134
139
  /*
135
140
  * call-seq:
136
- * array.add -> Groonga::Recordまたはnil
141
+ * array.add(values=nil) -> Groonga::Recordまたはnil
142
+ *
143
+ * レコード追加し、追加したレコードを返す。レコードの追加に失
144
+ * 敗した場合は+nil+を返す。
145
+ *
146
+ * _values_にはレコードのカラムに設定する値を指定する。省略
147
+ * した場合または+nil+を指定した場合はカラムは設定しない。カ
148
+ * ラムの値は<tt>{:カラム名1 => 値1, :カラム名2 => 値2,
149
+ * ...}</tt>と指定する。
150
+ *
151
+ * 使用例では、以下のようなユーザを格納するGroonga::Arrayが
152
+ * 定義されているものとする。
153
+ * users = Groonga::Array.create(:name => "<users>")
154
+ * users.define_column("name", "<shorttext>")
155
+ * users.define_column("uri", "<shorttext>")
137
156
  *
138
- * レコード追加し、追加したレコードを返します。レコードの追
139
- * 加に失敗した場合は+nil+を返します。
157
+ * ユーザを追加する。
158
+ * user = users.add
159
+ *
160
+ * daijiroユーザを追加する。
161
+ * daijiro = users.add(:name => "daijiro")
162
+ *
163
+ * gunyara-kunユーザを追加する。
164
+ * gunyara_kun = users.add(:name => "gunyara-kun",
165
+ * :uri => "http://d.hatena.ne.jp/tasukuchan/")
140
166
  */
141
167
  static VALUE
142
- rb_grn_array_add (VALUE self)
168
+ rb_grn_array_add (int argc, VALUE *argv, VALUE self)
143
169
  {
144
170
  grn_ctx *context = NULL;
145
171
  grn_obj *table;
146
172
  grn_id id;
173
+ VALUE values;
174
+
175
+ rb_scan_args(argc, argv, "01", &values);
147
176
 
148
177
  table = SELF(self, &context);
149
178
 
150
- id = grn_table_add(context, table);
179
+ id = grn_table_add(context, table, NULL, 0, NULL);
151
180
  rb_grn_context_check(context, self);
152
181
 
153
182
  if (GRN_ID_NIL == id)
154
183
  return Qnil;
155
184
  else
156
- return rb_grn_record_new(self, id);
185
+ return rb_grn_record_new(self, id, values);
157
186
  }
158
187
 
159
188
  void
@@ -164,5 +193,5 @@ rb_grn_init_array (VALUE mGrn)
164
193
  rb_define_singleton_method(rb_cGrnArray, "create",
165
194
  rb_grn_array_s_create, -1);
166
195
 
167
- rb_define_method(rb_cGrnArray, "add", rb_grn_array_add, 0);
196
+ rb_define_method(rb_cGrnArray, "add", rb_grn_array_add, -1);
168
197
  }
data/ext/rb-grn-column.c CHANGED
@@ -18,12 +18,35 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object, context) (RVAL2GRNCOLUMN(object, context))
21
+ #define SELF(object) ((RbGrnColumn *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_cGrnColumn;
24
- VALUE rb_cGrnFixSizeColumn;
25
24
  VALUE rb_cGrnVarSizeColumn;
26
- VALUE rb_cGrnIndexColumn;
25
+
26
+ /*
27
+ * Document-class: Groonga::Column < Groonga::Object
28
+ *
29
+ * テーブルに情報を付加するためのオブジェクト。テーブルに複
30
+ * 数のカラムを定義することによりレコード毎に複数の情報を付
31
+ * 加することができる。
32
+ *
33
+ * カラムには大きく分けて3種類ある。
34
+ * [Groonga::FixSizeColumn]
35
+ * 固定長のデータを格納するカラム。
36
+ * [Groonga::VarSizeColumn]
37
+ * 可変長のデータを格納するカラム。
38
+ * [Groonga::IndexColumn]
39
+ * 転置インデックスを格納するカラム。全文検索や参照元レコー
40
+ * ドの検索を行う場合はこのカラムを使用する。
41
+ *
42
+ * 固定長データ用カラム・可変長データ用カラムは1つのデータだ
43
+ * けを格納するか複数のデータを格納するかを選ぶことができる。
44
+ * 1つのデータの場合はスカラ値、複数のデータの場合はスカラー
45
+ * 値を格納するという。
46
+ *
47
+ * カラムは名前を持ち、1つのテーブルでは同じカラム名を持つカ
48
+ * ラムを複数定義することはできない。
49
+ */
27
50
 
28
51
  grn_obj *
29
52
  rb_grn_column_from_ruby_object (VALUE object, grn_ctx **context)
@@ -42,112 +65,12 @@ rb_grn_column_to_ruby_object (VALUE klass, grn_ctx *context, grn_obj *column,
42
65
  return GRNOBJECT2RVAL(klass, context, column, owner);
43
66
  }
44
67
 
45
- static VALUE
46
- rb_grn_fix_size_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
47
- {
48
- grn_ctx *context = NULL;
49
- grn_obj *column;
50
- grn_id range;
51
- grn_obj *range_object = NULL;
52
- grn_rc rc;
53
- grn_id id;
54
- grn_obj value;
55
-
56
- column = SELF(self, &context);
57
- id = NUM2UINT(rb_id);
58
-
59
- range = grn_obj_get_range(context, column);
60
- if (range != GRN_ID_NIL)
61
- range_object = grn_ctx_get(context, range);
62
-
63
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cGrnRecord))) {
64
- VALUE rb_id, rb_table;
65
- grn_obj *table;
66
-
67
- if (!range_object)
68
- rb_raise(rb_eArgError,
69
- "%s isn't associated with any table: %s",
70
- rb_grn_inspect(self), rb_grn_inspect(rb_value));
71
-
72
- rb_id = rb_funcall(rb_value, rb_intern("id"), 0);
73
- rb_table = rb_funcall(rb_value, rb_intern("table"), 0);
74
- table = RVAL2GRNTABLE(rb_table, &context);
75
- if (grn_obj_id(context, table) != range)
76
- rb_raise(rb_eArgError,
77
- "%s isn't associated with passed record's table: %s",
78
- rb_grn_inspect(self),
79
- rb_grn_inspect(rb_value));
80
-
81
- RVAL2GRNUVECTOR(rb_ary_new3(1, rb_id), context, &value);
82
- } else if (range_object &&
83
- RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cInteger))) {
84
- switch (range_object->header.type) {
85
- case GRN_TABLE_PAT_KEY:
86
- case GRN_TABLE_HASH_KEY:
87
- case GRN_TABLE_NO_KEY:
88
- RVAL2GRNUVECTOR(rb_ary_new3(1, rb_value), context, &value);
89
- break;
90
- default:
91
- RVAL2GRNBULK(rb_value, context, &value);
92
- break;
93
- }
94
- } else {
95
- RVAL2GRNBULK(rb_value, context, &value);
96
- }
97
-
98
- rc = grn_obj_set_value(context, column, id, &value, GRN_OBJ_SET);
99
- grn_obj_close(context, &value);
100
- rb_grn_rc_check(rc, self);
101
-
102
- return Qnil;
103
- }
104
-
105
- static VALUE
106
- rb_grn_index_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
107
- {
108
- grn_ctx *context = NULL;
109
- grn_obj *column;
110
- grn_rc rc;
111
- grn_id id;
112
- unsigned int section;
113
- grn_obj old_value, new_value;
114
- VALUE rb_section, rb_old_value, rb_new_value;
115
-
116
- column = SELF(self, &context);
117
-
118
- id = NUM2UINT(rb_id);
119
-
120
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
121
- VALUE hash_value;
122
- hash_value = rb_hash_new();
123
- rb_hash_aset(hash_value, RB_GRN_INTERN("value"), rb_value);
124
- rb_value = hash_value;
125
- }
126
-
127
- rb_grn_scan_options(rb_value,
128
- "section", &rb_section,
129
- "old_value", &rb_old_value,
130
- "value", &rb_new_value,
131
- NULL);
132
-
133
- if (NIL_P(rb_section))
134
- section = 1;
135
- else
136
- section = NUM2UINT(rb_section);
137
-
138
- RVAL2GRNBULK(rb_old_value, context, &old_value);
139
- RVAL2GRNBULK(rb_new_value, context, &new_value);
140
-
141
- rc = grn_column_index_update(context, column,
142
- id, section, &old_value, &new_value);
143
- grn_obj_close(context, &old_value);
144
- grn_obj_close(context, &new_value);
145
-
146
- rb_grn_rc_check(rc, self);
147
-
148
- return Qnil;
149
- }
150
-
68
+ /*
69
+ * call-seq:
70
+ * column.table -> Groonga::Table
71
+ *
72
+ * カラムが所属するテーブルを返す。
73
+ */
151
74
  static VALUE
152
75
  rb_grn_column_get_table (VALUE self)
153
76
  {
@@ -155,119 +78,25 @@ rb_grn_column_get_table (VALUE self)
155
78
  grn_obj *column;
156
79
  grn_obj *table;
157
80
 
158
- column = SELF(self, &context);
81
+ rb_grn_object_deconstruct((RbGrnObject *)(SELF(self)), &column, &context,
82
+ NULL, NULL,
83
+ NULL, NULL);
159
84
  table = grn_column_table(context, column);
160
85
  rb_grn_context_check(context, self);
161
86
 
162
87
  return GRNOBJECT2RVAL(Qnil, context, table, RB_GRN_FALSE);
163
88
  }
164
89
 
165
- static VALUE
166
- rb_grn_index_column_get_sources (VALUE self)
167
- {
168
- grn_ctx *context = NULL;
169
- grn_obj *column;
170
- grn_obj sources;
171
- grn_id *source_ids;
172
- VALUE rb_sources;
173
- int i, n;
174
-
175
- column = SELF(self, &context);
176
-
177
- grn_obj_get_info(context, column, GRN_INFO_SOURCE, &sources);
178
- rb_grn_context_check(context, self);
179
-
180
- n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
181
- source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
182
- rb_sources = rb_ary_new2(n);
183
- for (i = 0; i < n; i++) {
184
- grn_obj *source;
185
- VALUE rb_source;
186
-
187
- source = grn_ctx_get(context, *source_ids);
188
- rb_source = GRNOBJECT2RVAL(Qnil, context, source, RB_GRN_FALSE);
189
- rb_ary_push(rb_sources, rb_source);
190
- source_ids++;
191
- }
192
-
193
- return rb_sources;
194
- }
195
-
196
- static VALUE
197
- rb_grn_index_column_set_sources (VALUE self, VALUE rb_sources)
198
- {
199
- grn_ctx *context = NULL;
200
- grn_obj *column;
201
- int i, n;
202
- VALUE *rb_source_values;
203
- grn_id *sources;
204
- grn_rc rc;
205
-
206
- column = SELF(self, &context);
207
-
208
- n = RARRAY_LEN(rb_sources);
209
- rb_source_values = RARRAY_PTR(rb_sources);
210
- sources = ALLOCA_N(grn_id, n);
211
- for (i = 0; i < n; i++) {
212
- VALUE rb_source_id;
213
- grn_obj *source;
214
- grn_id source_id;
215
-
216
- rb_source_id = rb_source_values[i];
217
- if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source_id, rb_cInteger))) {
218
- source_id = NUM2UINT(rb_source_id);
219
- } else {
220
- source = RVAL2GRNOBJECT(rb_source_id, &context);
221
- rb_grn_context_check(context, rb_source_id);
222
- source_id = grn_obj_id(context, source);
223
- }
224
- sources[i] = source_id;
225
- }
226
-
227
- {
228
- grn_obj source;
229
- GRN_OBJ_INIT(&source, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY);
230
- GRN_BULK_SET(context, &source, sources, n * sizeof(grn_id));
231
- rc = grn_obj_set_info(context, column, GRN_INFO_SOURCE, &source);
232
- }
233
-
234
- rb_grn_context_check(context, self);
235
- rb_grn_rc_check(rc, self);
236
-
237
- return Qnil;
238
- }
239
-
240
- static VALUE
241
- rb_grn_index_column_set_source (VALUE self, VALUE rb_source)
242
- {
243
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cArray)))
244
- rb_source = rb_ary_new3(1, rb_source);
245
-
246
- return rb_grn_index_column_set_sources(self, rb_source);
247
- }
248
-
249
90
  void
250
91
  rb_grn_init_column (VALUE mGrn)
251
92
  {
252
93
  rb_cGrnColumn = rb_define_class_under(mGrn, "Column", rb_cGrnObject);
253
- rb_cGrnFixSizeColumn =
254
- rb_define_class_under(mGrn, "FixSizeColumn", rb_cGrnColumn);
94
+
255
95
  rb_cGrnVarSizeColumn =
256
96
  rb_define_class_under(mGrn, "VarSizeColumn", rb_cGrnColumn);
257
- rb_cGrnIndexColumn =
258
- rb_define_class_under(mGrn, "IndexColumn", rb_cGrnColumn);
259
-
260
- rb_define_method(rb_cGrnFixSizeColumn, "[]=",
261
- rb_grn_fix_size_column_array_set, 2);
262
- rb_define_method(rb_cGrnIndexColumn, "[]=",
263
- rb_grn_index_column_array_set, 2);
264
97
 
265
98
  rb_define_method(rb_cGrnColumn, "table", rb_grn_column_get_table, 0);
266
99
 
267
- rb_define_method(rb_cGrnIndexColumn, "sources",
268
- rb_grn_index_column_get_sources, 0);
269
- rb_define_method(rb_cGrnIndexColumn, "sources=",
270
- rb_grn_index_column_set_sources, 1);
271
- rb_define_method(rb_cGrnIndexColumn, "source=",
272
- rb_grn_index_column_set_source, 1);
100
+ rb_grn_init_fix_size_column(mGrn);
101
+ rb_grn_init_index_column(mGrn);
273
102
  }