groonga 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.ja.rdoc +13 -0
- data/NEWS.rdoc +13 -0
- data/README.ja.rdoc +2 -1
- data/README.rdoc +2 -1
- data/Rakefile +0 -1
- data/TUTORIAL.ja.rdoc +49 -4
- data/benchmark/read-write-many-small-items.rb +5 -4
- data/benchmark/write-many-small-items.rb +5 -4
- data/example/bookmark.rb +30 -1
- data/example/index-html.rb +79 -0
- data/example/search/config.ru +182 -0
- data/example/search/public/css/groonga.css +122 -0
- data/ext/rb-grn-array.c +12 -9
- data/ext/rb-grn-column.c +13 -8
- data/ext/rb-grn-context.c +34 -16
- data/ext/rb-grn-database.c +3 -2
- data/ext/rb-grn-expression-builder.c +8 -2
- data/ext/rb-grn-expression.c +3 -3
- data/ext/rb-grn-hash.c +13 -10
- data/ext/rb-grn-object.c +127 -19
- data/ext/rb-grn-patricia-trie.c +8 -7
- data/ext/rb-grn-table-cursor.c +2 -40
- data/ext/rb-grn-table.c +154 -42
- data/ext/rb-grn-type.c +18 -10
- data/ext/rb-grn-utils.c +22 -20
- data/ext/rb-grn.h +9 -12
- data/extconf.rb +1 -1
- data/html/developer.html +1 -1
- data/html/index.html +2 -2
- data/lib/groonga/expression-builder.rb +133 -63
- data/lib/groonga/schema.rb +229 -37
- data/test/groonga-test-utils.rb +1 -1
- data/test/test-array.rb +1 -0
- data/test/test-context.rb +7 -1
- data/test/test-database.rb +11 -3
- data/test/test-expression-builder.rb +26 -2
- data/test/test-fix-size-column.rb +2 -1
- data/test/test-hash.rb +6 -1
- data/test/test-record.rb +2 -1
- data/test/test-schema.rb +85 -10
- data/test/test-table.rb +99 -3
- data/test/test-type.rb +3 -2
- data/test/test-variable-size-column.rb +2 -1
- data/test-unit/Rakefile +6 -1
- data/test-unit/lib/test/unit/autorunner.rb +26 -3
- data/test-unit/lib/test/unit/priority.rb +21 -1
- data/test-unit/lib/test/unit/testcase.rb +101 -36
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +7 -4
- data/test-unit/test/{test_testcase.rb → test-testcase.rb} +30 -1
- data/test-unit/test/test_assertions.rb +1 -1
- metadata +9 -6
@@ -17,11 +17,8 @@
|
|
17
17
|
|
18
18
|
module Groonga
|
19
19
|
module ExpressionBuildable
|
20
|
-
|
20
|
+
attr_reader :table
|
21
21
|
def initialize(*args)
|
22
|
-
@builder = self
|
23
|
-
@expression = nil
|
24
|
-
@variable = nil
|
25
22
|
@table = nil
|
26
23
|
@name = nil
|
27
24
|
@query = nil
|
@@ -29,17 +26,119 @@ module Groonga
|
|
29
26
|
end
|
30
27
|
|
31
28
|
def build
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
29
|
+
expression = Expression.new(:table => @table,
|
30
|
+
:name => @name,
|
31
|
+
:query => @query,
|
32
|
+
:default_column => @default_column)
|
33
|
+
variable = expression.define_variable(:domain => @table)
|
34
|
+
|
35
|
+
builder = nil
|
36
|
+
builder = yield(self) if block_given?
|
37
|
+
if builder.nil? or builder == self
|
38
|
+
expression.append_constant(1)
|
39
|
+
expression.append_constant(1)
|
40
|
+
expression.append_operation(Groonga::Operation::OR, 2)
|
41
|
+
else
|
42
|
+
builder.build(expression, variable)
|
43
|
+
end
|
44
|
+
|
45
|
+
expression.compile
|
46
|
+
expression
|
47
|
+
end
|
48
|
+
|
49
|
+
class ExpressionBuilder
|
50
|
+
def initialize
|
51
|
+
super()
|
52
|
+
end
|
53
|
+
|
54
|
+
def &(other)
|
55
|
+
AndExpressionBuilder.new(self, other)
|
56
|
+
end
|
57
|
+
|
58
|
+
def |(other)
|
59
|
+
OrExpressionBuilder.new(self, other)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class SetExpressionBuilder < ExpressionBuilder
|
64
|
+
def initialize(operation, *expression_builders)
|
65
|
+
super()
|
66
|
+
@operation = operation
|
67
|
+
@expression_builders = expression_builders
|
68
|
+
end
|
69
|
+
|
70
|
+
def build(expression, variable)
|
71
|
+
return if @expression_builders.empty?
|
72
|
+
@expression_builders.each do |builder|
|
73
|
+
builder.build(expression, variable)
|
74
|
+
end
|
75
|
+
expression.append_operation(@operation, @expression_builders.size)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class AndExpressionBuilder < SetExpressionBuilder
|
80
|
+
def initialize(*expression_builders)
|
81
|
+
super(Groonga::Operation::AND, *expression_builders)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class OrExpressionBuilder < SetExpressionBuilder
|
86
|
+
def initialize(*expression_builders)
|
87
|
+
super(Groonga::Operation::OR, *expression_builders)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class BinaryExpressionBuilder < ExpressionBuilder
|
92
|
+
def initialize(operation, column_name, value)
|
93
|
+
super()
|
94
|
+
@operation = operation
|
95
|
+
@column_name = column_name
|
96
|
+
@value = value
|
97
|
+
end
|
98
|
+
|
99
|
+
def build(expression, variable)
|
100
|
+
expression.append_object(variable)
|
101
|
+
expression.append_constant(@column_name)
|
102
|
+
expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
103
|
+
expression.append_constant(@value)
|
104
|
+
expression.append_operation(@operation, 2)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class EqualExpressionBuilder < BinaryExpressionBuilder
|
109
|
+
def initialize(column_name, value)
|
110
|
+
super(Groonga::Operation::EQUAL, column_name, value)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class MatchExpressionBuilder < BinaryExpressionBuilder
|
115
|
+
def initialize(column_name, value)
|
116
|
+
super(Groonga::Operation::MATCH, column_name, value)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class LessExpressionBuilder < BinaryExpressionBuilder
|
121
|
+
def initialize(column_name, value)
|
122
|
+
super(Groonga::Operation::LESS, column_name, value)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class LessEqualExpressionBuilder < BinaryExpressionBuilder
|
127
|
+
def initialize(column_name, value)
|
128
|
+
super(Groonga::Operation::LESS_EQUAL, column_name, value)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class GreaterExpressionBuilder < BinaryExpressionBuilder
|
133
|
+
def initialize(column_name, value)
|
134
|
+
super(Groonga::Operation::GREATER, column_name, value)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class GreaterEqualExpressionBuilder < BinaryExpressionBuilder
|
139
|
+
def initialize(column_name, value)
|
140
|
+
super(Groonga::Operation::GREATER_EQUAL, column_name, value)
|
141
|
+
end
|
43
142
|
end
|
44
143
|
end
|
45
144
|
|
@@ -47,7 +146,7 @@ module Groonga
|
|
47
146
|
include ExpressionBuildable
|
48
147
|
|
49
148
|
def initialize(table, name)
|
50
|
-
super
|
149
|
+
super()
|
51
150
|
@table = table
|
52
151
|
@name = name
|
53
152
|
end
|
@@ -59,16 +158,7 @@ module Groonga
|
|
59
158
|
"for table <#{@table.inspect}>"
|
60
159
|
raise ArgumentError, message
|
61
160
|
end
|
62
|
-
|
63
|
-
builder.builder = @builder
|
64
|
-
builder.expression = @expression
|
65
|
-
builder.variable = @variable
|
66
|
-
builder
|
67
|
-
end
|
68
|
-
|
69
|
-
def &(other)
|
70
|
-
@expression.append_operation(Groonga::Operation::AND, 2)
|
71
|
-
@builder
|
161
|
+
ColumnExpressionBuilder.new(column, nil, nil)
|
72
162
|
end
|
73
163
|
end
|
74
164
|
|
@@ -76,8 +166,9 @@ module Groonga
|
|
76
166
|
include ExpressionBuildable
|
77
167
|
|
78
168
|
def initialize(column, name, query)
|
79
|
-
super
|
169
|
+
super()
|
80
170
|
@table = column.table
|
171
|
+
@range = column.range
|
81
172
|
@column = column
|
82
173
|
@default_column = column.local_name
|
83
174
|
@name = name
|
@@ -85,57 +176,36 @@ module Groonga
|
|
85
176
|
end
|
86
177
|
|
87
178
|
def ==(other)
|
88
|
-
@
|
89
|
-
@expression.append_constant(@column.local_name)
|
90
|
-
@expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
91
|
-
@expression.append_constant(other)
|
92
|
-
@expression.append_operation(Groonga::Operation::EQUAL, 2)
|
93
|
-
@builder
|
179
|
+
EqualExpressionBuilder.new(@column.local_name, normalize(other))
|
94
180
|
end
|
95
181
|
|
96
182
|
def =~(other)
|
97
|
-
@
|
98
|
-
@expression.append_constant(@column.local_name)
|
99
|
-
@expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
100
|
-
@expression.append_constant(other)
|
101
|
-
@expression.append_operation(Groonga::Operation::MATCH, 2)
|
102
|
-
@builder
|
183
|
+
MatchExpressionBuilder.new(@column.local_name, normalize(other))
|
103
184
|
end
|
104
185
|
|
105
186
|
def <(other)
|
106
|
-
@
|
107
|
-
@expression.append_constant(@column.local_name)
|
108
|
-
@expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
109
|
-
@expression.append_constant(other)
|
110
|
-
@expression.append_operation(Groonga::Operation::LESS, 2)
|
111
|
-
@builder
|
187
|
+
LessExpressionBuilder.new(@column.local_name, normalize(other))
|
112
188
|
end
|
113
189
|
|
114
190
|
def <=(other)
|
115
|
-
@
|
116
|
-
@expression.append_constant(@column.local_name)
|
117
|
-
@expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
118
|
-
@expression.append_constant(other)
|
119
|
-
@expression.append_operation(Groonga::Operation::LESS_EQUAL, 2)
|
120
|
-
@builder
|
191
|
+
LessEqualExpressionBuilder.new(@column.local_name, normalize(other))
|
121
192
|
end
|
122
193
|
|
123
194
|
def >(other)
|
124
|
-
@
|
125
|
-
@expression.append_constant(@column.local_name)
|
126
|
-
@expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2)
|
127
|
-
@expression.append_constant(other)
|
128
|
-
@expression.append_operation(Groonga::Operation::GREATER, 2)
|
129
|
-
@builder
|
195
|
+
GreaterExpressionBuilder.new(@column.local_name, normalize(other))
|
130
196
|
end
|
131
197
|
|
132
198
|
def >=(other)
|
133
|
-
@
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
@
|
199
|
+
GreaterEqualExpressionBuilder.new(@column.local_name, normalize(other))
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
def normalize(other)
|
204
|
+
if @range.is_a?(Groonga::Table) and other.is_a?(Integer)
|
205
|
+
Groonga::Record.new(@range, other)
|
206
|
+
else
|
207
|
+
other
|
208
|
+
end
|
139
209
|
end
|
140
210
|
end
|
141
211
|
end
|
data/lib/groonga/schema.rb
CHANGED
@@ -19,6 +19,29 @@
|
|
19
19
|
module Groonga
|
20
20
|
|
21
21
|
# groongaのスキーマ(データ構造)を管理するクラス。
|
22
|
+
#
|
23
|
+
# Groonga::Schemaを使うことにより簡単にテーブルやカラムを
|
24
|
+
# 追加・削除することができる。
|
25
|
+
#
|
26
|
+
# http://qwik.jp/senna/senna2.files/rect4605.png
|
27
|
+
# のようなスキーマを定義する場合は以下のようになる。
|
28
|
+
#
|
29
|
+
# Groonga::Schema.define do |schema|
|
30
|
+
# schema.create_table("items") do |table|
|
31
|
+
# table.short_text("title")
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# schema.create_table("users") do |table|
|
35
|
+
# table.short_text("name")
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# schema.create_table("comments") do |table|
|
39
|
+
# table.reference("item", "items")
|
40
|
+
# table.reference("author", "users")
|
41
|
+
# table.text("content")
|
42
|
+
# table.time("issued")
|
43
|
+
# end
|
44
|
+
# end
|
22
45
|
class Schema
|
23
46
|
class << self
|
24
47
|
|
@@ -70,16 +93,35 @@ module Groonga
|
|
70
93
|
# 合はパス名は自動的に作成される。デフォルトでは永続
|
71
94
|
# テーブルとなる。
|
72
95
|
#
|
73
|
-
# [+:
|
74
|
-
#
|
96
|
+
# [+:value_type+]
|
97
|
+
# 値の型を指定する。省略すると値のための領域を確保しない。
|
98
|
+
# 値を保存したい場合は必ず指定すること。
|
75
99
|
def create_table(name, options={}, &block)
|
76
100
|
define do |schema|
|
77
101
|
schema.create_table(name, options, &block)
|
78
102
|
end
|
79
103
|
end
|
80
104
|
|
105
|
+
# 名前が_name_のテーブルを削除する。
|
106
|
+
# _options_に指定可能な値は以下の通り。
|
107
|
+
#
|
108
|
+
# [+:context+]
|
109
|
+
# スキーマ定義時に使用するGroonga::Contextを指定する。
|
110
|
+
# 省略した場合はGroonga::Context.defaultを使用する。
|
111
|
+
def remove_table(name, options={})
|
112
|
+
define do |schema|
|
113
|
+
schema.remove_table(name, options)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def change_table(name, options={}, &block)
|
118
|
+
define do |schema|
|
119
|
+
schema.change_table(name, options, &block)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
81
123
|
# スキーマの内容を文字列で返す。返された値は
|
82
|
-
# Groonga::Schema
|
124
|
+
# Groonga::Schema.restoreすることによりスキーマ内に組
|
83
125
|
# み込むことができる。
|
84
126
|
#
|
85
127
|
# dump.rb:
|
@@ -90,9 +132,7 @@ module Groonga
|
|
90
132
|
# restore.rb:
|
91
133
|
# dumped_text = Groonga::Schema.dump
|
92
134
|
# Groonga::Database.create(:path => "/tmp/new-db.grn")
|
93
|
-
# Groonga::Schema.
|
94
|
-
# schema.restore(dumped_text)
|
95
|
-
# end
|
135
|
+
# Groonga::Schema.restore(dumped_text)
|
96
136
|
#
|
97
137
|
# _options_に指定可能な値は以下の通り。
|
98
138
|
#
|
@@ -103,6 +143,13 @@ module Groonga
|
|
103
143
|
Dumper.new(options).dump
|
104
144
|
end
|
105
145
|
|
146
|
+
# Groonga::Schema.dumpで文字列化したスキーマを組み込む。
|
147
|
+
def restore(dumped_text, options={})
|
148
|
+
define(options) do |schema|
|
149
|
+
schema.load(dumped_text)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
106
153
|
def normalize_type(type) # :nodoc:
|
107
154
|
return type if type.nil?
|
108
155
|
return type if type.is_a?(Groonga::Object)
|
@@ -152,7 +199,7 @@ module Groonga
|
|
152
199
|
#
|
153
200
|
# 読み込まれた内容は#defineを呼び出すまでは実行されない
|
154
201
|
# ことに注意すること。
|
155
|
-
def
|
202
|
+
def load(dumped_text)
|
156
203
|
instance_eval(dumped_text)
|
157
204
|
end
|
158
205
|
|
@@ -178,36 +225,97 @@ module Groonga
|
|
178
225
|
# 合はパス名は自動的に作成される。デフォルトでは永続
|
179
226
|
# テーブルとなる。
|
180
227
|
#
|
181
|
-
# [+:
|
182
|
-
#
|
228
|
+
# [+:value_type+]
|
229
|
+
# 値の型を指定する。省略すると値のための領域を確保しな
|
230
|
+
# い。値を保存したい場合は必ず指定すること。
|
231
|
+
#
|
232
|
+
# 参考: Groonga::Type.new
|
183
233
|
def create_table(name, options={})
|
184
234
|
definition = TableDefinition.new(name, @options.merge(options || {}))
|
185
235
|
yield(definition)
|
186
236
|
@definitions << definition
|
187
237
|
end
|
188
238
|
|
239
|
+
def remove_table(name, options={})
|
240
|
+
definition = TableRemoveDefinition.new(name, @options.merge(options || {}))
|
241
|
+
@definitions << definition
|
242
|
+
end
|
243
|
+
|
244
|
+
def change_table(name, options={})
|
245
|
+
options = @options.merge(options || {}).merge(:change => true)
|
246
|
+
definition = TableDefinition.new(name, options)
|
247
|
+
yield(definition)
|
248
|
+
@definitions << definition
|
249
|
+
end
|
250
|
+
|
189
251
|
class TableDefinition
|
252
|
+
attr_reader :name
|
253
|
+
|
190
254
|
def initialize(name, options)
|
191
255
|
@name = name
|
192
256
|
@name = @name.to_s if @name.is_a?(Symbol)
|
193
|
-
@
|
257
|
+
@definitions = []
|
258
|
+
validate_options(options)
|
194
259
|
@options = options
|
195
260
|
@table_type = table_type
|
196
261
|
end
|
197
262
|
|
198
263
|
def define
|
199
|
-
|
200
|
-
|
201
|
-
|
264
|
+
if @options[:change]
|
265
|
+
table = context[@name]
|
266
|
+
else
|
267
|
+
table = context[@name]
|
268
|
+
if table and @options[:force]
|
269
|
+
table.remove
|
270
|
+
end
|
271
|
+
table = @table_type.create(create_options)
|
272
|
+
end
|
273
|
+
@definitions.each do |definition|
|
274
|
+
definition.define(table)
|
202
275
|
end
|
203
276
|
table
|
204
277
|
end
|
205
278
|
|
206
279
|
def column(name, type, options={})
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
280
|
+
definition = self[name, ColumnDefinition]
|
281
|
+
if definition.nil?
|
282
|
+
definition = ColumnDefinition.new(name, options)
|
283
|
+
update_definition(name, ColumnDefinition, definition)
|
284
|
+
end
|
285
|
+
definition.type = type
|
286
|
+
definition.options.merge!(column_options.merge(options))
|
287
|
+
self
|
288
|
+
end
|
289
|
+
|
290
|
+
def remove_column(name, options={})
|
291
|
+
definition = self[name, ColumnRemoveDefinition]
|
292
|
+
if definition.nil?
|
293
|
+
definition = ColumnRemoveDefinition.new(name, options)
|
294
|
+
update_definition(name, ColumnRemoveDefinition, definition)
|
295
|
+
end
|
296
|
+
definition.options.merge!(options)
|
297
|
+
self
|
298
|
+
end
|
299
|
+
|
300
|
+
def index(target_column, options={})
|
301
|
+
name = options.delete(:name)
|
302
|
+
if name.nil?
|
303
|
+
target_column_name = nil
|
304
|
+
if target_column.is_a?(Groonga::Column)
|
305
|
+
target_column_name = target_column.name
|
306
|
+
else
|
307
|
+
target_column_name = target_column
|
308
|
+
end
|
309
|
+
name = target_column_name.gsub(/\./, "_")
|
310
|
+
end
|
311
|
+
|
312
|
+
definition = self[name, IndexColumnDefinition]
|
313
|
+
if definition.nil?
|
314
|
+
definition = IndexColumnDefinition.new(name, options)
|
315
|
+
update_definition(name, IndexColumnDefinition, definition)
|
316
|
+
end
|
317
|
+
definition.target = target_column
|
318
|
+
definition.options.merge!(column_options.merge(options))
|
211
319
|
self
|
212
320
|
end
|
213
321
|
|
@@ -254,19 +362,47 @@ module Groonga
|
|
254
362
|
column(name, "LongText", options)
|
255
363
|
end
|
256
364
|
|
257
|
-
def
|
258
|
-
column
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
365
|
+
def reference(name, table, options={})
|
366
|
+
column(name, table, options)
|
367
|
+
end
|
368
|
+
|
369
|
+
def [](name, definition_class=nil)
|
370
|
+
@definitions.find do |definition|
|
371
|
+
definition.name.to_s == name.to_s and
|
372
|
+
(definition_class.nil? or definition.is_a?(definition_class))
|
373
|
+
end
|
263
374
|
end
|
264
375
|
|
265
|
-
def
|
266
|
-
@
|
376
|
+
def context
|
377
|
+
@options[:context] || Groonga::Context.default
|
267
378
|
end
|
268
379
|
|
269
380
|
private
|
381
|
+
def update_definition(name, definition_class, definition)
|
382
|
+
old_definition = self[name, definition_class]
|
383
|
+
if old_definition
|
384
|
+
index = @definitions.index(old_definition)
|
385
|
+
@definitions[index] = definition
|
386
|
+
else
|
387
|
+
@definitions << definition
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
AVAILABLE_OPTION_KEYS = [:context, :change, :force,
|
392
|
+
:type, :path, :persistent,
|
393
|
+
:key_type, :value_type, :sub_records,
|
394
|
+
:default_tokenizer,
|
395
|
+
:key_normalize, :key_with_sis]
|
396
|
+
def validate_options(options)
|
397
|
+
return if options.nil?
|
398
|
+
unknown_keys = options.keys - AVAILABLE_OPTION_KEYS
|
399
|
+
unless unknown_keys.empty?
|
400
|
+
message = "unknown keys are specified: #{unknown_keys.inspect}"
|
401
|
+
message << ": available keys: #{AVAILABLE_OPTION_KEYS.inspect}"
|
402
|
+
raise ArgumentError, message
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
270
406
|
def table_type
|
271
407
|
type = @options[:type]
|
272
408
|
case type
|
@@ -286,8 +422,9 @@ module Groonga
|
|
286
422
|
:name => @name,
|
287
423
|
:path => @options[:path],
|
288
424
|
:persistent => persistent?,
|
289
|
-
:
|
425
|
+
:value_type => @options[:value_type],
|
290
426
|
:context => context,
|
427
|
+
:sub_records => @options[:sub_records],
|
291
428
|
}
|
292
429
|
key_support_table_common = {
|
293
430
|
:key_type => Schema.normalize_type(@options[:key_type]),
|
@@ -309,12 +446,24 @@ module Groonga
|
|
309
446
|
end
|
310
447
|
end
|
311
448
|
|
449
|
+
def column_options
|
450
|
+
{:persistent => persistent?}
|
451
|
+
end
|
452
|
+
|
312
453
|
def persistent?
|
313
454
|
@options[:persistent].nil? ? true : @options[:persistent]
|
314
455
|
end
|
456
|
+
end
|
315
457
|
|
316
|
-
|
317
|
-
|
458
|
+
class TableRemoveDefinition
|
459
|
+
def initialize(name, options={})
|
460
|
+
@name = name
|
461
|
+
@options = options
|
462
|
+
end
|
463
|
+
|
464
|
+
def define
|
465
|
+
context = @options[:context] || Groonga::Context.default
|
466
|
+
context[@name].remove
|
318
467
|
end
|
319
468
|
end
|
320
469
|
|
@@ -336,6 +485,21 @@ module Groonga
|
|
336
485
|
end
|
337
486
|
end
|
338
487
|
|
488
|
+
class ColumnRemoveDefinition
|
489
|
+
attr_accessor :name
|
490
|
+
attr_reader :options
|
491
|
+
|
492
|
+
def initialize(name, options={})
|
493
|
+
@name = name
|
494
|
+
@name = @name.to_s if @name.is_a?(Symbol)
|
495
|
+
@options = (options || {}).dup
|
496
|
+
end
|
497
|
+
|
498
|
+
def define(table)
|
499
|
+
table.column(@name).remove
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
339
503
|
class IndexColumnDefinition
|
340
504
|
attr_accessor :name, :target
|
341
505
|
attr_reader :options
|
@@ -350,6 +514,9 @@ module Groonga
|
|
350
514
|
def define(table)
|
351
515
|
target = @target
|
352
516
|
target = context[target] unless target.is_a?(Groonga::Object)
|
517
|
+
if target.nil?
|
518
|
+
raise ArgumentError, "Unknown index target: #{@target.inspect}"
|
519
|
+
end
|
353
520
|
index = table.define_index_column(@name,
|
354
521
|
target.table,
|
355
522
|
@options)
|
@@ -373,24 +540,49 @@ module Groonga
|
|
373
540
|
database = context.database
|
374
541
|
return nil if database.nil?
|
375
542
|
|
376
|
-
|
543
|
+
reference_columns = []
|
544
|
+
definitions = []
|
377
545
|
database.each do |object|
|
378
546
|
next unless object.is_a?(Groonga::Table)
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
547
|
+
schema = "create_table(#{object.name.inspect}) do |table|\n"
|
548
|
+
object.columns.sort_by {|column| column.local_name}.each do |column|
|
549
|
+
if column.range.is_a?(Groonga::Table)
|
550
|
+
reference_columns << column
|
551
|
+
else
|
552
|
+
type = column_method(column)
|
553
|
+
name = column.local_name
|
554
|
+
schema << " table.#{type}(#{name.inspect})\n"
|
555
|
+
end
|
556
|
+
end
|
557
|
+
schema << "end"
|
558
|
+
definitions << schema
|
559
|
+
end
|
560
|
+
|
561
|
+
reference_columns.group_by do |column|
|
562
|
+
column.table
|
563
|
+
end.each do |table, columns|
|
564
|
+
schema = "change_table(#{table.name.inspect}) do |table|\n"
|
565
|
+
columns.each do |column|
|
383
566
|
name = column.local_name
|
384
|
-
|
567
|
+
reference = column.range
|
568
|
+
schema << " table.reference(#{name.inspect}, " +
|
569
|
+
"#{reference.name.inspect})\n"
|
385
570
|
end
|
386
|
-
schema << "end
|
571
|
+
schema << "end"
|
572
|
+
definitions << schema
|
573
|
+
end
|
574
|
+
|
575
|
+
if definitions.empty?
|
576
|
+
""
|
577
|
+
else
|
578
|
+
definitions.join("\n\n") + "\n"
|
387
579
|
end
|
388
|
-
schema
|
389
580
|
end
|
390
581
|
|
391
582
|
private
|
392
583
|
def column_method(column)
|
393
|
-
|
584
|
+
range = column.range
|
585
|
+
case range.name
|
394
586
|
when "Int32"
|
395
587
|
"integer32"
|
396
588
|
when "Int64"
|
data/test/groonga-test-utils.rb
CHANGED
data/test/test-array.rb
CHANGED
data/test/test-context.rb
CHANGED
@@ -54,9 +54,15 @@ class ContextTest < Test::Unit::TestCase
|
|
54
54
|
context.inspect)
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
57
|
+
def test_array_reference_by_string
|
58
58
|
Groonga::Database.create
|
59
59
|
context = Groonga::Context.default
|
60
60
|
assert_equal("Int32", context["<int>"].name)
|
61
61
|
end
|
62
|
+
|
63
|
+
def test_array_reference_by_symbol
|
64
|
+
Groonga::Database.create
|
65
|
+
context = Groonga::Context.default
|
66
|
+
assert_equal("Bool", context[:Bool].name)
|
67
|
+
end
|
62
68
|
end
|