mimi-db 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67ce0ef4ee1bf56935424d8d4ea78fb43a1b502b
4
- data.tar.gz: bfca6acb463411916d0199a8c7cae5b657b792db
3
+ metadata.gz: eec89d0a86280f91bedbfb6593261807397f6ac1
4
+ data.tar.gz: e769745b46e668134cace4e827bd434a4cae4287
5
5
  SHA512:
6
- metadata.gz: 7eb1380db55e093e71b5a394bebb9667c6e1e028805a9543fdc0c3a187309e8dfb51750c196a2fb7611352449e034753d93e2933db17356262a84017a3f11498
7
- data.tar.gz: 0b1902f9fb5b5456cef3028175ac35e7c964f44cf3ea180a652592070bbda7db1d0cc89414c59467f577335542f603ad217fd5537005efff1d3308320eb1b478
6
+ metadata.gz: 0e330af2c6335bbab54cf6f8eb91416590adfa55dfbc5d3c2dc879b062e66cd67bd90e99b2d8b707c8f41724f12e0f4a182169572e49a94633d1ae168b012e56
7
+ data.tar.gz: aecc5b570e761ab14b13de6c19b50f65297ca46ac0d2be23404233f6b705add4c6ddaacfa4e95f97618d380c8b328c25bf2940c7c06015ecf70bf0cc2c97a518
data/examples/my_app.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ puts "Requiring mimi/db, mimi/logger"
3
4
  require 'mimi/db'
4
5
  require 'mimi/logger'
6
+ puts "DONE"
5
7
 
