octoshark 0.2.1 → 0.2.2
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/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:
|