rroonga 1.3.0 → 1.3.1

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.
@@ -211,13 +211,31 @@ VALUE
211
211
  rb_grn_context_rb_string_encode (grn_ctx *context, VALUE rb_string)
212
212
  {
213
213
  #ifdef HAVE_RUBY_ENCODING_H
214
- rb_encoding *encoding, *to_encode;
214
+ int index, to_index;
215
+ rb_encoding *encoding, *to_encoding;
216
+ grn_encoding context_encoding;
217
+
218
+ context_encoding = context->encoding;
219
+ if (context->encoding == GRN_ENC_DEFAULT)
220
+ context->encoding = grn_get_default_encoding();
221
+ if (context->encoding == GRN_ENC_NONE)
222
+ return rb_string;
223
+
224
+ if (RSTRING_LEN(rb_string) < 0)
225
+ return rb_string;
215
226
 
216
227
  encoding = rb_enc_get(rb_string);
217
- to_encode = rb_grn_encoding_to_ruby_encoding(context->encoding);
218
- if (rb_enc_to_index(encoding) != rb_enc_to_index(to_encode))
219
- rb_string = rb_str_encode(rb_string, rb_enc_from_encoding(to_encode),
220
- 0, Qnil);
228
+ to_encoding = rb_grn_encoding_to_ruby_encoding(context_encoding);
229
+ index = rb_enc_to_index(encoding);
230
+ to_index = rb_enc_to_index(to_encoding);
231
+ if (index == to_index)
232
+ return rb_string;
233
+
234
+ if (rb_enc_asciicompat(to_encoding) && rb_enc_str_asciionly_p(rb_string))
235
+ return rb_string;
236
+
237
+ rb_string = rb_str_encode(rb_string, rb_enc_from_encoding(to_encoding),
238
+ 0, Qnil);
221
239
  #endif
222
240
  return rb_string;
223
241
  }
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -453,11 +453,7 @@ rb_grn_index_column_search (int argc, VALUE *argv, VALUE self)
453
453
 
454
454
  rb_scan_args(argc, argv, "11", &rb_query, &options);
455
455
 
