rroonga 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/NEWS.ja.rdoc +29 -0
  2. data/NEWS.rdoc +29 -0
  3. data/Rakefile +5 -3
  4. data/ext/groonga/rb-grn-array.c +1 -1
  5. data/ext/groonga/rb-grn-context.c +15 -28
  6. data/ext/groonga/rb-grn-exception.c +46 -1
  7. data/ext/groonga/rb-grn-expression.c +22 -13
  8. data/ext/groonga/rb-grn-fix-size-column.c +2 -8
  9. data/ext/groonga/rb-grn-hash.c +8 -1
  10. data/ext/groonga/rb-grn-object.c +1 -1
  11. data/ext/groonga/rb-grn-patricia-trie.c +23 -1
  12. data/ext/groonga/rb-grn-table-key-support.c +22 -0
  13. data/ext/groonga/rb-grn-table.c +37 -5
  14. data/ext/groonga/rb-grn-utils.c +20 -2
  15. data/ext/groonga/rb-groonga.c +76 -38
  16. data/extconf.rb +17 -1
  17. data/html/developer.html +32 -7
  18. data/html/footer.html.erb +5 -0
  19. data/html/heading-mark.svg +393 -0
  20. data/html/index.html +33 -3
  21. data/lib/groonga.rb +3 -7
  22. data/lib/groonga/context.rb +2 -13
  23. data/lib/groonga/expression-builder.rb +273 -67
  24. data/lib/groonga/pagination.rb +143 -0
  25. data/lib/groonga/record.rb +2 -0
  26. data/lib/groonga/schema.rb +140 -29
  27. data/rroonga-build.rb +2 -2
  28. data/test-unit/Rakefile +40 -0
  29. data/test-unit/TODO +5 -0
  30. data/test-unit/bin/testrb +5 -0
  31. data/test-unit/html/classic.html +15 -0
  32. data/test-unit/html/index.html +25 -0
  33. data/test-unit/html/index.html.ja +27 -0
  34. data/test-unit/lib/test/unit.rb +323 -0
  35. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  36. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  37. data/test-unit/lib/test/unit/attribute.rb +125 -0
  38. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  39. data/test-unit/lib/test/unit/collector.rb +36 -0
  40. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  41. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  42. data/test-unit/lib/test/unit/collector/load.rb +144 -0
  43. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  44. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  45. data/test-unit/lib/test/unit/color.rb +96 -0
  46. data/test-unit/lib/test/unit/diff.rb +724 -0
  47. data/test-unit/lib/test/unit/error.rb +130 -0
  48. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  49. data/test-unit/lib/test/unit/failure.rb +136 -0
  50. data/test-unit/lib/test/unit/fixture.rb +176 -0
  51. data/test-unit/lib/test/unit/notification.rb +129 -0
  52. data/test-unit/lib/test/unit/omission.rb +191 -0
  53. data/test-unit/lib/test/unit/pending.rb +150 -0
  54. data/test-unit/lib/test/unit/priority.rb +180 -0
  55. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  56. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  57. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  58. data/test-unit/lib/test/unit/testcase.rb +476 -0
  59. data/test-unit/lib/test/unit/testresult.rb +89 -0
  60. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  61. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  62. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  63. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  64. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  65. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  66. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  67. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  68. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  69. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  70. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  71. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  72. data/test-unit/lib/test/unit/version.rb +7 -0
  73. data/test-unit/sample/adder.rb +13 -0
  74. data/test-unit/sample/subtracter.rb +12 -0
  75. data/test-unit/sample/test_adder.rb +20 -0
  76. data/test-unit/sample/test_subtracter.rb +20 -0
  77. data/test-unit/sample/test_user.rb +23 -0
  78. data/test-unit/test/collector/test-descendant.rb +133 -0
  79. data/test-unit/test/collector/test-load.rb +442 -0
  80. data/test-unit/test/collector/test_dir.rb +406 -0
  81. data/test-unit/test/collector/test_objectspace.rb +100 -0
  82. data/test-unit/test/run-test.rb +15 -0
  83. data/test-unit/test/test-attribute.rb +86 -0
  84. data/test-unit/test/test-color-scheme.rb +67 -0
  85. data/test-unit/test/test-color.rb +47 -0
  86. data/test-unit/test/test-diff.rb +518 -0
  87. data/test-unit/test/test-emacs-runner.rb +60 -0
  88. data/test-unit/test/test-fixture.rb +287 -0
  89. data/test-unit/test/test-notification.rb +33 -0
  90. data/test-unit/test/test-omission.rb +81 -0
  91. data/test-unit/test/test-pending.rb +70 -0
  92. data/test-unit/test/test-priority.rb +119 -0
  93. data/test-unit/test/test-testcase.rb +544 -0
  94. data/test-unit/test/test_assertions.rb +1151 -0
  95. data/test-unit/test/test_error.rb +26 -0
  96. data/test-unit/test/test_failure.rb +33 -0
  97. data/test-unit/test/test_testresult.rb +113 -0
  98. data/test-unit/test/test_testsuite.rb +129 -0
  99. data/test-unit/test/testunit-test-util.rb +14 -0
  100. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  101. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  102. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  103. data/test-unit/test/util/test_observable.rb +102 -0
  104. data/test-unit/test/util/test_procwrapper.rb +36 -0
  105. data/test/groonga-test-utils.rb +3 -2
  106. data/test/run-test.rb +14 -2
  107. data/test/test-column.rb +7 -7
  108. data/test/test-context-select.rb +34 -11
  109. data/test/test-exception.rb +3 -0
  110. data/test/test-expression-builder.rb +11 -0
  111. data/test/test-expression.rb +3 -6
  112. data/test/test-gqtp.rb +3 -5
  113. data/test/test-pagination.rb +249 -0
  114. data/test/test-record.rb +36 -8
  115. data/test/test-remote.rb +11 -4
  116. data/test/test-schema-create-table.rb +251 -0
  117. data/test/test-schema.rb +4 -24
  118. data/test/test-table-offset-and-limit.rb +3 -5
  119. data/test/test-table-select-mecab.rb +80 -0
  120. data/test/test-table-select-weight.rb +104 -0
  121. data/test/test-table.rb +22 -4
  122. data/test/test-version.rb +1 -1
  123. data/text/TUTORIAL.ja.rdoc +2 -0
  124. data/text/expression.rdoc +1 -0
  125. metadata +96 -35
