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.
- data/NEWS.ja.rdoc +11 -0
- data/NEWS.rdoc +11 -0
- data/README.ja.rdoc +4 -3
- data/README.rdoc +4 -3
- data/Rakefile +1 -1
- data/TUTORIAL.ja.rdoc +168 -44
- data/benchmark/common.rb +49 -0
- data/benchmark/read-write-small-many-items.rb +156 -0
- data/benchmark/write-small-many-items.rb +145 -0
- data/example/bookmark.rb +68 -20
- data/ext/rb-grn-array-cursor.c +8 -0
- data/ext/rb-grn-array.c +40 -11
- data/ext/rb-grn-column.c +38 -209
- data/ext/rb-grn-context.c +203 -56
- data/ext/rb-grn-database.c +119 -5
- data/ext/rb-grn-encoding-support.c +64 -0
- data/ext/rb-grn-encoding.c +58 -1
- data/ext/rb-grn-fix-size-column.c +220 -0
- data/ext/rb-grn-hash-cursor.c +8 -0
- data/ext/rb-grn-hash.c +244 -2
- data/ext/rb-grn-index-column.c +474 -0
- data/ext/rb-grn-object.c +143 -265
- data/ext/rb-grn-patricia-trie.c +148 -2
- data/ext/rb-grn-query.c +5 -3
- data/ext/rb-grn-record.c +3 -2
- data/ext/rb-grn-snippet.c +5 -3
- data/ext/rb-grn-table-cursor-key-support.c +3 -3
- data/ext/rb-grn-table-cursor.c +106 -112
- data/ext/rb-grn-table-key-support.c +220 -118
- data/ext/rb-grn-table.c +336 -80
- data/ext/rb-grn-type.c +5 -4
- data/ext/rb-grn-utils.c +62 -63
- data/ext/rb-grn.h +215 -14
- data/ext/rb-groonga.c +7 -16
- data/extconf.rb +3 -1
- data/html/favicon.ico +0 -0
- data/html/favicon.xcf +0 -0
- data/html/index.html +1 -7
- data/lib/groonga/record.rb +6 -1
- data/test/groonga-test-utils.rb +1 -0
- data/test/test-array.rb +81 -0
- data/test/test-column.rb +22 -12
- data/test/test-context.rb +1 -29
- data/test/test-database.rb +30 -0
- data/test/test-hash.rb +194 -0
- data/test/test-index-column.rb +57 -0
- data/test/test-patricia-trie.rb +82 -0
- data/test/test-record.rb +10 -10
- data/test/test-table.rb +37 -130
- data/test/test-type.rb +4 -3
- metadata +15 -4
- 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
|
-
|
21
|
-
:persistent => persistent)
|
20
|
+
p items.define_column("title", "<text>", :persistent => persistent)
|
22
21
|
|
23
|
-
terms = Groonga::Hash.create(:name => "<terms>",
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
34
|
-
items
|
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
|
37
|
-
|
38
|
-
|
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
|
data/ext/rb-grn-array-cursor.c
CHANGED
@@ -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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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,
|
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
|
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
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
268
|
-
|
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
|
}
|