janus-ar 0.6.0 → 0.7.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/ci.yml +6 -2
- data/.github/workflows/publish.yml +20 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +7 -0
- data/Gemfile.lock +26 -1
- data/README.md +2 -1
- data/janus-ar.gemspec +9 -5
- data/lib/active_record/connection_adapters/janus_mysql2_adapter.rb +12 -7
- data/lib/janus/logging/subscriber.rb +1 -1
- data/lib/janus/version.rb +1 -1
- data/spec/lib/active_record/connection_adapters/janus_mysql_adapter_spec.rb +125 -0
- data/spec/spec_helper.rb +37 -0
- metadata +62 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c7f4d589060d390c2a1c0697cdde34bb36e92a4daed4ab477d8fa543de113ae1
|
|
4
|
+
data.tar.gz: dd3e5fc8957cc36e5a06684934b7a9e41f37b5f5a2c749c686e42d77d49a650b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 68e6fab5ad4a07f4b872f9ddd76d0c74847380d6a2f690d98646a7d2b2d9110eb4fb9a095b8f42bd7912aaeb0774e239bbd9a9cbef9c65fa9fb6e9a9b386b54e
|
|
7
|
+
data.tar.gz: df1f1b37c36dea944d5ce6c1f05080eb119461f0e180edd6dcdb63768bf1f16101644eebc41d302f46c414219fd5cf28cddf6c7a2e9a3ac0632b2cd46627e494
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -19,8 +19,10 @@ jobs:
|
|
|
19
19
|
mysql:
|
|
20
20
|
image: mysql:5.7
|
|
21
21
|
env:
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
MYSQL_DATABASE: test
|
|
23
|
+
MYSQL_ROOT_PASSWORD: password
|
|
24
|
+
MYSQL_USER: primary
|
|
25
|
+
MYSQL_PASSWORD: primary_password
|
|
24
26
|
ports:
|
|
25
27
|
- 3306:3306
|
|
26
28
|
options: >-
|
|
@@ -34,6 +36,8 @@ jobs:
|
|
|
34
36
|
with:
|
|
35
37
|
ruby-version: ${{ matrix.ruby }}
|
|
36
38
|
bundler-cache: true
|
|
39
|
+
- run: |
|
|
40
|
+
mysql -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1 -e "CREATE USER 'replica'@'%' IDENTIFIED BY 'replica_password';GRANT SELECT ON test.* TO 'replica'@'%';FLUSH PRIVILEGES;"
|
|
37
41
|
- run: |
|
|
38
42
|
bundle exec rspec
|
|
39
43
|
env:
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Publish GEM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- v*
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v3
|
|
13
|
+
|
|
14
|
+
- name: Release GEM
|
|
15
|
+
if: contains(github.ref, 'refs/tags/v')
|
|
16
|
+
uses: cadwallion/publish-rubygems-action@master
|
|
17
|
+
env:
|
|
18
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
|
19
|
+
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
|
|
20
|
+
RELEASE_COMMAND: gem build && gem push janus-ar-*.gem
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
inherit_from:
|
|
2
|
+
- https://tech.olioex.com/.support/rubocop-styling-v1.0
|
|
3
|
+
|
|
1
4
|
require:
|
|
2
5
|
- rubocop-rails
|
|
3
6
|
|
|
@@ -11,5 +14,9 @@ Metrics/BlockLength:
|
|
|
11
14
|
Exclude:
|
|
12
15
|
- spec/**/*
|
|
13
16
|
|
|
17
|
+
Style/GlobalVars:
|
|
18
|
+
Exclude:
|
|
19
|
+
- 'spec/**/*'
|
|
20
|
+
|
|
14
21
|
Metrics/AbcSize:
|
|
15
22
|
Max: 22
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
janus-ar (0.
|
|
4
|
+
janus-ar (0.7.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: http://rubygems.org/
|
|
@@ -25,6 +25,7 @@ GEM
|
|
|
25
25
|
ast (2.4.2)
|
|
26
26
|
base64 (0.2.0)
|
|
27
27
|
bigdecimal (3.1.7)
|
|
28
|
+
coderay (1.1.3)
|
|
28
29
|
concurrent-ruby (1.2.3)
|
|
29
30
|
connection_pool (2.4.1)
|
|
30
31
|
diff-lcs (1.5.1)
|
|
@@ -33,6 +34,7 @@ GEM
|
|
|
33
34
|
concurrent-ruby (~> 1.0)
|
|
34
35
|
json (2.7.2)
|
|
35
36
|
language_server-protocol (3.17.0.3)
|
|
37
|
+
method_source (1.0.0)
|
|
36
38
|
minitest (5.22.3)
|
|
37
39
|
mutex_m (0.2.0)
|
|
38
40
|
mysql2 (0.5.6)
|
|
@@ -40,6 +42,9 @@ GEM
|
|
|
40
42
|
parser (3.3.0.5)
|
|
41
43
|
ast (~> 2.4.1)
|
|
42
44
|
racc
|
|
45
|
+
pry (0.14.2)
|
|
46
|
+
coderay (~> 1.1)
|
|
47
|
+
method_source (~> 1.0)
|
|
43
48
|
racc (1.7.3)
|
|
44
49
|
rack (3.0.10)
|
|
45
50
|
rainbow (3.1.1)
|
|
@@ -72,11 +77,27 @@ GEM
|
|
|
72
77
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
73
78
|
rubocop-ast (1.31.2)
|
|
74
79
|
parser (>= 3.3.0.4)
|
|
80
|
+
rubocop-capybara (2.20.0)
|
|
81
|
+
rubocop (~> 1.41)
|
|
82
|
+
rubocop-factory_bot (2.25.1)
|
|
83
|
+
rubocop (~> 1.41)
|
|
84
|
+
rubocop-performance (1.21.0)
|
|
85
|
+
rubocop (>= 1.48.1, < 2.0)
|
|
86
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
|
75
87
|
rubocop-rails (2.24.1)
|
|
76
88
|
activesupport (>= 4.2.0)
|
|
77
89
|
rack (>= 1.1)
|
|
78
90
|
rubocop (>= 1.33.0, < 2.0)
|
|
79
91
|
rubocop-ast (>= 1.31.1, < 2.0)
|
|
92
|
+
rubocop-rspec (2.29.1)
|
|
93
|
+
rubocop (~> 1.40)
|
|
94
|
+
rubocop-capybara (~> 2.17)
|
|
95
|
+
rubocop-factory_bot (~> 2.22)
|
|
96
|
+
rubocop-rspec_rails (~> 2.28)
|
|
97
|
+
rubocop-rspec_rails (2.28.3)
|
|
98
|
+
rubocop (~> 1.40)
|
|
99
|
+
rubocop-thread_safety (0.5.1)
|
|
100
|
+
rubocop (>= 0.90.0)
|
|
80
101
|
ruby-progressbar (1.13.0)
|
|
81
102
|
timeout (0.4.1)
|
|
82
103
|
tzinfo (2.0.6)
|
|
@@ -92,10 +113,14 @@ DEPENDENCIES
|
|
|
92
113
|
activesupport (>= 7.1.0)
|
|
93
114
|
janus-ar!
|
|
94
115
|
mysql2
|
|
116
|
+
pry
|
|
95
117
|
rake
|
|
96
118
|
rspec (~> 3)
|
|
97
119
|
rubocop (~> 1.63.0)
|
|
120
|
+
rubocop-performance
|
|
98
121
|
rubocop-rails (~> 2.24.0)
|
|
122
|
+
rubocop-rspec
|
|
123
|
+
rubocop-thread_safety
|
|
99
124
|
|
|
100
125
|
BUNDLED WITH
|
|
101
126
|
2.4.22
|
data/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
style="float: left; margin: 0 auto; height: 500px;" />
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-
](https://github.com/OLIOEX/janus-ar/actions/workflows/ci.yml)
|
|
10
|
+
[](https://badge.fury.io/rb/janus-ar)
|
|
10
11
|
|
|
11
12
|
> In ancient Roman religion and myth, Janus (/ˈdʒeɪnəs/ JAY-nəs; Latin: Ianvs [ˈi̯aːnʊs]) is the god of beginnings, gates, transitions, time, duality, doorways,[2] passages, frames, and endings. [(wikipedia)](https://en.wikipedia.org/wiki/Janus)
|
|
12
13
|
|
data/janus-ar.gemspec
CHANGED
|
@@ -5,18 +5,18 @@ require File.expand_path('lib/janus/version.rb', __dir__)
|
|
|
5
5
|
Gem::Specification.new do |gem|
|
|
6
6
|
gem.authors = ['Lloyd Watkin']
|
|
7
7
|
gem.email = ['lloyd@olioex.com']
|
|
8
|
-
gem.description = 'Read/Write proxy for ActiveRecord using primary/
|
|
9
|
-
gem.summary = 'Read/Write proxy for ActiveRecord using primary/
|
|
8
|
+
gem.description = 'Read/Write proxy for ActiveRecord using primary/replica databases'
|
|
9
|
+
gem.summary = 'Read/Write proxy for ActiveRecord using primary/replica databases'
|
|
10
10
|
gem.homepage = 'https://github.com/olioex/janus-ar'
|
|
11
|
-
gem.licenses =
|
|
11
|
+
gem.licenses = %w(MIT)
|
|
12
12
|
gem.metadata = {
|
|
13
|
-
'source_code_uri' => 'https://github.com/olioex/janus-ar'
|
|
13
|
+
'source_code_uri' => 'https://github.com/olioex/janus-ar',
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
|
17
17
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
18
18
|
gem.name = 'janus-ar'
|
|
19
|
-
gem.require_paths =
|
|
19
|
+
gem.require_paths = %w(lib)
|
|
20
20
|
gem.version = Janus::VERSION
|
|
21
21
|
|
|
22
22
|
gem.required_ruby_version = '>= 3.2.0'
|
|
@@ -24,8 +24,12 @@ Gem::Specification.new do |gem|
|
|
|
24
24
|
gem.add_development_dependency 'activerecord', '>= 7.1.0'
|
|
25
25
|
gem.add_development_dependency 'activesupport', '>= 7.1.0'
|
|
26
26
|
gem.add_development_dependency 'mysql2'
|
|
27
|
+
gem.add_development_dependency 'pry'
|
|
27
28
|
gem.add_development_dependency 'rake'
|
|
28
29
|
gem.add_development_dependency 'rspec', '~> 3'
|
|
29
30
|
gem.add_development_dependency 'rubocop', '~> 1.63.0'
|
|
30
31
|
gem.add_development_dependency 'rubocop-rails', '~> 2.24.0'
|
|
32
|
+
gem.add_development_dependency 'rubocop-rspec'
|
|
33
|
+
gem.add_development_dependency 'rubocop-thread_safety'
|
|
34
|
+
gem.add_development_dependency 'rubocop-performance'
|
|
31
35
|
end
|
|
@@ -15,6 +15,7 @@ end
|
|
|
15
15
|
module ActiveRecord
|
|
16
16
|
module ConnectionAdapters
|
|
17
17
|
class JanusMysql2Adapter < ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
|
18
|
+
FOUND_ROWS = 'FOUND_ROWS'
|
|
18
19
|
SQL_PRIMARY_MATCHERS = [
|
|
19
20
|
/\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i,
|
|
20
21
|
/\A\s*select.+(nextval|currval|lastval|get_lock|release_lock|pg_advisory_lock|pg_advisory_unlock)\(/i,
|
|
@@ -23,6 +24,9 @@ module ActiveRecord
|
|
|
23
24
|
SQL_REPLICA_MATCHERS = [/\A\s*(select|with.+\)\s*select)\s/i].freeze
|
|
24
25
|
SQL_ALL_MATCHERS = [/\A\s*set\s/i].freeze
|
|
25
26
|
SQL_SKIP_ALL_MATCHERS = [/\A\s*set\s+local\s/i].freeze
|
|
27
|
+
WRITE_PREFIXES = %w(INSERT UPDATE DELETE LOCK CREATE GRANT DROP).freeze
|
|
28
|
+
|
|
29
|
+
attr_reader :config
|
|
26
30
|
|
|
27
31
|
def initialize(*args)
|
|
28
32
|
args[0][:janus]['replica']['database'] = args[0][:database]
|
|
@@ -30,6 +34,7 @@ module ActiveRecord
|
|
|
30
34
|
|
|
31
35
|
@replica_config = args[0][:janus]['replica']
|
|
32
36
|
args[0] = args[0][:janus]['primary']
|
|
37
|
+
|
|
33
38
|
super(*args)
|
|
34
39
|
@connection_parameters ||= args[0]
|
|
35
40
|
update_config
|
|
@@ -48,7 +53,7 @@ module ActiveRecord
|
|
|
48
53
|
super(sql)
|
|
49
54
|
end
|
|
50
55
|
|
|
51
|
-
def execute_and_free(sql, name = nil, async: false)
|
|
56
|
+
def execute_and_free(sql, name = nil, async: false)
|
|
52
57
|
if should_send_to_all?(sql)
|
|
53
58
|
send_to_replica(sql, name, connection: :all)
|
|
54
59
|
return super(sql, name, async:)
|
|
@@ -81,6 +86,10 @@ module ActiveRecord
|
|
|
81
86
|
super
|
|
82
87
|
end
|
|
83
88
|
|
|
89
|
+
def replica_connection
|
|
90
|
+
@replica_connection ||= ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(@replica_config)
|
|
91
|
+
end
|
|
92
|
+
|
|
84
93
|
private
|
|
85
94
|
|
|
86
95
|
def should_send_to_all?(sql)
|
|
@@ -108,18 +117,14 @@ module ActiveRecord
|
|
|
108
117
|
end
|
|
109
118
|
|
|
110
119
|
def write_query?(sql)
|
|
111
|
-
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def replica_connection
|
|
115
|
-
@replica_connection ||= ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(@replica_config)
|
|
120
|
+
WRITE_PREFIXES.include?(sql.split(' ').first)
|
|
116
121
|
end
|
|
117
122
|
|
|
118
123
|
def update_config
|
|
119
124
|
@config[:flags] ||= 0
|
|
120
125
|
|
|
121
126
|
if @config[:flags].is_a? Array
|
|
122
|
-
@config[:flags].push
|
|
127
|
+
@config[:flags].push FOUND_ROWS
|
|
123
128
|
else
|
|
124
129
|
@config[:flags] |= ::Mysql2::Client::FOUND_ROWS
|
|
125
130
|
end
|
data/lib/janus/version.rb
CHANGED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe ActiveRecord::ConnectionAdapters::JanusMysql2Adapter do
|
|
4
|
+
subject { described_class.new(config) }
|
|
5
|
+
|
|
6
|
+
it { expect(described_class::FOUND_ROWS).to eq 'FOUND_ROWS' }
|
|
7
|
+
it { expect(described_class::SQL_SKIP_ALL_MATCHERS).to eq [/\A\s*set\s+local\s/i] }
|
|
8
|
+
it {
|
|
9
|
+
expect(described_class::SQL_PRIMARY_MATCHERS).to eq(
|
|
10
|
+
[
|
|
11
|
+
/\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i,
|
|
12
|
+
/\A\s*select.+(nextval|currval|lastval|get_lock|release_lock|pg_advisory_lock|pg_advisory_unlock)\(/i,
|
|
13
|
+
/\A\s*show/i
|
|
14
|
+
]
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
it { expect(described_class::SQL_REPLICA_MATCHERS).to eq([/\A\s*(select|with.+\)\s*select)\s/i]) }
|
|
18
|
+
it { expect(described_class::SQL_ALL_MATCHERS).to eq([/\A\s*set\s/i]) }
|
|
19
|
+
it { expect(described_class::WRITE_PREFIXES).to eq %w(INSERT UPDATE DELETE LOCK CREATE GRANT DROP) }
|
|
20
|
+
|
|
21
|
+
let(:database) { 'test' }
|
|
22
|
+
let(:primary_config) do
|
|
23
|
+
{
|
|
24
|
+
'username' => 'primary',
|
|
25
|
+
'password' => 'primary_password',
|
|
26
|
+
'host' => '127.0.0.1',
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
let(:replica_config) do
|
|
30
|
+
{
|
|
31
|
+
'username' => 'replica',
|
|
32
|
+
'password' => 'replica_password',
|
|
33
|
+
'host' => '127.0.0.1',
|
|
34
|
+
'pool' => 500,
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
let(:config) do
|
|
38
|
+
{
|
|
39
|
+
database:,
|
|
40
|
+
adapter: 'janus_mysql2',
|
|
41
|
+
janus: {
|
|
42
|
+
'primary' => primary_config,
|
|
43
|
+
'replica' => replica_config,
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe 'Configuration' do
|
|
49
|
+
it 'creates primary connection as expected' do
|
|
50
|
+
config = primary_config.dup.freeze
|
|
51
|
+
expect(subject.config).to eq config.merge('database' => database,
|
|
52
|
+
'flags' => ::Mysql2::Client::FOUND_ROWS).symbolize_keys
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'creates replica connection as expected' do
|
|
56
|
+
config = replica_config.dup.freeze
|
|
57
|
+
expect(
|
|
58
|
+
subject.replica_connection.instance_variable_get(:@config)
|
|
59
|
+
).to eq config.merge('database' => database, 'flags' => ::Mysql2::Client::FOUND_ROWS).symbolize_keys
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'Rails sets empty database for server connection' do
|
|
63
|
+
let(:database) { nil }
|
|
64
|
+
|
|
65
|
+
it 'creates primary connection as expected' do
|
|
66
|
+
config = primary_config.dup.freeze
|
|
67
|
+
expect(subject.config).to eq config.merge(
|
|
68
|
+
'database' => nil,
|
|
69
|
+
'flags' => ::Mysql2::Client::FOUND_ROWS
|
|
70
|
+
).symbolize_keys
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'creates replica connection as expected' do
|
|
74
|
+
config = replica_config.dup.freeze
|
|
75
|
+
expect(
|
|
76
|
+
subject.replica_connection.instance_variable_get(:@config)
|
|
77
|
+
).to eq config.merge('database' => nil, 'flags' => ::Mysql2::Client::FOUND_ROWS).symbolize_keys
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe 'Integration tests' do
|
|
83
|
+
let(:create_test_table) { ActiveRecord::Base.connection.execute('CREATE TABLE test_table (id INT);') }
|
|
84
|
+
|
|
85
|
+
before(:each) do
|
|
86
|
+
$query_logger.flush_all
|
|
87
|
+
ActiveRecord::Base.establish_connection(config)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
after(:each) do
|
|
91
|
+
ActiveRecord::Base.connection.execute(<<-SQL
|
|
92
|
+
SELECT CONCAT('DROP TABLE IF EXISTS `', table_name, '`;')
|
|
93
|
+
FROM information_schema.tables
|
|
94
|
+
WHERE table_schema = '#{database}';
|
|
95
|
+
SQL
|
|
96
|
+
).to_a.map { |row| ActiveRecord::Base.connection.execute(row[0]) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'can list tables' do
|
|
100
|
+
expect(ActiveRecord::Base.connection.execute('SHOW TABLES;').to_a).to eq []
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'can create table' do
|
|
104
|
+
create_test_table
|
|
105
|
+
expect(ActiveRecord::Base.connection.execute('SHOW TABLES;').to_a).to eq [%w(test_table)]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe 'SELECT' do
|
|
109
|
+
it 'reads from `replica` by default' do
|
|
110
|
+
create_test_table
|
|
111
|
+
Janus::Context.release_all
|
|
112
|
+
$query_logger.flush_all
|
|
113
|
+
ActiveRecord::Base.connection.execute('SELECT * FROM test_table;')
|
|
114
|
+
expect($query_logger.queries.first).to include '[replica]'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'will read from primary after a write operation' do
|
|
118
|
+
create_test_table
|
|
119
|
+
$query_logger.flush_all
|
|
120
|
+
ActiveRecord::Base.connection.execute('SELECT * FROM test_table;')
|
|
121
|
+
expect($query_logger.queries.first).to include '[primary]'
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'pry'
|
|
4
|
+
|
|
5
|
+
require 'active_record'
|
|
6
|
+
|
|
3
7
|
require './lib/janus'
|
|
8
|
+
require './lib/active_record/connection_adapters/janus_mysql2_adapter'
|
|
9
|
+
|
|
10
|
+
class QueryLogger
|
|
11
|
+
def initialize
|
|
12
|
+
@_logs = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def flush_all
|
|
16
|
+
@_logs = []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def log(level, message)
|
|
20
|
+
@_logs << "#{level}: #{message}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def error(message)
|
|
24
|
+
log('error', message)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def queries
|
|
28
|
+
@_logs
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def debug?
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def debug(message)
|
|
36
|
+
log('debug', message)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
$query_logger = ActiveRecord::Base.logger = QueryLogger.new
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: janus-ar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lloyd Watkin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-04-
|
|
11
|
+
date: 2024-04-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: pry
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: rake
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,7 +122,49 @@ dependencies:
|
|
|
108
122
|
- - "~>"
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: 2.24.0
|
|
111
|
-
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rubocop-rspec
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rubocop-thread_safety
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: rubocop-performance
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
167
|
+
description: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
112
168
|
email:
|
|
113
169
|
- lloyd@olioex.com
|
|
114
170
|
executables: []
|
|
@@ -117,6 +173,7 @@ extra_rdoc_files: []
|
|
|
117
173
|
files:
|
|
118
174
|
- ".github/dependabot.yml"
|
|
119
175
|
- ".github/workflows/ci.yml"
|
|
176
|
+
- ".github/workflows/publish.yml"
|
|
120
177
|
- ".gitignore"
|
|
121
178
|
- ".rspec"
|
|
122
179
|
- ".rubocop.yml"
|
|
@@ -134,6 +191,7 @@ files:
|
|
|
134
191
|
- lib/janus/logging/logger.rb
|
|
135
192
|
- lib/janus/logging/subscriber.rb
|
|
136
193
|
- lib/janus/version.rb
|
|
194
|
+
- spec/lib/active_record/connection_adapters/janus_mysql_adapter_spec.rb
|
|
137
195
|
- spec/lib/janus/context_spec.rb
|
|
138
196
|
- spec/lib/janus/logging/logger_spec.rb
|
|
139
197
|
- spec/spec_helper.rb
|
|
@@ -160,5 +218,5 @@ requirements: []
|
|
|
160
218
|
rubygems_version: 3.5.7
|
|
161
219
|
signing_key:
|
|
162
220
|
specification_version: 4
|
|
163
|
-
summary: Read/Write proxy for ActiveRecord using primary/
|
|
221
|
+
summary: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
164
222
|
test_files: []
|