groonga 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +4 -0
- data/NEWS.ja.rdoc +10 -0
- data/NEWS.rdoc +10 -0
- data/README.ja.rdoc +9 -3
- data/README.rdoc +10 -4
- data/Rakefile +1 -1
- data/TUTORIAL.ja.rdoc +3 -6
- data/example/bookmark.rb +1 -1
- data/example/search/config.ru +52 -28
- data/ext/rb-grn-column.c +24 -18
- data/ext/rb-grn-context.c +165 -17
- data/ext/rb-grn-encoding.c +37 -0
- data/ext/rb-grn-expression.c +286 -51
- data/ext/rb-grn-object.c +27 -8
- data/ext/rb-grn-operation.c +128 -22
- data/ext/rb-grn-patricia-trie.c +62 -0
- data/ext/rb-grn-snippet.c +7 -17
- data/ext/rb-grn-table.c +101 -31
- data/ext/rb-grn-utils.c +87 -22
- data/ext/rb-grn-variable-size-column.c +1 -1
- data/ext/rb-grn.h +27 -4
- data/ext/rb-groonga.c +12 -2
- data/extconf.rb +2 -1
- data/html/index.html +2 -2
- data/lib/groonga.rb +1 -0
- data/lib/groonga/expression-builder.rb +47 -12
- data/lib/groonga/patricia-trie.rb +40 -0
- data/lib/groonga/record.rb +17 -13
- data/misc/grnop2ruby.rb +49 -0
- data/pkg-config.rb +1 -1
- data/test-unit/lib/test/unit/assertions.rb +5 -2
- data/test-unit/lib/test/unit/autorunner.rb +19 -4
- data/test-unit/lib/test/unit/collector/load.rb +3 -1
- data/test-unit/lib/test/unit/color-scheme.rb +5 -1
- data/test-unit/lib/test/unit/error.rb +7 -5
- data/test-unit/lib/test/unit/runner/tap.rb +8 -0
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +63 -8
- data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
- data/test-unit/test/collector/test-load.rb +1 -5
- data/test-unit/test/test-color-scheme.rb +4 -0
- data/test/groonga-test-utils.rb +10 -0
- data/test/run-test.rb +5 -1
- data/test/test-column.rb +58 -0
- data/test/test-database.rb +8 -1
- data/test/test-expression.rb +48 -6
- data/test/test-hash.rb +7 -0
- data/test/test-patricia-trie.rb +39 -0
- data/test/test-record.rb +2 -2
- data/test/test-remote.rb +52 -0
- data/test/test-schema.rb +1 -1
- data/test/test-table-select-normalize.rb +48 -0
- data/test/test-table-select.rb +101 -0
- data/test/test-table.rb +0 -9
- data/test/test-variable-size-column.rb +28 -0
- metadata +16 -5
data/AUTHORS
CHANGED
data/NEWS.ja.rdoc
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= お知らせ
|
2
2
|
|
3
|
+
== 0.0.7: 2009-10-02
|
4
|
+
|
5
|
+
* groonga 0.1.4対応
|
6
|
+
* APIの追加
|
7
|
+
* Groonga::PatriciaTrie#scan
|
8
|
+
* Groonga::PatriciaTrie#tag_keys
|
9
|
+
* Groonga::Expression#snippet
|
10
|
+
* Groonga::Object#append
|
11
|
+
* Groonga::Object#prepend
|
12
|
+
|
3
13
|
== 0.0.6: 2009-07-31
|
4
14
|
|
5
15
|
* groonga 0.1.1対応
|
data/NEWS.rdoc
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= NEWS
|
2
2
|
|
3
|
+
== 0.0.7: 2009-10-02
|
4
|
+
|
5
|
+
* Supported groonga 0.1.4
|
6
|
+
* Added API
|
7
|
+
* Groonga::PatriciaTrie#scan
|
8
|
+
* Groonga::PatriciaTrie#tag_keys
|
9
|
+
* Groonga::Expression#snippet
|
10
|
+
* Groonga::Object#append
|
11
|
+
* Groonga::Object#prepend
|
12
|
+
|
3
13
|
== 0.0.6: 2009-07-31
|
4
14
|
|
5
15
|
* Supported groonga 0.1.1.
|
data/README.ja.rdoc
CHANGED
@@ -20,7 +20,11 @@ groongaに関する情報は以下を参照して下さい。
|
|
20
20
|
|
21
21
|
== 作者
|
22
22
|
|
23
|
-
Kouhei Sutou
|
23
|
+
Kouhei Sutou:: <tt><kou@clear-code.com></tt>
|
24
|
+
Tasuku SUENAGA:: <tt><a@razil.jp></tt>
|
25
|
+
daijiro:: <tt><morita@razil.jp></tt>
|
26
|
+
Yuto HAYAMIZU:: <tt><y.hayamizu@gmail.com></tt>
|
27
|
+
SHIDARA Yoji:: <tt><dara@shidara.net></tt>
|
24
28
|
|
25
29
|
== ライセンス
|
26
30
|
|
@@ -32,7 +36,7 @@ pkg-config.rbはrcairoに付属しているもので、これはRubyライセ
|
|
32
36
|
== 依存ソフトウェア
|
33
37
|
|
34
38
|
* Ruby >= 1.8 (1.9.1対応)
|
35
|
-
* groonga >= 0.1.
|
39
|
+
* groonga >= 0.1.4
|
36
40
|
|
37
41
|
== インストール
|
38
42
|
|
@@ -53,5 +57,7 @@ http://lists.sourceforge.jp/mailman/listinfo/groonga-dev
|
|
53
57
|
* 森さん: 最新groonga対応パッチをくれました。
|
54
58
|
* グニャラくん: バグレポートしてくれました。
|
55
59
|
* にくさん: バグレポートしてくれました。
|
56
|
-
* daraさん:
|
60
|
+
* daraさん:
|
61
|
+
* テストを書いてくれました。
|
62
|
+
* バグを直してくれました。
|
57
63
|
* id:mat_akiさん: チュートリアルのバグを教えてくれました。
|
data/README.rdoc
CHANGED
@@ -18,9 +18,13 @@ See the following URL about groonga.
|
|
18
18
|
|
19
19
|
* groonga: http://groonga.org/
|
20
20
|
|
21
|
-
==
|
21
|
+
== Authors
|
22
22
|
|
23
|
-
Kouhei Sutou
|
23
|
+
Kouhei Sutou:: <tt><kou@clear-code.com></tt>
|
24
|
+
Tasuku SUENAGA:: <tt><a@razil.jp></tt>
|
25
|
+
daijiro:: <tt><morita@razil.jp></tt>
|
26
|
+
Yuto HAYAMIZU:: <tt><y.hayamizu@gmail.com></tt>
|
27
|
+
SHIDARA Yoji:: <tt><dara@shidara.net></tt>
|
24
28
|
|
25
29
|
== License
|
26
30
|
|
@@ -33,7 +37,7 @@ license/GPL for details.
|
|
33
37
|
== Dependencies
|
34
38
|
|
35
39
|
* Ruby >= 1.8 (including 1.9.1)
|
36
|
-
* groonga >= 0.1.
|
40
|
+
* groonga >= 0.1.4
|
37
41
|
|
38
42
|
== Install
|
39
43
|
|
@@ -54,5 +58,7 @@ http://rubyforge.org/mailman/listinfo/groonga-users-en
|
|
54
58
|
* mori: sent patches to support the latest groonga.
|
55
59
|
* Tasuku SUENAGA: sent bug reports.
|
56
60
|
* niku: sent bug reports.
|
57
|
-
* dara:
|
61
|
+
* dara:
|
62
|
+
* wrote tests.
|
63
|
+
* fixed bugs.
|
58
64
|
* id:mat_aki: sent bug reports.
|
data/Rakefile
CHANGED
@@ -54,7 +54,7 @@ base_dir_included_components = %w(AUTHORS Rakefile
|
|
54
54
|
TUTORIAL.ja.rdoc
|
55
55
|
extconf.rb pkg-config.rb)
|
56
56
|
excluded_components = %w(.cvsignore .gdb_history CVS depend Makefile pkg
|
57
|
-
.svn .git doc vendor .test-result)
|
57
|
+
.svn .git doc vendor data .test-result)
|
58
58
|
excluded_suffixes = %w(.png .ps .pdf .o .so .a .txt .~)
|
59
59
|
Find.find(base_dir) do |target|
|
60
60
|
target = truncate_base_dir[target]
|
data/TUTORIAL.ja.rdoc
CHANGED
@@ -53,7 +53,7 @@ groongaには以下の3種類のテーブルがあります。
|
|
53
53
|
ここではハッシュテーブルを利用して、<tt><items></tt>という名前のテー
|
54
54
|
ブルを作成します。
|
55
55
|
|
56
|
-
>> items = Groonga::Hash.create(:name => "<items>"
|
56
|
+
>> items = Groonga::Hash.create(:name => "<items>")
|
57
57
|
=> #<Groonga::Hash ...>
|
58
58
|
|
59
59
|
|
@@ -93,7 +93,7 @@ groongaには以下の3種類のテーブルがあります。
|
|
93
93
|
|
94
94
|
まず<tt><items></tt>テーブルに+title+という名前のカラムを追加します。
|
95
95
|
|
96
|
-
>> title_column = items.define_column("title", "<text>"
|
96
|
+
>> title_column = items.define_column("title", "<text>")
|
97
97
|
=> #<Groonga::VarSizeColumn ...>
|
98
98
|
|
99
99
|
2番目の引数は、追加するカラムのデータ型を示しています。
|
@@ -106,7 +106,6 @@ groongaには以下の3種類のテーブルがあります。
|
|
106
106
|
|
107
107
|
>> terms = Groonga::Hash.create(:name => "<terms>",
|
108
108
|
:key_type => "<shorttext>",
|
109
|
-
:persistent => true,
|
110
109
|
:default_tokenizer => "<token:bigram>")
|
111
110
|
=> #<Groonga::Hash ...>
|
112
111
|
|
@@ -126,7 +125,6 @@ N-gramを利用した全文検索では、分解したN文字とその出現位
|
|
126
125
|
ルの+title+カラムに対するインデックスを定義します。
|
127
126
|
|
128
127
|
>> title_index_column = terms.define_index_column("item_title", items,
|
129
|
-
:persistent => true,
|
130
128
|
:source => "<items>.title")
|
131
129
|
=> #<Groonga::IndexColumn ...>
|
132
130
|
|
@@ -187,8 +185,7 @@ http://qwik.jp/senna/senna2.files/rect4605.png
|
|
187
185
|
|
188
186
|
次に、<tt><comments></tt>テーブルを追加します。
|
189
187
|
|
190
|
-
>> comments = Groonga::Array.create(:name => "<comments>"
|
191
|
-
:key_type => "<shorttext>")
|
188
|
+
>> comments = Groonga::Array.create(:name => "<comments>")
|
192
189
|
=> #<Groonga::Array ...>
|
193
190
|
>> comments.define_column("item", items)
|
194
191
|
=> #<Groonga::FixSizeColumn ..>
|
data/example/bookmark.rb
CHANGED
@@ -107,7 +107,7 @@ p add_bookmark("http://d.hatena.ne.jp/higepon/20070815/1187192864",
|
|
107
107
|
"末尾再帰", "taporobo", "末尾再帰 Scheme LISP", 1187568793)
|
108
108
|
p add_bookmark("http://practical-scheme.net/docs/cont-j.html",
|
109
109
|
"なんでも継続", "taporobo", "トランポリン LISP continuation",
|
110
|
-
1187568692)
|
110
|
+
1187568692.98765)
|
111
111
|
p add_bookmark("http://jp.rubyist.net/managinze",
|
112
112
|
"るびま", "moritan", "Ruby ドキュメント",
|
113
113
|
Time.now)
|
data/example/search/config.ru
CHANGED
@@ -71,8 +71,8 @@ EOF
|
|
71
71
|
request['query'] || ''
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
74
|
+
def page(request)
|
75
|
+
(request['page'] || 0).to_i
|
76
76
|
end
|
77
77
|
|
78
78
|
def render_search_box(request, response)
|
@@ -88,8 +88,10 @@ EOF
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def render_search_result(request, response)
|
91
|
-
|
92
|
-
|
91
|
+
_query = query(request)
|
92
|
+
_page = page(request)
|
93
|
+
limit = 20
|
94
|
+
if _query.empty?
|
93
95
|
records = []
|
94
96
|
response.write(<<-EOS)
|
95
97
|
<div class='search-summary'>
|
@@ -97,25 +99,16 @@ EOF
|
|
97
99
|
</div>
|
98
100
|
EOS
|
99
101
|
else
|
100
|
-
offset = 0
|
101
102
|
options = {}
|
102
103
|
before = Time.now
|
103
104
|
records = @documents.select do |record|
|
104
|
-
|
105
|
-
_words.each do |word|
|
106
|
-
sub_expression = record["content"] =~ word
|
107
|
-
if expression.nil?
|
108
|
-
expression = sub_expression
|
109
|
-
else
|
110
|
-
expression &= sub_expression
|
111
|
-
end
|
112
|
-
end
|
113
|
-
expression
|
105
|
+
record["content"].match(_query)
|
114
106
|
end
|
115
107
|
total_records = records.size
|
116
108
|
records = records.sort([[".:score", "descending"],
|
117
109
|
[".last-modified", "descending"]],
|
118
|
-
:
|
110
|
+
:offset => _page * limit,
|
111
|
+
:limit => limit)
|
119
112
|
elapsed = Time.now - before
|
120
113
|
|
121
114
|
response.write(<<-EOS)
|
@@ -124,9 +117,9 @@ EOS
|
|
124
117
|
<span class="keyword">#{escape_html(query(request))}</span>の検索結果:
|
125
118
|
<span class="total-entries">#{total_records}</span>件中
|
126
119
|
<span class="display-range">
|
127
|
-
#{total_records.zero? ? 0 :
|
120
|
+
#{total_records.zero? ? 0 : _page + 1}
|
128
121
|
-
|
129
|
-
#{
|
122
|
+
#{_page + records.size}
|
130
123
|
</span>
|
131
124
|
件(#{elapsed}秒)
|
132
125
|
</p>
|
@@ -139,6 +132,8 @@ EOS
|
|
139
132
|
render_record(request, response, record)
|
140
133
|
end
|
141
134
|
response.write(" </div>\n")
|
135
|
+
|
136
|
+
# render_pagination(request, response, _page, limit)
|
142
137
|
end
|
143
138
|
|
144
139
|
def render_record(request, response, record)
|
@@ -160,16 +155,11 @@ EOM
|
|
160
155
|
end
|
161
156
|
|
162
157
|
def render_snippet(request, response, record)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
:html_escape => true,
|
169
|
-
:normalize => true)
|
170
|
-
words(request).each do |word|
|
171
|
-
snippet.add_keyword(word)
|
172
|
-
end
|
158
|
+
expression = record.table.expression
|
159
|
+
snippet = expression.snippet([["<span class=\"keyword\">", "</span>"]],
|
160
|
+
:width => 100,
|
161
|
+
:html_escape => true,
|
162
|
+
:normalize => true)
|
173
163
|
separator = "\n<span class='separator'>...</span>\n"
|
174
164
|
response.write(<<-EOS)
|
175
165
|
<p class="snippet">
|
@@ -177,6 +167,40 @@ EOM
|
|
177
167
|
</p>
|
178
168
|
EOS
|
179
169
|
end
|
170
|
+
|
171
|
+
def render_pagination(request, response, page, limit)
|
172
|
+
_query = query(request)
|
173
|
+
return if _query.empty?
|
174
|
+
|
175
|
+
total_records = @documents.size
|
176
|
+
return if total_records < limit
|
177
|
+
|
178
|
+
last_page = total_records / limit
|
179
|
+
response.write("<div class='pagination'>\n")
|
180
|
+
if page > 0
|
181
|
+
render_pagination_link(request, response, _query, page - 1, "<<")
|
182
|
+
end
|
183
|
+
last_page.times do |i|
|
184
|
+
if i == page
|
185
|
+
response.write(pagination_span(escape_html(i)))
|
186
|
+
else
|
187
|
+
render_pagination_link(request, response, _query, i, i)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
if page < last_page
|
191
|
+
render_pagination_link(request, response, _query, page + 1, ">>")
|
192
|
+
end
|
193
|
+
response.write("</div>\n")
|
194
|
+
end
|
195
|
+
|
196
|
+
def render_pagination_link(request, response, query, page, label)
|
197
|
+
href = "./?query=#{escape_html(query)};page=#{escape_html(page)}"
|
198
|
+
response.write(pagination_span("<a href='#{href}'>#{label}</a>"))
|
199
|
+
end
|
200
|
+
|
201
|
+
def pagination_span(content)
|
202
|
+
"<span class='pagination-link'>#{content}</span>\n"
|
203
|
+
end
|
180
204
|
end
|
181
205
|
|
182
206
|
run Searcher.new
|
data/ext/rb-grn-column.c
CHANGED
@@ -167,33 +167,37 @@ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
|
|
167
167
|
grn_ctx *context;
|
168
168
|
grn_obj *table, *column, *result, *expression;
|
169
169
|
grn_operator operator = GRN_OP_OR;
|
170
|
-
grn_rc rc;
|
171
170
|
VALUE options;
|
172
|
-
VALUE rb_query, rb_name, rb_operator, rb_result;
|
173
|
-
|
174
|
-
|
171
|
+
VALUE rb_query, rb_query_or_options, rb_name, rb_operator, rb_result;
|
172
|
+
VALUE builder;
|
173
|
+
VALUE rb_expression;
|
174
|
+
|
175
|
+
rb_query = Qnil;
|
175
176
|
|
176
|
-
rb_scan_args(argc, argv, "
|
177
|
-
|
178
|
-
query = StringValueCStr(rb_query);
|
179
|
-
query_size = RSTRING_LEN(rb_query);
|
177
|
+
rb_scan_args(argc, argv, "02", &rb_query_or_options, &options);
|
180
178
|
|
181
179
|
rb_grn_column_deconstruct(SELF(self), &column, &context,
|
182
180
|
NULL, NULL,
|
183
181
|
NULL, NULL, NULL);
|
184
182
|
table = grn_column_table(context, column);
|
185
183
|
|
184
|
+
if (RVAL2CBOOL(rb_obj_is_kind_of(rb_query_or_options, rb_cString))) {
|
185
|
+
rb_query = rb_query_or_options;
|
186
|
+
} else {
|
187
|
+
if (!NIL_P(options))
|
188
|
+
rb_raise(rb_eArgError,
|
189
|
+
"should be [query_string, option_hash] "
|
190
|
+
"or [option_hash]: %s",
|
191
|
+
rb_grn_inspect(rb_ary_new4(argc, argv)));
|
192
|
+
options = rb_query_or_options;
|
193
|
+
}
|
194
|
+
|
186
195
|
rb_grn_scan_options(options,
|
187
196
|
"operator", &rb_operator,
|
188
197
|
"result", &rb_result,
|
189
198
|
"name", &rb_name,
|
190
199
|
NULL);
|
191
200
|
|
192
|
-
if (!NIL_P(rb_name)) {
|
193
|
-
name = StringValueCStr(rb_name);
|
194
|
-
name_size = RSTRING_LEN(rb_name);
|
195
|
-
}
|
196
|
-
|
197
201
|
if (!NIL_P(rb_operator))
|
198
202
|
operator = NUM2INT(rb_operator);
|
199
203
|
|
@@ -207,12 +211,14 @@ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
|
|
207
211
|
result = RVAL2GRNTABLE(rb_result, &context);
|
208
212
|
}
|
209
213
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
+
builder = rb_grn_column_expression_builder_new(self, rb_name, rb_query);
|
215
|
+
rb_expression = rb_grn_column_expression_builder_build(builder);
|
216
|
+
rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
|
217
|
+
&expression, NULL,
|
218
|
+
NULL, NULL, NULL, NULL);
|
219
|
+
|
220
|
+
grn_table_select(context, table, expression, result, operator);
|
214
221
|
rb_grn_context_check(context, self);
|
215
|
-
rb_grn_rc_check(rc, self);
|
216
222
|
|
217
223
|
return rb_result;
|
218
224
|
}
|
data/ext/rb-grn-context.c
CHANGED
@@ -53,7 +53,23 @@ rb_grn_context_from_ruby_object (VALUE object)
|
|
53
53
|
Data_Get_Struct(object, RbGrnContext, rb_grn_context);
|
54
54
|
if (!rb_grn_context)
|
55
55
|
rb_raise(rb_eGrnError, "groonga context is NULL");
|
56
|
-
return
|
56
|
+
return rb_grn_context->context;
|
57
|
+
}
|
58
|
+
|
59
|
+
void
|
60
|
+
rb_grn_context_fin (grn_ctx *context)
|
61
|
+
{
|
62
|
+
grn_obj *database;
|
63
|
+
|
64
|
+
if (context->stat == GRN_CTX_FIN)
|
65
|
+
return;
|
66
|
+
|
67
|
+
database = grn_ctx_db(context);
|
68
|
+
debug("context:database: %p:%p\n", context, database);
|
69
|
+
if (database && database->header.type == GRN_DB) {
|
70
|
+
grn_obj_close(context, database);
|
71
|
+
}
|
72
|
+
grn_ctx_fin(context);
|
57
73
|
}
|
58
74
|
|
59
75
|
static void
|
@@ -62,22 +78,12 @@ rb_grn_context_free (void *pointer)
|
|
62
78
|
RbGrnContext *rb_grn_context = pointer;
|
63
79
|
grn_ctx *context;
|
64
80
|
|
65
|
-
context =
|
81
|
+
context = rb_grn_context->context;
|
66
82
|
debug("context-free: %p\n", context);
|
67
|
-
if (
|
68
|
-
|
69
|
-
|
70
|
-
database = grn_ctx_db(context);
|
71
|
-
debug("context:database: %p:%p\n", context, database);
|
72
|
-
if (database && database->header.type == GRN_DB) {
|
73
|
-
grn_obj_close(context, database);
|
74
|
-
}
|
75
|
-
grn_ctx_fin(context);
|
76
|
-
}
|
83
|
+
if (!rb_grn_exited)
|
84
|
+
rb_grn_context_fin(context);
|
77
85
|
debug("context-free: %p: done\n", context);
|
78
86
|
xfree(rb_grn_context);
|
79
|
-
|
80
|
-
GRN_CTX_USER_DATA(context)->ptr = NULL;
|
81
87
|
}
|
82
88
|
|
83
89
|
static VALUE
|
@@ -142,6 +148,34 @@ rb_grn_context_ensure (VALUE *context)
|
|
142
148
|
return SELF(*context);
|
143
149
|
}
|
144
150
|
|
151
|
+
VALUE
|
152
|
+
rb_grn_context_rb_string_new (grn_ctx *context, const char *string, long length)
|
153
|
+
{
|
154
|
+
if (length < 0)
|
155
|
+
length = strlen(string);
|
156
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
157
|
+
return rb_enc_str_new(string, length,
|
158
|
+
rb_grn_encoding_to_ruby_encoding(context->encoding));
|
159
|
+
#else
|
160
|
+
return rb_str_new(string, length);
|
161
|
+
#endif
|
162
|
+
}
|
163
|
+
|
164
|
+
VALUE
|
165
|
+
rb_grn_context_rb_string_encode (grn_ctx *context, VALUE rb_string)
|
166
|
+
{
|
167
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
168
|
+
rb_encoding *encoding, *to_encode;
|
169
|
+
|
170
|
+
encoding = rb_enc_get(rb_string);
|
171
|
+
to_encode = rb_grn_encoding_to_ruby_encoding(context->encoding);
|
172
|
+
if (rb_enc_to_index(encoding) != rb_enc_to_index(to_encode))
|
173
|
+
rb_string = rb_str_encode(rb_string, rb_enc_from_encoding(to_encode),
|
174
|
+
0, Qnil);
|
175
|
+
#endif
|
176
|
+
return rb_string;
|
177
|
+
}
|
178
|
+
|
145
179
|
/*
|
146
180
|
* call-seq:
|
147
181
|
* Groonga::Context.default -> Groonga::Context
|
@@ -233,7 +267,6 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
|
|
233
267
|
RbGrnContext *rb_grn_context;
|
234
268
|
grn_ctx *context;
|
235
269
|
int flags = 0;
|
236
|
-
grn_rc rc;
|
237
270
|
VALUE options, default_options;
|
238
271
|
VALUE rb_encoding;
|
239
272
|
|
@@ -252,8 +285,7 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
|
|
252
285
|
|
253
286
|
rb_grn_context = ALLOC(RbGrnContext);
|
254
287
|
DATA_PTR(self) = rb_grn_context;
|
255
|
-
context =
|
256
|
-
rc = grn_ctx_init(context, flags);
|
288
|
+
context = rb_grn_context->context = grn_ctx_open(flags);
|
257
289
|
rb_grn_context_check(context, self);
|
258
290
|
|
259
291
|
GRN_CTX_USER_DATA(context)->ptr = rb_grn_context;
|
@@ -351,6 +383,108 @@ rb_grn_context_get_database (VALUE self)
|
|
351
383
|
return GRNDB2RVAL(context, grn_ctx_db(context), RB_GRN_FALSE);
|
352
384
|
}
|
353
385
|
|
386
|
+
/*
|
387
|
+
* call-seq:
|
388
|
+
* context.connect(options=nil)
|
389
|
+
*
|
390
|
+
* groongaサーバに接続する。_options_に指定可能な値は以下の通
|
391
|
+
* り。
|
392
|
+
*
|
393
|
+
* [+:host+]
|
394
|
+
* groongaサーバのホスト名。またはIPアドレス。省略すると
|
395
|
+
* "localhost"に接続する。
|
396
|
+
*
|
397
|
+
* [+:port+]
|
398
|
+
* groongaサーバのポート番号。省略すると10041番ポートに接
|
399
|
+
* 続する。
|
400
|
+
*/
|
401
|
+
static VALUE
|
402
|
+
rb_grn_context_connect (int argc, VALUE *argv, VALUE self)
|
403
|
+
{
|
404
|
+
grn_ctx *context;
|
405
|
+
char *host;
|
406
|
+
int port;
|
407
|
+
int flags = 0;
|
408
|
+
grn_rc rc;
|
409
|
+
VALUE options, rb_host, rb_port;
|
410
|
+
|
411
|
+
rb_scan_args(argc, argv, "01", &options);
|
412
|
+
rb_grn_scan_options(options,
|
413
|
+
"host", &rb_host,
|
414
|
+
"port", &rb_port,
|
415
|
+
NULL);
|
416
|
+
|
417
|
+
context = SELF(self);
|
418
|
+
|
419
|
+
if (NIL_P(rb_host)) {
|
420
|
+
host = "localhost";
|
421
|
+
} else {
|
422
|
+
host = StringValueCStr(rb_host);
|
423
|
+
}
|
424
|
+
|
425
|
+
if (NIL_P(rb_port)) {
|
426
|
+
port = 10041;
|
427
|
+
} else {
|
428
|
+
port = NUM2INT(rb_port);
|
429
|
+
}
|
430
|
+
|
431
|
+
rc = grn_ctx_connect(context, host, port, flags);
|
432
|
+
rb_grn_context_check(context, self);
|
433
|
+
rb_grn_rc_check(rc, self);
|
434
|
+
|
435
|
+
return Qnil;
|
436
|
+
}
|
437
|
+
|
438
|
+
/*
|
439
|
+
* call-seq:
|
440
|
+
* context.send(string) -> ID
|
441
|
+
*
|
442
|
+
* groongaサーバにクエリ文字列を送信する。
|
443
|
+
*
|
444
|
+
* 実験的: APIが変わる可能性があります。
|
445
|
+
*/
|
446
|
+
static VALUE
|
447
|
+
rb_grn_context_send (VALUE self, VALUE rb_string)
|
448
|
+
{
|
449
|
+
grn_ctx *context;
|
450
|
+
char *string;
|
451
|
+
unsigned int string_size;
|
452
|
+
int flags = 0;
|
453
|
+
unsigned int query_id;
|
454
|
+
|
455
|
+
context = SELF(self);
|
456
|
+
string = StringValuePtr(rb_string);
|
457
|
+
string_size = RSTRING_LEN(rb_string);
|
458
|
+
query_id = grn_ctx_send(context, string, string_size, flags);
|
459
|
+
rb_grn_context_check(context, self);
|
460
|
+
|
461
|
+
return UINT2NUM(query_id);
|
462
|
+
}
|
463
|
+
|
464
|
+
/*
|
465
|
+
* call-seq:
|
466
|
+
* context.receive -> [ID, String]
|
467
|
+
*
|
468
|
+
* groongaサーバからクエリ実行結果文字列を受信する。
|
469
|
+
*
|
470
|
+
* 実験的: APIが変わる可能性があります。
|
471
|
+
*/
|
472
|
+
static VALUE
|
473
|
+
rb_grn_context_receive (VALUE self)
|
474
|
+
{
|
475
|
+
grn_ctx *context;
|
476
|
+
char *string;
|
477
|
+
unsigned string_size;
|
478
|
+
int flags = 0;
|
479
|
+
unsigned int query_id;
|
480
|
+
|
481
|
+
context = SELF(self);
|
482
|
+
query_id = grn_ctx_recv(context, &string, &string_size, &flags);
|
483
|
+
rb_grn_context_check(context, self);
|
484
|
+
|
485
|
+
return rb_ary_new3(2, UINT2NUM(query_id), rb_str_new(string, string_size));
|
486
|
+
}
|
487
|
+
|
354
488
|
static const char *
|
355
489
|
grn_type_name_old_to_new (const char *name, unsigned int name_size)
|
356
490
|
{
|
@@ -472,6 +606,14 @@ rb_grn_context_array_reference (VALUE self, VALUE name_or_id)
|
|
472
606
|
return GRNOBJECT2RVAL(Qnil, context, object, RB_GRN_FALSE);
|
473
607
|
}
|
474
608
|
|
609
|
+
static VALUE
|
610
|
+
rb_grn_context_pop (VALUE self)
|
611
|
+
{
|
612
|
+
grn_ctx *context;
|
613
|
+
context = SELF(self);
|
614
|
+
return GRNOBJ2RVAL(Qnil, context, grn_ctx_pop(context), self);
|
615
|
+
}
|
616
|
+
|
475
617
|
void
|
476
618
|
rb_grn_init_context (VALUE mGrn)
|
477
619
|
{
|
@@ -500,4 +642,10 @@ rb_grn_init_context (VALUE mGrn)
|
|
500
642
|
rb_define_method(cGrnContext, "database", rb_grn_context_get_database, 0);
|
501
643
|
|
502
644
|
rb_define_method(cGrnContext, "[]", rb_grn_context_array_reference, 1);
|
645
|
+
|
646
|
+
rb_define_method(cGrnContext, "pop", rb_grn_context_pop, 0);
|
647
|
+
|
648
|
+
rb_define_method(cGrnContext, "connect", rb_grn_context_connect, -1);
|
649
|
+
rb_define_method(cGrnContext, "send", rb_grn_context_send, 1);
|
650
|
+
rb_define_method(cGrnContext, "receive", rb_grn_context_receive, 0);
|
503
651
|
}
|