data/html/index.html CHANGED
@@ -42,7 +42,7 @@
42
42
 
43
43
  <h3>rroongaの最新リリース</h3>
44
44
  <p>
45
- 2010-04-22にリリースされた0.9.4が最新です。
45
+ 2010-07-29にリリースされた0.9.5が最新です。
46
46
  </p>
47
47
 
48
48
  <h3 id="install-rroonga">rroongaのインストール</h3>
@@ -97,13 +97,38 @@
97
97
  <li><a href="active_groonga/">ActiveGroongaのリファレンスマニュアル</a></li>
98
98
  </ul>
99
99
 
100
+ <h2 id="about-racknga">racknga</h2>
101
+ <p>
102
+ racknga(らくんが)はRackベースのWebアプリケーションでrroongaを便利に使うための機能(ミドルウェアなど)を提供するライブラリです。
103
+ </p>
104
+
105
+ <h3>rackngaの最新リリース</h3>
106
+ <p>
107
+ 2010-07-04にリリースされた0.9.0が最新です。
108
+ </p>
109
+
110
+ <h3 id="install-racknga">rackngaのインストール</h3>
111
+ <p>
112
+ rackngaもRubyGemsでインストールできます。
113
+ </p>
114
+ <pre class="command">% sudo gem install racknga</pre>
115
+
116
+ <h3>racknagのドキュメント</h3>
117
+ <p>
118
+ rackngaのドキュメントはそれほどありません。
119
+ これから徐々に追加されていく予定です。
120
+ </p>
121
+ <ul>
122
+ <li><a href="racknga/">rackngaのリファレンスマニュアル</a></li>
123
+ </ul>
124
+
100
125
  <h2>ライセンス</h2>
