mimi-db 0.2.7 → 0.3.0

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.
@@ -3,65 +3,26 @@ require_relative 'dictate/schema_definition'
3
3
  require_relative 'dictate/schema_diff'
4
4
  require_relative 'dictate/explorer'
5
5
  require_relative 'dictate/migrator'
6
+ require_relative 'dictate/type_defaults'
6
7
 
7
8
  module Mimi
8
9
  module DB
9
10
  module Dictate
10
- TYPE_DEFAULTS = {
11
- # sqlite3: {
12
- # string: { name: 'varchar', limit: 32 }
13
- # }
14
- }.freeze
15
-
16
11
  def self.included(base)
17
12
  base.extend Mimi::DB::Dictate::DSL
18
13
  end
19
14
 
20
15
  def self.start
21
- ActiveRecord::Base.extend Mimi::DB::Dictate::DSL
22
16
  end
23
17
 
18
+ # Returns all registered schema definitions
19
+ #
20
+ # @return [Hash] a map of <table_name> -> <schema_definition>
21
+ #
24
22
  def self.schema_definitions
25
23
  @schema_definitions ||= {}
26
24
  end
27
25
 
28
- def self.adapter_type
29
- ca = ActiveRecord::ConnectionAdapters
30
- c = ActiveRecord::Base.connection
31
-
32
- # TODO: postgres???
33
- return :cockroachdb if ca.const_defined?(:CockroachDBAdapter) && c.is_a?(ca::PostgreSQLAdapter)
34
-
35
- return :postgresql if ca.const_defined?(:PostgreSQLAdapter) && c.is_a?(ca::PostgreSQLAdapter)
36
-
37
- return :mysql if ca.const_defined?(:AbstractMysqlAdapter) && c.is_a?(ca::AbstractMysqlAdapter)
38
-
39
- return :sqlite3 if ca.const_defined?(:SQLite3Adapter) && c.is_a?(ca::SQLite3Adapter)
40
-
41
- raise 'Unrecognized database adapter type'
42
- end
43
-
44
- # Returns type defaults based on given type:
45
- # :string
46
- # :text
47
- # :integer etc
48
- #
49
- def self.type_defaults(type)
50
- type = type.to_sym
51
- connection_defaults = ActiveRecord::Base.connection.native_database_types
52
- adapter_defaults = TYPE_DEFAULTS[DB::Dictate.adapter_type]
53
- d = (adapter_defaults && adapter_defaults[type]) || connection_defaults[type] || {}
54
- d = {
55
- sql_type: d.is_a?(String) ? d : d[:name],
56
- limit: d.is_a?(String) ? nil : d[:limit]
57
- }
58
- if type == :primary_key
59
- d[:primary_key] = true
60
- d[:not_null] = true
61
- end
62
- d
63
- end
64
-
65
26
  # Updates the DB schema to the target schema defined in models
66
27
  #
67
28
  # Default options from Migrator::DEFAULTS:
@@ -71,18 +32,18 @@ module Mimi
71
32
  # indexes: false
72
33
  # },
73
34
  # dry_run: false,
74
- # logger: nil # will use ActiveRecord::Base.logger
35
+ # logger: nil # will use Mimi::DB.logger
75
36
  #
76
37
  # @param opts [Hash]
77
38
  #
78
39
  def self.update_schema!(opts = {})
79
- logger = opts[:logger] || ActiveRecord::Base.logger
80
- logger.info "Mimi::DB::Dictate started updating DB schema"
40
+ logger = opts[:logger] || Mimi::DB.logger
41
+ logger.debug 'Mimi::DB::Dictate started updating DB schema'
81
42
  t_start = Time.now
82
43
  Mimi::DB.all_table_names.each { |t| Mimi::DB::Dictate::Migrator.new(t, opts).run! }
83
- logger.info 'Mimi::DB::Dictate finished updating DB schema (%.3fs)' % [Time.now - t_start]
44
+ logger.debug 'Mimi::DB::Dictate finished updating DB schema (%.3fs)' % [Time.now - t_start]
84
45
  rescue StandardError => e
85
- logger.error "DB::Dictate failed to update DB schema: #{e}"
46
+ logger.error "Mimi::DB::Dictate failed to update DB schema: #{e}"
86
47
  raise
87
48
  end
88
49
 
