database_cleaner-active_record 1.99.0 → 2.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +80 -0
- data/.gitignore +5 -0
- data/.travis.yml +23 -2
- data/Appraisals +23 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +8 -4
- data/README.md +37 -44
- data/bin/setup +0 -1
- data/database_cleaner-active_record.gemspec +12 -21
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.1.gemfile +13 -0
- data/gemfiles/rails_5.2.gemfile +13 -0
- data/gemfiles/rails_6.0.gemfile +13 -0
- data/gemfiles/rails_6.1.gemfile +20 -0
- data/gemfiles/rails_7.0.gemfile +13 -0
- data/gemfiles/rails_7.1.gemfile +13 -0
- data/lib/database_cleaner/active_record/base.rb +54 -55
- data/lib/database_cleaner/active_record/deletion.rb +49 -86
- data/lib/database_cleaner/active_record/transaction.rb +10 -47
- data/lib/database_cleaner/active_record/truncation.rb +184 -223
- data/lib/database_cleaner/active_record/version.rb +1 -1
- data/lib/database_cleaner/active_record.rb +3 -2
- metadata +38 -42
- data/Gemfile.lock +0 -73
@@ -1,107 +1,70 @@
|
|
1
1
|
require 'active_record'
|
2
|
-
require 'active_record/connection_adapters/abstract_adapter'
|
3
|
-
require "database_cleaner/generic/truncation"
|
4
2
|
require 'database_cleaner/active_record/truncation'
|
5
3
|
|
6
4
|
module DatabaseCleaner
|
7
|
-
module
|
8
|
-
|
9
|
-
def
|
10
|
-
|
5
|
+
module ActiveRecord
|
6
|
+
class Deletion < Truncation
|
7
|
+
def clean
|
8
|
+
connection.disable_referential_integrity do
|
9
|
+
if pre_count? && connection.respond_to?(:pre_count_tables)
|
10
|
+
delete_tables(connection, connection.pre_count_tables(tables_to_truncate(connection)))
|
11
|
+
else
|
12
|
+
delete_tables(connection, tables_to_truncate(connection))
|
13
|
+
end
|
14
|
+
end
|
11
15
|
end
|
12
|
-
end
|
13
16
|
|
14
|
-
|
15
|
-
def delete_table(table_name)
|
16
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
17
|
-
end
|
18
|
-
end
|
17
|
+
private
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def delete_tables(connection, table_names)
|
20
|
+
table_names.each do |table_name|
|
21
|
+
delete_table(connection, table_name)
|
22
|
+
end
|
23
23
|
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module ActiveRecord
|
29
|
-
module ConnectionAdapters
|
30
|
-
AbstractAdapter.class_eval { include DatabaseCleaner::ConnectionAdapters::AbstractDeleteAdapter }
|
31
|
-
|
32
|
-
JdbcAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(JdbcAdapter)
|
33
|
-
AbstractMysqlAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(AbstractMysqlAdapter)
|
34
|
-
Mysql2Adapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(Mysql2Adapter)
|
35
|
-
SQLiteAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(SQLiteAdapter)
|
36
|
-
SQLite3Adapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(SQLite3Adapter)
|
37
|
-
PostgreSQLAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(PostgreSQLAdapter)
|
38
|
-
IBM_DBAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(IBM_DBAdapter)
|
39
|
-
SQLServerAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::GenericDeleteAdapter } if defined?(SQLServerAdapter)
|
40
|
-
OracleEnhancedAdapter.class_eval { include ::DatabaseCleaner::ConnectionAdapters::OracleDeleteAdapter } if defined?(OracleEnhancedAdapter)
|
41
|
-
end
|
42
|
-
end
|
43
24
|
|
44
|
-
|
45
|
-
|
46
|
-
def tables_to_truncate(connection)
|
47
|
-
if information_schema_exists?(connection)
|
48
|
-
(@only || tables_with_new_rows(connection)) - @tables_to_exclude
|
49
|
-
else
|
50
|
-
super
|
25
|
+
def delete_table connection, table_name
|
26
|
+
connection.execute("DELETE FROM #{connection.quote_table_name(table_name)} WHERE 1=1")
|
51
27
|
end
|
52
|
-
end
|
53
28
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
29
|
+
def tables_to_truncate(connection)
|
30
|
+
if information_schema_exists?(connection)
|
31
|
+
@except += connection.database_cleaner_view_cache + migration_storage_names
|
32
|
+
(@only.any? ? @only : tables_with_new_rows(connection)) - @except
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
60
36
|
end
|
61
|
-
end
|
62
37
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
38
|
+
def tables_with_new_rows(connection)
|
39
|
+
stats = table_stats_query(connection)
|
40
|
+
if stats != ''
|
41
|
+
connection.select_values(stats)
|
42
|
+
else
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
68
46
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
WHERE table_schema = database()
|
74
|
-
AND #{::DatabaseCleaner::ActiveRecord::Base.exclusion_condition('table_name')};
|
75
|
-
SQL
|
76
|
-
queries = tables.map do |table|
|
77
|
-
"(SELECT #{connection.quote(table)} FROM #{connection.quote_table_name(table)} LIMIT 1)"
|
47
|
+
def table_stats_query(connection)
|
48
|
+
@table_stats_query ||= build_table_stats_query(connection)
|
49
|
+
ensure
|
50
|
+
@table_stats_query = nil unless @cache_tables
|
78
51
|
end
|
79
|
-
queries.join(' UNION ALL ')
|
80
|
-
end
|
81
52
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
53
|
+
def build_table_stats_query(connection)
|
54
|
+
tables = connection.select_values(<<-SQL)
|
55
|
+
SELECT table_name
|
56
|
+
FROM information_schema.tables
|
57
|
+
WHERE table_schema = database()
|
58
|
+
AND #{self.class.exclusion_condition('table_name')};
|
59
|
+
SQL
|
60
|
+
queries = tables.map do |table|
|
61
|
+
"(SELECT #{connection.quote(table)} FROM #{connection.quote_table_name(table)} LIMIT 1)"
|
90
62
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
class Deletion < Truncation
|
95
|
-
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
96
|
-
include SelectiveTruncation
|
97
|
-
end
|
63
|
+
queries.join(' UNION ALL ')
|
64
|
+
end
|
98
65
|
|
99
|
-
|
100
|
-
|
101
|
-
connection.disable_referential_integrity do
|
102
|
-
tables_to_truncate(connection).each do |table_name|
|
103
|
-
connection.delete_table table_name
|
104
|
-
end
|
66
|
+
def information_schema_exists? connection
|
67
|
+
connection.adapter_name == "Mysql2"
|
105
68
|
end
|
106
69
|
end
|
107
70
|
end
|
@@ -1,59 +1,22 @@
|
|
1
1
|
require 'database_cleaner/active_record/base'
|
2
|
-
require 'database_cleaner/generic/transaction'
|
3
2
|
|
4
|
-
module DatabaseCleaner
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module DatabaseCleaner
|
4
|
+
module ActiveRecord
|
5
|
+
class Transaction < Base
|
6
|
+
def start
|
7
|
+
# Hack to make sure that the connection is properly set up before cleaning
|
8
|
+
connection_class.connection.transaction {}
|
8
9
|
|
9
|
-
|
10
|
-
# Hack to make sure that the connection is properly setup for
|
11
|
-
# the clean code.
|
12
|
-
connection_class.connection.transaction{ }
|
13
|
-
|
14
|
-
if connection_maintains_transaction_count?
|
15
|
-
if connection_class.connection.respond_to?(:increment_open_transactions)
|
16
|
-
connection_class.connection.increment_open_transactions
|
17
|
-
else
|
18
|
-
connection_class.__send__(:increment_open_transactions)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
if connection_class.connection.respond_to?(:begin_transaction)
|
22
|
-
connection_class.connection.begin_transaction :joinable => false
|
23
|
-
else
|
24
|
-
connection_class.connection.begin_db_transaction
|
10
|
+
connection_class.connection.begin_transaction joinable: false
|
25
11
|
end
|
26
|
-
end
|
27
|
-
|
28
12
|
|
29
|
-
def clean
|
30
|
-
connection_class.connection_pool.connections.each do |connection|
|
31
|
-
next unless connection.open_transactions > 0
|
32
13
|
|
33
|
-
|
14
|
+
def clean
|
15
|
+
connection_class.connection_pool.connections.each do |connection|
|
16
|
+
next unless connection.open_transactions > 0
|
34
17
|
connection.rollback_transaction
|
35
|
-
else
|
36
|
-
connection.rollback_db_transaction
|
37
|
-
end
|
38
|
-
|
39
|
-
# The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99
|
40
|
-
if connection.respond_to?(:rollback_transaction_records, true)
|
41
|
-
connection.send(:rollback_transaction_records, true)
|
42
|
-
end
|
43
|
-
|
44
|
-
if connection_maintains_transaction_count?
|
45
|
-
if connection.respond_to?(:decrement_open_transactions)
|
46
|
-
connection.decrement_open_transactions
|
47
|
-
else
|
48
|
-
connection_class.__send__(:decrement_open_transactions)
|
49
|
-
end
|
50
18
|
end
|
51
19
|
end
|
52
20
|
end
|
53
|
-
|
54
|
-
def connection_maintains_transaction_count?
|
55
|
-
ActiveRecord::VERSION::MAJOR < 4
|
56
|
-
end
|
57
|
-
|
58
21
|
end
|
59
22
|
end
|