101
126
  <p>
102
- rroongaおよびActiveGroongaはフリーソフトウェアです。あなたは、 Free Software Foundationが公表した<a href="http://www.gnu.org/licenses/lgpl-2.1.txt">GNU Lesser General Public License 2.1</a>に定める条項に従って本プログラムを再頒布または変更することができます。
127
+ rroongaActiveGroonga、rackngaはフリーソフトウェアです。あなたは、 Free Software Foundationが公表した<a href="http://www.gnu.org/licenses/lgpl-2.1.txt">GNU Lesser General Public License 2.1</a>に定める条項に従って本プログラムを再頒布または変更することができます。
103
128
  </p>
104
129
 
105
130
  <p>
106
- rroongaおよびActiveGroongaは有用とは思いますが、頒布にあたっては、市場性及び特定目的適合性についての暗黙の保証を含めて、いかなる保証も行ないません。詳細については<a href="http://www.gnu.org/licenses/lgpl-2.1.txt">GNU Lesser General Public License 2.1</a>をお読みください。
131
+ rroongaActiveGroonga、rackngaは有用とは思いますが、頒布にあたっては、市場性及び特定目的適合性についての暗黙の保証を含めて、いかなる保証も行ないません。詳細については<a href="http://www.gnu.org/licenses/lgpl-2.1.txt">GNU Lesser General Public License 2.1</a>をお読みください。
107
132
  </div>
108
133
 
109
134
  <div class="sidebar">
@@ -123,6 +148,11 @@
123
148
  <img src="rubyforge.png" width="120" height="24" border="0" alt="ラングバプロジェクトはRubyForge.orgにホスティングしてもらっています。" />
124
149
  </a>
125
150
  </p>
151
+ <p id="sponsor-github">
152
+ <a href="http://github.com/ranguba/">
153
+ ラングバプロジェクトはGitHubにホスティングしてもらっています。
154
+ </a>
155
+ </p>
126
156
  <p id="sponsor-tango">
127
157
  <a href="http://tango.freedesktop.org/">
128
158
  <img width="120" height="53" border="0" alt="Tango Desktop Projectのアイコンを利用しています。" src="tango-logo.png" />
data/lib/groonga.rb CHANGED
@@ -31,12 +31,7 @@ if local_groonga_bin_dir.exist?
31
31
  end
32
32
  end
33
33
 
34
- case RUBY_PLATFORM
35
- when /mingw|mswin/
36
- prepend_path.call("PATH", ";")
37
- when /cygwin/
38
- prepend_path.call("PATH", ":")
39
- end
34
+ prepend_path.call("PATH", File::PATH_SEPARATOR)
40
35
  end
41
36
 
42
37
  require 'groonga/view-record'
@@ -50,7 +45,7 @@ rescue LoadError
50
45
  end
51
46
 
52
47
  ##
53
- # Ruby/groonga用のネームスペース。Ruby/groongaのクラスやメソッ
48
+ # rroonga用のネームスペース。rroongaのクラスやメソッ
54
49
  # ドなどはこのモジュール以下に定義される。
55
50
  module Groonga
56
51
  class << self
@@ -93,3 +88,4 @@ end
93
88
  require 'groonga/context'
94
89
  require 'groonga/patricia-trie'
95
90
  require 'groonga/schema'
91
+ require 'groonga/pagination'
@@ -36,19 +36,12 @@ module Groonga
36
36
  select.exec
37
37
  end
38
38
 