6
8
  CONFIG = {
7
9
  db_adapter: 'sqlite3',
@@ -12,18 +14,7 @@ CONFIG = {
12
14
  Mimi::DB.configure(CONFIG)
13
15
  Mimi::DB.start
14
16
 
15
- class MyModel < ActiveRecord::Base
16
- field :id, as: :integer, primary_key: true, not_null: true, autoincrement: true
17
- field :name, as: :string, limit: 64
18
- field :code, as: :string, default: -> { random_code }
19
- field :value, as: :decimal, precision: 10, scale: 3
20
-
21
- index :name
22
-
23
- def self.random_code
24
- SecureRandom.hex(16)
25
- end
26
- end # class MyModel
17
+ require_relative 'my_model'
27
18
 
28
19
  Mimi::DB.create_if_not_exist! # creates configured database
29
20
  Mimi::DB.update_schema!
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ puts "Requiring mimi/db, mimi/logger"
4
+ require 'mimi/db'
5
+ require 'mimi/logger'
6
+ puts "DONE"
7
+
8
+ CONFIG = {
9
+ db_adapter: 'sqlite3',
10
+ db_database: '../tmp/my_app_db',
11
+ db_log_level: :debug
12
+ }.freeze
13
+
14
+ Mimi::DB.configure(CONFIG)
15
+ Mimi::DB.start
16
+
17
+ require_relative 'my_model'
18
+
19
+ require 'pp'
20
+ pp Mimi::DB.diff_schema
@@ -0,0 +1,13 @@
1
+ class MyModel < Mimi::DB::Model
2
+ field :id, as: :integer, primary_key: true, not_null: true, auto_increment: true
3
+
4
+ field :name, as: :string, limit: 64
5
+ field :code, as: :blob, default: -> { random_code }
6
+ field :value, as: :decimal, precision: 10, scale: 3
7
+
8
+ index :name
9
+
10
+ def self.random_code
11
+ SecureRandom.hex(16)
12
+ end
13
+ end # class MyModel
@@ -52,8 +52,8 @@ module Mimi
52
52
  # Sets up a default as a block/Proc
53
53
  #
54
54
  def field_setup_default(name, block)
55
- before_validation on: :create do
56
- self.send :"#{name}=", block.call
55
+ self.before_validation do
56
+ send :"#{name}=", instance_exec(&block) unless send(name.to_sym)
57
57
  end
58
58
  end
59
59
  end # module DSL
@@ -9,10 +9,11 @@ module Mimi
9
9
  #
10
10
  # Returns nil if the DB table does not exist.
11
11
  #
12
- # @param table_name [String]
12
+ # @param table_name [String,Symbol]
13
13
  # @return [Mimi::DB::Dictate::SchemaDefinition,nil]
14
14
  #
15
15
  def self.discover_schema(table_name)
16
+ table_name = table_name.to_sym
16
17
  return nil unless connection.tables.include?(table_name)
17
18
  sd = Mimi::DB::Dictate::SchemaDefinition.new(table_name)
18
19
  discover_schema_columns(sd)
@@ -26,19 +27,20 @@ module Mimi
26
27
  # @param schema_definition [Mimi::DB::Dictate::SchemaDefinition]
27
28
  #
28
29
  def self.discover_schema_columns(schema_definition)
29
- columns = connection.columns(schema_definition.table_name)
30
- pk = connection.primary_key(schema_definition.table_name)
31
- columns.each do |c|
30
+ columns = connection.schema(schema_definition.table_name).to_h
31
+ columns.each do |name, c|
32
32
  params = {
33
- as: c.type,
34
- limit: c.limit,
35
- primary_key: (pk == c.name),
36
- auto_increment: false, # FIXME: SQLite does not report autoincremented fields
37
- not_null: !c.null,
38
- default: c.default,
39
- sql_type: c.sql_type
33
+ as: c[:type],
34
+ type: c[:type],
35
+ size: c[:max_length],
36
+ primary_key: c[:primary_key],
37
+ auto_increment: c[:auto_increment], # FIXME: SQLite does not report autoincremented fields
38
+ null: c[:allow_null],
39
+ db_default: c[:default],
40
+ default: c[:default],
41
+ db_type: c[:db_type]
40
42
  }
41
- schema_definition.field(c.name, params)
43
+ schema_definition.field(name, params)
42
44
  end
43
45
  end
44
46
  private_class_method :discover_schema_columns
@@ -49,23 +51,35 @@ module Mimi
49
51
  # @param schema_definition [Mimi::DB::Dictate::SchemaDefinition]
50
52
  #
51
53
  def self.discover_schema_indexes(schema_definition)
52
- indexes = connection.indexes(schema_definition.table_name)
53
- pk = connection.primary_key(schema_definition.table_name)
54
- indexes.each do |idx|
54
+ indexes = connection.indexes(schema_definition.table_name).to_h
55
+ pk = discover_primary_key(schema_definition.table_name)
56
+ indexes.each do |idx_name, idx_data|
55
57
  params = {
56
- name: idx.name,
57
- primary_key: idx.columns == [pk],
58
- unique: idx.unique
58
+ name: idx_name,
59
+ primary_key: idx_data[:columns] == pk,
60
+ unique: idx_data[:unique]
59
61
  }
60
- schema_definition.index(idx.columns, params)
62
+ schema_definition.index(idx_data[:columns], params)
61
63
  end
62
64
  end
63
65
  private_class_method :discover_schema_indexes
64
66
 
67
+ # Discovers primary key of an existing DB table
68
+ #
69
+ # @private
70
+ # @param table_name [String,Symbol]
71
+ #
72
+ # @return [Array<Symbol>]
73
+ #
74
+ def self.discover_primary_key(table_name)
75
+ s = connection.schema(table_name).to_h
76
+ s.keys.select { |name| s[name][:primary_key] }
77
+ end
78
+
65
79
  # Returns ActiveRecord DB connection
66
80
  #
67
81
  def self.connection
68
- ActiveRecord::Base.connection
82
+ Mimi::DB.connection
69
83
  end
70
84
  end # module Explorer
71
85
  end # module Dictate
@@ -22,12 +22,12 @@ module Mimi
22
22
  # @param options [Hash]
23
23
  #
24
24
  def initialize(table_name, options)
25
- @table_name = table_name
25
+ @table_name = table_name.to_sym
26
26
  @options = DEFAULTS.merge(options.dup)
27
- @from_schema = self.class.db_schema_definition(table_name.to_s)
28
- @to_schema = Mimi::DB::Dictate.schema_definitions[table_name.to_s]
27
+ @from_schema = self.class.db_schema_definition(@table_name)
28
+ @to_schema = Mimi::DB::Dictate.schema_definitions[@table_name]
29
29
  if from_schema.nil? && to_schema.nil?
30
- raise "Failed to migrate '#{table_name}', no DB or target schema found"
30
+ raise "Failed to migrate '#{@table_name}', no DB or target schema found"
31
31
  end
32
32
  end
33
33
 
@@ -36,7 +36,7 @@ module Mimi
36
36
  end
37
37
 
38
38
  def db_connection
39
- ActiveRecord::Base.connection
39
+ Mimi::DB.connection
40
40
  end
41
41
 
42
42
  # Returns true if the Migrator is configured to do a dry run (no actual changes to DB)
@@ -54,9 +54,11 @@ module Mimi
54
54
  end
55
55
 
56
56
  def run!
57
- run_drop_table! if from_schema && to_schema.nil?
58
- run_change_table! if from_schema && to_schema
59
- run_create_table! if from_schema.nil? && to_schema
57
+ db_ddl_transaction do
58
+ run_drop_table! if from_schema && to_schema.nil?
59
+ run_change_table! if from_schema && to_schema
60
+ run_create_table! if from_schema.nil? && to_schema
61
+ end
60
62
  self.class.reset_db_schema_definition!(table_name)
61
63
  end
62
64
 
@@ -110,15 +112,13 @@ module Mimi
110
112
  def run_create_table!
111
113
  columns = to_schema.columns.values
112
114
  column_pk = to_schema.primary_key
113
- params =
114
- column_pk.params.select { |_, v| v }.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
115
115
 
116
116
  # issue CREATE TABLE with primary key field
117
117
  logger.info "- CREATE TABLE: #{table_name}"
118
- logger.info "-- add column: #{table_name}.#{column_pk.name} (#{params})"
118
+ logger.info "-- add column: #{table_name}.#{column_pk}"
119
119
  unless dry_run?
120
- db_connection.create_table(table_name, id: false) do |t|
121
- t.column column_pk.name, column_pk.type, column_pk.to_ar_params
120
+ db_connection.create_table(table_name) do |_|
121
+ column column_pk.name, column_pk.sequel_type, column_pk.to_sequel_params
122
122
  end
123
123
  end
124
124
 
@@ -130,28 +130,34 @@ module Mimi
130
130
  def drop_column!(table_name, column_name)
131
131
  logger.info "-- drop column: #{table_name}.#{column_name}"
132
132
  return if dry_run? || !destructive?(:columns)
133
- db_connection.remove_column(table_name, column_name)
133
+ db_connection.drop_column(table_name, column_name)
134
134
  end
135
135
 
136
136
  def change_column!(table_name, column)
137
- params = column.params.select { |_, v| v }.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
138
- logger.info "-- change column: #{table_name}.#{column.name} (#{params})"
137
+ logger.info "-- change column: #{table_name}.#{column}"
139
138
  return if dry_run?
140
- db_connection.change_column(table_name, column.name, column.type, column.to_ar_params)
139
+ db_connection.alter_table(table_name) do
140
+ set_column_type column.name, column.sequel_type, column.to_sequel_params.except(:default, :null)
141
+ set_column_default column.name, column.params[:default]
142
+ if column.to_sequel_params[:null]
143
+ set_column_allow_null column.name
144
+ else
145
+ set_column_not_null column.name
146
+ end
147
+ end
141
148
  end
142
149
 
143
150
  def add_column!(table_name, column)
144
- params = column.params.select { |_, v| v }.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
145
- logger.info "-- add column: #{table_name}.#{column.name} (#{params})"
151
+ logger.info "-- add column: #{table_name}.#{column}"
146
152
  return if dry_run?
147
- db_connection.add_column(table_name, column.name, column.type, column.to_ar_params)
153
+ db_connection.add_column(table_name, column.name, column.sequel_type, column.to_sequel_params)
148
154
  end
149
155
 
150
156
  def drop_index!(table_name, idx)
151
157
  idx_column_names = idx.columns.join(', ')
152
158
  logger.info "-- drop index: #{idx.name} on #{table_name}(#{idx_column_names})"
153
159
  return if dry_run?
154
- db_connection.remove_index(table_name, column: idx.columns)
160
+ db_connection.drop_index(table_name, idx.columns)
155
161
  end
156
162
 
157
163
  def add_index!(table_name, idx)
@@ -161,6 +167,14 @@ module Mimi
161
167
  return if dry_run?
162
168
  db_connection.add_index(table_name, idx.columns, idx.params)
163
169
  end
170
+
171
+ def db_ddl_transaction(&_block)
172
+ supports_transactional_ddl =
173
+ db_connection.respond_to?(:supports_transactional_ddl?) &&
174
+ db_connection.supports_transactional_ddl?
175
+ return yield unless supports_transactional_ddl
176
+ db_connection.transaction { yield }
177
+ end
164
178
  end # class Migrator
165
179
  end # module Dictate
166
180
  end # module DB
@@ -12,28 +12,48 @@ module Mimi
12
12
  @indexes = []
13
13
  end
14
14
 
15
+ # Declares a field
16
+ #
17
+ # Example:
18
+ # field :s1, as: :string
19
+ # field :s2, type: :string, size: 64
20
+ # field :v1, as: :decimal, size: 10 # precision: 10
21
+ # field :v2, as: :decimal, size: [10, 3] # precision: 10, scale: 3
22
+ #
23
+ #
15
24
  def field(name, opts)
16
- name = name.to_s
25
+ name = name.to_sym
17
26
  raise "Cannot redefine field :#{name}" if @columns[name]
18
- if primary_key && (opts[:primary_key] || opts[:as] == :primary_key)
27
+ opts_type = opts[:type] || opts[:as]
28
+ if primary_key && (opts[:primary_key] || opts_type == :primary_key)
19
29
  raise "Cannot redefine primary key (:#{primary_key.name}) with :#{name}"
20
30
  end
21
31
  @columns[name] = Column.new(name, opts)
22
32
  end
23
33
 
34
+ # Declares an index
35
+ #
36
+ # Example:
37
+ # index :name
38
+ # index [:first_name, :last_name]
39
+ # index :ref_code, unique: true
40
+ #
41
+ # @param columns [String,Symbol,Array<String,Symbol>] columns to index on
42
+ # @param opts [Hash] index parameters (:unique, :name etc)
43
+ #
24
44
  def index(columns, opts)
25
45
  case columns
26
46
  when String, Symbol
27
- columns = [columns.to_s]
47
+ columns = [columns.to_sym]
28
48
  when Array
29
49
  unless columns.all? { |c| c.is_a?(String) || c.is_a?(Symbol) }
30
50
  raise "Invalid column reference in index definition [#{columns}]"
31
51
  end
32
- columns = columns.map(&:to_s)
52
+ columns = columns.map(&:to_sym)
33
53
  else
34
54
  raise 'Invalid columns argument to .index'
35
55
  end
36
- if columns == [primary_key]
56
+ if columns == [primary_key.name]
37
57
  # TODO: warn the primary key index is ignored
38
58
  end
39
59
  @indexes << Index.new(columns, opts)
@@ -57,24 +77,25 @@ module Mimi
57
77
  }
58
78
  end
59
79
 
80
+ # Represents a column in schema definition
81
+ #
60
82
  class Column
61
- DEFAULTS = {
62
- as: :string,
63
- limit: nil,
64
- primary_key: false,
65
- auto_increment: false,
66
- not_null: false,
67
- default: nil,
68
- sql_type: nil
69
- }.freeze
83
+ DEFAULT_TYPE = :string
70
84
 
71
- attr_reader :name, :type, :params
85
+ attr_reader :name, :type, :sequel_type, :params
72
86
 
87
+ # Creates a Column object
88
+ #
89
+ # @param name [String,Symbol]
90
+ # @param opts [Hash]
91
+ #
73
92
  def initialize(name, opts)
74
- @name = name
75
- @type = opts[:as] || DEFAULTS[:as]
76
- type_defaults = Mimi::DB::Dictate.type_defaults(type)
77
- @params = DEFAULTS.merge(type_defaults).merge(opts)
93
+ @name = name.to_sym
94
+ @params = opts.dup
95
+ @params[:type] ||= @params[:as] || DEFAULT_TYPE
96
+ @params = Mimi::DB::Dictate::TypeDefaults.infer_params(@params)
97
+ @type = @params[:type]
98
+ @sequel_type = @params[:sequel_type]
78
99
  end
79
100
 
80
101
  def to_h
@@ -84,28 +105,35 @@ module Mimi
84
105
  }
