rroonga 0.9.2-mswin32

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.
Files changed (202) hide show
  1. data/AUTHORS +5 -0
  2. data/NEWS.ja.rdoc +114 -0
  3. data/NEWS.rdoc +116 -0
  4. data/README.ja.rdoc +65 -0
  5. data/README.rdoc +66 -0
  6. data/Rakefile +217 -0
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-many-small-items.rb +144 -0
  9. data/benchmark/write-many-small-items.rb +135 -0
  10. data/example/bookmark.rb +161 -0
  11. data/example/index-html.rb +89 -0
  12. data/example/search/config.ru +211 -0
  13. data/example/search/public/css/groonga.css +122 -0
  14. data/ext/.gitignore +2 -0
  15. data/ext/libruby-groonga.a +0 -0
  16. data/ext/rb-grn-accessor.c +52 -0
  17. data/ext/rb-grn-array-cursor.c +36 -0
  18. data/ext/rb-grn-array.c +210 -0
  19. data/ext/rb-grn-column.c +573 -0
  20. data/ext/rb-grn-context.c +655 -0
  21. data/ext/rb-grn-database.c +472 -0
  22. data/ext/rb-grn-encoding-support.c +64 -0
  23. data/ext/rb-grn-encoding.c +257 -0
  24. data/ext/rb-grn-exception.c +1110 -0
  25. data/ext/rb-grn-expression-builder.c +75 -0
  26. data/ext/rb-grn-expression.c +735 -0
  27. data/ext/rb-grn-fix-size-column.c +166 -0
  28. data/ext/rb-grn-hash-cursor.c +38 -0
  29. data/ext/rb-grn-hash.c +294 -0
  30. data/ext/rb-grn-index-column.c +488 -0
  31. data/ext/rb-grn-logger.c +504 -0
  32. data/ext/rb-grn-object.c +1369 -0
  33. data/ext/rb-grn-operation.c +198 -0
  34. data/ext/rb-grn-patricia-trie-cursor.c +39 -0
  35. data/ext/rb-grn-patricia-trie.c +488 -0
  36. data/ext/rb-grn-procedure.c +52 -0
  37. data/ext/rb-grn-query.c +260 -0
  38. data/ext/rb-grn-record.c +40 -0
  39. data/ext/rb-grn-snippet.c +334 -0
  40. data/ext/rb-grn-table-cursor-key-support.c +69 -0
  41. data/ext/rb-grn-table-cursor.c +247 -0
  42. data/ext/rb-grn-table-key-support.c +731 -0
  43. data/ext/rb-grn-table.c +2141 -0
  44. data/ext/rb-grn-type.c +181 -0
  45. data/ext/rb-grn-utils.c +769 -0
  46. data/ext/rb-grn-variable-size-column.c +36 -0
  47. data/ext/rb-grn-variable.c +108 -0
  48. data/ext/rb-grn-view-accessor.c +53 -0
  49. data/ext/rb-grn-view-cursor.c +35 -0
  50. data/ext/rb-grn-view-record.c +41 -0
  51. data/ext/rb-grn-view.c +421 -0
  52. data/ext/rb-grn.h +700 -0
  53. data/ext/rb-groonga.c +117 -0
  54. data/extconf.rb +266 -0
  55. data/html/bar.svg +153 -0
  56. data/html/developer.html +117 -0
  57. data/html/developer.svg +469 -0
  58. data/html/download.svg +253 -0
  59. data/html/favicon.ico +0 -0
  60. data/html/favicon.xcf +0 -0
  61. data/html/footer.html.erb +28 -0
  62. data/html/head.html.erb +4 -0
  63. data/html/header.html.erb +17 -0
  64. data/html/index.html +147 -0
  65. data/html/install.svg +636 -0
  66. data/html/logo.xcf +0 -0
  67. data/html/ranguba.css +250 -0
  68. data/html/tutorial.svg +559 -0
  69. data/lib/groonga.rb +90 -0
  70. data/lib/groonga/context.rb +184 -0
  71. data/lib/groonga/expression-builder.rb +285 -0
  72. data/lib/groonga/patricia-trie.rb +53 -0
  73. data/lib/groonga/record.rb +311 -0
  74. data/lib/groonga/schema.rb +1191 -0
  75. data/lib/groonga/view-record.rb +56 -0
  76. data/license/GPL +340 -0
  77. data/license/LGPL +504 -0
  78. data/license/RUBY +59 -0
  79. data/misc/grnop2ruby.rb +49 -0
  80. data/pkg-config.rb +333 -0
  81. data/test-unit/Rakefile +40 -0
  82. data/test-unit/TODO +5 -0
  83. data/test-unit/bin/testrb +5 -0
  84. data/test-unit/html/classic.html +15 -0
  85. data/test-unit/html/index.html +25 -0
  86. data/test-unit/html/index.html.ja +27 -0
  87. data/test-unit/lib/test/unit.rb +323 -0
  88. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  89. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  90. data/test-unit/lib/test/unit/attribute.rb +125 -0
  91. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  92. data/test-unit/lib/test/unit/collector.rb +36 -0
  93. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  94. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  95. data/test-unit/lib/test/unit/collector/load.rb +136 -0
  96. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  97. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  98. data/test-unit/lib/test/unit/color.rb +96 -0
  99. data/test-unit/lib/test/unit/diff.rb +724 -0
  100. data/test-unit/lib/test/unit/error.rb +130 -0
  101. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  102. data/test-unit/lib/test/unit/failure.rb +136 -0
  103. data/test-unit/lib/test/unit/fixture.rb +176 -0
  104. data/test-unit/lib/test/unit/notification.rb +129 -0
  105. data/test-unit/lib/test/unit/omission.rb +191 -0
  106. data/test-unit/lib/test/unit/pending.rb +150 -0
  107. data/test-unit/lib/test/unit/priority.rb +180 -0
  108. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  109. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  110. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  111. data/test-unit/lib/test/unit/testcase.rb +476 -0
  112. data/test-unit/lib/test/unit/testresult.rb +89 -0
  113. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  114. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  115. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  116. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  117. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  118. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  119. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  120. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  121. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  122. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  123. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  124. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  125. data/test-unit/lib/test/unit/version.rb +7 -0
  126. data/test-unit/sample/adder.rb +13 -0
  127. data/test-unit/sample/subtracter.rb +12 -0
  128. data/test-unit/sample/test_adder.rb +20 -0
  129. data/test-unit/sample/test_subtracter.rb +20 -0
  130. data/test-unit/sample/test_user.rb +23 -0
  131. data/test-unit/test/collector/test-descendant.rb +133 -0
  132. data/test-unit/test/collector/test-load.rb +348 -0
  133. data/test-unit/test/collector/test_dir.rb +406 -0
  134. data/test-unit/test/collector/test_objectspace.rb +100 -0
  135. data/test-unit/test/run-test.rb +15 -0
  136. data/test-unit/test/test-attribute.rb +86 -0
  137. data/test-unit/test/test-color-scheme.rb +67 -0
  138. data/test-unit/test/test-color.rb +47 -0
  139. data/test-unit/test/test-diff.rb +518 -0
  140. data/test-unit/test/test-emacs-runner.rb +60 -0
  141. data/test-unit/test/test-fixture.rb +287 -0
  142. data/test-unit/test/test-notification.rb +33 -0
  143. data/test-unit/test/test-omission.rb +81 -0
  144. data/test-unit/test/test-pending.rb +70 -0
  145. data/test-unit/test/test-priority.rb +119 -0
  146. data/test-unit/test/test-testcase.rb +544 -0
  147. data/test-unit/test/test_assertions.rb +1151 -0
  148. data/test-unit/test/test_error.rb +26 -0
  149. data/test-unit/test/test_failure.rb +33 -0
  150. data/test-unit/test/test_testresult.rb +113 -0
  151. data/test-unit/test/test_testsuite.rb +129 -0
  152. data/test-unit/test/testunit-test-util.rb +14 -0
  153. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  154. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  155. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  156. data/test-unit/test/util/test_observable.rb +102 -0
  157. data/test-unit/test/util/test_procwrapper.rb +36 -0
  158. data/test/.gitignore +1 -0
  159. data/test/groonga-test-utils.rb +133 -0
  160. data/test/run-test.rb +58 -0
  161. data/test/test-array.rb +97 -0
  162. data/test/test-column.rb +316 -0
  163. data/test/test-context-select.rb +93 -0
  164. data/test/test-context.rb +73 -0
  165. data/test/test-database.rb +113 -0
  166. data/test/test-encoding.rb +33 -0
  167. data/test/test-exception.rb +93 -0
  168. data/test/test-expression-builder.rb +156 -0
  169. data/test/test-expression.rb +134 -0
  170. data/test/test-fix-size-column.rb +65 -0
  171. data/test/test-gqtp.rb +72 -0
  172. data/test/test-hash.rb +312 -0
  173. data/test/test-index-column.rb +81 -0
  174. data/test/test-logger.rb +37 -0
  175. data/test/test-patricia-trie.rb +189 -0
  176. data/test/test-procedure.rb +37 -0
  177. data/test/test-query.rb +22 -0
  178. data/test/test-record.rb +279 -0
  179. data/test/test-remote.rb +54 -0
  180. data/test/test-schema-view.rb +90 -0
  181. data/test/test-schema.rb +459 -0
  182. data/test/test-snippet.rb +130 -0
  183. data/test/test-table-cursor.rb +153 -0
  184. data/test/test-table-offset-and-limit.rb +102 -0
  185. data/test/test-table-select-normalize.rb +53 -0
  186. data/test/test-table-select.rb +150 -0
  187. data/test/test-table.rb +690 -0
  188. data/test/test-type.rb +71 -0
  189. data/test/test-variable-size-column.rb +98 -0
  190. data/test/test-variable.rb +28 -0
  191. data/test/test-vector-column.rb +76 -0
  192. data/test/test-version.rb +31 -0
  193. data/test/test-view.rb +72 -0
  194. data/text/TUTORIAL.ja.rdoc +392 -0
  195. data/text/expression.rdoc +284 -0
  196. data/vendor/local/bin/grntest.exe +0 -0
  197. data/vendor/local/bin/groonga.exe +0 -0
  198. data/vendor/local/bin/libgroonga.dll +0 -0
  199. data/vendor/local/bin/libmecab.dll +0 -0
  200. data/vendor/local/include/groonga.h +2285 -0
  201. data/vendor/local/lib/libgroonga.lib +0 -0
  202. metadata +280 -0
