database_rewinder 0.9.8 → 1.0.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/main.yml +69 -15
- data/Gemfile +1 -0
- data/README.md +2 -2
- data/database_rewinder.gemspec +1 -1
- data/lib/database_rewinder/active_record_monkey.rb +22 -50
- data/lib/database_rewinder/multiple_statements_executor.rb +7 -7
- data/lib/database_rewinder.rb +15 -2
- data/test/database_rewinder_test.rb +26 -8
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fba90991ea75253ed37624e82b4f6c26ae379f4c3b1d24a522192befb8529757
|
|
4
|
+
data.tar.gz: 70c3c776b0e291b49a873e503f4111cb537e9685479176527cd94de9a663cff2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 457ed185619931c3aba3c9dd0b1a03b2156e712bfae655300d737bb1ac54ccc86a2d0256878ca7e765a2bd55e8798f6a855a9420eb5c2b8123cbd68b1298646b
|
|
7
|
+
data.tar.gz: ad40ddaa9b69d852a3001d60c6673dcd335a4171c7c77d05245b94f0c022a71a33bef1c323d7ddc6c1297498ea18ad52037ea78f8c17335a15d7a280fcf378a8
|
data/.github/workflows/main.yml
CHANGED
|
@@ -6,7 +6,7 @@ jobs:
|
|
|
6
6
|
build:
|
|
7
7
|
services:
|
|
8
8
|
postgres:
|
|
9
|
-
image: postgres:
|
|
9
|
+
image: postgres:12
|
|
10
10
|
env:
|
|
11
11
|
POSTGRES_USER: postgres
|
|
12
12
|
POSTGRES_PASSWORD: postgres
|
|
@@ -27,30 +27,83 @@ jobs:
|
|
|
27
27
|
|
|
28
28
|
matrix:
|
|
29
29
|
db: [sqlite3, postgresql, mysql]
|
|
30
|
-
ruby_version: [ruby-head, '3.
|
|
31
|
-
rails_version: [edge, '7.
|
|
30
|
+
ruby_version: [ruby-head, '3.3', '3.2', '3.1']
|
|
31
|
+
rails_version: [edge, '7.1', '7.0', '6.1']
|
|
32
32
|
|
|
33
33
|
exclude:
|
|
34
|
-
- ruby_version:
|
|
35
|
-
rails_version:
|
|
34
|
+
- ruby_version: ruby-head
|
|
35
|
+
rails_version: '6.1'
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
include:
|
|
38
|
+
- ruby_version: '3.0'
|
|
39
|
+
rails_version: '7.1'
|
|
40
|
+
db: sqlite3
|
|
41
|
+
- ruby_version: '3.0'
|
|
42
|
+
rails_version: '7.1'
|
|
43
|
+
db: postgresql
|
|
44
|
+
- ruby_version: '3.0'
|
|
45
|
+
rails_version: '7.1'
|
|
46
|
+
db: mysql
|
|
47
|
+
|
|
48
|
+
- ruby_version: '2.7'
|
|
49
|
+
rails_version: '7.1'
|
|
50
|
+
db: sqlite3
|
|
51
|
+
- ruby_version: '2.7'
|
|
52
|
+
rails_version: '7.1'
|
|
53
|
+
db: postgresql
|
|
54
|
+
- ruby_version: '2.7'
|
|
55
|
+
rails_version: '7.1'
|
|
56
|
+
db: mysql
|
|
57
|
+
|
|
58
|
+
- ruby_version: '2.7'
|
|
59
|
+
rails_version: '7.0'
|
|
60
|
+
db: sqlite3
|
|
61
|
+
- ruby_version: '2.7'
|
|
38
62
|
rails_version: '7.0'
|
|
63
|
+
db: postgresql
|
|
64
|
+
- ruby_version: '2.7'
|
|
65
|
+
rails_version: '7.0'
|
|
66
|
+
db: mysql
|
|
39
67
|
|
|
40
|
-
- ruby_version:
|
|
68
|
+
- ruby_version: '3.0'
|
|
69
|
+
rails_version: '6.1'
|
|
70
|
+
db: sqlite3
|
|
71
|
+
- ruby_version: '3.0'
|
|
72
|
+
rails_version: '6.1'
|
|
73
|
+
db: postgresql
|
|
74
|
+
- ruby_version: '3.0'
|
|
41
75
|
rails_version: '6.1'
|
|
76
|
+
db: mysql
|
|
42
77
|
|
|
43
|
-
- ruby_version:
|
|
78
|
+
- ruby_version: '2.6'
|
|
79
|
+
rails_version: '6.1'
|
|
80
|
+
db: sqlite3
|
|
81
|
+
- ruby_version: '2.6'
|
|
82
|
+
rails_version: '6.1'
|
|
83
|
+
db: postgresql
|
|
84
|
+
- ruby_version: '2.6'
|
|
85
|
+
rails_version: '6.1'
|
|
86
|
+
db: mysql
|
|
87
|
+
|
|
88
|
+
- ruby_version: '2.7'
|
|
44
89
|
rails_version: '6.0'
|
|
45
|
-
|
|
90
|
+
db: sqlite3
|
|
91
|
+
- ruby_version: '2.7'
|
|
92
|
+
rails_version: '6.0'
|
|
93
|
+
db: postgresql
|
|
94
|
+
- ruby_version: '2.7'
|
|
46
95
|
rails_version: '6.0'
|
|
96
|
+
db: mysql
|
|
47
97
|
|
|
48
|
-
- ruby_version:
|
|
98
|
+
- ruby_version: '2.7'
|
|
49
99
|
rails_version: '5.2'
|
|
50
|
-
|
|
100
|
+
db: sqlite3
|
|
101
|
+
- ruby_version: '2.7'
|
|
51
102
|
rails_version: '5.2'
|
|
52
|
-
|
|
53
|
-
|
|
103
|
+
db: postgresql
|
|
104
|
+
- ruby_version: '2.7'
|
|
105
|
+
rails_version: '5.2'
|
|
106
|
+
db: mysql
|
|
54
107
|
- ruby_version: '2.4'
|
|
55
108
|
rails_version: '5.2'
|
|
56
109
|
db: sqlite3
|
|
@@ -91,18 +144,19 @@ jobs:
|
|
|
91
144
|
rails_version: '4.2'
|
|
92
145
|
db: mysql
|
|
93
146
|
|
|
94
|
-
runs-on: ubuntu-
|
|
147
|
+
runs-on: ubuntu-20.04
|
|
95
148
|
|
|
96
149
|
env:
|
|
97
150
|
RAILS_VERSION: ${{ matrix.rails_version }}
|
|
98
151
|
DB: ${{ matrix.db }}
|
|
99
152
|
|
|
100
153
|
steps:
|
|
101
|
-
- uses: actions/checkout@
|
|
154
|
+
- uses: actions/checkout@v4
|
|
102
155
|
|
|
103
156
|
- uses: ruby/setup-ruby@v1
|
|
104
157
|
with:
|
|
105
158
|
ruby-version: ${{ matrix.ruby_version }}
|
|
159
|
+
rubygems: ${{ matrix.ruby_version < '2.6' && 'default' || 'latest' }}
|
|
106
160
|
bundler: ${{ startsWith(matrix.rails_version, '4.') && '1' || 'latest' }}
|
|
107
161
|
bundler-cache: true
|
|
108
162
|
continue-on-error: ${{ (matrix.ruby_version == 'ruby-head') || (matrix.allow_failures == 'true') }}
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -23,9 +23,9 @@ This strategy was originally devised and implemented by Shingo Morita (@eudoxa)
|
|
|
23
23
|
|
|
24
24
|
## Supported versions
|
|
25
25
|
|
|
26
|
-
* ActiveRecord 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0 (edge)
|
|
26
|
+
* ActiveRecord 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2 (edge)
|
|
27
27
|
|
|
28
|
-
* Ruby 2.4, 2.5, 2.6, 2.7, 3.0, 3.1 (trunk)
|
|
28
|
+
* Ruby 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3 (trunk)
|
|
29
29
|
|
|
30
30
|
## Installation
|
|
31
31
|
|
data/database_rewinder.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = "database_rewinder"
|
|
9
|
-
spec.version = '0.
|
|
9
|
+
spec.version = '1.0.0'
|
|
10
10
|
spec.authors = ["Akira Matsuda"]
|
|
11
11
|
spec.email = ["ronnie@dio.jp"]
|
|
12
12
|
spec.description = "A minimalist's tiny and ultra-fast database cleaner for Active Record"
|
|
@@ -2,57 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
module DatabaseRewinder
|
|
4
4
|
module InsertRecorder
|
|
5
|
-
module Execute
|
|
6
|
-
module NoKwargs
|
|
7
|
-
def execute(sql, *)
|
|
8
|
-
DatabaseRewinder.record_inserted_table self, sql
|
|
9
|
-
super
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
module WithKwargs
|
|
14
|
-
def execute(sql, *, **)
|
|
15
|
-
DatabaseRewinder.record_inserted_table self, sql
|
|
16
|
-
super
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def raw_execute(sql, *, **)
|
|
20
|
-
DatabaseRewinder.record_inserted_table self, sql
|
|
21
|
-
super
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
module ExecQuery
|
|
27
|
-
module NoKwargs
|
|
28
|
-
def exec_query(sql, *)
|
|
29
|
-
DatabaseRewinder.record_inserted_table self, sql
|
|
30
|
-
super
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
module WithKwargs
|
|
35
|
-
def exec_query(sql, *, **)
|
|
36
|
-
DatabaseRewinder.record_inserted_table self, sql
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
5
|
# This method actually no longer has to be a `prepended` hook because InsertRecorder is a module without a direct method now, but still doing this just for compatibility
|
|
43
6
|
def self.prepended(mod)
|
|
44
|
-
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
7
|
+
[:execute, :exec_query, :internal_exec_query].each do |method_name|
|
|
8
|
+
if mod.instance_methods.include?(method_name) && (meth = mod.instance_method(method_name))
|
|
9
|
+
method_body = if meth.parameters.any? {|type, _name| [:key, :keyreq, :keyrest].include? type }
|
|
10
|
+
<<-RUBY
|
|
11
|
+
def #{method_name}(sql, *, **)
|
|
12
|
+
DatabaseRewinder.record_inserted_table self, sql
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
RUBY
|
|
16
|
+
else
|
|
17
|
+
<<-RUBY
|
|
18
|
+
def #{method_name}(sql, *)
|
|
19
|
+
DatabaseRewinder.record_inserted_table self, sql
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
RUBY
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
mod.send :prepend, Module.new { class_eval method_body }
|
|
56
26
|
end
|
|
57
27
|
end
|
|
58
28
|
end
|
|
@@ -62,7 +32,9 @@ end
|
|
|
62
32
|
|
|
63
33
|
# Already loaded adapters (SQLite3Adapter, PostgreSQLAdapter, AbstractMysqlAdapter, and possibly another third party adapter)
|
|
64
34
|
::ActiveRecord::ConnectionAdapters::AbstractAdapter.descendants.each do |adapter|
|
|
65
|
-
#
|
|
35
|
+
# In order not to touch AbstractMysqlAdapter thing, but to surely patch the concrete classes
|
|
36
|
+
next if adapter.descendants.any?
|
|
37
|
+
|
|
66
38
|
adapter.send :prepend, DatabaseRewinder::InsertRecorder unless adapter < DatabaseRewinder::InsertRecorder
|
|
67
39
|
end
|
|
68
40
|
|
|
@@ -12,18 +12,18 @@ module DatabaseRewinder
|
|
|
12
12
|
#TODO Use ADAPTER_NAME when we've dropped AR 4.1 support
|
|
13
13
|
case self.class.name
|
|
14
14
|
when 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
|
|
15
|
-
disable_referential_integrity { log(sql) { @connection.exec sql } }
|
|
15
|
+
disable_referential_integrity { log(sql) { (@raw_connection || @connection).exec sql } }
|
|
16
16
|
when 'ActiveRecord::ConnectionAdapters::Mysql2Adapter'
|
|
17
|
-
if @connection.query_options[:connect_flags] & Mysql2::Client::MULTI_STATEMENTS != 0
|
|
17
|
+
if (@raw_connection || @connection).query_options[:connect_flags] & Mysql2::Client::MULTI_STATEMENTS != 0
|
|
18
18
|
disable_referential_integrity do
|
|
19
|
-
_result = log(sql) { @connection.query sql }
|
|
20
|
-
while @connection.next_result
|
|
19
|
+
_result = log(sql) { (@raw_connection || @connection).query sql }
|
|
20
|
+
while (@raw_connection || @connection).next_result
|
|
21
21
|
# just to make sure that all queries are finished
|
|
22
|
-
_result = @connection.store_result
|
|
22
|
+
_result = (@raw_connection || @connection).store_result
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
else
|
|
26
|
-
query_options = @connection.query_options.dup
|
|
26
|
+
query_options = (@raw_connection || @connection).query_options.dup
|
|
27
27
|
query_options[:connect_flags] |= Mysql2::Client::MULTI_STATEMENTS
|
|
28
28
|
# opens another connection to the DB
|
|
29
29
|
client = Mysql2::Client.new query_options
|
|
@@ -40,7 +40,7 @@ module DatabaseRewinder
|
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
when 'ActiveRecord::ConnectionAdapters::SQLite3Adapter'
|
|
43
|
-
disable_referential_integrity { log(sql) { @connection.execute_batch sql } }
|
|
43
|
+
disable_referential_integrity { log(sql) { (@raw_connection || @connection).execute_batch sql } }
|
|
44
44
|
else
|
|
45
45
|
raise 'Multiple deletion is not supported with the current database adapter.'
|
|
46
46
|
end
|
data/lib/database_rewinder.rb
CHANGED
|
@@ -22,6 +22,8 @@ module DatabaseRewinder
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def [](connection)
|
|
25
|
+
init unless defined? @cleaners
|
|
26
|
+
|
|
25
27
|
@cleaners.detect {|c| c.connection_name == connection} || create_cleaner(connection)
|
|
26
28
|
end
|
|
27
29
|
|
|
@@ -75,9 +77,20 @@ module DatabaseRewinder
|
|
|
75
77
|
def all_table_names(connection)
|
|
76
78
|
cache_key = get_cache_key(connection.pool)
|
|
77
79
|
#NOTE connection.tables warns on AR 5 with some adapters
|
|
78
|
-
tables =
|
|
80
|
+
tables =
|
|
81
|
+
if Rails.application.respond_to?(:deprecators) # AR >= 7.1
|
|
82
|
+
Rails.application.deprecators.silence { connection.tables }
|
|
83
|
+
else
|
|
84
|
+
ActiveSupport::Deprecation.silence { connection.tables }
|
|
85
|
+
end
|
|
86
|
+
schema_migraion_table_name =
|
|
87
|
+
if ActiveRecord::SchemaMigration.respond_to?(:table_name)
|
|
88
|
+
ActiveRecord::SchemaMigration.table_name
|
|
89
|
+
else
|
|
90
|
+
ActiveRecord::SchemaMigration.new(connection).table_name # AR >= 7.1
|
|
91
|
+
end
|
|
79
92
|
@table_names_cache[cache_key] ||= tables.reject do |t|
|
|
80
|
-
(t ==
|
|
93
|
+
(t == schema_migraion_table_name) ||
|
|
81
94
|
(ActiveRecord::Base.respond_to?(:internal_metadata_table_name) && (t == ActiveRecord::Base.internal_metadata_table_name))
|
|
82
95
|
end
|
|
83
96
|
end
|
|
@@ -209,16 +209,34 @@ class DatabaseRewinder::DatabaseRewinderTest < ActiveSupport::TestCase
|
|
|
209
209
|
|
|
210
210
|
if ActiveRecord::VERSION::MAJOR >= 4
|
|
211
211
|
sub_test_case 'migrations' do
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
if ActiveRecord::VERSION::STRING >= '7.1'
|
|
213
|
+
test '.clean_all should not touch AR::SchemaMigration' do
|
|
214
|
+
schema_migration = ActiveRecord::SchemaMigration.new(ActiveRecord::Base.connection)
|
|
215
|
+
schema_migration.create_table
|
|
216
|
+
|
|
217
|
+
begin
|
|
218
|
+
schema_migration.create_version '001'
|
|
219
|
+
DatabaseRewinder.clean_all
|
|
220
|
+
|
|
221
|
+
assert_equal 0, Foo.count
|
|
222
|
+
assert_equal 1, schema_migration.count
|
|
223
|
+
ensure
|
|
224
|
+
schema_migration.drop_table
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
else
|
|
228
|
+
test '.clean_all should not touch AR::SchemaMigration' do
|
|
214
229
|
ActiveRecord::SchemaMigration.create_table
|
|
215
|
-
ActiveRecord::SchemaMigration.create! version: '001'
|
|
216
|
-
DatabaseRewinder.clean_all
|
|
217
230
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
231
|
+
begin
|
|
232
|
+
ActiveRecord::SchemaMigration.create! version: '001'
|
|
233
|
+
DatabaseRewinder.clean_all
|
|
234
|
+
|
|
235
|
+
assert_equal 0, Foo.count
|
|
236
|
+
assert_equal 1, ActiveRecord::SchemaMigration.count
|
|
237
|
+
ensure
|
|
238
|
+
ActiveRecord::SchemaMigration.drop_table
|
|
239
|
+
end
|
|
222
240
|
end
|
|
223
241
|
end
|
|
224
242
|
end
|
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: 1.0.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:
|
|
11
|
+
date: 2024-01-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
113
113
|
- !ruby/object:Gem::Version
|
|
114
114
|
version: '0'
|
|
115
115
|
requirements: []
|
|
116
|
-
rubygems_version: 3.
|
|
116
|
+
rubygems_version: 3.6.0.dev
|
|
117
117
|
signing_key:
|
|
118
118
|
specification_version: 4
|
|
119
119
|
summary: A minimalist's tiny and ultra-fast database cleaner
|