kudu_adapter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rubocop.yml +8 -0
  4. data/Gemfile +9 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +178 -0
  7. data/kudu_adapter.gemspec +33 -0
  8. data/lib/active_record/connection_adapters/kudu/column.rb +17 -0
  9. data/lib/active_record/connection_adapters/kudu/database_statements.rb +41 -0
  10. data/lib/active_record/connection_adapters/kudu/quoting.rb +51 -0
  11. data/lib/active_record/connection_adapters/kudu/schema_creation.rb +89 -0
  12. data/lib/active_record/connection_adapters/kudu/schema_statements.rb +507 -0
  13. data/lib/active_record/connection_adapters/kudu/sql_type_metadata.rb +16 -0
  14. data/lib/active_record/connection_adapters/kudu/table_definition.rb +32 -0
  15. data/lib/active_record/connection_adapters/kudu/type/big_int.rb +22 -0
  16. data/lib/active_record/connection_adapters/kudu/type/boolean.rb +23 -0
  17. data/lib/active_record/connection_adapters/kudu/type/char.rb +17 -0
  18. data/lib/active_record/connection_adapters/kudu/type/date_time.rb +21 -0
  19. data/lib/active_record/connection_adapters/kudu/type/double.rb +17 -0
  20. data/lib/active_record/connection_adapters/kudu/type/float.rb +18 -0
  21. data/lib/active_record/connection_adapters/kudu/type/integer.rb +22 -0
  22. data/lib/active_record/connection_adapters/kudu/type/small_int.rb +22 -0
  23. data/lib/active_record/connection_adapters/kudu/type/string.rb +17 -0
  24. data/lib/active_record/connection_adapters/kudu/type/time.rb +30 -0
  25. data/lib/active_record/connection_adapters/kudu/type/tiny_int.rb +22 -0
  26. data/lib/active_record/connection_adapters/kudu_adapter.rb +173 -0
  27. data/lib/active_record/tasks/kudu_database_tasks.rb +29 -0
  28. data/lib/arel/visitors/kudu.rb +7 -0
  29. data/lib/kudu_adapter/bind_substitution.rb +15 -0
  30. data/lib/kudu_adapter/table_definition_extensions.rb +28 -0
  31. data/lib/kudu_adapter/version.rb +5 -0
  32. data/lib/kudu_adapter.rb +5 -0
  33. data/spec/spec_config.yaml.template +8 -0
  34. data/spec/spec_helper.rb +124 -0
  35. metadata +205 -0