@@ -92,22 +53,23 @@ module Mimi
92
53
  # @return [Hash]
93
54
  #
94
55
  def self.diff_schema(opts = {})
95
- logger = opts[:logger] || ActiveRecord::Base.logger
96
- diff = { add_tables: [], change_tables: [], drop_tables: []}
56
+ logger = opts[:logger] || Mimi::DB.logger
57
+ diff = { add_tables: [], change_tables: [], drop_tables: [] }
97
58
  Mimi::DB.all_table_names.each do |t|
98
59
  m = Mimi::DB::Dictate::Migrator.new(t, opts)
99
60
  if m.from_schema && m.to_schema.nil?
100
61
  diff[:drop_tables] << t
101
62
  elsif m.from_schema && m.to_schema
63
+ logger.debug "DB::Dictate comparing '#{t}'"
102
64
  t_diff = Mimi::DB::Dictate::SchemaDiff.diff(m.from_schema, m.to_schema)
103
65
  diff[:change_tables] << t_diff unless t_diff[:columns].empty? && t_diff[:indexes].empty?
104
- elsif m.from_schema.nil? && m.to_schema
66
+ elsif m.from_schema.nil? && m.to_schema
105
67
  diff[:add_tables] << m.to_schema
106
68
  end
107
69
  end
108
70
  diff
109
71
  rescue StandardError => e
110
- logger.error "DB::Dictate failed to update DB schema: #{e}"
72
+ logger.error "DB::Dictate failed to compare schema: #{e}"
111
73
  raise
112
74
  end
113
75
  end # module Dictate
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel/adapters/postgres'
4
+
5
+ module Sequel
6
+ #
7
+ # A simplistic and not fully functional CockroachDB adapter
8
+ #
9
+ # TODO: to replace with a better alternative once available
10
+ #
11
+ module Cockroach
12
+ class Database < Sequel::Postgres::Database
13
+ set_adapter_scheme :cockroach
14
+ set_adapter_scheme :cockroachdb
15
+
16
+ # Cockroach DB only supports one savepoint
17
+ def supports_savepoints?
18
+ false
19
+ end
20
+
21
+ def server_version(*)
22
+ 80000 # mimics Postgres v8
23
+ # 100000 # mimics Postgres v10
24
+ end
25
+
26
+ private
27
+
28
+ def dataset_class_default
29
+ Dataset
30
+ end
31
+ end
32
+
33
+ class Dataset < Sequel::Postgres::Dataset
34
+ def default_timestamp_format
35
+ "'%Y-%m-%d %H:%M:%S%N%:z'"
36
+ end
37
+ end # class Dataset
38
+ end # module Cockroach
39
+ end # module Sequel
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel'
4
+
5
+ module Sequel
6
+ class Database
7
+ #
8
+ # Fixed behaviour for Sequel's log_exception()
9
+ #
10
+ # Reason:
11
+ # * handled exceptions should not be logged as errors
12
+ # * unhandled exceptions will be logged at the application level
13
+ #
14
+ def log_exception(exception, message, *)
15
+ text_message = "#{self.class}(#{exception.class}): #{exception.message}"
16
+ logger_message = { m: text_message, sql: message }
17
+
18
+ # In case logger does not support structured data, implement a #to_s method
19
+ logger_message.define_singleton_method(:to_s) { text_message }
20
+ log_each(:debug, logger_message)
21
+ end
22
+ end # class Database
23
+ end # module Sequel
@@ -0,0 +1,3 @@
1
+ # require 'sequel/adapters/postgres'
2
+
3
+ # Extensions to Postgres adapter
@@ -0,0 +1,3 @@
1
+ # require 'sequel/adapters/sqlite'
2
+
3
+ # Extensions to Postgres adapter
@@ -2,16 +2,20 @@ module Mimi
2
2
  module DB
3
3
  module Extensions
4
4
  def self.start