39
- class SelectResult < Struct.new(:return_code, :start_time, :elapsed,
40
- :error_message,
41
- :n_hits, :columns, :values,
39
+ class SelectResult < Struct.new(:n_hits, :columns, :values,
42
40
  :drill_down)
43
41
  class << self
44
42
  def parse(json, drill_down_keys)
45
- status, (select_result, *drill_down_results) = parse_json(json)
43
+ select_result, *drill_down_results = parse_json(json)
46
44
  result = new
47
- return_code, start_time, elapsed, error_message = status
48
- result.return_code = return_code
49
- result.start_time = Time.at(start_time)
50
- result.elapsed = elapsed
51
- result.error_message = error_message
52
45
  n_hits, columns, values = extract_result(select_result)
53
46
  result.n_hits = n_hits
54
47
  result.columns = columns
@@ -118,10 +111,6 @@ module Groonga
118
111
  @records ||= self.class.create_records(columns, values)
119
112
  end
120
113
 
121
- def success?
122
- return_code.zero?
123
- end
124
-
125
114
  class DrillDownResult < Struct.new(:n_hits, :columns, :values)
126
115
  def records
127
116
  @records ||= SelectResult.create_records(columns, values)
@@ -38,29 +38,10 @@ module Groonga
38
38
  @default_column = nil
39
39
  end
40
40
 
41
- def build
41
+ def build(&block)
42
42
  expression = Expression.new(:name => @name)
43
43
  variable = expression.define_variable(:domain => @table)
44
-
45
- builder = nil
46
- builder = match(@query, default_parse_options) if @query
47
- if block_given?
48
- if builder
49
- builder &= yield(self)
50
- else
51
- builder = yield(self)
52
- end
53
- end
54
- if builder.nil? or builder == self
55
- expression.append_constant(1)
56
- expression.append_constant(1)
57
- expression.append_operation(Groonga::Operation::OR, 2)
58
- else
59
- builder.build(expression, variable)
60
- end
61
-
62
- expression.compile
63
- expression
44
+ build_expression(expression, variable, &block)
64
45
  end
65
46
 
66
47
  def &(other)
@@ -82,6 +63,37 @@ module Groonga
82
63
  }
83
64
  end
84
65
 
66
+ def build_expression(expression, variable)
67
+ builders = []
68
+ builders << match(@query, default_parse_options) if @query
69
+ if block_given?
70
+ custom_builder = yield(self)
71
+ if custom_builder.is_a?(::Array)
72
+ builders.concat(custom_builder)
73
+ else
74
+ builders << custom_builder
75
+ end
76
+ end
77
+
78
+ if builders.empty? or builders == [self]
79
+ expression.append_constant(1)
80
+ expression.append_constant(1)
81
+ expression.append_operation(Groonga::Operation::OR, 2)
82
+ else
83
+ combined_builder = builders.inject(nil) do |previous, builder|
84
+ if previous.nil?
85
+ builder
86
+ else
87
+ previous & builder
88
+ end
89
+ end
90
+ combined_builder.build(expression, variable)
91
+ end
92
+
93
+ expression.compile
94
+ expression
95
+ end
96
+
85
97
  class ExpressionBuilder # :nodoc:
86
98
  def initialize
87
99
  super()
@@ -124,60 +136,215 @@ module Groonga
124
136
  end
125
137
  end
126
138
 
127
- class BinaryExpressionBuilder < ExpressionBuilder # :nodoc:
128
- def initialize(operation, column, value)
139
+ class ColumnValueExpressionBuilder < ExpressionBuilder # :nodoc:
140
+ def initialize(column, options={})
129
141
  super()
130
- @operation = operation
131
- @default_column = column
132
- @value = value
142
+ @table = options[:table] || column.table
143
+ @column = column
144
+ @column_name = options[:column_name] || @column.local_name
145
+ @range = options[:range] || @column.range
146
+ @name = options[:name]
133
147
  end
134
148
 
135
149
  def build(expression, variable)
136
150
  expression.append_object(variable)
