database_recorder 0.1.0 → 0.1.1
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/README.md +40 -8
- data/lib/database_recorder/active_record/abstract_adapter_ext.rb +13 -0
- data/lib/database_recorder/{activerecord → active_record}/base_ext.rb +0 -0
- data/lib/database_recorder/{activerecord → active_record}/recorded_result.rb +0 -0
- data/lib/database_recorder/{activerecord/abstract_adapter_ext.rb → active_record/recorder.rb} +23 -8
- data/lib/database_recorder/config.rb +26 -10
- data/lib/database_recorder/core.rb +10 -8
- data/lib/database_recorder/mysql2/client_ext.rb +19 -0
- data/lib/database_recorder/mysql2/recorded_result.rb +3 -1
- data/lib/database_recorder/mysql2/recorder.rb +40 -37
- data/lib/database_recorder/mysql2/statement_ext.rb +13 -0
- data/lib/database_recorder/pg/connection_ext.rb +53 -0
- data/lib/database_recorder/pg/recorder.rb +23 -67
- data/lib/database_recorder/recording.rb +7 -2
- data/lib/database_recorder/rspec.rb +1 -2
- data/lib/database_recorder/storage/base.rb +12 -0
- data/lib/database_recorder/storage/file.rb +2 -7
- data/lib/database_recorder/storage/redis.rb +1 -6
- data/lib/database_recorder/version.rb +1 -1
- data/lib/database_recorder.rb +12 -12
- metadata +10 -6
- data/lib/database_recorder/activerecord/recorder.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd8b63b3fa1b57dd6c2c5cdf501af590f75a5fcb52c322bc4eee702c55026db6
|
4
|
+
data.tar.gz: f2753254f7c7d79ef0fd7dd65e3439197419ae01d96e4625eb3a9f4632835bd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 343167b893fd491b57405ad465e1b835fcf077d3cc806a4c3a4e6ca7c1253e0967acca90760c30e395de30aa8529421305910f9714879f118892259acf03dbe7
|
7
|
+
data.tar.gz: a2f8defdbd1e9f251afd6c999077870689c20f9c7868cc5d01a2947ab63c3ee1eec2c5401b14eef1378e450dbeb2fb170f93d011e54f8c8e677c150394f0b024
|
data/README.md
CHANGED
@@ -1,34 +1,66 @@
|
|
1
1
|
# Database Recorder
|
2
|
+
[](https://badge.fury.io/rb/database_recorder)
|
3
|
+
[](https://github.com/blocknotes/database_recorder/actions/workflows/linters.yml)
|
4
|
+
[](https://github.com/blocknotes/database_recorder/actions/workflows/specs_active_record.yml)
|
5
|
+
[](https://github.com/blocknotes/database_recorder/actions/workflows/specs_mysql.yml)
|
6
|
+
[](https://github.com/blocknotes/database_recorder/actions/workflows/specs_postgres.yml)
|
2
7
|
|
3
|
-
Record database queries for testing and development purposes
|
4
|
-
|
8
|
+
Record database queries for testing and development purposes.
|
9
|
+
Supports only RSpec at the moment. Store queries information on files or Redis.
|
5
10
|
|
6
11
|
Main features:
|
7
12
|
- store the history of the queries of a test when it run (for monitoring);
|
8
13
|
- eventually check if the current queries match the recorded ones (to prevent regressions);
|
9
14
|
- [EXPERIMENTAL] optionally replay the recorded queries replacing the original requests.
|
10
15
|
|
11
|
-
|
16
|
+
Sample output: [test.yml](extra/sample.yml)
|
12
17
|
|
13
18
|
## Install
|
14
19
|
|
15
|
-
- Add to your Gemfile: `gem 'database_recorder'` (:development, :test groups recommended)
|
16
|
-
-
|
17
|
-
+ Add to the `spec_helper.rb` (or rails_helper): `DatabaseRecorder::RSpec.setup`
|
18
|
-
+ In RSpec examples: add `:dbr` metadata
|
19
|
-
+ To verify the matching with the recorded query use: `dbr: { verify_queries: true }`
|
20
|
+
- Add to your Gemfile: `gem 'database_recorder', require: false` (:development, :test groups recommended)
|
21
|
+
- Using RSpec, add in **rails_helper.rb**:
|
20
22
|
|
21
23
|
```rb
|
24
|
+
require 'database_recorder'
|
25
|
+
DatabaseRecorder::RSpec.setup
|
26
|
+
```
|
27
|
+
|
28
|
+
- In the tests add `:dbr` metadata, examples:
|
29
|
+
|
30
|
+
```rb
|
31
|
+
# Activate DatabaseRecorder with the default options
|
22
32
|
it 'returns 3 posts', :dbr do
|
23
33
|
# ...
|
24
34
|
end
|
35
|
+
|
36
|
+
# Verify queries comparing with the stored ones:
|
37
|
+
it 'returns more posts', dbr: { verify_queries: true } do
|
38
|
+
# ...
|
39
|
+
end
|
25
40
|
```
|
26
41
|
|
42
|
+
Or eventually apply the metadata per path:
|
43
|
+
|
44
|
+
```rb
|
45
|
+
RSpec.configure do |config|
|
46
|
+
config.define_derived_metadata(file_path: %r{/spec/models/}) do |metadata|
|
47
|
+
metadata[:dbr] = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
Using an environment variable to enable it:
|
53
|
+
|
54
|
+

|
55
|
+
|
27
56
|
## Config
|
28
57
|
|
29
58
|
Add to your _spec_helper.rb_:
|
30
59
|
|
31
60
|
```rb
|
61
|
+
# Database driver to use: :active_record | :mysql2 | :pg
|
62
|
+
DatabaseRecorder::Config.db_driver = :pg
|
63
|
+
|
32
64
|
# To print the queries while executing the specs: false | true | :color
|
33
65
|
DatabaseRecorder::Config.print_queries = true
|
34
66
|
|
File without changes
|
File without changes
|
data/lib/database_recorder/{activerecord/abstract_adapter_ext.rb → active_record/recorder.rb}
RENAMED
@@ -2,12 +2,17 @@
|
|
2
2
|
|
3
3
|
module DatabaseRecorder
|
4
4
|
module ActiveRecord
|
5
|
-
module
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
module Recorder
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def ignore_query?(sql, name)
|
9
|
+
!Recording.started? ||
|
10
|
+
%w[schema transaction].include?(name&.downcase) ||
|
11
|
+
sql.downcase.match?(/\A(begin|commit|release|rollback|savepoint)/i)
|
12
|
+
end
|
13
|
+
|
14
|
+
def record(adapter, sql, name = 'SQL', binds = [], type_casted_binds = [], *args)
|
15
|
+
return yield if ignore_query?(sql, name)
|
11
16
|
|
12
17
|
Core.log_query(sql, name)
|
13
18
|
if Config.replay_recordings && Recording.from_cache
|
@@ -17,9 +22,9 @@ module DatabaseRecorder
|
|
17
22
|
|
18
23
|
RecordedResult.new(data['result']['fields'], data['result']['values'])
|
19
24
|
else
|
20
|
-
|
25
|
+
yield.tap do |result|
|
21
26
|
result_data =
|
22
|
-
if result.
|
27
|
+
if result && (result.respond_to?(:fields) || result.respond_to?(:columns))
|
23
28
|
fields = result.respond_to?(:fields) ? result.fields : result.columns
|
24
29
|
values = result.respond_to?(:values) ? result.values : result.to_a
|
25
30
|
{ 'count' => result.count, 'fields' => fields, 'values' => values }
|
@@ -28,6 +33,16 @@ module DatabaseRecorder
|
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
36
|
+
|
37
|
+
def setup
|
38
|
+
::ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
39
|
+
prepend AbstractAdapterExt
|
40
|
+
end
|
41
|
+
|
42
|
+
# ::ActiveRecord::Base.class_eval do
|
43
|
+
# prepend BaseExt
|
44
|
+
# end
|
45
|
+
end
|
31
46
|
end
|
32
47
|
end
|
33
48
|
end
|
@@ -7,28 +7,44 @@ module DatabaseRecorder
|
|
7
7
|
class Config
|
8
8
|
include Singleton
|
9
9
|
|
10
|
+
DEFAULT_DB_DRIVER = :active_record
|
11
|
+
DEFAULT_STORAGE = DatabaseRecorder::Storage::File
|
12
|
+
|
13
|
+
DB_DRIVER_VALUES = %i[active_record mysql2 pg].freeze
|
14
|
+
PRINT_QUERIES_VALUES = [false, true, :color].freeze
|
15
|
+
STORAGE_VALUES = {
|
16
|
+
file: DatabaseRecorder::Storage::File,
|
17
|
+
redis: DatabaseRecorder::Storage::Redis
|
18
|
+
}.freeze
|
19
|
+
|
10
20
|
attr_accessor :db_driver, :print_queries, :replay_recordings, :storage
|
11
21
|
|
12
22
|
class << self
|
13
23
|
extend Forwardable
|
14
24
|
|
15
|
-
def_delegators :instance, :db_driver, :
|
16
|
-
:replay_recordings=, :storage
|
25
|
+
def_delegators :instance, :db_driver, :print_queries, :replay_recordings, :replay_recordings=, :storage
|
17
26
|
|
18
27
|
def load_defaults
|
19
|
-
instance.db_driver =
|
20
|
-
instance.print_queries = false
|
28
|
+
instance.db_driver = DEFAULT_DB_DRIVER
|
29
|
+
instance.print_queries = false
|
21
30
|
instance.replay_recordings = false
|
22
|
-
|
31
|
+
instance.storage = DEFAULT_STORAGE
|
32
|
+
end
|
33
|
+
|
34
|
+
def db_driver=(value)
|
35
|
+
instance.db_driver = DB_DRIVER_VALUES.include?(value) ? value : DEFAULT_DB_DRIVER
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_queries=(value)
|
39
|
+
instance.print_queries = PRINT_QUERIES_VALUES.include?(value) ? value : false
|
23
40
|
end
|
24
41
|
|
25
42
|
def storage=(value)
|
26
43
|
instance.storage =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
else raise ArgumentError, "Unknown storage: #{value}"
|
44
|
+
if value.is_a?(Class) && value < Storage::Base
|
45
|
+
value
|
46
|
+
else
|
47
|
+
STORAGE_VALUES[value]
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
@@ -5,19 +5,21 @@ module DatabaseRecorder
|
|
5
5
|
module_function
|
6
6
|
|
7
7
|
def log_query(sql, source = nil)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
log =
|
9
|
+
case DatabaseRecorder::Config.print_queries
|
10
|
+
when true then "[DB] #{sql} [#{source}]"
|
11
|
+
when :color then "[DB] #{CodeRay.scan(sql, :sql).term} [#{source}]"
|
12
|
+
end
|
13
|
+
|
14
|
+
puts log if log
|
15
|
+
log
|
14
16
|
end
|
15
17
|
|
16
18
|
def setup
|
17
19
|
case DatabaseRecorder::Config.db_driver
|
18
20
|
when :active_record then ActiveRecord::Recorder.setup
|
19
|
-
when :mysql2 then Mysql2.setup
|
20
|
-
when :pg then PG.setup
|
21
|
+
when :mysql2 then Mysql2::Recorder.setup
|
22
|
+
when :pg then PG::Recorder.setup
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseRecorder
|
4
|
+
module Mysql2
|
5
|
+
module ClientExt
|
6
|
+
def query(sql, options = {})
|
7
|
+
Recorder.record(self, sql: sql) do
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare(*args)
|
13
|
+
Recorder.record(self, sql: args[0]) do
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,50 +3,53 @@
|
|
3
3
|
module DatabaseRecorder
|
4
4
|
module Mysql2
|
5
5
|
module Recorder
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def ignore_query?(sql)
|
9
|
+
!Recording.started? ||
|
10
|
+
sql == 'SELECT LAST_INSERT_ID() AS _dbr_last_insert_id' ||
|
11
|
+
sql.downcase.match?(/\A(begin|commit|release|rollback|savepoint|show full fields from)/i) ||
|
12
|
+
sql.match?(/information_schema.statistics/)
|
10
13
|
end
|
11
|
-
end
|
12
14
|
|
13
|
-
|
15
|
+
def record(adapter, sql:)
|
16
|
+
return yield if ignore_query?(sql)
|
17
|
+
|
18
|
+
Core.log_query(sql)
|
19
|
+
if Config.replay_recordings && !Recording.cache.nil?
|
20
|
+
Recording.push(sql: sql)
|
21
|
+
data = Recording.cached_query_for(sql)
|
22
|
+
return yield unless data # cache miss
|
23
|
+
|
24
|
+
RecordedResult.new.prepare(data['result'].slice('count', 'fields', 'values')) if data['result']
|
25
|
+
else
|
26
|
+
yield.tap do |result|
|
27
|
+
result_data =
|
28
|
+
if result.is_a? ::Mysql2::Result
|
29
|
+
{ 'count' => result.count, 'fields' => result.fields, 'values' => result.to_a }
|
30
|
+
# else
|
31
|
+
# last_insert_id = adapter.query('SELECT LAST_INSERT_ID() AS _dbr_last_insert_id').to_a
|
32
|
+
# { 'count' => last_insert_id.count, 'fields' => ['id'], 'values' => last_insert_id }
|
33
|
+
end
|
34
|
+
|
35
|
+
Recording.push(sql: sql, result: result_data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
14
39
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
sql.match?(/information_schema.statistics/)
|
20
|
-
end
|
40
|
+
def setup
|
41
|
+
::Mysql2::Client.class_eval do
|
42
|
+
prepend ClientExt
|
43
|
+
end
|
21
44
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Core.log_query(sql)
|
26
|
-
if Config.replay_recordings && !Recording.cache.nil?
|
27
|
-
Recording.push(sql: sql)
|
28
|
-
data = Recording.cached_query_for(sql)
|
29
|
-
return yield unless data # cache miss
|
30
|
-
|
31
|
-
RecordedResult.new.prepare(data['result'].slice('count', 'fields', 'values')) if data['result']
|
32
|
-
else
|
33
|
-
yield.tap do |result|
|
34
|
-
result_data =
|
35
|
-
if result
|
36
|
-
{ 'count' => result.count, 'fields' => result.fields, 'values' => result.to_a }
|
37
|
-
else
|
38
|
-
last_insert_id = recorder.query('SELECT LAST_INSERT_ID() AS _dbr_last_insert_id').to_a
|
39
|
-
{ 'count' => last_insert_id.count, 'fields' => ['id'], 'values' => last_insert_id }
|
40
|
-
end
|
41
|
-
|
42
|
-
Recording.push(sql: sql, result: result_data)
|
45
|
+
::Mysql2::Statement.class_eval do
|
46
|
+
prepend StatementExt
|
43
47
|
end
|
44
48
|
end
|
45
|
-
end
|
46
49
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
def update_record(adapter, *args)
|
51
|
+
Recording.update_last(*args)
|
52
|
+
yield
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatabaseRecorder
|
4
|
+
module PG
|
5
|
+
module ConnectionExt
|
6
|
+
def async_exec(sql)
|
7
|
+
Recorder.record(sql: sql, source: :async_exec) do
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def sync_exec(sql)
|
13
|
+
Recorder.record(sql: sql, source: :sync_exec) do
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def exec(*args)
|
19
|
+
Recorder.record(sql: args[0], source: :exec) do
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def query(*args)
|
25
|
+
Recorder.record(sql: args[0], source: :query) do
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def exec_params(*args)
|
31
|
+
Recorder.record(sql: args[0], binds: args[1], source: :exec_params) do
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# def async_exec_params(*args)
|
37
|
+
# puts ">>> #{args[0]}"
|
38
|
+
# super
|
39
|
+
# end
|
40
|
+
|
41
|
+
# def sync_exec_params(*args)
|
42
|
+
# puts ">>> #{args[0]}"
|
43
|
+
# super
|
44
|
+
# end
|
45
|
+
|
46
|
+
def exec_prepared(*args)
|
47
|
+
Recorder.record(sql: args[0], binds: args[1], source: :exec_prepared) do
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -3,81 +3,37 @@
|
|
3
3
|
module DatabaseRecorder
|
4
4
|
module PG
|
5
5
|
module Recorder
|
6
|
-
|
7
|
-
PG.record(sql: sql, source: :async_exec) do
|
8
|
-
super
|
9
|
-
end
|
10
|
-
end
|
6
|
+
module_function
|
11
7
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
def ignore_query?(sql)
|
9
|
+
!Recording.started? ||
|
10
|
+
sql.downcase.match?(/\A(begin|commit|release|rollback|savepoint)/i) ||
|
11
|
+
sql.match?(/ pg_attribute |SHOW max_identifier_length|SHOW search_path/)
|
16
12
|
end
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
14
|
+
def record(sql:, binds: nil, source: nil)
|
15
|
+
return yield if ignore_query?(sql)
|
16
|
+
|
17
|
+
Core.log_query(sql, source)
|
18
|
+
if Config.replay_recordings && !Recording.cache.nil?
|
19
|
+
Recording.push(sql: sql, binds: binds)
|
20
|
+
data = Recording.cached_query_for(sql)
|
21
|
+
return yield unless data # cache miss
|
22
|
+
|
23
|
+
RecordedResult.new(data['result'].slice('count', 'fields', 'values'))
|
24
|
+
else
|
25
|
+
yield.tap do |result|
|
26
|
+
result_data = result ? { 'count' => result.count, 'fields' => result.fields, 'values' => result.values } : nil
|
27
|
+
Recording.push(sql: sql, binds: binds, result: result_data)
|
28
|
+
end
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# end
|
38
|
-
|
39
|
-
# def sync_exec_params(*args)
|
40
|
-
# puts ">>> #{args[0]}"
|
41
|
-
# super
|
42
|
-
# end
|
43
|
-
|
44
|
-
def exec_prepared(*args)
|
45
|
-
PG.record(sql: args[0], binds: args[1], source: :exec_prepared) do
|
46
|
-
super
|
32
|
+
def setup
|
33
|
+
::PG::Connection.class_eval do
|
34
|
+
prepend ConnectionExt
|
47
35
|
end
|
48
36
|
end
|
49
37
|
end
|
50
|
-
|
51
|
-
module_function
|
52
|
-
|
53
|
-
def ignore_query?(sql)
|
54
|
-
!Recording.started? ||
|
55
|
-
sql.downcase.match?(/\A(begin|commit|release|rollback|savepoint)/i) ||
|
56
|
-
sql.match?(/ pg_attribute |SHOW max_identifier_length|SHOW search_path/)
|
57
|
-
end
|
58
|
-
|
59
|
-
def record(sql:, binds: nil, source: nil)
|
60
|
-
return yield if ignore_query?(sql)
|
61
|
-
|
62
|
-
Core.log_query(sql, source)
|
63
|
-
if Config.replay_recordings && !Recording.cache.nil?
|
64
|
-
Recording.push(sql: sql, binds: binds)
|
65
|
-
data = Recording.cached_query_for(sql)
|
66
|
-
return yield unless data # cache miss
|
67
|
-
|
68
|
-
RecordedResult.new(data['result'].slice('count', 'fields', 'values'))
|
69
|
-
else
|
70
|
-
yield.tap do |result|
|
71
|
-
result_data = result ? { 'count' => result.count, 'fields' => result.fields, 'values' => result.values } : nil
|
72
|
-
Recording.push(sql: sql, binds: binds, result: result_data)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def setup
|
78
|
-
::PG::Connection.class_eval do
|
79
|
-
prepend Recorder
|
80
|
-
end
|
81
|
-
end
|
82
38
|
end
|
83
39
|
end
|
@@ -20,7 +20,7 @@ module DatabaseRecorder
|
|
20
20
|
current = @search_index
|
21
21
|
match = cache[@search_index..].find do |item|
|
22
22
|
current += 1
|
23
|
-
item['sql'] == sql
|
23
|
+
item['sql'] == sql
|
24
24
|
end
|
25
25
|
return unless match
|
26
26
|
|
@@ -55,10 +55,15 @@ module DatabaseRecorder
|
|
55
55
|
result
|
56
56
|
end
|
57
57
|
|
58
|
+
def update_last(*args)
|
59
|
+
@queries.last['binds'] = args
|
60
|
+
end
|
61
|
+
|
58
62
|
class << self
|
59
63
|
extend Forwardable
|
60
64
|
|
61
|
-
def_delegators :current_instance, :cache, :cached_query_for, :from_cache, :new_entity, :pull_entity, :push
|
65
|
+
def_delegators :current_instance, :cache, :cached_query_for, :from_cache, :new_entity, :pull_entity, :push,
|
66
|
+
:queries, :update_last
|
62
67
|
|
63
68
|
def current_instance
|
64
69
|
(@@instances ||= {})[Process.pid]
|
@@ -14,8 +14,7 @@ module DatabaseRecorder
|
|
14
14
|
ref = (example.metadata[:scoped_id] || '').split(':')[-1]
|
15
15
|
options = {}
|
16
16
|
options.merge!(example.metadata[:dbr]) if example.metadata[:dbr].is_a?(Hash)
|
17
|
-
options.merge!(example: example)
|
18
|
-
options.merge!(name: "#{example.full_description}__#{ref}") # TODO: if name is already set, append ref
|
17
|
+
options.merge!(example: example, name: "#{example.full_description}__#{ref}")
|
19
18
|
Recording.new(options: options).tap do |recording|
|
20
19
|
result = recording.start { example.run }
|
21
20
|
if options[:verify_queries] && result[:stored_queries]
|
@@ -2,16 +2,11 @@
|
|
2
2
|
|
3
3
|
module DatabaseRecorder
|
4
4
|
module Storage
|
5
|
-
class File
|
6
|
-
def initialize(recording, name:)
|
7
|
-
@recording = recording
|
8
|
-
@name = name
|
9
|
-
end
|
10
|
-
|
5
|
+
class File < Base
|
11
6
|
def load
|
12
7
|
stored_data = ::File.exist?(record_file) ? ::File.read(record_file) : false
|
13
8
|
if stored_data
|
14
|
-
data = YAML.load(stored_data)
|
9
|
+
data = YAML.load(stored_data) # rubocop:disable Security/YAMLLoad
|
15
10
|
@recording.cache = data['queries']
|
16
11
|
@recording.entities = data['entities']
|
17
12
|
true
|
data/lib/database_recorder.rb
CHANGED
@@ -3,22 +3,22 @@
|
|
3
3
|
require_relative 'database_recorder/core'
|
4
4
|
|
5
5
|
if defined? ::ActiveRecord
|
6
|
-
require_relative 'database_recorder/
|
7
|
-
require_relative 'database_recorder/
|
8
|
-
require_relative 'database_recorder/
|
9
|
-
require_relative 'database_recorder/
|
6
|
+
require_relative 'database_recorder/active_record/abstract_adapter_ext'
|
7
|
+
require_relative 'database_recorder/active_record/base_ext'
|
8
|
+
require_relative 'database_recorder/active_record/recorded_result'
|
9
|
+
require_relative 'database_recorder/active_record/recorder'
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
require_relative 'database_recorder/mysql2/client_ext'
|
13
|
+
require_relative 'database_recorder/mysql2/recorded_result'
|
14
|
+
require_relative 'database_recorder/mysql2/recorder'
|
15
|
+
require_relative 'database_recorder/mysql2/statement_ext'
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
17
|
+
require_relative 'database_recorder/pg/connection_ext'
|
18
|
+
require_relative 'database_recorder/pg/recorded_result'
|
19
|
+
require_relative 'database_recorder/pg/recorder'
|
21
20
|
|
21
|
+
require_relative 'database_recorder/storage/base'
|
22
22
|
require_relative 'database_recorder/storage/file'
|
23
23
|
require_relative 'database_recorder/storage/redis'
|
24
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_recorder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattia Roccoberton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coderay
|
@@ -35,18 +35,22 @@ files:
|
|
35
35
|
- MIT-LICENSE
|
36
36
|
- README.md
|
37
37
|
- lib/database_recorder.rb
|
38
|
-
- lib/database_recorder/
|
39
|
-
- lib/database_recorder/
|
40
|
-
- lib/database_recorder/
|
41
|
-
- lib/database_recorder/
|
38
|
+
- lib/database_recorder/active_record/abstract_adapter_ext.rb
|
39
|
+
- lib/database_recorder/active_record/base_ext.rb
|
40
|
+
- lib/database_recorder/active_record/recorded_result.rb
|
41
|
+
- lib/database_recorder/active_record/recorder.rb
|
42
42
|
- lib/database_recorder/config.rb
|
43
43
|
- lib/database_recorder/core.rb
|
44
|
+
- lib/database_recorder/mysql2/client_ext.rb
|
44
45
|
- lib/database_recorder/mysql2/recorded_result.rb
|
45
46
|
- lib/database_recorder/mysql2/recorder.rb
|
47
|
+
- lib/database_recorder/mysql2/statement_ext.rb
|
48
|
+
- lib/database_recorder/pg/connection_ext.rb
|
46
49
|
- lib/database_recorder/pg/recorded_result.rb
|
47
50
|
- lib/database_recorder/pg/recorder.rb
|
48
51
|
- lib/database_recorder/recording.rb
|
49
52
|
- lib/database_recorder/rspec.rb
|
53
|
+
- lib/database_recorder/storage/base.rb
|
50
54
|
- lib/database_recorder/storage/file.rb
|
51
55
|
- lib/database_recorder/storage/redis.rb
|
52
56
|
- lib/database_recorder/version.rb
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DatabaseRecorder
|
4
|
-
module ActiveRecord
|
5
|
-
module Recorder
|
6
|
-
module_function
|
7
|
-
|
8
|
-
def setup
|
9
|
-
::ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
10
|
-
prepend AbstractAdapterExt
|
11
|
-
end
|
12
|
-
|
13
|
-
# ::ActiveRecord::Base.class_eval do
|
14
|
-
# prepend BaseExt
|
15
|
-
# end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|