5
- # install DB::Dictate
6
- ActiveRecord::Base.send(:include, Mimi::DB::Dictate)
7
-
8
- # FIXME: refactor DSL for primary/foreign keys
9
- # install_primary_keys!
10
- # install_bigint_foreign_keys!
11
- end
12
-
13
- def self.install_bigint_foreign_keys!
14
- # ActiveRecord::Base.send(:include, Mimi::DB::ForeignKey)
5
+ adapter_name = Mimi::DB.sequel_config[:adapter]
6
+ require_relative 'extensions/sequel-database'
7
+ case adapter_name
8
+ when 'sqlite'
9
+ require_relative 'extensions/sequel-sqlite'
10
+ when 'postgres'
11
+ require_relative 'extensions/sequel-postgres'
12
+ when 'cockroachdb'
13
+ require_relative 'extensions/sequel-postgres'
14
+ require_relative 'extensions/sequel-cockroachdb'
15
+ else
16
+ # load nothing
17
+ end
18
+ Sequel::Model.plugin :timestamps
15
19
  end
16
20
  end # module Extensions
17
21
  end # module DB
@@ -1,20 +1,22 @@
1
1
  module Mimi
2
2
  module DB
3
3
  module ForeignKey
4
- extend ActiveSupport::Concern
4
+ # TODO: refactor and re-implement
5
5
 
6
- class_methods do
6
+ # extend ActiveSupport::Concern
7
+
8
+ # class_methods do
7
9
  #
8
10
  # Explicitly specify a (bigint) foreign key
9
11
  #
10
- def foreign_key(name, opts = {})
11
- # TODO: refactor and re-implement
12
- raise 'Not implemented'
12
+ # def foreign_key(name, opts = {})
13
+
14
+ # raise 'Not implemented'
13
15
 
14
16
  # opts = { as: :integer, limit: 8 }.merge(opts)
15
17
  # field(name, opts)
16
18
  # index(name)
17
- end
19
+ # end
18
20
 
19
21
  # Redefines .belongs_to() with explicitly specified .foreign_key
20
22
  #
@@ -25,7 +27,7 @@ module Mimi
25
27
  # # orig_belongs_to(name, opts)
26
28
  # super
27
29
  # end
28
- end
30
+ # end
29
31
  end # module ForeignKey
30
32
  end # module DB
31
33
  end # module Mimi
@@ -7,7 +7,7 @@ module Mimi
7
7
  # @return [Array<ActiveRecord::Base>]
8
8
  #
9
9
  def models
10
- ActiveRecord::Base.descendants
10
+ Mimi::DB::Model.descendants
11
11
  end
12
12
 
13
13
  # Returns a list of table names defined in models
@@ -23,7 +23,7 @@ module Mimi
23
23
  # @return [Array<String>]
24
24
  #
25
25
  def db_table_names
26
- ActiveRecord::Base.connection.tables
26
+ Mimi::DB.connection.tables
27
27
  end
28
28
 
29
29
  # Returns a list of all discovered table names,
@@ -56,6 +56,7 @@ module Mimi
56
56
  # Mimi::DB.update_schema!(destructive: true)
57
57
  #
58
58
  def update_schema!(opts = {})
59
+ Mimi::DB.start
59
60
  opts[:logger] ||= Mimi::DB.logger
60
61
  Mimi::DB::Dictate.update_schema!(opts)
61
62
  end
@@ -84,6 +85,7 @@ module Mimi
84
85
  # @return [Hash]
85
86
  #
86
87
  def diff_schema(opts = {})
88
+ Mimi::DB.start
87
89
  opts[:logger] ||= Mimi::DB.logger
88
90
  Mimi::DB::Dictate.diff_schema(opts)
89
91
  end
@@ -91,29 +93,16 @@ module Mimi
91
93
  # Creates the database specified in the current configuration.
92
94
  #
93
95
  def create!
94
- db_adapter = Mimi::DB.active_record_config['adapter']
95
- db_database = Mimi::DB.active_record_config['database']
96
- slim_url = "#{db_adapter}//<host>:<port>/#{db_database}"
97
- Mimi::DB.logger.info "Mimi::DB.create! creating database: #{slim_url}"
98
- original_stdout = $stdout
99
- original_stderr = $stderr
100
- $stdout = StringIO.new
101
- $stderr = StringIO.new
102
- ActiveRecord::Tasks::DatabaseTasks.root = Mimi.app_root_path
103
- ActiveRecord::Tasks::DatabaseTasks.create(Mimi::DB.active_record_config)
104
- Mimi::DB.logger.debug "Mimi::DB.create! out:#{$stdout.string}, err:#{$stderr.string}"
105
- ensure
106
- $stdout = original_stdout
107
- $stderr = original_stderr
96
+ raise 'Not implemented'
108
97
  end