137
- if @default_column.is_a?(String)
138
- expression.append_constant(@default_column)
151
+ if @column.is_a?(String)
152
+ expression.append_constant(@column)
153
+ else
154
+ expression.append_object(@column)
155
+ end
156
+ expression.append_operation(Groonga::Operation::GET_VALUE, 2)
157
+ end
158
+
159
+ def ==(other)
160
+ EqualExpressionBuilder.new(self, normalize(other))
161
+ end
162
+
163
+ def =~(other)
164
+ if other.nil?
165
+ full_column_name = "#{@table.name}.#{@column_name}"
166
+ raise ArgumentError,
167
+ "match word should not be nil: #{full_column_name}"
168
+ end
169
+ MatchExpressionBuilder.new(self, normalize(other))
170
+ end
171
+
172
+ def <(other)
173
+ LessExpressionBuilder.new(self, normalize(other))
174
+ end
175
+
176
+ def <=(other)
177
+ LessEqualExpressionBuilder.new(self, normalize(other))
178
+ end
179
+
180
+ def >(other)
181
+ GreaterExpressionBuilder.new(self, normalize(other))
182
+ end
183
+
184
+ def >=(other)
185
+ GreaterEqualExpressionBuilder.new(self, normalize(other))
186
+ end
187
+
188
+ def +(other)
189
+ PlusExpressionBuilder.new(self, normalize(other))
190
+ end
191
+
192
+ def -(other)
193
+ MinusExpressionBuilder.new(self, normalize(other))
194
+ end
195
+
196
+ def *(other)
197
+ StarExpressionBuilder.new(self, normalize(other))
198
+ end
199
+
200
+ def /(other)
201
+ SlashExpressionBuilder.new(self, normalize(other))
202
+ end
203
+
204
+ def %(other)
205
+ ModExpressionBuilder.new(self, normalize(other))
206
+ end
207
+
208
+ def match(query, options={})
209
+ options = options.dup
210
+ options[:syntax] ||= :query
211
+ options[:default_column] = @column_name
212
+ SubExpressionBuilder.new(query, options)
213
+ end
214
+
215
+ private
216
+ def normalize(other)
217
+ if @range.is_a?(Groonga::Table) and other.is_a?(Integer)
218
+ Groonga::Record.new(@range, other)
219
+ else
220
+ other
221
+ end
222
+ end
223
+
224
+ def method_missing(name, *args, &block)
225
+ return super if block
226
+ return super unless args.empty?
227
+ if VALID_COLUMN_NAME_RE =~ name.to_s
228
+ RecordExpressionBuilder.new(@table, @name)["#{@column_name}.#{name}"]
229
+ else
230
+ super
231
+ end
232
+ end
233
+ end
234
+
235
+ class MatchTargetColumnExpressionBuilder < ColumnValueExpressionBuilder # :nodoc:
236
+ def build(expression, variable)
237
+ if @column.is_a?(String)
238
+ expression.append_constant(@column)
139
239
  else
140
- expression.append_object(@default_column)
240
+ expression.append_object(@column)
141
241
  end
242
+ end
243
+
244
+ private
245
+ def normalize(other)
246
+ other
247
+ end
248
+ end
249
+
250
+ class MatchTargetExpressionBuilder < ExpressionBuilder # :nodoc:
251
+ def initialize(target)
252
+ super()
253
+ @target = target
254
+ end
255
+
256
+ def build(expression, variable)
257
+ expression.append_object(variable)
258
+ expression.append_object(@target)
142
259
  expression.append_operation(Groonga::Operation::GET_VALUE, 2)
260
+ end
261
+
262
+ def =~(query)
263
+ if query.nil?
264
+ raise ArgumentError, "match word should not be nil"
265
+ end
266
+ MatchExpressionBuilder.new(self, query)
267
+ end
268
+ end
269
+
270
+ class BinaryExpressionBuilder < ExpressionBuilder # :nodoc:
271
+ def initialize(operation, column_value_builder, value)
272
+ super()
273
+ @operation = operation
274
+ @column_value_builder = column_value_builder
275
+ @value = value
276
+ end
277
+
278
+ def build(expression, variable)
279
+ @column_value_builder.build(expression, variable)
143
280
  expression.append_constant(@value)
144
281
  expression.append_operation(@operation, 2)
145
282
  end
146
283
  end
147
284
 
148
285
  class EqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
149
- def initialize(column, value)
150
- super(Groonga::Operation::EQUAL, column, value)
286
+ def initialize(column_value_builder, value)
287
+ super(Groonga::Operation::EQUAL, column_value_builder, value)
151
288
  end
152
289
  end
153
290
 
154
291
  class MatchExpressionBuilder < BinaryExpressionBuilder # :nodoc:
