groonga 0.0.6 → 0.0.7
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/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
|
}
|