database_rewinder 0.7.1 → 0.8.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/.travis.yml +4 -2
- data/README.md +36 -0
- data/database_rewinder.gemspec +2 -1
- data/lib/database_rewinder.rb +5 -5
- data/lib/database_rewinder/active_record_monkey.rb +1 -0
- data/lib/database_rewinder/cleaner.rb +20 -13
- data/lib/database_rewinder/compatibility.rb +2 -2
- data/lib/database_rewinder/multiple_statements_executor.rb +2 -2
- data/test/active_record_monkey_test.rb +1 -1
- data/test/config/database.yml +2 -2
- data/test/database_rewinder_test.rb +1 -1
- data/test/db/.keep +0 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f5c97bcefcc1123d7adf1d809c1ef4107ce0ef8
|
4
|
+
data.tar.gz: 889bc139276c81073d6d89870eedecfb4bafa664
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b9b9cfa9c8bce163ef37ac406aaa3b90c5c5046cb5852eb697d1ae3e48316035ab26378a3294a12d948a189654e17978d932c86f585952f865d09ca296293d2
|
7
|
+
data.tar.gz: 38cf26cf1d6d947c3eb726bdf28b58175e599decb8757c8185ebfcab2e8d21bb90aadb23b727ab669ae53bf495c01d029e3a076624e67e1a7a14fc91fb3f2cb3
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -15,6 +15,7 @@ database\_rewinder is a minimalist's tiny and ultra-fast database cleaner.
|
|
15
15
|
database\_rewinder memorizes every table name into which `INSERT` SQL was performed during each test case.
|
16
16
|
Then it executes `DELETE` SQL only against these tables when cleaning.
|
17
17
|
So, the more number of tables you have in your database, the more benefit you will get.
|
18
|
+
Also, database\_rewinder joins all `DELETE` SQL statements and casts it in one DB server call.
|
18
19
|
|
19
20
|
### Credit
|
20
21
|
|
@@ -83,6 +84,41 @@ RSpec.configure do |config|
|
|
83
84
|
end
|
84
85
|
```
|
85
86
|
|
87
|
+
### MySQL + use\_transactional\_tests Specific Problems
|
88
|
+
|
89
|
+
database\_rewinder tries to create a new DB connection for deletion when you're running tests on MySQL.
|
90
|
+
You would occasionally hit some weird errors (e.g. query execution timeout) because of this, especially when your tests are run with the `use_transactional_tests` option enabled (which is Rails' default).
|
91
|
+
|
92
|
+
#### 1. Properly understand what `use_transactional_tests` means, and consider turning it off
|
93
|
+
|
94
|
+
`use_transactional_tests` is the option that surrounds each of your test case with a DB transaction to roll back all your test data after each test run.
|
95
|
+
So far as this works properly, you won't really need to use database\_rewinder.
|
96
|
+
However, this simple mechanism doesn't work well when you're running integration tests with capybara + js mode.
|
97
|
+
In cases of this situation, bundle database\_rewinder and add the following configuration.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
RSpec.configure do |config|
|
101
|
+
config.use_transactional_examples = false
|
102
|
+
|
103
|
+
...
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
#### 2. Cleaning with `multiple: false` option
|
108
|
+
If you're really sure you need to keep using transational tests + database\_rewinder for some reason, then explicitly pass in `multiple: false` option to `DatabaseRewinder.clean_all` and `DatabaseRewinder.clean` invocations as follows. Note that you won't be able to get full performance merit that database\_rewinder provides though.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
RSpec.configure do |config|
|
112
|
+
config.before :suite do
|
113
|
+
DatabaseRewinder.clean_all multiple: false
|
114
|
+
end
|
115
|
+
|
116
|
+
config.after :each do
|
117
|
+
DatabaseRewinder.clean multiple: false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
86
122
|
### Pro Tip
|
87
123
|
|
88
124
|
database\_rewinder is designed to be almost compatible with database\_cleaner.
|
data/database_rewinder.gemspec
CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "database_rewinder"
|
8
|
-
spec.version = '0.
|
8
|
+
spec.version = '0.8.0'
|
9
9
|
spec.authors = ["Akira Matsuda"]
|
10
10
|
spec.email = ["ronnie@dio.jp"]
|
11
11
|
spec.description = "A minimalist's tiny and ultra-fast database cleaner"
|
@@ -25,4 +25,5 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'sqlite3'
|
26
26
|
spec.add_development_dependency 'mysql2'
|
27
27
|
spec.add_development_dependency 'pg'
|
28
|
+
spec.required_ruby_version = '>= 2.0.0'
|
28
29
|
end
|
data/lib/database_rewinder.rb
CHANGED
@@ -58,16 +58,16 @@ module DatabaseRewinder
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def clean
|
61
|
+
def clean(multiple: true)
|
62
62
|
if @clean_all
|
63
|
-
clean_all
|
63
|
+
clean_all multiple: multiple
|
64
64
|
else
|
65
|
-
cleaners.each
|
65
|
+
cleaners.each {|c| c.clean multiple: multiple}
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def clean_all
|
70
|
-
cleaners.each
|
69
|
+
def clean_all(multiple: true)
|
70
|
+
cleaners.each {|c| c.clean_all multiple: multiple}
|
71
71
|
end
|
72
72
|
|
73
73
|
# cache AR connection.tables
|
@@ -16,7 +16,7 @@ module DatabaseRewinder
|
|
16
16
|
config['database']
|
17
17
|
end
|
18
18
|
|
19
|
-
def clean
|
19
|
+
def clean(multiple: true)
|
20
20
|
return if !pool || inserted_tables.empty?
|
21
21
|
|
22
22
|
# When the application uses multiple database connections, a connection
|
@@ -24,19 +24,19 @@ module DatabaseRewinder
|
|
24
24
|
# In this case, we have to reconnect to the database to clean inserted
|
25
25
|
# tables.
|
26
26
|
with_automatic_reconnect(pool) do
|
27
|
-
delete_all (ar_conn = pool.connection), DatabaseRewinder.all_table_names(ar_conn) & inserted_tables
|
27
|
+
delete_all (ar_conn = pool.connection), DatabaseRewinder.all_table_names(ar_conn) & inserted_tables, multiple: multiple
|
28
28
|
end
|
29
29
|
reset
|
30
30
|
end
|
31
31
|
|
32
|
-
def clean_all
|
32
|
+
def clean_all(multiple: true)
|
33
33
|
if pool
|
34
34
|
ar_conn = pool.connection
|
35
|
-
delete_all ar_conn, DatabaseRewinder.all_table_names(ar_conn)
|
35
|
+
delete_all ar_conn, DatabaseRewinder.all_table_names(ar_conn), multiple: multiple
|
36
36
|
else
|
37
37
|
require 'database_rewinder/dummy_model'
|
38
38
|
DummyModel.with_temporary_connection(config) do |temporary_connection|
|
39
|
-
delete_all temporary_connection, DatabaseRewinder.all_table_names(temporary_connection)
|
39
|
+
delete_all temporary_connection, DatabaseRewinder.all_table_names(temporary_connection), multiple: multiple
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -44,18 +44,25 @@ module DatabaseRewinder
|
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
47
|
-
def delete_all(ar_conn, tables)
|
47
|
+
def delete_all(ar_conn, tables, multiple: true)
|
48
48
|
tables = tables & @only if @only.any?
|
49
49
|
tables -= @except if @except.any?
|
50
50
|
return if tables.empty?
|
51
51
|
|
52
|
-
if tables.many? && ar_conn.supports_multiple_statements?
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
if multiple && tables.many? && ar_conn.supports_multiple_statements?
|
53
|
+
#TODO Use ADAPTER_NAME when we've dropped AR 4.1 support
|
54
|
+
if (ar_conn.class.name == 'ActiveRecord::ConnectionAdapters::Mysql2Adapter') && ar_conn.transaction_open?
|
55
|
+
# Print the warning message, then fall back to non-multiple deletion
|
56
|
+
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."
|
57
|
+
else
|
58
|
+
ar_conn.execute_multiple tables.map {|t| "DELETE FROM #{ar_conn.quote_table_name(t)}"}.join(';')
|
59
|
+
return
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
ar_conn.disable_referential_integrity do
|
64
|
+
tables.each do |table_name|
|
65
|
+
ar_conn.execute "DELETE FROM #{ar_conn.quote_table_name(table_name)};"
|
59
66
|
end
|
60
67
|
end
|
61
68
|
end
|
@@ -52,10 +52,10 @@ module DatabaseRewinder
|
|
52
52
|
|
53
53
|
class Cleaner
|
54
54
|
module Compatibility
|
55
|
-
def clean_with(_strategy, only: nil, except: nil, **)
|
55
|
+
def clean_with(_strategy, only: nil, except: nil, multiple: true, **)
|
56
56
|
originals = @only, @except
|
57
57
|
self.only, self.except = Array(only), Array(except)
|
58
|
-
clean_all
|
58
|
+
clean_all multiple: multiple
|
59
59
|
ensure
|
60
60
|
self.only, self.except = originals
|
61
61
|
end
|
@@ -13,8 +13,7 @@ module DatabaseRewinder
|
|
13
13
|
when 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
|
14
14
|
disable_referential_integrity { log(sql) { @connection.exec sql } }
|
15
15
|
when 'ActiveRecord::ConnectionAdapters::Mysql2Adapter'
|
16
|
-
|
17
|
-
if query_options[:connect_flags] & Mysql2::Client::MULTI_STATEMENTS != 0
|
16
|
+
if @connection.query_options[:connect_flags] & Mysql2::Client::MULTI_STATEMENTS != 0
|
18
17
|
disable_referential_integrity do
|
19
18
|
_result = log(sql) { @connection.query sql }
|
20
19
|
while @connection.next_result
|
@@ -23,6 +22,7 @@ module DatabaseRewinder
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
else
|
25
|
+
query_options = @connection.query_options.dup
|
26
26
|
query_options[:connect_flags] |= Mysql2::Client::MULTI_STATEMENTS
|
27
27
|
# opens another connection to the DB
|
28
28
|
client = Mysql2::Client.new query_options
|
@@ -10,7 +10,7 @@ class DatabaseRewinder::InsertRecorderTest < ActiveSupport::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
test '#execute' do
|
13
|
-
cleaner = DatabaseRewinder.instance_variable_get(:'@cleaners').detect {|c| c.db == (ENV['DB'] == 'sqlite3' ? 'database_rewinder_test.sqlite3' : 'database_rewinder_test')}
|
13
|
+
cleaner = DatabaseRewinder.instance_variable_get(:'@cleaners').detect {|c| c.db == (ENV['DB'] == 'sqlite3' ? 'db/database_rewinder_test.sqlite3' : 'database_rewinder_test')}
|
14
14
|
|
15
15
|
assert_equal %w(foos bars), cleaner.inserted_tables
|
16
16
|
assert_not_nil cleaner.pool
|
data/test/config/database.yml
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
sqlite3: &sqlite3
|
2
2
|
adapter: sqlite3
|
3
|
-
database: database_rewinder_test.sqlite3
|
3
|
+
database: db/database_rewinder_test.sqlite3
|
4
4
|
pool: 5
|
5
5
|
timeout: 5000
|
6
6
|
|
7
7
|
sqlite3_2: &sqlite3_2
|
8
8
|
adapter: sqlite3
|
9
|
-
database: database_rewinder_test2.sqlite3
|
9
|
+
database: db/database_rewinder_test2.sqlite3
|
10
10
|
pool: 5
|
11
11
|
timeout: 5000
|
12
12
|
|
@@ -66,7 +66,7 @@ class DatabaseRewinder::DatabaseRewinderTest < ActiveSupport::TestCase
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def perform_insert(sql)
|
69
|
-
@cleaner = DatabaseRewinder.instance_variable_get(:'@cleaners').detect {|c| c.db == (ENV['DB'] == 'sqlite3' ? 'database_rewinder_test.sqlite3' : 'database_rewinder_test')}
|
69
|
+
@cleaner = DatabaseRewinder.instance_variable_get(:'@cleaners').detect {|c| c.db == (ENV['DB'] == 'sqlite3' ? 'db/database_rewinder_test.sqlite3' : 'database_rewinder_test')}
|
70
70
|
|
71
71
|
connection = ::ActiveRecord::Base.connection
|
72
72
|
DatabaseRewinder.record_inserted_table(connection, sql)
|
data/test/db/.keep
ADDED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_rewinder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akira Matsuda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- test/cleaner_test.rb
|
139
139
|
- test/config/database.yml
|
140
140
|
- test/database_rewinder_test.rb
|
141
|
+
- test/db/.keep
|
141
142
|
- test/fake_app.rb
|
142
143
|
- test/test_helper.rb
|
143
144
|
homepage: https://github.com/amatsuda/database_rewinder
|
@@ -152,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
153
|
requirements:
|
153
154
|
- - ">="
|
154
155
|
- !ruby/object:Gem::Version
|
155
|
-
version:
|
156
|
+
version: 2.0.0
|
156
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
158
|
requirements:
|
158
159
|
- - ">="
|
@@ -169,5 +170,6 @@ test_files:
|
|
169
170
|
- test/cleaner_test.rb
|
170
171
|
- test/config/database.yml
|
171
172
|
- test/database_rewinder_test.rb
|
173
|
+
- test/db/.keep
|
172
174
|
- test/fake_app.rb
|
173
175
|
- test/test_helper.rb
|