85
106
  end
86
107
 
87
- def to_ar_params
88
- p = params.dup
89
- p[:null] = !p[:not_null]
108
+ def to_sequel_params
109
+ p = params.dup.except(:type, :as)
110
+ p[:null] = !p[:not_null] if p.key?(:not_null)
90
111
  p
91
112
  end
92
113
 
114
+ def to_s
115
+ public_params = params.only(
116
+ :type, :primary_key, :auto_increment, :not_null, :default, :size
117
+ ).select { |_, v| v }.to_h
118
+ public_params = public_params.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
119
+ "#{name}(#{public_params})"
120
+ end
121
+
93
122
  def ==(other)
94
123
  unless other.name == name
95
124
  raise ArgumentError, 'Cannot compare columns with different names'
96
125
  end
97
126
  equal = true
98
- equal &&= params[:as] == other.params[:as]
99
- equal &&= params[:limit] == other.params[:limit]
127
+ equal &&= params[:db_type] == other.params[:db_type]
100
128
  equal &&= params[:primary_key] == other.params[:primary_key]
101
- # FIXME: auto_increment ignored
102
129
  equal &&= params[:not_null] == other.params[:not_null]
103
- equal &&= params[:default].to_s == other.params[:default].to_s
104
- # FIXME: sql_type ignored
130
+ equal &&= params[:db_default].to_s == other.params[:db_default].to_s
105
131
  equal