@@ -0,0 +1,507 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/kudu/column'
4
+ require 'active_record/connection_adapters/kudu/schema_creation'
5
+ require 'active_record/connection_adapters/kudu/sql_type_metadata'
6
+ require 'active_record/connection_adapters/kudu/table_definition'
7
+ require 'active_record/migration/join_table'
8
+
9
+ # :nodoc:
10
+ module ActiveRecord
11
+ module ConnectionAdapters
12
+ module Kudu
13
+ include ::ActiveRecord::Migration::JoinTable
14
+
15
+ # TODO methods delegate :quote_column_name, :quote_default_expression, :type_to_sql,
16
+ # :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?,
17
+ # :foreign_key_options, to: :@conn
18
+ # ^^^ THOSE ARE FROM SCHEMACREATION ^^^
19
+
20
+ # :nodoc:
21
+ module SchemaStatements
22
+
23
+ def table_options(table_name)
24
+ nil
25
+ end
26
+
27
+ def table_comment(table_name)
28
+ raise NotImplementedError, '#table_comment Comments not implemented'
29
+ end
30
+
31
+ def table_alias_for(table_name)
32
+ table_name.tr('.', '_')
33
+ end
34
+
35
+ def data_sources
36
+ tables | views
37
+ end
38
+
39
+ def data_source_exists?(name)
40
+ data_sources.include? name.to_s
41
+ end
42
+
43
+ def tables
44
+ connection.query('SHOW TABLES').map { |table| table[:name] }
45
+ end
46
+
47
+ def table_exists?(table_name)
48
+ tables.include? table_name.to_s
49
+ end
50
+
51
+ # Return list of existing views. As we are not supporting them,
52
+ # this list will be always empty
53
+ def views
54
+ []
55
+ end
56
+
57
+ # Check if given view exists. As we are not supporting views,
58
+ # it'll be always false
59
+ def view_exists?(_)
60
+ false
61
+ end
62
+
63
+ def indexes(table_name, name = nil)
64
+ []
65
+ end
66
+
67
+ def index_exists?(table_name, column_name, options = {})
68
+ raise NotImplementedError, '#index_exists? Indexing not implemented'
69
+ end
70
+
71
+ def columns(table_name)
72
+ table_structure(table_name).map do |col_def|
73
+ type = if col_def[:type] == 'int'
74
+ :integer
75
+ elsif col_def[:type] == 'bigint' && /_at$/ =~ col_def[:name]
76
+ :datetime
77
+ else
78
+ col_def[:type].to_sym
79
+ end
80
+ stm = ::ActiveRecord::ConnectionAdapters::Kudu::SqlTypeMetadata.new(sql_type: col_def[:type], type: type)
81
+ ::ActiveRecord::ConnectionAdapters::Kudu::Column.new(
82
+ col_def[:name],
83
+ col_def[:default_value]&.empty? ? nil : col_def[:default_value],
84
+ stm,
85
+ col_def[:null] == 'true',
86
+ table_name,
87
+ col_def[:comment]
88
+ )
89
+ end
90
+ end
91
+
92
+ def column_exists?(table_name, column_name, type = nil, options = {})
93
+ column_name = column_name.to_s
94
+ checks = []
95
+ checks << lambda { |c| c.name == column_name }
96
+ checks << lambda { |c| c.type == type } if type
97
+ column_options_keys.each do |attr|
98
+ checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
99
+ end
100
+ columns(table_name).any? { |c| checks.all? { |check| check[c] } }
101
+ end
102
+
103
+ def primary_key(table_name)
104
+ pks = table_structure(table_name).select { |col| col[:primary_key] == 'true' }
105
+ pks.map! { |pk| pk[:name] }
106
+ pks.size == 1 ? pks.first : pks
107
+ end
108
+
109
+ def create_table(table_name, comment: nil, **options)
110
+ td = create_table_definition table_name, options[:temporary], options[:options], options[:as], comment: comment
111
+ if options[:id] != false && !options[:as]
112
+ pk = options.fetch(:primary_key) do
113
+ Base.get_primary_key table_name.to_s.singularize
114
+ end
115
+
116
+ if pk.is_a?(Array)
117
+ td.primary_keys pk
118
+ else
119
+ td.primary_key pk, options.fetch(:id, :primary_key), options
120
+ end
121
+ end
122
+
123
+ yield td if block_given?
124
+
125
+ options[:force] && drop_table(table_name, **options, if_exists: true)
126
+
127
+ result = execute schema_creation.accept td
128
+
129
+ unless supports_indexes_in_create?
130
+ td.indexes.each do |column_name, index_options|
131
+ add_index(table_name, column_name, index_options)
132
+ end
133
+ end
134
+
135
+ if supports_comments? && !supports_comments_in_create?
136
+ change_table_comment(table_name, comment) if comment.present?
137
+ td.columns.each do |column|
138
+ change_column_comment(table_name, column.name, column.comment) if column.comment.present?
139
+ end
140
+ end
141
+
142
+ result
143
+ end
144
+
145
+ def drop_table(table_name, **options)
146
+ execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
147
+ end
148
+
149
+ def drop_temp_tables
150
+ tbl = tables
151
+ to_delete = tbl.select {|tbl| tbl.include? '_temp' }
152
+ to_delete.each do |dt|
153
+ drop_table(dt)
154
+ end
155
+ end
156
+
157
+ def create_join_table(table_1, table_2, colum_options: {}, **options)
158
+ join_table_name = find_join_table_name(table_1, table_2, options)
159
+
160
+ column_options = options.delete(:column_options) || {}
161
+ column_options.reverse_merge!(null: false)
162
+ column_options.merge!(primary_key: true)
163
+
164
+ t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }
165
+
166
+ create_table(join_table_name, options.merge!(id: false)) do |td|
167
+ td.string t1_column, column_options
168
+ td.string t2_column, column_options
169
+ yield td if block_given?
170
+ end
171
+ end
172
+
173
+ def drop_join_table(table_1, table_2, options = {})
174
+ join_table_name = find_join_table_name(table_1, table_2, options)
175
+ drop_table join_table_name
176
+ end
177
+
178
+ def change_table(table_name, options = {})
179
+ if supports_bulk_alter? && options[:bulk]
180
+ recorder = ActiveRecord::Migration::CommandRecorder.new(self)
181
+ yield update_table_definition(table_name, recorder)
182
+ bulk_change_table(table_name, recorder.commands)
183
+ else
184
+ yield update_table_definition(table_name, self)
185
+ end
186
+ end
187
+
188
+ def rename_table(table_name, new_name)
189
+ db_name = Rails.configuration.database_configuration[Rails.env]['database']
190
+ execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
191
+ execute "ALTER TABLE #{quote_table_name(new_name)} SET TblProperties('kudu.table_name' = 'impala::#{db_name}.#{new_name}')"
192
+ end
193
+
194
+ def add_column(table_name, column_name, type, options = {})
195
+ if options_has_primary_key(options)
196
+ # be aware of primary key columns
197
+ redefine_table_add_primary_key(table_name, column_name, type, options)
198
+ else
199
+ at = create_alter_table table_name
200
+ at.add_column(column_name, type, options)
201
+ execute schema_creation.accept at
202
+ end
203
+ end
204
+
205
+ def remove_columns(table_name, column_names)
206
+ raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.empty?
207
+ column_names.each do |column_name|
208
+ remove_column(table_name, column_name)
209
+ end
210
+ end
211
+
212
+ def remove_column(table_name, column_name, type = nil, options = {})
213
+ if primary_keys_contain_column_name(table_name, column_name)
214
+ # be aware of primary key columns
215
+ #raise ArgumentError.new("You cannot drop primary key fields")
216
+ redefine_table_drop_primary_key(table_name, column_name, type, options)
217
+ else
218
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
219
+ end
220
+ end
221
+
222
+ def change_column(table_name, column_name, type, options)
223
+ raise NotImplementedError, '#change_column Altering columns not implemented'
224
+ end
225
+
226
+ def change_column_default(table_name, column_name, default_or_changes)
227
+ raise NotImplementedError, '#change_column_default Altering column defaults not implemented'
228
+ end
229
+
230
+ def change_column_null(table_name, column_name, null, default = nil)
231
+ raise NotImplementedError, '#change_column_null Altering column null not implemented'
232
+ end
233
+
234
+ def rename_column(table_name, column_name, new_column_name)
235
+ raise ArgumentError.new('You cannot rename primary key fields') if primary_keys_contain_column_name(table_name, column_name)
236
+ column = columns(table_name).find { |c| c.name.to_s == column_name.to_s }
237
+ execute "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{column.sql_type}"
238
+ end
239
+
240
+ # It will reload all data from temp table name into new one.
241
+ # We're seeking for table_name_temp while we inserting data with additional new column and it's value.
242
+ # At the end table_name_temp is dropped indeed.
243
+ def reload_table_data(table_name, column_name, options = {})
244
+ temp_table_name = table_name + '_temp'
245
+
246
+ # get table structure and remove our column name
247
+ columns = table_structure table_name
248
+ columns.reject! { |c| c[:name] == column_name.to_s }
249
+
250
+ select_qry = columns.map {|col| col[:name].to_s }.join(',')
251
+
252
+ # values with additional column name
253
+ values = select_qry + ',' + column_name.to_s
254
+ # fetch values with our column name and value to insert
255
+ fetch_values = select_qry + ',' + quote(options[:default]) + ' AS ' + column_name.to_s
256
+
257
+ insert_qry = "INSERT INTO #{quote_table_name(table_name)} (#{values}) SELECT #{fetch_values} FROM #{quote_table_name(temp_table_name)}"
258
+ execute insert_qry
259
+
260
+ drop_table(temp_table_name)
261
+ end
262
+
263
+ def add_index(table_name, column_name, options = {})
264
+ p '(add_index) Indexing not supported by Apache KUDU'
265
+ end
266
+
267
+ def remove_index(table_name, options = {})
268
+ p '(remove_index) Indexing not supported by Apache KUDU'
269
+ end
270
+
271
+ def rename_index(table_name, old_name, new_name)
272
+ p '(rename_index) Indexing not supported by Apache KUDU'
273
+ end
274
+
275
+ def index_name(table_name, options)
276
+ p '(index_name) Indexing not supported by Apache KUDU'
277
+ end
278
+
279
+ def index_name_exists?(table_name, index_name, default = nil)
280
+ p '(index_name_exists?) Indexing not supported by Apache KUDU'
281
+ end
282
+
283
+ def add_reference(table_name, ref_name, **options)
284
+ p '(add_reference) Traditional referencing not supported by Apache KUDU'
285
+ end
286
+ alias add_belongs_to add_reference
287
+
288
+ def remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
289
+ p '(remove_reference) Traditional referencing not supported by Apache KUDU'
290
+ end
291
+
292
+ def foreign_keys(table_name)
293
+ p '(foreign_keys) Foreign keys not supported by Apache KUDU'
294
+ end
295
+
296
+ def add_foreign_key(from_table, to_table, options = {})
297
+ p '(add_foreign_key) Foreign keys not supported by Apache KUDU'
298
+ end
299
+
300
+ def remove_foreign_key(from_table, options_or_to_table = {})
301
+ p '(remove_foreign_key) Foreign keys not supported by Apache KUDU'
302
+ end
303
+
304
+ def foreign_key_exists?(from_table, options_or_to_table = {})
305
+ p '(foreign_key_exists?) Foreign keys not supported by Apache KUDU'
306
+ end
307
+
308
+ def foreign_key_for(from_table, options_or_to_table = {})
309
+ p '(foreign_key_for?) Foreign keys not supported by Apache KUDU'
310
+ end
311
+
312
+ def foreign_key_for!(from_table, options_or_to_table = {})
313
+ p '(foreign_key_for!) Foreign keys not supported by Apache KUDU'
314
+ end
315
+
316
+ def foreign_key_for_column_for(table_name)
317
+ p '(foreign_key_for_column_for) Foreign keys not supported by Apache KUDU'
318
+ end
319
+
320
+ def foreign_key_options(from_table, to_table, options)
321
+ p '(foreign_key_options) Foreign keys not supported by Apache KUDU'
322
+ end
323
+
324
+ def assume_migrated_upto_version(version, migrations_paths)
325
+ migrations_paths = Array(migrations_paths)
326
+ version = version.to_i
327
+ sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
328
+
329
+ migrated = ActiveRecord::SchemaMigration.all_versions.map(&:to_i)
330
+ versions = ActiveRecord::Migrator.migration_files(migrations_paths).map do |file|
331
+ ActiveRecord::Migrator.parse_migration_filename(file).first.to_i
332
+ end
333
+
334
+ unless migrated.include?(version)
335
+ execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version.to_s)})"
336
+ end
337
+
338
+ inserting = (versions - migrated).select { |v| v < version }
339
+ if inserting.any?
340
+ if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
341
+ raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
342
+ end
343
+ if supports_multi_insert?
344
+ execute insert_versions_sql(inserting)
345
+ else
346
+ inserting.each do |v|
347
+ execute insert_versions_sql(v.to_s)
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
354
+ case type
355
+ when 'integer'
356
+ case limit
357
+ when 1 then 'TINYINT'
358
+ when 2 then 'SMALLINT'
359
+ when 3..4, nil then 'INT'
360
+ when 5..8 then 'BIGINT'
361
+ else
362
+ raise(ActiveRecordError, 'Invalid integer precision')
363
+ end
364
+ else
365
+ super
366
+ end
367
+ end
368
+
369
+ def columns_for_distinct(columns, orders)
370
+ columns
371
+ end
372
+
373
+ def add_timestamps(table_name, options = {})
374
+ options[:null] = false if options[:null].nil?
375
+ add_column table_name, :created_at, :bigint, options
376
+ add_column table_name, :updated_at, :bigint, options
377
+ end
378
+
379
+ def remove_timestamps(table_name, options = {})
380
+ remove_column table_name, :updated_at
381
+ remove_column table_name, :created_at
382
+ end
383
+
384
+ def update_table_definition(table_name, base)
385
+ Table.new(table_name, base)
386
+ end
387
+
388
+ def add_index_options(table_name, column_name, comment: nil, **options)
389
+ p '(add_index_options) Indexing not supported by Apache KUDU'
390
+ end
391
+
392
+ def options_include_default?(options)
393
+ options.include?(:default) && !(options[:null] == false && options[:default].nil?)
394
+ end
395
+
396
+ def change_table_comment(table_name, comment)
397
+ p '(change_table_comment) Altering table comments not supported by Apache KUDU'
398
+ end
399
+
400
+ def change_column_comment(table_name, column_name, comment)
401
+ p '(change_column_comment) Altering column comments not supported by Apache KUDU'
402
+ end
403
+
404
+ private
405
+
406
+ def schema_creation
407
+ ::ActiveRecord::ConnectionAdapters::Kudu::SchemaCreation.new(self)
408
+ end
409
+
410
+ def create_table_definition(*args)
411
+ ::ActiveRecord::ConnectionAdapters::Kudu::TableDefinition.new(*args)
412
+ end
413
+
414
+ def table_structure(table_name)
415
+ quoted = quote_table_name table_name
416
+ connection.query('DESCRIBE ' + quoted)
417
+ end
418
+
419
+ # check if options contains primary_key
420
+ def options_has_primary_key(options)
421
+ options[:primary_key] = false if options[:primary_key].nil?
422
+ options[:primary_key]
423
+ end
424
+
425
+ def primary_keys_contain_column_name(table_name, column_name)
426
+ pks = primary_key(table_name)
427
+ pks.include? column_name.to_s
428
+ end
429
+
430
+ def set_options_from_column_definition(column)
431
+ opt = {}
432
+ opt[:primary_key] = ActiveModel::Type::Boolean.new.cast(column[:primary_key]) if column[:primary_key].present?
433
+ opt[:null] = ActiveModel::Type::Boolean.new.cast(column[:nullable]) if column[:nullable].present?
434
+ opt[:default] = lookup_cast_type(column[:type]).serialize(column[:default_value]) if column[:default_value].present?
435
+ # TODO: Do we have more options ?
436
+ opt
437
+ end
438
+
439
+ # This method will copy existing structure of table with added new field.
440
+ # It works only if we're adding new primary key on existing table.
441
+ def redefine_table_add_primary_key(table_name, column_name, type, options = {})
442
+
443
+ redefined_table_name = table_name + '_redefined'
444
+ temp_table_name = table_name + '_temp'
445
+
446
+ columns = table_structure table_name
447
+ pk_columns = columns.select {|c| c[:primary_key] == 'true'}
448
+ non_pk_columns = columns.select {|c| c[:primary_key] == 'false'}
449
+
450
+ create_table(redefined_table_name, { id: false }) do |td|
451
+
452
+ # existing pk columns
453
+ pk_columns.each do |col|
454
+ td.send col[:type].to_sym, col[:name], set_options_from_column_definition(col)
455
+ end
456
+
457
+ # add new column
458
+ td.send type, column_name, options
459
+
460
+ non_pk_columns.each do |col|
461
+ td.send col[:type].to_sym, col[:name], set_options_from_column_definition(col)
462
+ end
463
+
464
+ end
465
+
466
+ # rename existing table to temp
467
+ rename_table(table_name, temp_table_name)
468
+ # rename newly created to active one
469
+ rename_table(redefined_table_name, table_name)
470
+
471
+ end
472
+
473
+ # This method will copy existing structure of table with primary key field removed.
474
+ # It works only if we're removing primary key on existing table.
475
+ def redefine_table_drop_primary_key(table_name, column_name, type, options = {})
476
+
477
+ redefined_table_name = table_name + '_redefined'
478
+ temp_table_name = table_name + '_temp'
479
+
480
+ columns = table_structure table_name
481
+ columns.reject! { |c| c[:name] == column_name.to_s }
482
+
483
+ create_table(redefined_table_name, { id: false }) do |td|
484
+ columns.each do |col|
485
+ td.send col[:type].to_sym, col[:name], set_options_from_column_definition(col)
486
+ end
487
+ end
488
+
489
+ # rename existing table to temp
490
+ rename_table(table_name, temp_table_name)
491
+ # rename newly created to active one
492
+ rename_table(redefined_table_name, table_name)
493
+
494
+ # copy reduced existing data into new table
495
+ select_qry = columns.map {|col| col[:name].to_s }.join(',')
496
+ copy_qry = "INSERT INTO #{quote_table_name(table_name)} (#{select_qry}) SELECT #{select_qry} FROM #{quote_table_name(temp_table_name)}"
497
+ execute copy_qry
498
+
499
+ # finally, drop temp table
500
+ drop_table(temp_table_name)
501
+
502
+ end
503
+
504
+ end
505
+ end
506
+ end
507
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/sql_type_metadata'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ # :nodoc:
9
+ class SqlTypeMetadata < ::ActiveRecord::ConnectionAdapters::SqlTypeMetadata
10
+ def initialize(sql_type: nil, type: nil)
11
+ super(sql_type: sql_type, type: type, limit: nil, precision: nil, scale: nil)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/abstract/schema_definitions'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ # :nodoc:
9
+ class TableDefinition < ::ActiveRecord::ConnectionAdapters::TableDefinition
10
+ attr_reader :external
11
+ attr_reader :partitions_count
12
+ attr_reader :partition_columns
13
+
14
+ def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
15
+ super
16
+ @external = options&.[](:external)
17
+ @partitions_count = options&.[](:partitions_count)
18
+ @partition_columns = options&.[](:partition_columns)
19
+ end
20
+
21
+ def double(*args, **options)
22
+ args.each { |name| column(name, :double, options) }
23
+ end
24
+
25
+ def float(*args, **options)
26
+ args.each { |name| column(name, :float, options) }
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/integer'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ module Type
9
+ # :nodoc:
10
+ class BigInt < ::ActiveModel::Type::Integer
11
+ def type
12
+ :bigint
13
+ end
14
+
15
+ def limit
16
+ 8
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/boolean'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ module Type
9
+ class Boolean < ::ActiveModel::Type::Boolean
10
+
11
+ def type
12
+ :boolean
13
+ end
14
+
15
+ def serialize(value)
16
+ ActiveModel::Type::Boolean.new.cast(value)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/string'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ module Type
9
+ class Char < ::ActiveModel::Type::String
10
+ def type
11
+ :char
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/helpers/time_value'
4
+ require 'active_record/connection_adapters/kudu/type/time'
5
+
6
+ module ActiveRecord
7
+ module ConnectionAdapters
8
+ module Kudu
9
+ module Type
10
+ include ::ActiveModel::Type::Helpers::TimeValue
11
+
12
+ # :nodoc:
13
+ class DateTime < ::ActiveRecord::ConnectionAdapters::Kudu::Type::Time
14
+ def type
15
+ :datetime
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/float'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ module Type
9
+ class Double < ::ActiveModel::Type::Float
10
+ def type
11
+ :double
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model/type/float'
4
+
5
+ module ActiveRecord
6
+ module ConnectionAdapters
7
+ module Kudu
8
+ module Type
9
+ # :nodoc:
10
+ class Float < ::ActiveModel::Type::Float
11
+ def type
12
+ :float
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end