155
- def initialize(column, value)
156
- super(Groonga::Operation::MATCH, column, value)
292
+ def initialize(column_value_builder, value)
293
+ super(Groonga::Operation::MATCH, column_value_builder, value)
157
294
  end
158
295
  end
159
296
 
160
297
  class LessExpressionBuilder < BinaryExpressionBuilder # :nodoc:
161
- def initialize(column, value)
162
- super(Groonga::Operation::LESS, column, value)
298
+ def initialize(column_value_builder, value)
299
+ super(Groonga::Operation::LESS, column_value_builder, value)
163
300
  end
164
301
  end
165
302
 
166
303
  class LessEqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
167
- def initialize(column, value)
168
- super(Groonga::Operation::LESS_EQUAL, column, value)
304
+ def initialize(column_value_builder, value)
305
+ super(Groonga::Operation::LESS_EQUAL, column_value_builder, value)
169
306
  end
170
307
  end
171
308
 
172
309
  class GreaterExpressionBuilder < BinaryExpressionBuilder # :nodoc:
173
- def initialize(column, value)
174
- super(Groonga::Operation::GREATER, column, value)
310
+ def initialize(column_value_builder, value)
311
+ super(Groonga::Operation::GREATER, column_value_builder, value)
175
312
  end
176
313
  end
177
314
 
178
315
  class GreaterEqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
179
- def initialize(column, value)
180
- super(Groonga::Operation::GREATER_EQUAL, column, value)
316
+ def initialize(column_value_builder, value)
317
+ super(Groonga::Operation::GREATER_EQUAL, column_value_builder, value)
318
+ end
319
+ end
320
+
321
+ class PlusExpressionBuilder < BinaryExpressionBuilder # :nodoc:
322
+ def initialize(column_value_builder, value)
323
+ super(Groonga::Operation::PLUS, column_value_builder, value)
324
+ end
325
+ end
326
+
327
+ class MinusExpressionBuilder < BinaryExpressionBuilder # :nodoc:
328
+ def initialize(column_value_builder, value)
329
+ super(Groonga::Operation::MINUS, column_value_builder, value)
330
+ end
331
+ end
332
+
333
+ class StarExpressionBuilder < BinaryExpressionBuilder # :nodoc:
334
+ def initialize(column_value_builder, value)
335
+ super(Groonga::Operation::STAR, column_value_builder, value)
336
+ end
337
+ end
338
+
339
+ class SlashExpressionBuilder < BinaryExpressionBuilder # :nodoc:
340
+ def initialize(column_value_builder, value)
341
+ super(Groonga::Operation::SLASH, column_value_builder, value)
342
+ end
343
+ end
344
+
345
+ class ModExpressionBuilder < BinaryExpressionBuilder # :nodoc:
346
+ def initialize(column_value_builder, value)
347
+ super(Groonga::Operation::MOD, column_value_builder, value)
181
348
  end
182
349
  end
183
350
 
@@ -210,9 +377,7 @@ module Groonga
210
377
  "for table <#{@table.inspect}>"
211
378
  raise ArgumentError, message
212
379
  end
213
- ColumnExpressionBuilder.new(column, nil, nil,
214
- :table => @table,
215
- :column_name => name)
380
+ column_expression_builder(column, name)
216
381
  end
217
382
 
218
383
  def id
@@ -231,7 +396,7 @@ module Groonga
231
396
  self["_nsubrecs"]
232
397
  end
233
398
 
234
- def match(query, options_or_default_column={})
399
+ def match(query, options_or_default_column={}, &block)
235
400
  if options_or_default_column.is_a?(String)
236
401
  options = {:default_column => options_or_default_column}
237
402
  else
@@ -239,10 +404,30 @@ module Groonga
239
404
  end
240
405
  options = options.dup
241
406
  options[:syntax] ||= :query
407
+ if block_given? and options[:default_column].nil?
408
+ options[:default_column] = build_match_target(&block)
409
+ end
242
410
  SubExpressionBuilder.new(query, options)
243
411
  end
244
412
 
