-
Notifications
You must be signed in to change notification settings - Fork 93
/
Copy pathcleaner.rb
84 lines (70 loc) · 2.82 KB
/
cleaner.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# frozen_string_literal: true
require_relative 'multiple_statements_executor'
using DatabaseRewinder::MultipleStatementsExecutor
module DatabaseRewinder
class Cleaner
attr_accessor :config, :connection_name, :only, :except, :inserted_tables, :pool
def initialize(config: nil, connection_name: nil, only: nil, except: nil)
@config, @connection_name, @only, @except = config, connection_name, Array(only), Array(except)
reset
end
def db
config['database']
end
def clean(multiple: true)
return if !pool || inserted_tables.empty?
# When the application uses multiple database connections, a connection
# pool used in test could be already removed (i.e., pool.connected? = false).
# In this case, we have to reconnect to the database to clean inserted
# tables.
with_automatic_reconnect(pool) do
delete_all (ar_conn = pool.connection), DatabaseRewinder.all_table_names(ar_conn) & inserted_tables, multiple: multiple
end
reset
end
def clean_all(multiple: true)
if pool
ar_conn = pool.connection
delete_all ar_conn, DatabaseRewinder.all_table_names(ar_conn), multiple: multiple
else
require 'database_rewinder/dummy_model'
DummyModel.with_temporary_connection(config) do |temporary_connection|
delete_all temporary_connection, DatabaseRewinder.all_table_names(temporary_connection), multiple: multiple
end
end
reset
end
private
def delete_all(ar_conn, tables, multiple: true)
tables = tables & @only if @only.any?
tables -= @except if @except.any?
return if tables.empty?
if multiple && tables.many? && ar_conn.supports_multiple_statements?
#TODO Use ADAPTER_NAME when we've dropped AR 4.1 support
if (ar_conn.class.name == 'ActiveRecord::ConnectionAdapters::Mysql2Adapter') && ar_conn.transaction_open?
# Print the warning message, then fall back to non-multiple deletion
Kernel.warn "WARNING: You may be executing DatabaseRewinder inside a transactional test. You're presumably misconfiguring your tests. Please read DatabaseRewinder's document, and properly configure your tests."
else
ar_conn.execute_multiple tables.map {|t| "DELETE FROM #{ar_conn.quote_table_name(t)}"}.join(';')
return
end
end
ar_conn.disable_referential_integrity do
tables.each do |table_name|
ar_conn.execute "DELETE FROM #{ar_conn.quote_table_name(table_name)};"
end
end
end
def reset
@inserted_tables = []
end
def with_automatic_reconnect(pool)
reconnect = pool.automatic_reconnect
pool.automatic_reconnect = true
yield
ensure
pool.automatic_reconnect = reconnect
end
end
end
require_relative 'compatibility'