bigbroda 0.0.7 → 0.1.0.pre
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.
- checksums.yaml +4 -4
- data/Appraisals +15 -0
- data/Gemfile +1 -0
- data/README.md +39 -21
- data/Rakefile +5 -2
- data/{google_bigquery.gemspec → bigbroda.gemspec} +2 -2
- data/gemfiles/rails_3.gemfile +20 -0
- data/gemfiles/rails_4.0.3.gemfile +20 -0
- data/gemfiles/rails_4.0.3.gemfile.lock +176 -0
- data/gemfiles/rails_4.1.gemfile +20 -0
- data/gemfiles/rails_4.1.gemfile.lock +182 -0
- data/gemfiles/rails_4.2.gemfile +20 -0
- data/gemfiles/rails_4.2.gemfile.lock +202 -0
- data/gemfiles/rails_4.gemfile +20 -0
- data/gemfiles/rails_4.gemfile.lock +176 -0
- data/lib/active_record/connection_adapters/bigquery_adapter.rb +32 -601
- data/lib/active_record/connection_adapters/rails_41.rb +607 -0
- data/lib/active_record/connection_adapters/rails_42.rb +628 -0
- data/lib/{google_bigquery → bigbroda}/auth.rb +3 -3
- data/lib/{google_bigquery → bigbroda}/client.rb +3 -3
- data/lib/{google_bigquery → bigbroda}/config.rb +1 -1
- data/lib/{google_bigquery → bigbroda}/dataset.rb +23 -23
- data/lib/{google_bigquery → bigbroda}/engine.rb +4 -4
- data/lib/{google_bigquery → bigbroda}/jobs.rb +28 -28
- data/lib/bigbroda/project.rb +16 -0
- data/lib/{google_bigquery → bigbroda}/railtie.rb +3 -3
- data/lib/{google_bigquery → bigbroda}/table.rb +19 -19
- data/lib/{google_bigquery → bigbroda}/table_data.rb +7 -7
- data/lib/bigbroda/version.rb +3 -0
- data/lib/bigbroda.rb +27 -0
- data/lib/generators/{google_bigquery → bigbroda}/install/install_generator.rb +2 -2
- data/lib/generators/templates/{bigquery.rb.erb → bigbroda.rb.erb} +1 -1
- data/spec/dummy/config/application.rb +1 -1
- data/spec/functional/adapter/adapter_spec.rb +40 -38
- data/spec/functional/auth_spec.rb +3 -3
- data/spec/functional/config_spec.rb +5 -5
- data/spec/functional/dataset_spec.rb +19 -19
- data/spec/functional/project_spec.rb +4 -4
- data/spec/functional/table_data_spec.rb +13 -13
- data/spec/functional/table_spec.rb +30 -30
- data/spec/spec_helper.rb +2 -2
- metadata +32 -20
- data/lib/google_bigquery/project.rb +0 -16
- data/lib/google_bigquery/version.rb +0 -3
- data/lib/google_bigquery.rb +0 -27
@@ -0,0 +1,607 @@
|
|
1
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
2
|
+
require 'active_record/connection_adapters/statement_pool'
|
3
|
+
require 'active_record/connection_adapters/abstract/schema_statements'
|
4
|
+
require 'arel/visitors/bind_visitor'
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
|
8
|
+
module ConnectionAdapters
|
9
|
+
|
10
|
+
|
11
|
+
class BigqueryColumn < Column
|
12
|
+
class << self
|
13
|
+
TRUE_VALUES = [true, 1, '1', 'true', 'TRUE'].to_set
|
14
|
+
FALSE_VALUES = [false, 0, '0','false', 'FALSE'].to_set
|
15
|
+
|
16
|
+
def binary_to_string(value)
|
17
|
+
if value.encoding != Encoding::ASCII_8BIT
|
18
|
+
value = value.force_encoding(Encoding::ASCII_8BIT)
|
19
|
+
end
|
20
|
+
value
|
21
|
+
end
|
22
|
+
|
23
|
+
def string_to_time(string)
|
24
|
+
return string unless string.is_a?(String)
|
25
|
+
return nil if string.empty?
|
26
|
+
fast_string_to_time(string) || fallback_string_to_time(string) || Time.at(string.to_f).send(Base.default_timezone)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class BigqueryAdapter < AbstractAdapter
|
32
|
+
|
33
|
+
include SchemaStatements
|
34
|
+
|
35
|
+
class Version
|
36
|
+
end
|
37
|
+
|
38
|
+
class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
|
39
|
+
attr_accessor :array
|
40
|
+
end
|
41
|
+
|
42
|
+
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
43
|
+
|
44
|
+
def primary_key(name, type = :primary_key, options = {})
|
45
|
+
return column name, :string, options
|
46
|
+
end
|
47
|
+
|
48
|
+
def record(*args)
|
49
|
+
options = args.extract_options!
|
50
|
+
column(:created_at, :record, options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def timestamps(*args)
|
54
|
+
options = args.extract_options!
|
55
|
+
column(:created_at, :timestamp, options)
|
56
|
+
column(:updated_at, :timestamp, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def references(*args)
|
60
|
+
options = args.extract_options!
|
61
|
+
polymorphic = options.delete(:polymorphic)
|
62
|
+
index_options = options.delete(:index)
|
63
|
+
args.each do |col|
|
64
|
+
column("#{col}_id", :string, options)
|
65
|
+
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
66
|
+
index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
class StatementPool < ConnectionAdapters::StatementPool
|
73
|
+
def initialize(connection, max)
|
74
|
+
super
|
75
|
+
@cache = Hash.new { |h,pid| h[pid] = {} }
|
76
|
+
end
|
77
|
+
|
78
|
+
def each(&block); cache.each(&block); end
|
79
|
+
def key?(key); cache.key?(key); end
|
80
|
+
def [](key); cache[key]; end
|
81
|
+
def length; cache.length; end
|
82
|
+
|
83
|
+
def []=(sql, key)
|
84
|
+
while @max <= cache.size
|
85
|
+
dealloc(cache.shift.last[:stmt])
|
86
|
+
end
|
87
|
+
cache[sql] = key
|
88
|
+
end
|
89
|
+
|
90
|
+
def clear
|
91
|
+
cache.values.each do |hash|
|
92
|
+
dealloc hash[:stmt]
|
93
|
+
end
|
94
|
+
cache.clear
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def cache
|
99
|
+
@cache[$$]
|
100
|
+
end
|
101
|
+
|
102
|
+
def dealloc(stmt)
|
103
|
+
stmt.close unless stmt.closed?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class BindSubstitution < Arel::Visitors::SQLite # :nodoc:
|
108
|
+
include Arel::Visitors::BindVisitor
|
109
|
+
end
|
110
|
+
|
111
|
+
def initialize(connection, logger, config)
|
112
|
+
super(connection, logger)
|
113
|
+
|
114
|
+
@active = nil
|
115
|
+
@statements = StatementPool.new(@connection,
|
116
|
+
self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 }))
|
117
|
+
@config = config
|
118
|
+
|
119
|
+
#if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
120
|
+
# @prepared_statements = true
|
121
|
+
# @visitor = Arel::Visitors::SQLite.new self
|
122
|
+
#else
|
123
|
+
#use the sql without prepraded statements, as I know BQ doesn't support them.
|
124
|
+
|
125
|
+
@visitor = unprepared_visitor unless ActiveRecord::VERSION::MINOR >= 2
|
126
|
+
end
|
127
|
+
|
128
|
+
def adapter_name #:nodoc:
|
129
|
+
'BigQuery'
|
130
|
+
end
|
131
|
+
|
132
|
+
def supports_ddl_transactions?
|
133
|
+
false
|
134
|
+
end
|
135
|
+
|
136
|
+
def supports_savepoints?
|
137
|
+
false
|
138
|
+
end
|
139
|
+
|
140
|
+
def supports_partial_index?
|
141
|
+
true
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns true, since this connection adapter supports prepared statement
|
145
|
+
# caching.
|
146
|
+
def supports_statement_cache?
|
147
|
+
false
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns true, since this connection adapter supports migrations.
|
151
|
+
def supports_migrations? #:nodoc:
|
152
|
+
true
|
153
|
+
end
|
154
|
+
|
155
|
+
def supports_primary_key? #:nodoc:
|
156
|
+
true
|
157
|
+
end
|
158
|
+
|
159
|
+
def requires_reloading?
|
160
|
+
false
|
161
|
+
end
|
162
|
+
|
163
|
+
def supports_add_column?
|
164
|
+
true
|
165
|
+
end
|
166
|
+
|
167
|
+
def active?
|
168
|
+
@active != false
|
169
|
+
end
|
170
|
+
|
171
|
+
# Disconnects from the database if already connected. Otherwise, this
|
172
|
+
# method does nothing.
|
173
|
+
def disconnect!
|
174
|
+
super
|
175
|
+
@active = false
|
176
|
+
@connection.close rescue nil
|
177
|
+
end
|
178
|
+
|
179
|
+
# Clears the prepared statements cache.
|
180
|
+
def clear_cache!
|
181
|
+
@statements.clear
|
182
|
+
end
|
183
|
+
|
184
|
+
def supports_index_sort_order?
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns true
|
189
|
+
def supports_count_distinct? #:nodoc:
|
190
|
+
true
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns false
|
194
|
+
def supports_autoincrement? #:nodoc:
|
195
|
+
false
|
196
|
+
end
|
197
|
+
|
198
|
+
def supports_index_sort_order?
|
199
|
+
false
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns 62. SQLite supports index names up to 64
|
203
|
+
# characters. The rest is used by rails internally to perform
|
204
|
+
# temporary rename operations
|
205
|
+
def allowed_index_name_length
|
206
|
+
index_name_length - 2
|
207
|
+
end
|
208
|
+
|
209
|
+
def default_primary_key_type
|
210
|
+
if supports_autoincrement?
|
211
|
+
'STRING'
|
212
|
+
else
|
213
|
+
'STRING'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def native_database_types #:nodoc:
|
218
|
+
{
|
219
|
+
:primary_key => default_primary_key_type,
|
220
|
+
:string => { :name => "STRING", :default=> nil },
|
221
|
+
#:text => { :name => "text" },
|
222
|
+
:integer => { :name => "INTEGER", :default=> nil },
|
223
|
+
:float => { :name => "FLOAT", :default=> 0.0 },
|
224
|
+
#:decimal => { :name => "decimal" },
|
225
|
+
:datetime => { :name => "TIMESTAMP" },
|
226
|
+
#:timestamp => { :name => "datetime" },
|
227
|
+
:timestamp => { name: "TIMESTAMP" },
|
228
|
+
#:time => { :name => "time" },
|
229
|
+
:date => { :name => "TIMESTAMP" },
|
230
|
+
:record => { :name => "RECORD" },
|
231
|
+
:boolean => { :name => "BOOLEAN" }
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
# Returns the current database encoding format as a string, eg: 'UTF-8'
|
236
|
+
def encoding
|
237
|
+
@connection.encoding.to_s
|
238
|
+
end
|
239
|
+
|
240
|
+
# Returns false.
|
241
|
+
def supports_explain?
|
242
|
+
false
|
243
|
+
end
|
244
|
+
|
245
|
+
def create_database(database)
|
246
|
+
result = BigBroda::Dataset.create(@config[:project],
|
247
|
+
{"datasetReference"=> { "datasetId" => database }} )
|
248
|
+
result
|
249
|
+
end
|
250
|
+
|
251
|
+
def drop_database(database)
|
252
|
+
tables = BigBroda::Table.list(@config[:project], database)["tables"]
|
253
|
+
unless tables.blank?
|
254
|
+
tables.map!{|o| o["tableReference"]["tableId"]}
|
255
|
+
tables.each do |table_id|
|
256
|
+
BigBroda::Table.delete(@config[:project], database, table_id)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
result = BigBroda::Dataset.delete(@config[:project], database )
|
260
|
+
result
|
261
|
+
end
|
262
|
+
|
263
|
+
# QUOTING ==================================================
|
264
|
+
|
265
|
+
def quote(value, column = nil)
|
266
|
+
if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
|
267
|
+
s = column.class.string_to_binary(value).unpack("H*")[0]
|
268
|
+
"x'#{s}'"
|
269
|
+
else
|
270
|
+
super
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def quote_table_name(name)
|
275
|
+
"#{@config[:database]}.#{name}"
|
276
|
+
end
|
277
|
+
|
278
|
+
def quote_table_name_for_assignment(table, attr)
|
279
|
+
quote_column_name(attr)
|
280
|
+
end
|
281
|
+
|
282
|
+
def quote_column_name(name) #:nodoc:
|
283
|
+
name
|
284
|
+
end
|
285
|
+
|
286
|
+
# Quote date/time values for use in SQL input. Includes microseconds
|
287
|
+
# if the value is a Time responding to usec.
|
288
|
+
def quoted_date(value) #:nodoc:
|
289
|
+
if value.respond_to?(:usec)
|
290
|
+
"#{super}.#{sprintf("%06d", value.usec)}"
|
291
|
+
else
|
292
|
+
super
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def quoted_true
|
297
|
+
"1"
|
298
|
+
end
|
299
|
+
|
300
|
+
def quoted_false
|
301
|
+
"0"
|
302
|
+
end
|
303
|
+
|
304
|
+
def type_cast(value, column) # :nodoc:
|
305
|
+
return value.to_f if BigDecimal === value
|
306
|
+
return super unless String === value
|
307
|
+
return super unless column && value
|
308
|
+
|
309
|
+
value = super
|
310
|
+
if column.type == :string && value.encoding == Encoding::ASCII_8BIT
|
311
|
+
logger.error "Binary data inserted for `string` type on column `#{column.name}`" if logger
|
312
|
+
value = value.encode Encoding::UTF_8
|
313
|
+
end
|
314
|
+
value
|
315
|
+
end
|
316
|
+
|
317
|
+
# DATABASE STATEMENTS ======================================
|
318
|
+
|
319
|
+
def explain(arel, binds = [])
|
320
|
+
bypass_feature
|
321
|
+
end
|
322
|
+
|
323
|
+
class ExplainPrettyPrinter
|
324
|
+
# Pretty prints the result of a EXPLAIN QUERY PLAN in a way that resembles
|
325
|
+
# the output of the SQLite shell:
|
326
|
+
#
|
327
|
+
# 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
|
328
|
+
# 0|1|1|SCAN TABLE posts (~100000 rows)
|
329
|
+
#
|
330
|
+
def pp(result) # :nodoc:
|
331
|
+
result.rows.map do |row|
|
332
|
+
row.join('|')
|
333
|
+
end.join("\n") + "\n"
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def exec_query(sql, name = nil, binds = [])
|
338
|
+
log(sql, name, binds) do
|
339
|
+
|
340
|
+
# Don't cache statements if they are not prepared
|
341
|
+
#we set prepared_statements to false in config initialization
|
342
|
+
#if without_prepared_statement?(binds)
|
343
|
+
result = BigBroda::Jobs.query(@config[:project], {"query"=> sql })
|
344
|
+
cols = result["schema"]["fields"].map{|o| o["name"] }
|
345
|
+
records = result["totalRows"].to_i.zero? ? [] : result["rows"].map{|o| o["f"].map{|k,v| k["v"]} }
|
346
|
+
stmt = records
|
347
|
+
#else
|
348
|
+
#binding.pry
|
349
|
+
#BQ does not support prepared statements, yiak!
|
350
|
+
#end
|
351
|
+
|
352
|
+
ActiveRecord::Result.new(cols, stmt)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def exec_delete(sql, name = 'SQL', binds = [])
|
357
|
+
exec_query(sql, name, binds)
|
358
|
+
@connection.changes
|
359
|
+
end
|
360
|
+
|
361
|
+
alias :exec_update :exec_delete
|
362
|
+
|
363
|
+
def last_inserted_id(result)
|
364
|
+
@connection.last_insert_row_id
|
365
|
+
end
|
366
|
+
|
367
|
+
def execute(sql, name = nil) #:nodoc:
|
368
|
+
log(sql, name) { @connection.execute(sql) }
|
369
|
+
end
|
370
|
+
|
371
|
+
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
372
|
+
super
|
373
|
+
id_value || @connection.last_insert_row_id
|
374
|
+
end
|
375
|
+
alias :create :insert_sql
|
376
|
+
|
377
|
+
def select_rows(sql, name = nil)
|
378
|
+
exec_query(sql, name).rows
|
379
|
+
end
|
380
|
+
|
381
|
+
def begin_db_transaction #:nodoc:
|
382
|
+
log('begin transaction',nil) { } #@connection.transaction
|
383
|
+
end
|
384
|
+
|
385
|
+
def commit_db_transaction #:nodoc:
|
386
|
+
log('commit transaction',nil) { } #@connection.commit
|
387
|
+
end
|
388
|
+
|
389
|
+
def rollback_db_transaction #:nodoc:
|
390
|
+
log('rollback transaction',nil) { } #@connection.rollback
|
391
|
+
end
|
392
|
+
|
393
|
+
# SCHEMA STATEMENTS ========================================
|
394
|
+
|
395
|
+
def tables(name = nil, table_name = nil) #:nodoc:
|
396
|
+
table = BigBroda::Table.list(@config[:project], @config[:database])
|
397
|
+
return [] if table["tables"].blank?
|
398
|
+
table_names = table["tables"].map{|o| o["tableReference"]["tableId"]}
|
399
|
+
table_names = table_names.select{|o| o == table_name } if table_name
|
400
|
+
table_names
|
401
|
+
end
|
402
|
+
|
403
|
+
def table_exists?(table_name)
|
404
|
+
table_name && tables(nil, table_name).any?
|
405
|
+
end
|
406
|
+
|
407
|
+
# Returns an array of +SQLite3Column+ objects for the table specified by +table_name+.
|
408
|
+
def columns(table_name) #:nodoc:
|
409
|
+
schema = BigBroda::Table.get(@config[:project], @config[:database], table_name)
|
410
|
+
schema["schema"]["fields"].map do |field|
|
411
|
+
mode = field['mode'].present? && field['mode'] == "REQUIRED" ? false : true
|
412
|
+
#column expects (name, default, sql_type = nil, null = true)
|
413
|
+
BigqueryColumn.new(field['name'], nil, field['type'], mode )
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
# Returns an array of indexes for the given table.
|
418
|
+
def indexes(table_name, name = nil) #:nodoc:
|
419
|
+
[]
|
420
|
+
end
|
421
|
+
|
422
|
+
def primary_key(table_name) #:nodoc:
|
423
|
+
"id"
|
424
|
+
end
|
425
|
+
|
426
|
+
def remove_index!(table_name, index_name) #:nodoc:
|
427
|
+
#exec_query "DROP INDEX #{quote_column_name(index_name)}"
|
428
|
+
end
|
429
|
+
|
430
|
+
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
431
|
+
if supports_add_column? && valid_alter_table_options( type, options )
|
432
|
+
super(table_name, column_name, type, options)
|
433
|
+
else
|
434
|
+
alter_table(table_name) do |definition|
|
435
|
+
definition.column(column_name, type, options)
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
# See also TableDefinition#column for details on how to create columns.
|
441
|
+
def create_table(table_name, options = {})
|
442
|
+
td = create_table_definition table_name, options[:temporary], options[:options]
|
443
|
+
|
444
|
+
unless options[:id] == false
|
445
|
+
pk = options.fetch(:primary_key) {
|
446
|
+
Base.get_primary_key table_name.to_s.singularize
|
447
|
+
}
|
448
|
+
|
449
|
+
td.primary_key pk, options.fetch(:id, :primary_key), options
|
450
|
+
end
|
451
|
+
|
452
|
+
yield td if block_given?
|
453
|
+
|
454
|
+
if options[:force] && table_exists?(table_name)
|
455
|
+
drop_table(table_name, options)
|
456
|
+
end
|
457
|
+
|
458
|
+
hsh = td.columns.map { |c| {"name"=> c[:name], "type"=> type_to_sql(c[:type]) } }
|
459
|
+
|
460
|
+
@table_body = { "tableReference"=> {
|
461
|
+
"projectId"=> @config[:project],
|
462
|
+
"datasetId"=> @config[:database],
|
463
|
+
"tableId"=> td.name},
|
464
|
+
"schema"=> [fields: hsh]
|
465
|
+
}
|
466
|
+
|
467
|
+
res = BigBroda::Table.create(@config[:project], @config[:database], @table_body )
|
468
|
+
|
469
|
+
raise res["error"]["errors"].map{|o| "[#{o['domain']}]: #{o['reason']} #{o['message']}" }.join(", ") if res["error"].present?
|
470
|
+
end
|
471
|
+
|
472
|
+
# See also Table for details on all of the various column transformation.
|
473
|
+
def change_table(table_name, options = {})
|
474
|
+
if supports_bulk_alter? && options[:bulk]
|
475
|
+
recorder = ActiveRecord::Migration::CommandRecorder.new(self)
|
476
|
+
yield update_table_definition(table_name, recorder)
|
477
|
+
bulk_change_table(table_name, recorder.commands)
|
478
|
+
else
|
479
|
+
yield update_table_definition(table_name, self)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
# Renames a table.
|
483
|
+
#
|
484
|
+
# Example:
|
485
|
+
# rename_table('octopuses', 'octopi')
|
486
|
+
def rename_table(table_name, new_name)
|
487
|
+
raise Error::PendingFeature
|
488
|
+
end
|
489
|
+
|
490
|
+
# See: http://www.sqlite.org/lang_altertable.html
|
491
|
+
# SQLite has an additional restriction on the ALTER TABLE statement
|
492
|
+
def valid_alter_table_options( type, options)
|
493
|
+
type.to_sym != :primary_key
|
494
|
+
end
|
495
|
+
|
496
|
+
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
497
|
+
|
498
|
+
if supports_add_column? && valid_alter_table_options( type, options )
|
499
|
+
|
500
|
+
hsh = table_name.classify.constantize.columns.map { |c| {"name"=> c.name, "type"=> c.type } }
|
501
|
+
hsh << {"name"=> column_name, :type=> type}
|
502
|
+
fields = [ fields: hsh ]
|
503
|
+
|
504
|
+
res = BigBroda::Table.patch(@config[:project], @config[:database], table_name,
|
505
|
+
{"tableReference"=> {
|
506
|
+
"projectId" => @config[:project],
|
507
|
+
"datasetId" =>@config[:database],
|
508
|
+
"tableId" => table_name },
|
509
|
+
"schema" => fields,
|
510
|
+
"description"=> "added from migration"} )
|
511
|
+
|
512
|
+
else
|
513
|
+
bypass_feature
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def bypass_feature
|
518
|
+
begin
|
519
|
+
raise Error::NotImplementedColumnOperation
|
520
|
+
rescue => e
|
521
|
+
puts e.message
|
522
|
+
logger.warn(e.message)
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
|
527
|
+
bypass_feature
|
528
|
+
end
|
529
|
+
|
530
|
+
def change_column_default(table_name, column_name, default) #:nodoc:
|
531
|
+
bypass_feature
|
532
|
+
end
|
533
|
+
|
534
|
+
def change_column_null(table_name, column_name, null, default = nil)
|
535
|
+
bypass_feature
|
536
|
+
end
|
537
|
+
|
538
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
539
|
+
bypass_feature
|
540
|
+
end
|
541
|
+
|
542
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
543
|
+
bypass_feature
|
544
|
+
end
|
545
|
+
|
546
|
+
def add_reference(table_name, ref_name, options = {})
|
547
|
+
polymorphic = options.delete(:polymorphic)
|
548
|
+
index_options = options.delete(:index)
|
549
|
+
add_column(table_name, "#{ref_name}_id", :string, options)
|
550
|
+
add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
551
|
+
add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options
|
552
|
+
end
|
553
|
+
|
554
|
+
def drop_table(table_name)
|
555
|
+
BigBroda::Table.delete(@config[:project], @config[:database], table_name )
|
556
|
+
end
|
557
|
+
|
558
|
+
def dump_schema_information #:nodoc:
|
559
|
+
bypass_feature
|
560
|
+
end
|
561
|
+
|
562
|
+
def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths)
|
563
|
+
bypass_feature
|
564
|
+
end
|
565
|
+
|
566
|
+
|
567
|
+
protected
|
568
|
+
def select(sql, name = nil, binds = []) #:nodoc:
|
569
|
+
exec_query(sql, name, binds)
|
570
|
+
end
|
571
|
+
|
572
|
+
def table_structure(table_name)
|
573
|
+
structure = BigBroda::Table.get(@config[:project], @config[:database], table_name)["schema"]["fields"]
|
574
|
+
raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
|
575
|
+
structure
|
576
|
+
end
|
577
|
+
|
578
|
+
def alter_table(table_name, options = {}) #:nodoc:
|
579
|
+
|
580
|
+
end
|
581
|
+
|
582
|
+
def move_table(from, to, options = {}, &block) #:nodoc:
|
583
|
+
copy_table(from, to, options, &block)
|
584
|
+
drop_table(from)
|
585
|
+
end
|
586
|
+
|
587
|
+
def copy_table(from, to, options = {}) #:nodoc:
|
588
|
+
|
589
|
+
end
|
590
|
+
|
591
|
+
def copy_table_indexes(from, to, rename = {}) #:nodoc:
|
592
|
+
|
593
|
+
end
|
594
|
+
|
595
|
+
def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
|
596
|
+
|
597
|
+
end
|
598
|
+
|
599
|
+
def create_table_definition(name, temporary, options)
|
600
|
+
TableDefinition.new native_database_types, name, temporary, options
|
601
|
+
end
|
602
|
+
|
603
|
+
end
|
604
|
+
|
605
|
+
end
|
606
|
+
|
607
|
+
end
|