database_cleaner-active_record 1.99.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 ConnectionAdapters
8
- module AbstractDeleteAdapter
9
- def delete_table(table_name)
10
- raise NotImplementedError
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
- module GenericDeleteAdapter
15
- def delete_table(table_name)
16
- execute("DELETE FROM #{quote_table_name(table_name)};")
17
- end
18
- end
17
+ private
19
18
 
20
- module OracleDeleteAdapter
21
- def delete_table(table_name)
22
- execute("DELETE FROM #{quote_table_name(table_name)}")
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
- module DatabaseCleaner::ActiveRecord
45
- module SelectiveTruncation
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
- def tables_with_new_rows(connection)
55
- stats = table_stats_query(connection)
56
- if stats != ''
57
- connection.select_values(stats)
58
- else
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
- def table_stats_query(connection)
64
- @table_stats_query ||= build_table_stats_query(connection)
65
- ensure
66
- @table_stats_query = nil unless @cache_tables
67
- end
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
- def build_table_stats_query(connection)
70
- tables = connection.select_values(<<-SQL)
71
- SELECT table_name
72
- FROM information_schema.tables
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
- def information_schema_exists? connection
83
- return false unless connection.is_a? ActiveRecord::ConnectionAdapters::Mysql2Adapter
84
- @information_schema_exists ||=
85
- begin
86
- connection.execute("SELECT 1 FROM information_schema.tables")
87
- true
88
- rescue
89
- false
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
- end
92
- end
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
- def clean
100
- connection = connection_class.connection
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::ActiveRecord
5
- class Transaction
6
- include ::DatabaseCleaner::ActiveRecord::Base
7
- include ::DatabaseCleaner::Generic::Transaction
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
- def start
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
- if connection.respond_to?(:rollback_transaction)
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