Module: DatabaseRewinder

Extended by:
Compatibility
Defined in:
lib/database_rewinder.rb,
lib/database_rewinder/cleaner.rb,
lib/database_rewinder/railtie.rb,
lib/database_rewinder/dummy_model.rb,
lib/database_rewinder/compatibility.rb,
lib/database_rewinder/active_record_monkey.rb,
lib/database_rewinder/multiple_statements_executor.rb

Defined Under Namespace

Modules: Compatibility, InsertRecorder, MultipleStatementsExecutor Classes: Cleaner, DummyModel, Railtie

Constant Summary collapse

VERSION =
Gem.loaded_specs['database_rewinder'].version.to_s

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from Compatibility

[], clean_with, cleaning, start, strategy=

Class Attribute Details

.database_configurationObject



14
15
16
# File 'lib/database_rewinder.rb', line 14

def database_configuration
  @database_configuration || ActiveRecord::Base.configurations
end

Class Method Details

.[](connection) ⇒ Object



24
25
26
27
28
# File 'lib/database_rewinder.rb', line 24

def [](connection)
  init unless defined? @cleaners

  @cleaners.detect {|c| c.connection_name == connection} || create_cleaner(connection)
end

.all=(v) ⇒ Object



30
31
32
# File 'lib/database_rewinder.rb', line 30

def all=(v)
  @clean_all = v
end

.all_table_names(connection) ⇒ Object

cache AR connection.tables



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/database_rewinder.rb', line 77

def all_table_names(connection)
  cache_key = get_cache_key(connection.pool)
  #NOTE connection.tables warns on AR 5 with some adapters
  tables =
    if Rails.application.respond_to?(:deprecators) # AR >= 7.1
      Rails.application.deprecators.silence { connection.tables }
    else
      ActiveSupport::Deprecation.silence { connection.tables }
    end
  schema_migraion_table_name =
    if ActiveRecord::SchemaMigration.respond_to?(:table_name)
      ActiveRecord::SchemaMigration.table_name
    else
      ActiveRecord::SchemaMigration.new(connection).table_name  # AR >= 7.1
    end
  @table_names_cache[cache_key] ||= tables.reject do |t|
    (t == schema_migraion_table_name) ||
    (ActiveRecord::Base.respond_to?(:internal_metadata_table_name) && (t == ActiveRecord::Base.))
  end
end

.clean(multiple: true) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/database_rewinder.rb', line 64

def clean(multiple: true)
  if @clean_all
    clean_all multiple: multiple
  else
    cleaners.each {|c| c.clean multiple: multiple}
  end
end

.clean_all(multiple: true) ⇒ Object



72
73
74
# File 'lib/database_rewinder.rb', line 72

def clean_all(multiple: true)
  cleaners.each {|c| c.clean_all multiple: multiple}
end

.cleanersObject



34
35
36
37
# File 'lib/database_rewinder.rb', line 34

def cleaners
  create_cleaner 'test' if @cleaners.empty?
  @cleaners
end

.create_cleaner(connection_name) ⇒ Object



18
19
20
21
22
# File 'lib/database_rewinder.rb', line 18

def create_cleaner(connection_name)
  config = configuration_hash_for(connection_name) or raise %Q[Database configuration named "#{connection_name}" is not configured.]

  Cleaner.new(config: config, connection_name: connection_name, only: @only, except: @except).tap {|c| @cleaners << c}
end

.database_configuration_for(connection_name) ⇒ Object



121
122
123
# File 'lib/database_rewinder.rb', line 121

def database_configuration_for(connection_name)
  traditional_configuration_for(connection_name) || multiple_database_configuration_for(connection_name)
end

.initObject



10
11
12
# File 'lib/database_rewinder.rb', line 10

def init
  @cleaners, @table_names_cache, @clean_all, @only, @except, @database_configuration = [], {}, false
end

.multiple_database_configuration_for(connection_name) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/database_rewinder.rb', line 129

def multiple_database_configuration_for(connection_name)
  if (ActiveRecord::VERSION::MAJOR >= 7) || ((ActiveRecord::VERSION::MAJOR >= 6) && (ActiveRecord::VERSION::MINOR >= 1))
    database_configuration.configs_for(name: connection_name)
  else
    database_configuration.configs_for(spec_name: connection_name)
  end
end

.record_inserted_table(connection, sql) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/database_rewinder.rb', line 39

def record_inserted_table(connection, sql)
  config = connection.instance_variable_get(:'@config')
  database = config[:database]
  #NOTE What's the best way to get the app dir besides Rails.root? I know Dir.pwd here might not be the right solution, but it should work in most cases...
  root_dir = defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : Dir.pwd
  cleaner = cleaners.detect do |c|
    if (config[:adapter] == 'sqlite3') && (config[:database] != ':memory:')
      File.expand_path(c.db, root_dir) == File.expand_path(database, root_dir)
    else
      c.db == database
    end
  end or return

  sql.split(';').each do |statement|
    match = statement.match(/\A\s*INSERT(?:\s+IGNORE)?(?:\s+INTO)?\s+(?:\.*[`"]?([^.\s`"(]+)[`"]?)*/i)
    next unless match

    table = match[1]
    if table
      cleaner.inserted_tables << table unless cleaner.inserted_tables.include? table
      cleaner.pool ||= connection.pool
    end
  end
end

.traditional_configuration_for(connection_name) ⇒ Object



125
126
127
# File 'lib/database_rewinder.rb', line 125

def traditional_configuration_for(connection_name)
  database_configuration.configs_for(env_name: connection_name).first
end