activegroonga 0.0.2 → 0.0.6
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/NEWS.ja.rdoc +4 -0
- data/NEWS.rdoc +4 -0
- data/README.ja.rdoc +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +3 -4
- data/lib/active_groonga.rb +2 -0
- data/lib/active_groonga/base.rb +125 -99
- data/lib/active_groonga/column.rb +9 -0
- data/lib/active_groonga/dynamic_record_expression_builder.rb +40 -0
- data/lib/active_groonga/schema.rb +107 -204
- data/lib/active_groonga/schema_dumper.rb +40 -25
- data/lib/active_groonga/tasks/groonga.rake +2 -0
- data/lib/active_groonga/version.rb +1 -1
- data/rails_generators/index_table_groonga/USAGE +23 -0
- data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +44 -0
- data/rails_generators/index_table_groonga/templates/migration.rb +12 -0
- data/rails_generators/migration_groonga/USAGE +29 -0
- data/rails_generators/migration_groonga/migration_groonga_generator.rb +19 -0
- data/rails_generators/migration_groonga/templates/migration.rb +11 -0
- 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
- data/test/active-groonga-test-utils.rb +25 -26
- data/test/test-base.rb +16 -6
- data/test/test-schema-dumper.rb +48 -0
- data/test/test-schema.rb +20 -4
- data/test/tmp/database/database.groonga +0 -0
- data/test/tmp/database/database.groonga.0000000 +0 -0
- data/test/tmp/database/database.groonga.0000100 +0 -0
- data/test/tmp/database/database.groonga.0000101 +0 -0
- metadata +19 -7
@@ -60,6 +60,14 @@ module ActiveGroonga
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def index?
|
64
|
+
@type == :index
|
65
|
+
end
|
66
|
+
|
67
|
+
def index_sources
|
68
|
+
@column.sources
|
69
|
+
end
|
70
|
+
|
63
71
|
def reference_type?
|
64
72
|
@type == :references
|
65
73
|
end
|
@@ -77,6 +85,7 @@ module ActiveGroonga
|
|
77
85
|
|
78
86
|
private
|
79
87
|
def detect_type
|
88
|
+
return :index if @column.is_a?(Groonga::IndexColumn)
|
80
89
|
case @column.range
|
81
90
|
when Groonga::Type
|
82
91
|
case @column.range.id
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License version 2.1 as published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
10
|
+
# Lesser General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
13
|
+
# License along with this library; if not, write to the Free Software
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
|
+
|
16
|
+
module ActiveGroonga
|
17
|
+
class DynamicRecordExpressionBuilder
|
18
|
+
# Instantiates a new dynamic record expression builder.
|
19
|
+
#
|
20
|
+
# +record+ is a Groonga::RecordExpressionBuilder.
|
21
|
+
def initialize(record)
|
22
|
+
@record = record
|
23
|
+
define_column_readers
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](name)
|
27
|
+
@record[name]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def define_column_readers
|
32
|
+
singleton_class = class << self; self; end
|
33
|
+
@record.table.columns.each do |column|
|
34
|
+
singleton_class.send(:define_method, column.local_name) do ||
|
35
|
+
self[column.local_name]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -54,155 +54,54 @@ module ActiveGroonga
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def initialize_schema_management_tables
|
57
|
-
initialize_index_management_table
|
58
|
-
initialize_index_table
|
59
57
|
initialize_migrations_table
|
60
58
|
end
|
61
59
|
|
62
|
-
def create_table(name, options={})
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
def create_table(name, options={}, &block)
|
61
|
+
table_file = File.join(Base.tables_directory, "#{name}.groonga")
|
62
|
+
table_name = Base.groonga_table_name(name)
|
63
|
+
options = {:path => table_file}.merge(options)
|
64
|
+
options = default_table_options(options).merge(options)
|
65
|
+
options = options.merge(:context => Base.context)
|
66
|
+
Groonga::Schema.create_table(table_name, options) do |table|
|
67
|
+
block.call(TableDefinitionWrapper.new(table))
|
68
|
+
end
|
66
69
|
end
|
67
70
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
table.remove
|
72
|
-
index_management_table.open_cursor do |cursor|
|
73
|
-
while cursor.next
|
74
|
-
cursor.delete if cursor.table_id == table_id
|
75
|
-
end
|
76
|
-
end
|
71
|
+
def remove_table(name, options={})
|
72
|
+
options = options.merge(:context => Base.context)
|
73
|
+
Groonga::Schema.remove_table(name, options)
|
77
74
|
end
|
75
|
+
alias_method :drop_table, :remove_table
|
78
76
|
|
79
77
|
def add_column(table_name, column_name, type, options={})
|
80
|
-
|
81
|
-
|
82
|
-
table =
|
83
|
-
column
|
84
|
-
else
|
85
|
-
column.type = type
|
78
|
+
options_with_context = options.merge(:context => Base.context)
|
79
|
+
Groonga::Schema.change_table(table_name, options_with_context) do |table|
|
80
|
+
table = TableDefinitionWrapper.new(table)
|
81
|
+
table.column(column_name, type, options)
|
86
82
|
end
|
87
|
-
column.create(options)
|
88
83
|
end
|
89
84
|
|
90
85
|
def remove_column(table_name, *column_names)
|
91
|
-
|
92
|
-
|
86
|
+
options_with_context = options.merge(:context => Base.context)
|
87
|
+
Groonga::Schema.change_table(table_name, options_with_context) do |table|
|
88
|
+
column_names.each do |column_name|
|
89
|
+
table.remove_column(column_name)
|
90
|
+
end
|
93
91
|
end
|
94
92
|
end
|
95
93
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
index_table_name,
|
104
|
-
table_name)
|
105
|
-
FileUtils.mkdir_p(base_dir)
|
106
|
-
|
107
|
-
name = "#{table_name}/#{column_name}"
|
108
|
-
path = File.join(base_dir, "#{column_name}.groonga")
|
109
|
-
index_column = index_table.define_index_column(name, table,
|
110
|
-
:path => path,
|
111
|
-
:compress => "zlib",
|
112
|
-
# :with_section => true,
|
113
|
-
# :with_weight => true,
|
114
|
-
:with_position => true)
|
115
|
-
index_column.source = column
|
116
|
-
|
117
|
-
record = index_management_table.add
|
118
|
-
record["table"] = groonga_table_name
|
119
|
-
record["column"] = column_name
|
120
|
-
record["index"] = name
|
121
|
-
end
|
122
|
-
|
123
|
-
def index_management_table
|
124
|
-
Base.context[groonga_index_management_table_name]
|
125
|
-
end
|
126
|
-
|
127
|
-
def index_table
|
128
|
-
Base.context[groonga_index_table_name]
|
129
|
-
end
|
130
|
-
|
131
|
-
def indexes(table_or_table_name)
|
132
|
-
if table_or_table_name.is_a?(String)
|
133
|
-
table_name = table_or_table_name
|
134
|
-
table = Base.context[Base.groonga_table_name(table_name)]
|
135
|
-
else
|
136
|
-
table = table_or_table_name
|
137
|
-
table_name = table.name.gsub(/(?:\A<table:|>\z)/, '')
|
138
|
-
end
|
139
|
-
indexes = []
|
140
|
-
index_management_table.records.each do |record|
|
141
|
-
next if record["table"] != table.name
|
142
|
-
indexes << IndexDefinition.new(table_name, record["index"],
|
143
|
-
false, record["column"])
|
94
|
+
def add_index_column(table_name, target_table_name, target_column_name,
|
95
|
+
options={})
|
96
|
+
options_for_table = options.reject {|key, value| key == :name}
|
97
|
+
options_for_table = options_for_table.merge(:context => Base.context)
|
98
|
+
Groonga::Schema.change_table(table_name, options_for_table) do |table|
|
99
|
+
table = TableDefinitionWrapper.new(table)
|
100
|
+
table.index(target_table_name, target_column_name, options)
|
144
101
|
end
|
145
|
-
indexes
|
146
102
|
end
|
147
103
|
|
148
104
|
private
|
149
|
-
def index_management_table_name
|
150
|
-
Base.table_name_prefix + 'indexes' + Base.table_name_suffix
|
151
|
-
end
|
152
|
-
|
153
|
-
def groonga_index_management_table_name
|
154
|
-
Base.groonga_metadata_table_name(index_management_table_name)
|
155
|
-
end
|
156
|
-
|
157
|
-
def index_table_name
|
158
|
-
Base.table_name_prefix + 'index' + Base.table_name_suffix
|
159
|
-
end
|
160
|
-
|
161
|
-
def groonga_index_table_name
|
162
|
-
Base.groonga_metadata_table_name(index_table_name)
|
163
|
-
end
|
164
|
-
|
165
|
-
def initialize_index_management_table
|
166
|
-
table_name = index_management_table_name
|
167
|
-
groonga_table_name = groonga_index_management_table_name
|
168
|
-
if Base.context[groonga_table_name].nil?
|
169
|
-
table_file = File.join(Base.metadata_directory,
|
170
|
-
"#{table_name}.groonga")
|
171
|
-
table = Groonga::Array.create(:name => groonga_table_name,
|
172
|
-
:path => table_file)
|
173
|
-
|
174
|
-
base_dir = File.join(Base.metadata_directory, table_name)
|
175
|
-
FileUtils.mkdir_p(base_dir)
|
176
|
-
|
177
|
-
column_file = File.join(base_dir, "table.groonga")
|
178
|
-
table.define_column("table", "<shorttext>", :path => column_file)
|
179
|
-
|
180
|
-
column_file = File.join(base_dir, "column.groonga")
|
181
|
-
table.define_column("column", "<shorttext>", :path => column_file)
|
182
|
-
|
183
|
-
column_file = File.join(base_dir, "index.groonga")
|
184
|
-
table.define_column("index", "<shorttext>", :path => column_file)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def initialize_index_table
|
189
|
-
table_name = index_table_name
|
190
|
-
groonga_table_name = groonga_index_table_name
|
191
|
-
if Base.context[groonga_table_name].nil?
|
192
|
-
table_file = File.join(Base.metadata_directory,
|
193
|
-
"#{table_name}.groonga")
|
194
|
-
table = Groonga::PatriciaTrie.create(:name => groonga_table_name,
|
195
|
-
:key_type => "<shorttext>",
|
196
|
-
# :key_with_sis => true,
|
197
|
-
# :key_normalize => true,
|
198
|
-
:path => table_file)
|
199
|
-
table.default_tokenizer = "<token:bigram>"
|
200
|
-
|
201
|
-
base_dir = File.join(Base.metadata_directory, table_name)
|
202
|
-
FileUtils.mkdir_p(base_dir)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
105
|
def initialize_migrations_table
|
207
106
|
table_name = Migrator.schema_migrations_table_name
|
208
107
|
groonga_table_name = Migrator.groonga_schema_migrations_table_name
|
@@ -211,104 +110,108 @@ module ActiveGroonga
|
|
211
110
|
"#{table_name}.groonga")
|
212
111
|
Groonga::Hash.create(:name => groonga_table_name,
|
213
112
|
:path => table_file,
|
214
|
-
:key_type => "
|
113
|
+
:key_type => "ShortText")
|
215
114
|
end
|
216
115
|
end
|
116
|
+
|
117
|
+
def default_table_options(options)
|
118
|
+
default_options = {:sub_records => true}
|
119
|
+
case options[:type]
|
120
|
+
when :hash, :patricia_trie
|
121
|
+
default_options[:default_tokenizer] = "TokenBigram"
|
122
|
+
end
|
123
|
+
default_options
|
124
|
+
end
|
217
125
|
end
|
218
126
|
|
219
|
-
class
|
220
|
-
|
127
|
+
class TableDefinitionWrapper
|
128
|
+
def initialize(definition)
|
129
|
+
@definition = definition
|
130
|
+
end
|
131
|
+
|
132
|
+
def column(name, type, options={})
|
133
|
+
column_file = File.join(Base.columns_directory(@definition.name),
|
134
|
+
"#{name}.groonga")
|
135
|
+
options = {:path => column_file}.merge(options)
|
136
|
+
@definition.column(name, type, options)
|
137
|
+
end
|
138
|
+
|
139
|
+
def remove_column(name, options={})
|
140
|
+
@definition.remove_column(name, options)
|
141
|
+
end
|
142
|
+
alias_method :remove_index, :remove_column
|
143
|
+
|
144
|
+
def index(target_table_name, target_column_name, options={})
|
145
|
+
column_name = options.delete(:name)
|
146
|
+
column_name ||= [target_table_name, target_column_name].join("_")
|
147
|
+
column_dir = Base.index_columns_directory(@definition.name,
|
148
|
+
target_table_name.to_s)
|
149
|
+
column_file = File.join(column_dir, "#{column_name}.groonga")
|
150
|
+
options = {
|
151
|
+
:with_position => true,
|
152
|
+
:path => column_file,
|
153
|
+
:name => column_name,
|
154
|
+
}.merge(options)
|
155
|
+
target_table = @definition.context[target_table_name]
|
156
|
+
target_column = target_table.column(target_column_name)
|
157
|
+
@definition.index(target_column, options)
|
158
|
+
end
|
159
|
+
|
160
|
+
def timestamps(*args)
|
161
|
+
options = args.extract_options!
|
162
|
+
column(:created_at, :datetime, options)
|
163
|
+
column(:updated_at, :datetime, options)
|
164
|
+
end
|
221
165
|
|
222
|
-
def
|
223
|
-
|
224
|
-
@name = name
|
225
|
-
@indexes = []
|
166
|
+
def string(*args)
|
167
|
+
columns("ShortText", *args)
|
226
168
|
end
|
227
169
|
|
228
|
-
def
|
229
|
-
|
230
|
-
Groonga::Array.create(:name => Base.groonga_table_name(@name),
|
231
|
-
:path => table_file)
|
232
|
-
@columns.each(&:create)
|
233
|
-
@indexes.each do |column_name, options|
|
234
|
-
Schema.add_index(@name.to_s, column_name, options)
|
235
|
-
end
|
170
|
+
def text(*args)
|
171
|
+
columns("Text", *args)
|
236
172
|
end
|
237
173
|
|
238
|
-
def
|
239
|
-
|
240
|
-
column.type = type
|
241
|
-
@columns << column unless @columns.include?(column)
|
242
|
-
self
|
174
|
+
def integer(*args)
|
175
|
+
columns("Int32", *args)
|
243
176
|
end
|
244
177
|
|
245
|
-
def
|
246
|
-
|
178
|
+
def float(*args)
|
179
|
+
columns("Float", *args)
|
247
180
|
end
|
248
181
|
|
249
|
-
def
|
250
|
-
|
251
|
-
args.each do |col|
|
252
|
-
groonga_table_name = Base.groonga_table_name(col.to_s.pluralize)
|
253
|
-
table = Base.context[groonga_table_name]
|
254
|
-
column(col, table, options)
|
255
|
-
end
|
182
|
+
def decimal(*args)
|
183
|
+
columns("Int64", *args)
|
256
184
|
end
|
257
|
-
alias :belongs_to :references
|
258
|
-
end
|
259
185
|
|
260
|
-
|
261
|
-
|
186
|
+
def time(*args)
|
187
|
+
columns("Time", *args)
|
188
|
+
end
|
189
|
+
alias_method :datetime, :time
|
190
|
+
alias_method :timestamp, :time
|
262
191
|
|
263
|
-
def
|
264
|
-
|
265
|
-
@name = name
|
266
|
-
@name = @name.to_s if @name.is_a?(Symbol)
|
267
|
-
@type = nil
|
192
|
+
def binary(*args)
|
193
|
+
columns("LongText", *args)
|
268
194
|
end
|
269
195
|
|
270
|
-
def
|
271
|
-
|
272
|
-
"#{@name}.groonga")
|
273
|
-
options = options.merge(:path => column_file)
|
274
|
-
table = Base.context[Base.groonga_table_name(@table_name)]
|
275
|
-
table.define_column(@name,
|
276
|
-
normalize_type(@type),
|
277
|
-
options)
|
196
|
+
def boolean(*args)
|
197
|
+
columns("Bool", *args)
|
278
198
|
end
|
279
199
|
|
280
|
-
def
|
281
|
-
Base.
|
200
|
+
def reference(name, table=nil, options={})
|
201
|
+
table = Base.groonga_table_name(table || name.to_s.pluralize)
|
202
|
+
column(name, table, options)
|
282
203
|
end
|
204
|
+
alias_method :references, :reference
|
205
|
+
alias_method :belongs_to, :references
|
283
206
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
"<text>"
|
291
|
-
when "integer"
|
292
|
-
"<int>"
|
293
|
-
when "float"
|
294
|
-
"<float>"
|
295
|
-
when "decimal"
|
296
|
-
"<int64>"
|
297
|
-
when "datetime", "timestamp", "time", "date"
|
298
|
-
"<time>"
|
299
|
-
when "binary"
|
300
|
-
"<longtext>"
|
301
|
-
when "boolean"
|
302
|
-
"<int>"
|
303
|
-
else
|
304
|
-
type
|
207
|
+
private
|
208
|
+
def columns(type, *args)
|
209
|
+
options = args.extract_options!
|
210
|
+
column_names = args
|
211
|
+
column_names.each do |name|
|
212
|
+
column(name, type, options)
|
305
213
|
end
|
306
214
|
end
|
307
215
|
end
|
308
|
-
|
309
|
-
class IndexDefinition < ActiveRecord::ConnectionAdapters::IndexDefinition
|
310
|
-
alias_method :column, :columns
|
311
|
-
alias_method :column=, :columns=
|
312
|
-
end
|
313
216
|
end
|
314
217
|
end
|
@@ -28,9 +28,11 @@ module ActiveGroonga
|
|
28
28
|
|
29
29
|
def dump(stream)
|
30
30
|
@references = []
|
31
|
+
@indexes = []
|
31
32
|
header(stream)
|
32
33
|
dump_tables(stream)
|
33
34
|
dump_references(stream)
|
35
|
+
dump_indexes(stream)
|
34
36
|
trailer(stream)
|
35
37
|
stream
|
36
38
|
end
|
@@ -52,13 +54,34 @@ module ActiveGroonga
|
|
52
54
|
def dump_table(name, stream)
|
53
55
|
begin
|
54
56
|
table_schema = StringIO.new
|
55
|
-
|
57
|
+
|
58
|
+
table_name = Base.groonga_table_name(name)
|
59
|
+
table = Base.context[table_name]
|
60
|
+
options = [":force => true"]
|
61
|
+
case table
|
62
|
+
when Groonga::Hash
|
63
|
+
options << ":type => :hash"
|
64
|
+
when Groonga::PatriciaTrie
|
65
|
+
options << ":type => :patricia_trie"
|
66
|
+
end
|
67
|
+
if table.domain
|
68
|
+
options << ":key_type => #{table.domain.name.inspect}"
|
69
|
+
end
|
70
|
+
if table.respond_to?(:default_tokenizer) and table.default_tokenizer
|
71
|
+
options << ":default_tokenizer => #{table.default_tokenizer.name.inspect}"
|
72
|
+
end
|
73
|
+
|
74
|
+
table_schema.puts " create_table #{name.inspect}, #{options.join(', ')} do |t|"
|
56
75
|
column_specs = []
|
57
76
|
columns(name).each do |column|
|
58
77
|
if column.reference_type?
|
59
78
|
@references << [name, column]
|
60
79
|
next
|
61
80
|
end
|
81
|
+
if column.index?
|
82
|
+
@indexes << [name, column]
|
83
|
+
next
|
84
|
+
end
|
62
85
|
|
63
86
|
spec = {}
|
64
87
|
spec[:type] = column.type.to_s
|
@@ -74,8 +97,6 @@ module ActiveGroonga
|
|
74
97
|
table_schema.puts " end"
|
75
98
|
table_schema.puts
|
76
99
|
|
77
|
-
dump_indexes(name, table_schema)
|
78
|
-
|
79
100
|
stream.print table_schema.string
|
80
101
|
rescue => e
|
81
102
|
stream.puts "# Could not dump table #{name.inspect} because of following #{e.class}"
|
@@ -89,42 +110,36 @@ module ActiveGroonga
|
|
89
110
|
stream
|
90
111
|
end
|
91
112
|
|
92
|
-
def dump_indexes(table, stream)
|
93
|
-
_indexes = indexes(table)
|
94
|
-
return if _indexes.empty?
|
95
|
-
|
96
|
-
add_index_statements = _indexes.collect do |index|
|
97
|
-
statement_parts = []
|
98
|
-
statement_parts << "add_index #{index.table.inspect}"
|
99
|
-
statement_parts << index.columns.inspect
|
100
|
-
statement_parts << ":name => #{index.name.inspect}"
|
101
|
-
' ' + statement_parts.join(', ')
|
102
|
-
end
|
103
|
-
|
104
|
-
stream.puts add_index_statements.sort.join("\n")
|
105
|
-
stream.puts
|
106
|
-
end
|
107
|
-
|
108
113
|
def dump_references(stream)
|
109
114
|
@references.sort_by do |name, column|
|
110
115
|
[name, column.name]
|
111
116
|
end.each do |name, column|
|
112
117
|
statement = " add_column #{name.inspect}, "
|
113
|
-
statement << "#{column.name.inspect},
|
114
|
-
statement << "
|
118
|
+
statement << "#{column.name.inspect}, "
|
119
|
+
statement << "#{column.reference_object_name.inspect}"
|
115
120
|
stream.puts(statement)
|
116
121
|
end
|
117
122
|
end
|
118
123
|
|
124
|
+
def dump_indexes(stream)
|
125
|
+
@indexes.sort_by do |name, column|
|
126
|
+
[name, column.name]
|
127
|
+
end.each do |name, column|
|
128
|
+
column.index_sources.each do |source|
|
129
|
+
statement = " add_index_column #{name.inspect}, "
|
130
|
+
statement << "#{source.table.name.inspect}, "
|
131
|
+
statement << "#{source.local_name.inspect}, "
|
132
|
+
statement << ":name => #{column.name.inspect}"
|
133
|
+
stream.puts(statement)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
119
138
|
def columns(table_name)
|
120
139
|
table_name = Base.groonga_table_name(table_name)
|
121
140
|
Base.context[table_name].columns.collect {|column| Column.new(column)}
|
122
141
|
end
|
123
142
|
|
124
|
-
def indexes(table_name)
|
125
|
-
Schema.indexes(table_name)
|
126
|
-
end
|
127
|
-
|
128
143
|
class StreamWrapper
|
129
144
|
def initialize(stream)
|
130
145
|
@stream = stream
|