109
98
 
110
99
  # Tries to establish connection, returns true if the database exist
111
100
  #
112
101
  def database_exist?
113
- ActiveRecord::Base.establish_connection(Mimi::DB.active_record_config)
114
- ActiveRecord::Base.connection
102
+ Mimi::DB.connection.test_connection
115
103
  true
116
- rescue ActiveRecord::NoDatabaseError
104
+ rescue StandardError => e
105
+ Mimi::DB.logger.error "DB: database_exist? failed with: #{e}"
117
106
  false
118
107
  end
119
108
 
@@ -130,31 +119,17 @@ module Mimi
130
119
  # Drops the database specified in the current configuration.
131
120
  #
132
121
  def drop!
133
- original_stdout = $stdout
134
- original_stderr = $stderr
135
- $stdout = StringIO.new
136
- $stderr = StringIO.new
137
- ActiveRecord::Tasks::DatabaseTasks.root = Mimi.app_root_path
138
- ActiveRecord::Tasks::DatabaseTasks.drop(Mimi::DB.active_record_config)
139
- Mimi::DB.logger.debug "Mimi::DB.drop! out:#{$stdout.string}, err:#{$stderr.string}"
140
- ensure
141
- $stdout = original_stdout
142
- $stderr = original_stderr
122
+ raise 'Not implemented'
143
123
  end
144
124
 
145
125
  # Clears (but not drops) the database specified in the current configuration.
146
126
  #
147
127
  def clear!
148
- original_stdout = $stdout
149
- original_stderr = $stderr
150
- $stdout = StringIO.new
151
- $stderr = StringIO.new
152
- ActiveRecord::Tasks::DatabaseTasks.root = Mimi.app_root_path
153
- ActiveRecord::Tasks::DatabaseTasks.purge(Mimi::DB.active_record_config)
154
- Mimi::DB.logger.debug "Mimi::DB.clear! out:#{$stdout.string}, err:#{$stderr.string}"
155
- ensure
156
- $stdout = original_stdout
157
- $stderr = original_stderr
128
+ Mimi::DB.start
129
+ db_table_names.each do |table_name|
130
+ Mimi::DB.logger.debug "Mimi::DB dropping table: #{table_name}"
131
+ Mimi::DB.connection.drop_table(table_name)
132
+ end
158
133
  end
159
134
 
160
135
  # Executes raw SQL, with variables interpolation.
@@ -163,8 +138,31 @@ module Mimi
163
138
  # Mimi::DB.execute('insert into table1 values(?, ?, ?)', 'foo', :bar, 123)
164
139
  #
165
140
  def execute(statement, *args)
166
- sql = ActiveRecord::Base.send(:replace_bind_variables, statement, args)
167
- ActiveRecord::Base.connection.execute(sql)
141
+ sql = Sequel.fetch(statement, *args).sql
142
+ Mimi::DB.connection.run(sql)
143
+ end
144
+
145
+ # Starts a transaction and executes a given block within the transaction
146
+ #
147
+ # @param params [Hash] parameters to Sequel #transaction() method
148
+ #
149
+ def transaction(params = {}, &_block)
150
+ unless Mimi::DB.connection
151
+ raise 'Failed to start transaction, Mimi::DB.connection not available'
152
+ end
153
+ Mimi::DB.connection.transaction(params) { yield }
154
+ end
155
+
156
+ # Executes a block with a given DB log level
157
+ #
158
+ # @param log_level [Symbol,nil] :debug, :info etc
159
+ #
160
+ def with_log_level(log_level, &_block)
161
+ current_log_level = Mimi::DB.connection.sql_log_level
162
+ Mimi::DB.connection.sql_log_level = log_level
163
+ yield
164
+ ensure
165
+ Mimi::DB.connection.sql_log_level = current_log_level
168
166
  end
169
167
  end # module Helpers
170
168
 
data/lib/mimi/db/lock.rb CHANGED
@@ -49,6 +49,10 @@ module Mimi
49
49
  end
50
50
 
51
51
  def lock!(name, opts = {}, &block)
52
+ raise 'Not implemented'
53
+
54
+ # FIXME: migrate Mimi::DB::Lock to Sequel
55
+
52
56
  opts = Mimi::DB::Lock.module_options[:default_lock_options].merge(opts.dup)