data/lib/groonga.rb ADDED
@@ -0,0 +1,90 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2009-2010 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
+ require 'pathname'
19
+
20
+ base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path
21
+ local_groonga_dir = base_dir + "vendor" + "local"
22
+ local_groonga_bin_dir = local_groonga_dir + "bin"
23
+ if local_groonga_bin_dir.exist?
24
+ prepend_path = Proc.new do |environment_name, separator|
25
+ paths = (ENV[environment_name] || '').split(/#{separator}/)
26
+ dir = local_groonga_bin_dir.to_s
27
+ dir = dir.gsub(/\//, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
28
+ unless paths.include?(dir)
29
+ paths = [dir] + paths
30
+ ENV[environment_name] = paths.join(separator)
31
+ end
32
+ end
33
+
34
+ case RUBY_PLATFORM
35
+ when /mingw|mswin/
36
+ prepend_path.call("PATH", ";")
37
+ when /cygwin/
38
+ prepend_path.call("PATH", ":")
39
+ end
40
+ end
41
+
42
+ require 'groonga/view-record'
43
+ require 'groonga/record'
44
+ require 'groonga/expression-builder'
45
+ require 'groonga.so'
46
+
47
+ ##
48
+ # Ruby/groonga用のネームスペース。Ruby/groongaのクラスやメソッ
49
+ # ドなどはこのモジュール以下に定義される。
50
+ module Groonga
51
+ class << self
52
+ ##
53
+ # BUILD_VERSIONを"."で結合して<tt>"メジャーバージョン.マ
54
+ # イナーバージョン.マイクロバージョン"</tt>という形式の
55
+ # 文字列にしたもの。
56
+ def build_version
57
+ BUILD_VERSION.join(".")
58
+ end
59
+
60
+ ##
61
+ # VERSIONを"."で結合して<tt>"メジャーバージョン.マイナー
62
+ # バージョン.マイクロバージョン"</tt>という形式の文字列に
63
+ # したもの。
64
+ def version
65
+ VERSION.join(".")
66
+ end
67
+
68
+ ##
69
+ # BINDINGS_VERSIONを"."で結合して<tt>"メジャーバージョン.マ
70
+ # イナーバージョン.マイクロバージョン"</tt>という形式の文
71
+ # 字列にしたもの。
72
+ def bindings_version
73
+ BINDINGS_VERSION.join(".")
74
+ end
75
+
76
+ ##
77
+ # call-seq:
78
+ # Groonga[name] -> Groonga::Object or nil
79
+ # Groonga[id] -> Groonga::Object or nil
80
+ #
81
+ # 便利メソッド。Groonga::Context.default[name]と同じ。
82
+ def [](name)
83
+ Context.default[name]
84
+ end
85
+ end
86
+ end
87
+
88
+ require 'groonga/context'
89
+ require 'groonga/patricia-trie'
90
+ require 'groonga/schema'
@@ -0,0 +1,184 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2010 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
+ class Context
20
+ # call-seq:
21
+ # context.select(table, options={}) -> SelectResult
22
+ #
23
+ # _table_から指定した条件にマッチするレコードの値を取得
24
+ # する。_table_はテーブル名かテーブルオブジェクトを指定
25
+ # する。
26
+ #
27
+ # _options_に指定できるキーは以下の通り。
28
+ #
29
+ # [_output_columns_] 値を取得するカラムを指定する。
30
+ # [_XXX_] TODO
31
+ #
32
+ # 例:
33
+ # TODO
34
+ def select(table, options={})
35
+ select = SelectCommand.new(self, table, options)
36
+ select.exec
37
+ end
38
+
39
+ class SelectResult < Struct.new(:return_code, :start_time, :elapsed,
40
+ :error_message,
41
+ :n_hits, :columns, :values,
42
+ :drill_down)
43
+ class << self
44
+ def parse(json, drill_down_keys)
45
+ status, (select_result, *drill_down_results) = parse_json(json)
46
+ 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
+ n_hits, columns, values = extract_result(select_result)
53
+ result.n_hits = n_hits
54
+ result.columns = columns
55
+ result.values = values
56
+ if drill_down_results
57
+ result.drill_down = parse_drill_down_results(drill_down_results,
58
+ drill_down_keys)
59
+ end
60
+ result
61
+ end
62
+
63
+ def create_records(columns, values)
64
+ records = []
65
+ values.each do |value|
66
+ record = {}
67
+ columns.each_with_index do |(name, type), i|
68
+ record[name] = convert_value(value[i], type)
69
+ end
70
+ records << record
71
+ end
72
+ records
73
+ end
74
+
75
+ private
76
+ def parse_drill_down_results(results, keys)
77
+ named_results = {}
78
+ results.each_with_index do |drill_down, i|
79
+ n_hits, columns, values = extract_result(drill_down)
80
+ drill_down_result = DrillDownResult.new
81
+ drill_down_result.n_hits = n_hits
82
+ drill_down_result.columns = columns
83
+ drill_down_result.values = values
84
+ named_results[keys[i]] = drill_down_result
85
+ end
86
+ named_results
87
+ end
88
+
89
+ def extract_result(result)
90
+ meta_data, columns, *values = result
91
+ n_hits, = meta_data
92
+ [n_hits, columns, values]
93
+ end
94
+
95
+ def convert_value(value, type)
96
+ case type
97
+ when "Time"
98
+ Time.at(value)
99
+ else
100
+ value
101
+ end
102
+ end
103
+
104
+ begin
105
+ require 'json'
106
+ def parse_json(json)
107
+ JSON.parse(json)
108
+ end
109
+ rescue LoadError
110
+ require 'yaml'
111
+ def parse_json(json)
112
+ YAML.load(json)
113
+ end
114
+ end
115
+ end
116
+
117
+ def records
118
+ @records ||= self.class.create_records(columns, values)
119
+ end
120
+
121
+ def success?
122
+ return_code.zero?
123
+ end
124
+
125
+ class DrillDownResult < Struct.new(:n_hits, :columns, :values)
126
+ def records
127
+ @records ||= SelectResult.create_records(columns, values)
128
+ end
129
+ end
130
+ end
131
+
132
+ class SelectCommand
133
+ def initialize(context, table, options)
134
+ @context = context
135
+ @table = table
136
+ @options = normalize_options(options)
137
+ end
138
+
139
+ def exec
140
+ request_id = @context.send(query)
141
+ loop do
142
+ response_id, result = @context.receive
143
+ if request_id == response_id
144
+ drill_down_keys = @options["drilldown"]
145
+ if drill_down_keys.is_a?(String)
146
+ drill_down_keys = drill_down_keys.split(/(?:\s+|\s*,\s*)/)
147
+ end
148
+ return SelectResult.parse(result, drill_down_keys)
149
+ end
150
+ # raise if request_id < response_id
151
+ end
152
+ end
153
+
154
+ private
155
+ def normalize_options(options)
156
+ normalized_options = {}
157
+ options.each do |key, value|
158
+ normalized_options[normalize_option_name(key)] = value
159
+ end
160
+ normalized_options
161
+ end
162
+
163
+ def normalize_option_name(name)
164
+ name = name.to_s.gsub(/-/, "_").gsub(/drill_down/, "drilldown")
165
+ name.gsub(/sort_by/, 'sortby')
166
+ end
167
+
168
+ def query
169
+ if @table.is_a?(String)
170
+ table_name = @table
171
+ else
172
+ table_name = @table.name
173
+ end
174
+ _query = "select #{table_name}"
175
+ @options.each do |key, value|
176
+ value = value.join(", ") if value.is_a?(::Array)
177
+ escaped_value = value.to_s.gsub(/"/, '\\"')
178
+ _query << " --#{key} \"#{escaped_value}\""
179
+ end
180
+ _query
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,285 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2009 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 ExpressionBuildable # :nodoc:
20
+ attr_reader :table
21
+ attr_accessor :query
22
+ attr_accessor :syntax
23
+ attr_accessor :allow_pragma
24
+ attr_accessor :allow_column
25
+ attr_accessor :allow_update
26
+ attr_accessor :default_column
27
+
28
+ def initialize(*args)
29
+ @table = nil
30
+ @name = nil
31
+ @query = nil
32
+ @syntax = nil
33
+ @allow_pragma = nil
34
+ @allow_column = nil
35
+ @allow_update = nil
36
+ @default_column = nil
37
+ end
38
+
39
+ def build
40
+ expression = Expression.new(:name => @name)
41
+ variable = expression.define_variable(:domain => @table)
42
+
43
+ builder = nil
44
+ builder = match(@query, default_parse_options) if @query
45
+ if block_given?
46
+ if builder
47
+ builder &= yield(self)
48
+ else
49
+ builder = yield(self)
50
+ end
51
+ end
52
+ if builder.nil? or builder == self
53
+ expression.append_constant(1)
54
+ expression.append_constant(1)
55
+ expression.append_operation(Groonga::Operation::OR, 2)
56
+ else
57
+ builder.build(expression, variable)
58
+ end
59
+
60
+ expression.compile
61
+ expression
62
+ end
63
+
64
+ def &(other)
65
+ other
66
+ end
67
+
68
+ def |(other)
69
+ other
70
+ end
71
+
72
+ private
73
+ def default_parse_options
74
+ {
75
+ :syntax => @syntax,
76
+ :allow_pragma => @allow_pragma,
77
+ :allow_column => @allow_column,
78
+ :allow_update => @allow_update,
79
+ :default_column => @default_column,
80
+ }
81
+ end
82
+
83
+ class ExpressionBuilder # :nodoc:
84
+ def initialize
85
+ super()
86
+ end
87
+
88
+ def &(other)
89
+ AndExpressionBuilder.new(self, other)
90
+ end
91
+
92
+ def |(other)
93
+ OrExpressionBuilder.new(self, other)
94
+ end
95
+ end
96
+
97
+ class SetExpressionBuilder < ExpressionBuilder # :nodoc:
98
+ def initialize(operation, *expression_builders)
99
+ super()
100
+ @operation = operation
101
+ @expression_builders = expression_builders
102
+ end
103
+
104
+ def build(expression, variable)
105
+ return if @expression_builders.empty?
106
+ @expression_builders.each do |builder|
107
+ builder.build(expression, variable)
108
+ end
109
+ expression.append_operation(@operation, @expression_builders.size)
110
+ end
111
+ end
112
+
113
+ class AndExpressionBuilder < SetExpressionBuilder # :nodoc:
114
+ def initialize(*expression_builders)
115
+ super(Groonga::Operation::AND, *expression_builders)
116
+ end
117
+ end
118
+
119
+ class OrExpressionBuilder < SetExpressionBuilder # :nodoc:
120
+ def initialize(*expression_builders)
121
+ super(Groonga::Operation::OR, *expression_builders)
122
+ end
123
+ end
124
+
125
+ class BinaryExpressionBuilder < ExpressionBuilder # :nodoc:
126
+ def initialize(operation, column, value)
127
+ super()
128
+ @operation = operation
129
+ @default_column = column
130
+ @value = value
131
+ end
132
+
133
+ def build(expression, variable)
134
+ expression.append_object(variable)
135
+ if @default_column.is_a?(String)
136
+ expression.append_constant(@default_column)
137
+ else
138
+ expression.append_object(@default_column)
139
+ end
140
+ expression.append_operation(Groonga::Operation::GET_VALUE, 2)
141
+ expression.append_constant(@value)
142
+ expression.append_operation(@operation, 2)
143
+ end
144
+ end
145
+
146
+ class EqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
147
+ def initialize(column, value)
148
+ super(Groonga::Operation::EQUAL, column, value)
149
+ end
150
+ end
151
+
152
+ class MatchExpressionBuilder < BinaryExpressionBuilder # :nodoc:
153
+ def initialize(column, value)
154
+ super(Groonga::Operation::MATCH, column, value)
155
+ end
156
+ end
157
+
158
+ class LessExpressionBuilder < BinaryExpressionBuilder # :nodoc:
159
+ def initialize(column, value)
160
+ super(Groonga::Operation::LESS, column, value)
161
+ end
162
+ end
163
+
164
+ class LessEqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
165
+ def initialize(column, value)
166
+ super(Groonga::Operation::LESS_EQUAL, column, value)
167
+ end
168
+ end
169
+
170
+ class GreaterExpressionBuilder < BinaryExpressionBuilder # :nodoc:
171
+ def initialize(column, value)
172
+ super(Groonga::Operation::GREATER, column, value)
173
+ end
174
+ end
175
+
176
+ class GreaterEqualExpressionBuilder < BinaryExpressionBuilder # :nodoc:
177
+ def initialize(column, value)
178
+ super(Groonga::Operation::GREATER_EQUAL, column, value)
179
+ end
180
+ end
181
+
182
+ class SubExpressionBuilder < ExpressionBuilder # :nodoc:
183
+ def initialize(query, options)
184
+ super()
185
+ @query = query
186
+ @options = options
187
+ end
188
+
189
+ def build(expression, variable)
190
+ expression.parse(@query, @options)
191
+ end
192
+ end
193
+ end
194
+
195
+ class RecordExpressionBuilder # :nodoc:
196
+ include ExpressionBuildable
197
+
198
+ def initialize(table, name)
199
+ super()
200
+ @table = table
201
+ @name = name
202
+ end
203
+
204
+ def [](name)
205
+ column = @table.column(name)
206
+ if column.nil?
207
+ message = "unknown column <#{name.inspect}> " +
208
+ "for table <#{@table.inspect}>"
209
+ raise ArgumentError, message
210
+ end
211
+ ColumnExpressionBuilder.new(column, nil, nil,
212
+ :table => @table,
213
+ :column_name => name)
214
+ end
215
+
216
+ def match(query, options_or_default_column={})
217
+ if options_or_default_column.is_a?(String)
218
+ options = {:default_column => options_or_default_column}
219
+ else
220
+ options = options_or_default_column
221
+ end
222
+ options = options.dup
223
+ options[:syntax] ||= :query
224
+ SubExpressionBuilder.new(query, options)
225
+ end
226
+ end
227
+
228
+ class ColumnExpressionBuilder # :nodoc:
229
+ include ExpressionBuildable
230
+
231
+ def initialize(column, name, query, options={})
232
+ super()
233
+ @table = options[:table] || column.table
234
+ @default_column = column
235
+ @column_name = options[:column_name] || @default_column.local_name
236
+ @range = @default_column.range
237
+ @name = name
238
+ @query = query
239
+ end
240
+
241
+ def ==(other)
242
+ EqualExpressionBuilder.new(@default_column, normalize(other))
243
+ end
244
+
245
+ def =~(other)
246
+ if other.nil?
247
+ full_column_name = "#{@table.name}.#{@column_name}"
248
+ raise ArgumentError, "match word should not be nil: #{full_column_name}"
249
+ end
250
+ MatchExpressionBuilder.new(@default_column, normalize(other))
251
+ end
252
+
253
+ def <(other)
254
+ LessExpressionBuilder.new(@default_column, normalize(other))
255
+ end
256
+
257
+ def <=(other)
258
+ LessEqualExpressionBuilder.new(@default_column, normalize(other))
259
+ end
260
+
261
+ def >(other)
262
+ GreaterExpressionBuilder.new(@default_column, normalize(other))
263
+ end
264
+
265
+ def >=(other)
266
+ GreaterEqualExpressionBuilder.new(@default_column, normalize(other))
267
+ end
268
+
269
+ def match(query, options={})
270
+ options = options.dup
271
+ options[:syntax] ||= :query
272
+ options[:default_column] = @column_name
273
+ SubExpressionBuilder.new(query, options)
274
+ end
275
+
276
+ private
277
+ def normalize(other)
278
+ if @range.is_a?(Groonga::Table) and other.is_a?(Integer)
279
+ Groonga::Record.new(@range, other)
280
+ else
281
+ other
282
+ end
283
+ end
284
+ end
285
+ end