456
- if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cGrnQuery))) {
457
- grn_query *_query;
458
- _query = RVAL2GRNQUERY(rb_query);
459
- query = (grn_obj *)_query;
460
- } else if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cInteger))) {
456
+ if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cInteger))) {
461
457
  grn_id id;
462
458
  id = NUM2UINT(rb_query);
463
459
  GRN_TEXT_SET(context, id_query, &id, sizeof(grn_id));
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,36 @@
20
20
 
21
21
  VALUE rb_mGrnOperator;
22
22
 
23
+ grn_operator
24
+ rb_grn_operator_from_ruby_object (VALUE rb_operator)
25
+ {
26
+ grn_operator operator = GRN_OP_OR;
27
+
28
+ if (NIL_P(rb_operator) ||
29
+ rb_grn_equal_option(rb_operator, "or") ||
30
+ rb_grn_equal_option(rb_operator, "||")) {
31
+ operator = GRN_OP_OR;
32
+ } else if (rb_grn_equal_option(rb_operator, "and") ||
33
+ rb_grn_equal_option(rb_operator, "+") ||
34
+ rb_grn_equal_option(rb_operator, "&&")) {
35
+ operator = GRN_OP_AND;
36
+ } else if (rb_grn_equal_option(rb_operator, "but") ||
37
+ rb_grn_equal_option(rb_operator, "not") ||
38
+ rb_grn_equal_option(rb_operator, "-")) {
39
+ operator = GRN_OP_BUT;
40
+ } else if (rb_grn_equal_option(rb_operator, "adjust") ||
41
+ rb_grn_equal_option(rb_operator, ">")) {
42
+ operator = GRN_OP_ADJUST;
43
+ } else {
44
+ rb_raise(rb_eArgError,
45
+ "operator should be one of "
46
+ "[:or, :||, :and, :+, :&&, :but, :not, :-, :adjust, :>]: <%s>",
47
+ rb_grn_inspect(rb_operator));
48
+ }
49
+
50
+ return operator;
51
+ }
52
+
23
53
  void
24
54
  rb_grn_init_operator (VALUE mGrn)
25
55
  {
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,80 @@ VALUE rb_cGrnVariableSizeColumn;
28
28
  * 可変長データ用のカラム。
29
29
  */
30
30
 
31
+ /*
32
+ * Document-method: compressed?
33
+ *
34
+ * call-seq:
35
+ * column.compressed? -> boolean
36
+ * column.compressed?(type) -> boolean
37
+ *
38
+ * Returns whether the column is compressed or not. If
39
+ * @type@ is specified, it returns whether the column is
40
+ * compressed by @type@ or not.
41
+ *
42
+ * @return [Boolean] whether the column is compressed or not.
43
+ * @param [:zlib, :lzo] type (nil) If @type@ isn't @nil@,
44
+ * it checks whether specified compressed type is used or
45
+ * not.
46
+ * @since 1.3.1
47
+ */
48
+ static VALUE
49
+ rb_grn_variable_size_column_compressed_p (int argc, VALUE *argv, VALUE self)
50
+ {
51
+ RbGrnColumn *rb_grn_column;
52
+ grn_ctx *context = NULL;
53
+ grn_obj *column;
54
+ grn_obj_flags flags;
55
+ VALUE type;
56
+ grn_bool compressed_p = GRN_FALSE;
57
+ grn_bool accept_any_type = GRN_FALSE;
58
+ grn_bool need_zlib_check = GRN_FALSE;
59
+ grn_bool need_lzo_check = GRN_FALSE;
60
+
61
+ rb_scan_args(argc, argv, "01", &type);
62
+
63
+ if (NIL_P(type)) {
64
+ accept_any_type = GRN_TRUE;
65
+ } else {
66
+ if (rb_grn_equal_option(type, "zlib")) {
67
+ need_zlib_check = GRN_TRUE;
68
+ } else if (rb_grn_equal_option(type, "lzo")) {
69
+ need_lzo_check = GRN_TRUE;
70
+ } else {
71
+ rb_raise(rb_eArgError,
72
+ "compressed type should be <:zlib> or <:lzo>: <%s>",
73
+ rb_grn_inspect(type));
74
+ }
75
+ }
76
+
77
+ rb_grn_column = SELF(self);
78
+ rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
79
+ NULL, NULL,
80
+ NULL, NULL);
81
+
82
+ flags = column->header.flags;
83
+ switch (flags & GRN_OBJ_COMPRESS_MASK) {
84
+ case GRN_OBJ_COMPRESS_ZLIB:
85
+ if (accept_any_type || need_zlib_check) {
86
+ grn_obj support_p;
87
+ GRN_BOOL_INIT(&support_p, 0);
88
+ grn_obj_get_info(context, NULL, GRN_INFO_SUPPORT_ZLIB, &support_p);
89
+ compressed_p = GRN_BOOL_VALUE(&support_p);
90
+ }
91
+ break;
92
+ case GRN_OBJ_COMPRESS_LZO:
93
+ if (accept_any_type || need_lzo_check) {
94
+ grn_obj support_p;
95
+ GRN_BOOL_INIT(&support_p, 0);
96
+ grn_obj_get_info(context, NULL, GRN_INFO_SUPPORT_LZO, &support_p);
97
+ compressed_p = GRN_BOOL_VALUE(&support_p);
98
+ }
99
+ break;
100
+ }
101
+
102
+ return CBOOL2RVAL(compressed_p);
103
+ }
104
+
31
105
  /*
32
106
  * Document-method: defrag
33
107
  *
@@ -77,6 +151,8 @@ rb_grn_init_variable_size_column (VALUE mGrn)
77
151
  rb_cGrnVariableSizeColumn =
78
152
  rb_define_class_under(mGrn, "VariableSizeColumn", rb_cGrnColumn);
79
153
 
154
+ rb_define_method(rb_cGrnVariableSizeColumn, "compressed?",
155
+ rb_grn_variable_size_column_compressed_p, -1);
80
156
  rb_define_method(rb_cGrnVariableSizeColumn, "defrag",
81
157
  rb_grn_variable_size_column_defrag, -1);
82
158
  }
data/ext/groonga/rb-grn.h CHANGED
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -72,7 +72,7 @@ RB_GRN_BEGIN_DECLS
72
72
 
73
73
  #define RB_GRN_MAJOR_VERSION 1
74
74
  #define RB_GRN_MINOR_VERSION 3
75
- #define RB_GRN_MICRO_VERSION 0
75
+ #define RB_GRN_MICRO_VERSION 1
76
76
 
77
77
  #define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
78
78
 
@@ -227,7 +227,6 @@ RB_GRN_VAR VALUE rb_cGrnAccessor;
227
227
  RB_GRN_VAR VALUE rb_cGrnViewAccessor;
228
228
  RB_GRN_VAR VALUE rb_cGrnRecord;
229
229
  RB_GRN_VAR VALUE rb_cGrnViewRecord;
230
- RB_GRN_VAR VALUE rb_cGrnQuery;
231
230
  RB_GRN_VAR VALUE rb_cGrnLogger;
232
231
  RB_GRN_VAR VALUE rb_cGrnSnippet;
233
232
  RB_GRN_VAR VALUE rb_cGrnVariable;
@@ -270,7 +269,6 @@ void rb_grn_init_accessor (VALUE mGrn);
270
269
  void rb_grn_init_view_accessor (VALUE mGrn);
271
270
  void rb_grn_init_record (VALUE mGrn);
272
271
  void rb_grn_init_view_record (VALUE mGrn);
273
- void rb_grn_init_query (VALUE mGrn);
274
272
  void rb_grn_init_variable (VALUE mGrn);
275
273
  void rb_grn_init_operator (VALUE mGrn);
276
274
  void rb_grn_init_expression (VALUE mGrn);
@@ -555,9 +553,6 @@ VALUE rb_grn_column_expression_builder_build
555
553
  #define GRNACCESSOR2RVAL(context, accessor, owner) \
556
554
  (rb_grn_accessor_to_ruby_object(context, accessor, owner))
557
555
 
558
- #define RVAL2GRNQUERY(object) (rb_grn_query_from_ruby_object(object))
559
- #define GRNQUERY2RVAL(context, column)(rb_grn_query_to_ruby_object(context, column))
560
-
561
556
  #define RVAL2GRNOPERATOR(object) (rb_grn_operator_from_ruby_object(object))
562
557
 
563
558
  #define RVAL2GRNLOGGER(object) (rb_grn_logger_from_ruby_object(object))
@@ -665,10 +660,6 @@ VALUE rb_grn_index_cursor_to_ruby_object (grn_ctx *context,
665
660
  grn_obj *cursor,
666
661
  grn_bool owner);
667
662
 
668
- grn_query *rb_grn_query_from_ruby_object (VALUE object);
669
- VALUE rb_grn_query_to_ruby_object (grn_ctx *context,
670
- grn_query *query);
671
-
672
663
  grn_operator rb_grn_operator_from_ruby_object (VALUE object);
673
664
 
674
665
  grn_logger_info *
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -138,7 +138,6 @@ Init_groonga (void)
138
138
  rb_grn_init_view_accessor(mGrn);
139
139
  rb_grn_init_record(mGrn);
140
140
  rb_grn_init_view_record(mGrn);
141
- rb_grn_init_query(mGrn);
142
141
  rb_grn_init_variable(mGrn);
143
142
  rb_grn_init_operator(mGrn);
144
143
  rb_grn_init_expression(mGrn);
@@ -0,0 +1,169 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ module Groonga
19
+ module Command
20
+ class Builder
21
+ class << self
22
+ def escape_value(value)
23
+ escaped_value = value.to_s.gsub(/"/, '\\"')
24
+ "\"#{escaped_value}\""
25
+ end
26
+ end
27
+
28
+ attr_reader :command, :arguments
29
+ def initialize(command, arguments={})
30
+ @command = command
31
+ @arguments = arguments
32
+ end
33
+
34
+ def [](key)
35
+ @arguments[key]
36
+ end
37
+
38
+ def []=(key, value)
39
+ @arguments[key] = value
40
+ end
41
+
42
+ def build
43
+ query = "#{@command} "
44
+ @arguments.each do |key, value|
45
+ value = value.join(", ") if value.is_a?(::Array)
46
+ escaped_value = self.class.escape_value(value)
47
+ query << " --#{key} #{escaped_value}"
48
+ end
49
+ query
50
+ end
51
+ end
52
+
53
+ class Select
54
+ def initialize(context, table, options)
55
+ @context = context
56
+ @table = table
57
+ @options = normalize_options(options)
58
+ end
59
+
60
+ def exec
61
+ request_id = @context.send(query)
62
+ loop do
63
+ response_id, result = @context.receive
64
+ if request_id == response_id
65
+ drill_down_keys = @options["drilldown"]
66
+ if drill_down_keys.is_a?(String)
67
+ drill_down_keys = drill_down_keys.split(/(?:\s+|\s*,\s*)/)
68
+ end
69
+ return Result.parse(result, drill_down_keys)
70
+ end
71
+ # raise if request_id < response_id
72
+ end
73
+ end
74
+
75
+ private
76
+ def normalize_options(options)
77
+ normalized_options = {}
78
+ options.each do |key, value|
79
+ normalized_options[normalize_option_name(key)] = value
80
+ end
81
+ normalized_options
82
+ end
83
+
84
+ def normalize_option_name(name)
85
+ name = name.to_s.gsub(/-/, "_").gsub(/drill_down/, "drilldown")
86
+ name.gsub(/sort_by/, 'sortby')
87
+ end
88
+
89
+ def query
90
+ if @table.is_a?(String)
91
+ table_name = @table
92
+ else
93
+ table_name = @table.name
94
+ end
95
+ builder = Builder.new("select", @options.merge(:table => table_name))
96
+ builder.build
97
+ end
98
+
99
+ class Result < Struct.new(:n_hits, :columns, :values, :drill_down)
100
+ class << self
101
+ def parse(json, drill_down_keys)
102
+ select_result, *drill_down_results = JSON.parse(json)
103
+ result = new
104
+ n_hits, columns, values = extract_result(select_result)
105
+ result.n_hits = n_hits
106
+ result.columns = columns
107
+ result.values = values
108
+ if drill_down_results
109
+ result.drill_down = parse_drill_down_results(drill_down_results,
110
+ drill_down_keys)
111
+ end
112
+ result
113
+ end
114
+
115
+ def create_records(columns, values)
116
+ records = []
117
+ values.each do |value|
118
+ record = {}
119
+ columns.each_with_index do |(name, type), i|
120
+ record[name] = convert_value(value[i], type)
121
+ end
122
+ records << record
123
+ end
124
+ records
125
+ end
126
+
127
+ private
128
+ def parse_drill_down_results(results, keys)
129
+ named_results = {}
130
+ results.each_with_index do |drill_down, i|
131
+ n_hits, columns, values = extract_result(drill_down)
132
+ drill_down_result = DrillDownResult.new
133
+ drill_down_result.n_hits = n_hits
134
+ drill_down_result.columns = columns
135
+ drill_down_result.values = values
136
+ named_results[keys[i]] = drill_down_result
137
+ end
138
+ named_results
139
+ end
140
+
141
+ def extract_result(result)
142
+ meta_data, columns, *values = result
143
+ n_hits, = meta_data
144
+ [n_hits, columns, values]
145
+ end
146
+
147
+ def convert_value(value, type)
148
+ case type
149
+ when "Time"
150
+ Time.at(value)
151
+ else
152
+ value
153
+ end
154
+ end
155
+ end
156
+
157
+ def records
158
+ @records ||= self.class.create_records(columns, values)
159
+ end
160
+
161
+ class DrillDownResult < Struct.new(:n_hits, :columns, :values)
162
+ def records
163
+ @records ||= Result.create_records(columns, values)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2010-2011 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2010-2012 Kouhei Sutou <kou@clear-code.com>
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -15,6 +15,8 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
+ require "groonga/command"
19
+
18
20
  module Groonga
19
21
  class Context
20
22
  # _path_ にある既存のデータベースを開く。ブロックを指定した場
@@ -70,130 +72,8 @@ module Groonga
70
72
  # @option options [Array] XXX TODO
71
73
  # TODO
72
74
  def select(table, options={})
73
- select = SelectCommand.new(self, table, options)
75
+ select = Command::Select.new(self, table, options)
74
76
  select.exec
75
77
  end
76
-
77
- class SelectResult < Struct.new(:n_hits, :columns, :values,
78
- :drill_down)
79
- class << self
80
- def parse(json, drill_down_keys)
81
- select_result, *drill_down_results = JSON.parse(json)
82
- result = new
83
- n_hits, columns, values = extract_result(select_result)
84
- result.n_hits = n_hits
85
- result.columns = columns
86
- result.values = values
87
- if drill_down_results
88
- result.drill_down = parse_drill_down_results(drill_down_results,
89
- drill_down_keys)
90
- end
91
- result
92
- end
93
-
94
- def create_records(columns, values)
95
- records = []
96
- values.each do |value|
97
- record = {}
98
- columns.each_with_index do |(name, type), i|
99
- record[name] = convert_value(value[i], type)
100
- end
101
- records << record
102
- end
103
- records
104
- end
105
-
106
- private
107
- def parse_drill_down_results(results, keys)
108
- named_results = {}
109
- results.each_with_index do |drill_down, i|
110
- n_hits, columns, values = extract_result(drill_down)
111
- drill_down_result = DrillDownResult.new
112
- drill_down_result.n_hits = n_hits
113
- drill_down_result.columns = columns
114
- drill_down_result.values = values
115
- named_results[keys[i]] = drill_down_result
116
- end
117
- named_results
118
- end
119
-
120
- def extract_result(result)
121
- meta_data, columns, *values = result
122
- n_hits, = meta_data
123
- [n_hits, columns, values]
124
- end
125
-
126
- def convert_value(value, type)
127
- case type
128
- when "Time"
129
- Time.at(value)
130
- else
131
- value
132
- end
133
- end
134
- end
135
-
136
- def records
137
- @records ||= self.class.create_records(columns, values)
138
- end
139
-
140
- class DrillDownResult < Struct.new(:n_hits, :columns, :values)
141
- def records
142
- @records ||= SelectResult.create_records(columns, values)
143
- end
144
- end
145
- end
146
-
147
- class SelectCommand
148
- def initialize(context, table, options)
149
- @context = context
150
- @table = table
151
- @options = normalize_options(options)
152
- end
153
-
154
- def exec
155
- request_id = @context.send(query)
156
- loop do
157
- response_id, result = @context.receive
158
- if request_id == response_id
159
- drill_down_keys = @options["drilldown"]
160
- if drill_down_keys.is_a?(String)
161
- drill_down_keys = drill_down_keys.split(/(?:\s+|\s*,\s*)/)
162
- end
163
- return SelectResult.parse(result, drill_down_keys)
164
- end
165
- # raise if request_id < response_id
166
- end
167
- end
168
-
169
- private
170
- def normalize_options(options)
171
- normalized_options = {}
172
- options.each do |key, value|
173
- normalized_options[normalize_option_name(key)] = value
174
- end
175
- normalized_options
176
- end
177
-
178
- def normalize_option_name(name)
179
- name = name.to_s.gsub(/-/, "_").gsub(/drill_down/, "drilldown")
180
- name.gsub(/sort_by/, 'sortby')
181
- end
182
-
183
- def query
184
- if @table.is_a?(String)
185
- table_name = @table
186
- else
187
- table_name = @table.name
188
- end
189
- _query = "select #{table_name}"
190
- @options.each do |key, value|
191
- value = value.join(", ") if value.is_a?(::Array)
192
- escaped_value = value.to_s.gsub(/"/, '\\"')
193
- _query << " --#{key} \"#{escaped_value}\""
194
- end
195
- _query
196
- end
197
- end
198
78
  end
199
79
  end