106
132
  end
107
133
  end # class Column
108
134
 
135
+ # Represents an index in schema definition
136
+ #
109
137
  class Index
110
138
  DEFAULTS = {
111
139
  unique: false
@@ -113,9 +141,14 @@ module Mimi
113
141
 
114
142
  attr_reader :name, :columns, :params
115
143
 
144
+ # Creates an Index object
145
+ #
146
+ # @param columns [Array<String,Symbol>]
147
+ # @param params [Hash]
148
+ #
116
149
  def initialize(columns, params)
117
150
  @name = params[:name]
118
- @columns = columns
151
+ @columns = columns.map(&:to_sym)
119
152
  @params = DEFAULTS.merge(params)
120
153
  end
121
154
 
@@ -5,11 +5,6 @@ module Mimi
5
5
  module Dictate
6
6
  module SchemaDiff
7
7
  DEFAULT_OPTIONS = {
8
- # Force updates on fields defined as :primary_key type.
9
- # If disabled, the field definition will only be used in 'CREATE TABLE'.
10
- # (forced updates on :primary_key break on Postgres, at least)
11
- #
12
- force_primary_key: false
13
8
  }.freeze
14
9
 
15
10
  #
@@ -18,7 +13,7 @@ module Mimi
18
13
  # @return [Hash] :columns, :indexes => :from, :to
19
14
  #
20
15
  def self.diff(from, to, opts = {})
21
- options = DEFAULT_OPTIONS.merge(opts)
16
+ _options = DEFAULT_OPTIONS.merge(opts)
22
17
  result = { table_name: from.table_name, columns: {}, indexes: {} }
23
18
  all_column_names = (from.columns.values.map(&:name) + to.columns.values.map(&:name)).uniq
24
19
  all_column_names.each do |c|
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mimi
4
+ module DB
5
+ module Dictate
6
+ module TypeDefaults
7
+
8
+ # Constructs a Proc that returns "<type>" or "<type>(n)" depending on whether the size is provided
9
+ #
10
+ DEF_OPT_SIZE_PROC = lambda do |type, default_size_suffix = ''|
11
+ ->(p) { p[:size] ? { db_type: "#{type}(#{p[:size]})" } : { db_type: type + default_size_suffix } }
12
+ end
13
+
14
+ # Produces a "string" or "string(n)" depending on whether the size is provided
15
+ #
16
+ TYPE_STRING_PROC = DEF_OPT_SIZE_PROC.call('string')
17
+
18
+ # Produces an "integer" or "integer(n)" depending on whether size is provided
19
+ #
20
+ TYPE_INTEGER_PROC = DEF_OPT_SIZE_PROC.call('integer')
21
+
22
+ # Produces a "decimal", "decimal(p)" or "decimal(p,s)" depending on whether size is provided
23
+ #
24
+ TYPE_DECIMAL_PROC = lambda do |p|
25
+ p[:size] ? { db_type: "decimal(#{[*p[:size]].join(',')})" } : { db_type: 'decimal' }
26
+ end
27
+
28
+ # Produces a "decimal", "decimal(p)" or "decimal(p, s)" depending on whether size is provided
29
+ #
30
+ TYPE_SQLITE_DECIMAL_PROC = lambda do |p|
31
+ p[:size] ? { db_type: "decimal(#{[*p[:size]].join(', ')})" } : { db_type: 'decimal' }
32
+ end
33
+
34
+ # Produces a "numeric" or "numeric(p, s)" depending on whether size is provided
35
+ #
36
+ TYPE_POSTGRES_NUMERIC_PROC = lambda do |p|
37
+ if p[:size]
38
+ # p[:size] is either a number (precision) or an array (precision, scale)
39
+ p1, p2 = [*p[:size]]
40
+ { db_type: "numeric(#{p1},#{p2 || 0})" }
41
+ else
42
+ { db_type: 'numeric' }
43
+ end
44
+ end
45
+
46
+ # Produces a "character varying" or "character varying(n)" depending on whether the size is provided
47
+ #
48
+ TYPE_POSTGRES_VARCHAR_PROC = lambda do |p|
49
+ if p[:size]
50
+ { db_type: "character varying(#{p[:size]})", sequel_type: :varchar }
51
+ else
52
+ { db_type: 'character varying(255)', sequel_type: :varchar }
53
+ end
54
+ end
55
+
56
+ # Type converters, accept Sequel type (field as: ...) as a key,
57
+ # return:
58
+ # * a Hash of field params or
59
+ # * a Proc returning a Hash of field params
60
+ #
61
+ TYPE_MAP = {
62
+ default: {
63
+ },
64
+ sqlite: {
65
+ bigint: { db_type: 'bigint' },
66
+ integer: TYPE_INTEGER_PROC,
67
+ int: { db_type: 'integer', sequel_type: :integer },
68
+ smallint: { db_type: 'smallint' },
69
+
70
+ decimal: TYPE_SQLITE_DECIMAL_PROC,
71
+
72
+ string: DEF_OPT_SIZE_PROC.call('string'),
73
+ varchar: DEF_OPT_SIZE_PROC.call('varchar', '(255)'),
74
+ text: { db_type: 'text' },
75
+
76
+ bytes: { db_type: 'bytea', sequel_type: :bytea },
77
+ bytea: { db_type: 'bytea' },
78
+ blob: { db_type: 'blob' },
79
+
80
+ bool: { db_type: 'bool', sequel_type: :bool },
81
+ boolean: { db_type: 'bool', sequel_type: :bool },
82
+
83
+ date: { db_type: 'date' },
84
+ timestamp: { db_type: 'timestamp' },
85
+ datetime: { db_type: 'timestamp', sequel_type: :timestamp },
86
+
87
+ float: { db_type: 'double precision' }
88
+ },
89
+ postgres: {
90
+ bigserial: { db_type: 'bigint', db_default: "nextval('tests_id_seq'::regclass)" },
91
+ bigint: { db_type: 'bigint' },
92
+ integer: { db_type: 'integer', sequel_type: :integer },
93
+ int: { db_type: 'integer', sequel_type: :integer },
94
+ smallint: { db_type: 'smallint' },
95
+
96
+ decimal: TYPE_POSTGRES_NUMERIC_PROC,
97
+
98
+ string: TYPE_POSTGRES_VARCHAR_PROC,
99
+ varchar: TYPE_POSTGRES_VARCHAR_PROC,
100
+ text: { db_type: 'text' },
101
+
102
+ bytes: { db_type: 'bytea', sequel_type: :bytea },
103
+ bytea: { db_type: 'bytea' },
104
+ blob: { db_type: 'bytea', sequel_type: :bytea },
105
+
106
+ bool: { db_type: 'boolean' },
107
+ boolean: { db_type: 'boolean' },
108
+
109
+ date: { db_type: 'date' },
110
+ timestamp: { db_type: 'timestamp without time zone' },
111
+ datetime: { db_type: 'timestamp without time zone', sequel_type: :timestamp },
112
+
113
+ float: { db_type: 'double precision' }
114
+ },
115
+ cockroachdb: {
116
+ bigserial: { db_type: 'bigint', db_default: 'unique_rowid()' },
117
+ bigint: { db_type: 'bigint' },
118
+ integer: { db_type: 'bigint' },
119
+ int: { db_type: 'bigint', sequel_type: :integer },
120
+ smallint: { db_type: 'bigint', sequel_type: :integer },
121
+
122
+ decimal: { db_type: 'numeric' },
123
+
124
+ string: { db_type: 'text', sequel_type: :string },
125
+ varchar: { db_type: 'text', sequel_type: :string },
126
+ text: { db_type: 'text' },
127
+
128
+ bytes: { db_type: 'bytea' },
129
+ bytea: { db_type: 'bytea', sequel_type: :bytes },
130
+ blob: { db_type: 'bytea', sequel_type: :bytes },
131
+
132
+ bool: { db_type: 'boolean' },
133
+ boolean: { db_type: 'boolean' },
134
+
135
+ date: { db_type: 'date' },
136
+ timestamp: { db_type: 'timestamp without time zone' },
137
+ datetime: { db_type: 'timestamp without time zone', sequel_type: :timestamp },
138
+
139
+ float: { db_type: 'double precision' }
140
+ }
141
+ }.freeze
142
+
143
+ #
144
+ # The method infers column params based on column definition
145
+ #
146
+ # @param params [Hash]
147
+ # @return [Hash]
148
+ #
149
+ def self.infer_params(params)
150
+ type = params[:type].to_sym
151
+ defaults = {
152
+ db_type: type.to_s,
153
+ sequel_type: type,
154
+ primary_key: !!params[:primary_key],
155
+ not_null: !!params[:primary_key],
156
+ db_default: params[:default]
157
+ }
158
+ adapter_name = Mimi::DB.sequel_config[:adapter]
159
+ raise "Failed to infer_params, adapter is not set: #{adapter_name}" unless adapter_name
160
+ inferred_params = TYPE_MAP[adapter_name.to_sym][type] || TYPE_MAP[:default][type] || {}
161
+ inferred_params = inferred_params.call(params) if inferred_params.is_a?(Proc)
162
+ defaults.merge(inferred_params).merge(params)
163
+ end
164
+ end # module TypeDefaults
165
+ end # module Dictate
166
+ end # module DB
167
+ end # module Mimi