413
+ def match_target(&block)
414
+ MatchTargetExpressionBuilder.new(build_match_target(&block))
415
+ end
416
+
245
417
  private
418
+ def build_match_target(&block)
419
+ sub_builder = MatchTargetRecordExpressionBuilder.new(@table, nil)
420
+ sub_builder.build do |record|
421
+ block.call(record)
422
+ end
423
+ end
424
+
425
+ def column_expression_builder(column, name)
426
+ ColumnValueExpressionBuilder.new(column,
427
+ :table => @table,
428
+ :column_name => name)
429
+ end
430
+
246
431
  def method_missing(name, *args, &block)
247
432
  return super if block
248
433
  return super unless args.empty?
@@ -254,6 +439,15 @@ module Groonga
254
439
  end
255
440
  end
256
441
 
442
+ class MatchTargetRecordExpressionBuilder < RecordExpressionBuilder # :nodoc:
443
+ private
444
+ def column_expression_builder(column, name)
445
+ MatchTargetColumnExpressionBuilder.new(column,
446
+ :table => @table,
447
+ :column_name => name)
448
+ end
449
+ end
450
+
257
451
  class ColumnExpressionBuilder # :nodoc:
258
452
  include ExpressionBuildable
259
453
 
@@ -268,54 +462,66 @@ module Groonga
268
462
  end
269
463
 
270
464
  def ==(other)
271
- EqualExpressionBuilder.new(@default_column, normalize(other))
465
+ column_value_builder == other
272
466
  end
273
467
 
274
468
  def =~(other)
275
- if other.nil?
276
- full_column_name = "#{@table.name}.#{@column_name}"
277
- raise ArgumentError, "match word should not be nil: #{full_column_name}"
278
- end
279
- MatchExpressionBuilder.new(@default_column, normalize(other))
469
+ column_value_builder =~ other
280
470
  end
281
471
 
282
472
  def <(other)
283
- LessExpressionBuilder.new(@default_column, normalize(other))
473
+ column_value_builder < other
284
474
  end
285
475
 
286
476
  def <=(other)
287
- LessEqualExpressionBuilder.new(@default_column, normalize(other))
477
+ column_value_builder <= other
288
478
  end
289
479
 
290
480
  def >(other)
291
- GreaterExpressionBuilder.new(@default_column, normalize(other))
481
+ column_value_builder > other
292
482
  end
293
483
 
294
484
  def >=(other)
295
- GreaterEqualExpressionBuilder.new(@default_column, normalize(other))
485
+ column_value_builder >= other
296
486
  end
297
487
 
298
- def match(query, options={})
299
- options = options.dup
300
- options[:syntax] ||= :query
301
- options[:default_column] = @column_name
302
- SubExpressionBuilder.new(query, options)
488
+ def +(other)
489
+ column_value_builder + other
490
+ end
491
+
492
+ def -(other)
493
+ column_value_builder - other
494
+ end
495
+
496
+ def *(other)
497
+ column_value_builder * other
498
+ end
499
+
500
+ def /(other)
501
+ column_value_builder / other
502
+ end
503
+
504
+ def %(other)
505
+ column_value_builder % other
506
+ end
507
+
508
+ def match(query, options={}, &block)
509
+ column_value_builder.match(query, options, &block)
303
510
  end
304
511
 
305
512
  private
306
- def normalize(other)
307
- if @range.is_a?(Groonga::Table) and other.is_a?(Integer)
308
- Groonga::Record.new(@range, other)
309
- else
310
- other
311
- end
513
+ def column_value_builder
514
+ ColumnValueExpressionBuilder.new(@default_column,
515
+ :table => @table,
516
+ :column_name => @column_name,
517
+ :range => @range)
312
518
  end
313
519
 
314
520
  def method_missing(name, *args, &block)
315
521
  return super if block
316
522
  return super unless args.empty?
317
523
  if VALID_COLUMN_NAME_RE =~ name.to_s
318
- RecordExpressionBuilder.new(@table, @name)["#{@column_name}.#{name}"]
524
+ column_value_builder.send(name)
319
525
  else
320
526
  super
321
527
  end