53
57
  adapter_name = ActiveRecord::Base.connection.adapter_name.downcase.to_sym
54
58
  case adapter_name
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE: this is the way to create an abstract class that inherits from Sequel::Model
4
+ Mimi::DB::Model = Class.new(Sequel::Model)
5
+
6
+ module Mimi
7
+ module DB
8
+ class Model
9
+ include Mimi::DB::Dictate
10
+
11
+ self.require_valid_table = false
12
+ plugin :timestamps, create: :created_at, update: :updated_at, update_on_create: true
13
+ plugin :validation_helpers
14
+
15
+ # Keeps messages as error types, not human readable strings
16
+ #
17
+ def default_validation_helpers_options(type)
18
+ { message: type }
19
+ end
20
+
21
+ def before_validation
22
+ super
23
+ call_hooks(:before_validation)
24
+ end
25
+
26
+ # Defines a hook the ActiveRecord way
27
+ #
28
+ # Example:
29
+ #
30
+ # class A < Mimi::DB::Model
31
+ # before_validation :set_detaults
32
+ #
33
+ # def set_defaults
34
+ # self.name = "John Doe"
35
+ # end
36
+ # end
37
+ #
38
+ def self.before_validation(method = nil, &block)
39
+ if method && block
40
+ raise ArgumentError, '.before_validation() cannot accept both method and a block'
41
+ end
42
+ block = -> { send(method) } if method
43
+ register_hook(:before_validation, block)
44
+ end
45
+
46
+ private
47
+
48
+ def self.registered_hooks(name)
49
+ @registered_hooks ||= {}
50
+ @registered_hooks[name] ||= []
51
+ end
52
+
53
+ def self.register_hook(name, block)
54
+ registered_hooks(name) << block
55
+ end
56
+
57
+ def call_hooks(name)
58
+ self.class.registered_hooks(name).each do |block|
59
+ instance_eval(&block)
60
+ end
61
+ end
62
+ end # class Model
63
+ end # module DB
64
+ end # module Mimi
@@ -1,5 +1,5 @@
1
1
  module Mimi
2
2
  module DB
3
- VERSION = '0.2.7'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  end
data/lib/mimi/db.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'mimi/core'
2
- require 'active_record'
2
+ require 'sequel'
3
3
 
4
4
  module Mimi
5
5
  module DB
@@ -13,12 +13,8 @@ module Mimi
13
13
  db_port: nil,
14
14
  db_username: nil,
15
15
  db_password: nil,
16
- db_log_level: :info,
17
- db_pool: 15,
18
- db_primary_key_cockroachdb: nil,
19
- db_primary_key_postgresql: nil,
20
- db_primary_key_mysql: nil,
21
- db_primary_key_sqlite3: nil
16
+ db_log_level: :debug,
17
+ db_pool: 15
22
18
  # db_encoding:
23
19
  )
24
20
 
@@ -58,45 +54,75 @@ module Mimi
58
54
  },
59
55
  db_log_level: {
60
56
  desc: 'Logging level for database layer ("debug", "info" etc)',
61
- default: 'info'
57
+ default: 'debug'
62
58
  }
63
59
  }
64
60
  end
65
61
 
66
62
  def self.configure(*)
67
63
  super
68
- ActiveSupport::LogSubscriber.colorize_logging = false
69
- ActiveRecord::Base.logger = logger
70
- ActiveRecord::Base.configurations = { 'default' => active_record_config }
71
-
72
- # TODO: test and remove deprectated ...
73
- # ActiveRecord::Base.raise_in_transactional_callbacks = true
64
+ if Mimi.const_defined?(:Application)
65
+ @logger = Mimi::Application.logger
66
+ end
74
67
  end
75
68
 
76
69
  def self.logger
77
- @logger ||= Mimi::Logger.new(level: module_options[:db_log_level])
70
+ @logger ||= Mimi::Logger.new
71
+ end
72
+
73
+ # Returns active DB connection
74
+ #
75
+ # @return [Sequel::<...>::Database]
76
+ #
77
+ def self.connection
78
+ @connection
78
79
  end
79
80
 
80
81
  def self.start
81
- ActiveRecord::Base.establish_connection(:default)
82
82
  Mimi::DB::Extensions.start
83
- Mimi::DB::Dictate.start
83
+ @connection = Sequel.connect(sequel_config)
84
84
  Mimi.require_files(module_options[:require_files]) if module_options[:require_files]
