octoshark 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +71 -28
- data/Rakefile +3 -3
- data/lib/octoshark/active_record_extensions.rb +16 -28
- data/lib/octoshark/connection_pools_manager.rb +1 -1
- data/lib/octoshark/version.rb +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a5b422e9a70b5d3ea461f8f1d60d00fdf95fcc2
|
4
|
+
data.tar.gz: 67b85692596f3c3414239b4820a0415e40c09af4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41d351c20e433d40caa1f3e1888360911a8440a03aeded1092d618b78b91febbf6f3a8cdffc8e537ee6cf482d017500a495019191902a6f77904c165c236e099
|
7
|
+
data.tar.gz: a1f0f8e84cd69a8445e5ce0e6c9abcb53ac1a9b144d7141f8e36ea3596a2ec15c639a6515da9df8554f3e37066aa3368bae76794d2b990ed88ca542b197a96ed
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -163,7 +163,7 @@ When using `Octoshark::ConnectionPoolsManager`, whenever ActiveRecord::Base call
|
|
163
163
|
|
164
164
|
## Cleaning test databases
|
165
165
|
|
166
|
-
|
166
|
+
For `Octoshark::ConnectionPoolsManager`, we can use [DatabaseCleaner](https://github.com/DatabaseCleaner/database_cleaner) and RSpec like:
|
167
167
|
|
168
168
|
```ruby
|
169
169
|
config.before(:suite) do
|
@@ -177,7 +177,6 @@ config.before(:each) do
|
|
177
177
|
end
|
178
178
|
|
179
179
|
config.after(:each) do
|
180
|
-
setup_database_cleaner
|
181
180
|
DatabaseCleaner.clean_with(:transaction)
|
182
181
|
end
|
183
182
|
|
@@ -191,49 +190,93 @@ def setup_database_cleaner
|
|
191
190
|
end
|
192
191
|
```
|
193
192
|
|
194
|
-
|
193
|
+
For `Octoshark::ConnectionManager` where connections and databases are dynamically created and cannot be configured in the test setup, we can write a custom database cleaner inspired by [DatabaseRewinder](https://github.com/amatsuda/database_rewinder). The example below is for a multi-tenant test setup with a main (core) database and a tenant database for the `CURRENT_USER` in the test suite. `CustomDatabaseCleaner.clean_all` cleans all core database tables before test suite and `CustomDatabaseCleaner.clean` cleans used tables in both core and tenant databases after each test.
|
194
|
+
|
195
195
|
|
196
196
|
```ruby
|
197
|
-
module
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
197
|
+
module CustomDatabaseCleaner
|
198
|
+
INSERT_REGEX = /\AINSERT(?:\s+IGNORE)?\s+INTO\s+(?:\.*[`"]?(?<table>[^.\s`"]+)[`"]?)*/i
|
199
|
+
|
200
|
+
@@tables_with_inserts = []
|
201
|
+
|
202
|
+
class << self
|
203
|
+
def record_inserted_table(connection, sql)
|
204
|
+
match = sql.match(INSERT_REGEX)
|
205
|
+
|
206
|
+
if match && match[:table] && tables_with_inserts.exclude?(match[:table])
|
207
|
+
tables_with_inserts << match[:table]
|
208
|
+
end
|
202
209
|
end
|
203
210
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
211
|
+
def clean_all
|
212
|
+
with_core_db_connection do |connection|
|
213
|
+
clean_tables(connection)
|
214
|
+
end
|
215
|
+
|
216
|
+
reset_tables_with_inserts
|
207
217
|
end
|
208
|
-
end
|
209
218
|
|
210
|
-
|
219
|
+
def clean
|
220
|
+
with_core_db_connection do |connection|
|
221
|
+
clean_tables(connection, { 'users' => [CURRENT_USER.id] })
|
222
|
+
end
|
211
223
|
|
212
|
-
|
213
|
-
|
214
|
-
|
224
|
+
CURRENT_USER.with_tenant do |connection|
|
225
|
+
clean_tables(connection)
|
226
|
+
end
|
215
227
|
|
216
|
-
|
217
|
-
|
218
|
-
tables << match[1] if match && !tables.include?(match[1])
|
219
|
-
end
|
228
|
+
reset_tables_with_inserts
|
229
|
+
end
|
220
230
|
|
221
|
-
|
222
|
-
|
223
|
-
(
|
224
|
-
|
225
|
-
|
231
|
+
private
|
232
|
+
def with_core_db_connection(&block)
|
233
|
+
CoreDBManager.with_connection(ActiveRecord::Base.configurations[Rails.env].symbolize_keys, &block)
|
234
|
+
end
|
235
|
+
|
236
|
+
def clean_tables(connection, keep_data = {})
|
237
|
+
tables_to_clean = connection.tables.reject { |t| t == ActiveRecord::Migrator.schema_migrations_table_name }
|
238
|
+
tables_to_clean = tables_to_clean & tables_with_inserts if tables_with_inserts.present?
|
239
|
+
|
240
|
+
tables_to_clean.each do |table|
|
226
241
|
connection.disable_referential_integrity do
|
227
|
-
|
242
|
+
table_name = connection.quote_table_name(table)
|
243
|
+
keep_ids = keep_data[table]
|
244
|
+
|
245
|
+
if keep_ids
|
246
|
+
connection.execute("DELETE FROM #{table_name} WHERE id NOT IN (#{keep_ids.join(',')});")
|
247
|
+
else
|
248
|
+
connection.execute("DELETE FROM #{table_name};")
|
249
|
+
end
|
228
250
|
end
|
229
251
|
end
|
230
252
|
end
|
231
|
-
|
253
|
+
|
254
|
+
def reset_tables_with_inserts
|
255
|
+
@@tables_with_inserts = []
|
256
|
+
end
|
257
|
+
|
258
|
+
def tables_with_inserts
|
259
|
+
@@tables_with_inserts
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
module CustomDatabaseCleaner
|
265
|
+
module InsertRecorder
|
266
|
+
def execute(sql, *)
|
267
|
+
CustomDatabaseCleaner.record_inserted_table(self, sql)
|
268
|
+
super
|
269
|
+
end
|
270
|
+
|
271
|
+
def exec_query(sql, *)
|
272
|
+
CustomDatabaseCleaner.record_inserted_table(self, sql)
|
273
|
+
super
|
274
|
+
end
|
232
275
|
end
|
233
276
|
end
|
234
277
|
|
235
278
|
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
236
|
-
ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.send(:prepend,
|
279
|
+
ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.send(:prepend, CustomDatabaseCleaner::InsertRecorder)
|
237
280
|
```
|
238
281
|
|
239
282
|
|
data/Rakefile
CHANGED
@@ -10,9 +10,9 @@ task :default => :spec
|
|
10
10
|
|
11
11
|
namespace :db do
|
12
12
|
task :establish_connection do
|
13
|
-
configs = YAML.load_file('spec/support/config.yml')
|
14
|
-
config = configs[
|
15
|
-
@databases = configs.map { |_, config| config[
|
13
|
+
configs = YAML.load_file('spec/support/config.yml')
|
14
|
+
config = configs['db1'].reject { |k, v| k == 'database' }
|
15
|
+
@databases = configs.map { |_, config| config['database'] }
|
16
16
|
ActiveRecord::Base.establish_connection(config)
|
17
17
|
end
|
18
18
|
|
@@ -1,43 +1,31 @@
|
|
1
1
|
module Octoshark
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class << self
|
7
|
-
alias_method_chain :establish_connection, :octoshark
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
# When a connection is established in an ancestor process that must have
|
13
|
-
# subsequently forked, ActiveRecord establishes a new connection because
|
14
|
-
# it can't reuse the existing one. When that happens, we need to reconnect
|
15
|
-
# Octoshark connection managers.
|
16
|
-
def establish_connection_with_octoshark(*args)
|
17
|
-
establish_connection_without_octoshark(*args)
|
18
|
-
Octoshark::ConnectionPoolsManager.reset_connection_managers!
|
19
|
-
end
|
2
|
+
module ConnectionHandler
|
3
|
+
def establish_connection(*args)
|
4
|
+
Octoshark::ConnectionPoolsManager.reset_connection_managers!
|
5
|
+
super(*args)
|
20
6
|
end
|
21
7
|
end
|
22
8
|
|
23
9
|
module ActiveRecordAbstractAdapter
|
24
|
-
extend ActiveSupport::Concern
|
25
|
-
|
26
10
|
attr_accessor :connection_name, :database_name
|
27
11
|
|
28
|
-
|
29
|
-
alias_method_chain :log, :octoshark
|
30
|
-
end
|
31
|
-
|
32
|
-
def log_with_octoshark(sql, name = "SQL", *other_args, &block)
|
12
|
+
def log(sql, name = "SQL", *other_args, &block)
|
33
13
|
if connection_name || database_name
|
34
14
|
name = "[Octoshark: #{[connection_name, database_name].compact.join(' ')}] #{name}"
|
35
15
|
end
|
36
16
|
|
37
|
-
|
17
|
+
super(sql, name, *other_args, &block)
|
38
18
|
end
|
39
19
|
end
|
40
20
|
end
|
41
21
|
|
42
|
-
ActiveRecord::
|
43
|
-
|
22
|
+
if defined?(ActiveRecord::ConnectionAdapters::ConnectionHandler)
|
23
|
+
# Rails 3.2, 4.0, 4.1, 4.2, 5.0
|
24
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, Octoshark::ConnectionHandler)
|
25
|
+
else
|
26
|
+
# Rails 3.0 and 3.1 does not lazy load
|
27
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
28
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, Octoshark::ConnectionHandler)
|
29
|
+
end
|
30
|
+
|
31
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:prepend, Octoshark::ActiveRecordAbstractAdapter)
|
data/lib/octoshark/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: octoshark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dalibor Nasevic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -181,4 +181,3 @@ test_files:
|
|
181
181
|
- spec/support/config.yml.template
|
182
182
|
- spec/support/config.yml.travis
|
183
183
|
- spec/support/helpers.rb
|
184
|
-
has_rdoc:
|