85
85
  super
86
86
  end
87
87
 
88
- def self.active_record_config
88
+ # Returns a standard Sequel adapter name converted from any variation of adapter names.
89
+ #
90
+ # @example
91
+ # sequel_config_canonical_adapter_name(:sqlite3) # => 'sqlite'
92
+ #
93
+ # @param adapter_name [String,Symbol]
94
+ # @return [String]
95
+ #
96
+ def self.sequel_config_canonical_adapter_name(adapter_name)
97
+ case adapter_name.to_s.downcase
98
+ when 'sqlite', 'sqlite3'
99
+ 'sqlite'
100
+ when 'postgres', 'postgresql'
101
+ 'postgres'
102
+ when 'cockroach', 'cockroachdb'
103
+ 'cockroachdb'
104
+ else
105
+ adapter_name.to_s.downcase
106
+ end
107
+ end
108
+
109
+ # Returns Sequel connection parameters
110
+ #
111
+ # @return [Hash]
112
+ #
113
+ def self.sequel_config
89
114
  {
90
- adapter: module_options[:db_adapter],
115
+ adapter: sequel_config_canonical_adapter_name(module_options[:db_adapter]),
91
116
  database: module_options[:db_database],
92
117
  host: module_options[:db_host],
93
118
  port: module_options[:db_port],
94
- username: module_options[:db_username],
119
+ user: module_options[:db_username],
95
120
  password: module_options[:db_password],
96
121
  encoding: module_options[:db_encoding],
97
- pool: module_options[:db_pool],
98
- reaping_frequency: 15
99
- }.stringify_keys
122
+ max_connections: module_options[:db_pool],
123
+ sql_log_level: module_options[:db_log_level],
124
+ logger: logger
125
+ }
100
126
  end
101
127
  end # module DB
102
128
  end # module Mimi
@@ -106,3 +132,4 @@ require_relative 'db/extensions'
106
132
  require_relative 'db/helpers'
107
133
  require_relative 'db/foreign_key'
108
134
  require_relative 'db/dictate'
135
+ require_relative 'db/model'
data/lib/tasks/db.rake CHANGED
@@ -40,17 +40,22 @@ namespace :db do
40
40
  namespace :migrate do
41
41
  desc 'Migrate database (seeds only)'
42
42
  task seeds: :"db:start" do
43
+ logger.info "* Processing database seeds: #{Mimi::DB.module_options[:db_database]}"
44
+ t_start = Time.now
43
45
  seeds = Pathname.glob(Mimi.app_path_to('db', 'seeds', '**', '*.rb')).sort
44
46
  seeds.each do |seed_filename|
45
- logger.info "* Processing seed: #{seed_filename}"
47
+ logger.info "-- Processing seed: #{seed_filename}"
46
48
  load seed_filename
47
49
  end
50
+ logger.info '* Finished processing database seeds (%.3fs)' % (Time.now - t_start)
48
51
  end
49
52
 
50
53
  desc 'Migrate database (schema only)'
51
54
  task schema: :"db:start" do
52
55
  logger.info "* Updating database schema: #{Mimi::DB.module_options[:db_database]}"
56
+ t_start = Time.now
53
57
  Mimi::DB.update_schema!(destructive: true)
58
+ logger.info '* Finished updating database schema (%.3fs)' % (Time.now - t_start)
54
59
  end
55
60
 
56
61
  namespace :schema do
@@ -88,6 +93,9 @@ namespace :db do
88
93
  diff[:drop_tables].each do |t|
89
94
  puts "-- DROP table: #{t}"
90
95
  end
96
+ if diff[:add_tables].empty? && diff[:change_tables].empty? && diff[:drop_tables].empty?
97
+ logger.info '* Diff database schema: no changes detected'
98
+ end
91
99
  end
92
100
  end
93
101
  end
data/mimi-db.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency 'mimi-core', '~> 0.2'
31
31
  spec.add_dependency 'mimi-logger', '~> 0.2'
32
- spec.add_dependency 'activerecord', '~> 5.0'
32
+ spec.add_dependency 'sequel', '~> 5.8'
33
33
 
34
34
  spec.add_development_dependency 'bundler', '~> 1.11'
35
35
  spec.add_development_dependency 'rake', '~> 10.0'