janus-ar 8.0.0 → 8.1.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/Gemfile +1 -1
- data/Gemfile.lock +142 -125
- data/README.md +153 -131
- data/janus-ar.gemspec +38 -36
- data/lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter.rb +32 -149
- data/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter.rb +32 -149
- data/lib/janus-ar/adapter_extensions.rb +112 -0
- data/lib/janus-ar/client.rb +6 -6
- data/lib/janus-ar/context.rb +79 -80
- data/lib/janus-ar/db_console_config.rb +17 -17
- data/lib/janus-ar/logging/logger.rb +15 -15
- data/lib/janus-ar/logging/subscriber.rb +27 -27
- data/lib/janus-ar/query_director.rb +87 -54
- data/lib/janus-ar/railtie.rb +15 -0
- data/lib/janus-ar/version.rb +17 -17
- data/lib/janus-ar.rb +24 -22
- metadata +10 -30
- data/.bundle/config +0 -5
- data/.github/dependabot.yml +0 -7
- data/.github/workflows/ci.yml +0 -60
- data/.github/workflows/publish.yml +0 -25
- data/.gitignore +0 -2
- data/.rspec +0 -3
- data/.rubocop.yml +0 -26
- data/assets/.gitkeep +0 -1
- data/assets/janus-logo.png +0 -0
- data/bin/release.sh +0 -3
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb +0 -82
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb +0 -82
- data/spec/lib/janus-ar/client_spec.rb +0 -7
- data/spec/lib/janus-ar/context_spec.rb +0 -46
- data/spec/lib/janus-ar/logging/logger_spec.rb +0 -31
- data/spec/lib/janus-ar/query_director_spec.rb +0 -59
- data/spec/shared_examples/a_mysql_like_server.rb +0 -85
- data/spec/spec_helper.rb +0 -46
data/.github/workflows/ci.yml
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
pull_request:
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
strategy:
|
|
13
|
-
fail-fast: false
|
|
14
|
-
matrix:
|
|
15
|
-
ruby:
|
|
16
|
-
- '3.2'
|
|
17
|
-
name: Ruby ${{ matrix.ruby }}
|
|
18
|
-
services:
|
|
19
|
-
mysql:
|
|
20
|
-
image: mysql:8
|
|
21
|
-
env:
|
|
22
|
-
MYSQL_DATABASE: test
|
|
23
|
-
MYSQL_ROOT_PASSWORD: password
|
|
24
|
-
MYSQL_USER: test
|
|
25
|
-
MYSQL_PASSWORD: test_password
|
|
26
|
-
ports:
|
|
27
|
-
- 3306:3306
|
|
28
|
-
options: >-
|
|
29
|
-
--health-cmd "mysqladmin ping"
|
|
30
|
-
--health-interval 10s
|
|
31
|
-
--health-timeout 5s
|
|
32
|
-
--health-retries 5
|
|
33
|
-
steps:
|
|
34
|
-
- uses: actions/checkout@v2
|
|
35
|
-
- uses: ruby/setup-ruby@v1
|
|
36
|
-
with:
|
|
37
|
-
ruby-version: ${{ matrix.ruby }}
|
|
38
|
-
bundler-cache: true
|
|
39
|
-
- run: |
|
|
40
|
-
mysql -e "CREATE USER 'replica'@'%' IDENTIFIED BY 'replica_password';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
41
|
-
mysql -e "GRANT SELECT ON test.* TO 'replica'@'%'" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
42
|
-
|
|
43
|
-
mysql -e "CREATE USER 'primary'@'%' IDENTIFIED BY 'primary_password';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
44
|
-
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'primary'@'%';" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
45
|
-
mysql -e "FLUSH PRIVILEGES;" -u root -p${{ env.MYSQL_PASSWORD || 'password' }} -h 127.0.0.1
|
|
46
|
-
- run: |
|
|
47
|
-
bundle exec rspec
|
|
48
|
-
env:
|
|
49
|
-
MYSQL_HOST: 127.0.0.1
|
|
50
|
-
RAILS_ENV: test
|
|
51
|
-
RuboCop:
|
|
52
|
-
runs-on: ubuntu-latest
|
|
53
|
-
steps:
|
|
54
|
-
- uses: actions/checkout@v2
|
|
55
|
-
- uses: ruby/setup-ruby@v1
|
|
56
|
-
with:
|
|
57
|
-
ruby-version: '3.2'
|
|
58
|
-
bundler-cache: true
|
|
59
|
-
- run: |
|
|
60
|
-
bundle exec rubocop --parallel --color
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: Publish GEM
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- v*
|
|
7
|
-
jobs:
|
|
8
|
-
push:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write
|
|
13
|
-
id-token: write
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
# Set up
|
|
17
|
-
- uses: actions/checkout@v4
|
|
18
|
-
- name: Set up Ruby
|
|
19
|
-
uses: ruby/setup-ruby@v1
|
|
20
|
-
with:
|
|
21
|
-
bundler-cache: true
|
|
22
|
-
ruby-version: ruby
|
|
23
|
-
|
|
24
|
-
# Release
|
|
25
|
-
- uses: rubygems/release-gem@v1
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
inherit_from:
|
|
2
|
-
- https://tech.olioex.com/.support/rubocop-styling-v1.0
|
|
3
|
-
|
|
4
|
-
require:
|
|
5
|
-
- rubocop-rails
|
|
6
|
-
|
|
7
|
-
Style/Documentation:
|
|
8
|
-
Enabled: false
|
|
9
|
-
|
|
10
|
-
Rails/Delegate:
|
|
11
|
-
Enabled: false
|
|
12
|
-
|
|
13
|
-
Metrics/BlockLength:
|
|
14
|
-
Exclude:
|
|
15
|
-
- spec/**/*
|
|
16
|
-
|
|
17
|
-
Style/GlobalVars:
|
|
18
|
-
Exclude:
|
|
19
|
-
- 'spec/**/*'
|
|
20
|
-
|
|
21
|
-
Naming/FileName:
|
|
22
|
-
Exclude:
|
|
23
|
-
- lib/janus-ar.rb
|
|
24
|
-
|
|
25
|
-
Metrics/AbcSize:
|
|
26
|
-
Max: 25
|
data/assets/.gitkeep
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
data/assets/janus-logo.png
DELETED
|
Binary file
|
data/bin/release.sh
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
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
|
-
|
|
8
|
-
let(:database) { 'test' }
|
|
9
|
-
let(:primary_config) do
|
|
10
|
-
{
|
|
11
|
-
'username' => 'primary',
|
|
12
|
-
'password' => 'primary_password',
|
|
13
|
-
'host' => '127.0.0.1',
|
|
14
|
-
'ssl' => true,
|
|
15
|
-
'ssl_mode' => 'REQUIRED',
|
|
16
|
-
'tls_min_version' => 3,
|
|
17
|
-
}
|
|
18
|
-
end
|
|
19
|
-
let(:replica_config) do
|
|
20
|
-
{
|
|
21
|
-
'username' => 'replica',
|
|
22
|
-
'password' => 'replica_password',
|
|
23
|
-
'host' => '127.0.0.1',
|
|
24
|
-
'pool' => 500,
|
|
25
|
-
'ssl' => true,
|
|
26
|
-
'ssl_mode' => 'REQUIRED',
|
|
27
|
-
'tls_min_version' => 3,
|
|
28
|
-
}
|
|
29
|
-
end
|
|
30
|
-
let(:config) do
|
|
31
|
-
{
|
|
32
|
-
database:,
|
|
33
|
-
adapter: 'janus_mysql2',
|
|
34
|
-
janus: {
|
|
35
|
-
'primary' => primary_config,
|
|
36
|
-
'replica' => replica_config,
|
|
37
|
-
},
|
|
38
|
-
}
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
describe 'Configuration' do
|
|
42
|
-
it 'creates primary connection as expected' do
|
|
43
|
-
config = primary_config.dup.freeze
|
|
44
|
-
expect(subject.config).to eq config.merge('database' => database,
|
|
45
|
-
'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'creates replica connection as expected' do
|
|
49
|
-
config = replica_config.dup.freeze
|
|
50
|
-
expect(
|
|
51
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
52
|
-
).to eq config.merge('database' => database, 'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context 'Rails sets empty database for server connection' do
|
|
56
|
-
let(:database) { nil }
|
|
57
|
-
|
|
58
|
-
it 'creates primary connection as expected' do
|
|
59
|
-
config = primary_config.dup.freeze
|
|
60
|
-
expect(subject.config).to eq config.merge(
|
|
61
|
-
'database' => nil,
|
|
62
|
-
'flags' => ::Janus::Client::FOUND_ROWS
|
|
63
|
-
).symbolize_keys
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'creates replica connection as expected' do
|
|
67
|
-
config = replica_config.dup.freeze
|
|
68
|
-
expect(
|
|
69
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
70
|
-
).to eq config.merge('database' => nil, 'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
describe 'Integration tests' do
|
|
76
|
-
describe 'Integration tests' do
|
|
77
|
-
let(:table_name) { 'table_name_mysql2' }
|
|
78
|
-
|
|
79
|
-
it_behaves_like 'a mysql like server'
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe ActiveRecord::ConnectionAdapters::JanusTrilogyAdapter do
|
|
4
|
-
subject { described_class.new(config) }
|
|
5
|
-
|
|
6
|
-
it { expect(described_class::FOUND_ROWS).to eq 'FOUND_ROWS' }
|
|
7
|
-
|
|
8
|
-
let(:database) { 'test' }
|
|
9
|
-
let(:primary_config) do
|
|
10
|
-
{
|
|
11
|
-
'username' => 'primary',
|
|
12
|
-
'password' => 'primary_password',
|
|
13
|
-
'host' => '127.0.0.1',
|
|
14
|
-
'ssl' => true,
|
|
15
|
-
'ssl_mode' => 'REQUIRED',
|
|
16
|
-
'tls_min_version' => Trilogy::TLS_VERSION_12,
|
|
17
|
-
'found_rows' => true,
|
|
18
|
-
}
|
|
19
|
-
end
|
|
20
|
-
let(:replica_config) do
|
|
21
|
-
{
|
|
22
|
-
'username' => 'replica',
|
|
23
|
-
'password' => 'replica_password',
|
|
24
|
-
'host' => '127.0.0.1',
|
|
25
|
-
'pool' => 500,
|
|
26
|
-
'ssl' => true,
|
|
27
|
-
'ssl_mode' => 'REQUIRED',
|
|
28
|
-
'tls_min_version' => Trilogy::TLS_VERSION_12,
|
|
29
|
-
'found_rows' => true,
|
|
30
|
-
}
|
|
31
|
-
end
|
|
32
|
-
let(:config) do
|
|
33
|
-
{
|
|
34
|
-
database:,
|
|
35
|
-
adapter: 'janus_trilogy',
|
|
36
|
-
janus: {
|
|
37
|
-
'primary' => primary_config,
|
|
38
|
-
'replica' => replica_config,
|
|
39
|
-
},
|
|
40
|
-
}
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
describe 'Configuration' do
|
|
44
|
-
it 'creates primary connection as expected' do
|
|
45
|
-
config = primary_config.dup.freeze
|
|
46
|
-
expect(subject.config).to eq config.merge('database' => database,
|
|
47
|
-
'flags' => ::Janus::Client::FOUND_ROWS).symbolize_keys
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it 'creates replica connection as expected' do
|
|
51
|
-
config = replica_config.dup.freeze
|
|
52
|
-
expect(
|
|
53
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
54
|
-
).to eq config.merge('database' => database).symbolize_keys
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
context 'Rails sets empty database for server connection' do
|
|
58
|
-
let(:database) { nil }
|
|
59
|
-
|
|
60
|
-
it 'creates primary connection as expected' do
|
|
61
|
-
config = primary_config.dup.freeze
|
|
62
|
-
expect(subject.config).to eq config.merge(
|
|
63
|
-
'database' => nil,
|
|
64
|
-
'flags' => ::Janus::Client::FOUND_ROWS
|
|
65
|
-
).symbolize_keys
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it 'creates replica connection as expected' do
|
|
69
|
-
config = replica_config.dup.freeze
|
|
70
|
-
expect(
|
|
71
|
-
subject.replica_connection.instance_variable_get(:@config)
|
|
72
|
-
).to eq config.merge('database' => nil).symbolize_keys
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
describe 'Integration tests' do
|
|
78
|
-
let(:table_name) { 'table_name_trilogy' }
|
|
79
|
-
|
|
80
|
-
it_behaves_like 'a mysql like server'
|
|
81
|
-
end
|
|
82
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'janus-ar/context'
|
|
4
|
-
|
|
5
|
-
RSpec.describe Janus::Context do
|
|
6
|
-
describe '#initialize' do
|
|
7
|
-
it 'sets the primary flag and expiry' do
|
|
8
|
-
context = described_class.new(primary: true, expiry: 60)
|
|
9
|
-
expect(context.use_primary?).to be true
|
|
10
|
-
expect(context.last_used_connection).to eq(:primary)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe '#stick_to_primary' do
|
|
15
|
-
it 'sets the primary flag to true' do
|
|
16
|
-
context = described_class.new
|
|
17
|
-
context.stick_to_primary
|
|
18
|
-
expect(context.use_primary?).to be true
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe '#potential_write' do
|
|
23
|
-
it 'calls stick_to_primary' do
|
|
24
|
-
context = described_class.new
|
|
25
|
-
expect(context).to receive(:stick_to_primary)
|
|
26
|
-
context.potential_write
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe '#release_all' do
|
|
31
|
-
it 'resets the primary flag and expiry' do
|
|
32
|
-
context = described_class.new(primary: true, expiry: 60)
|
|
33
|
-
context.release_all
|
|
34
|
-
expect(context.use_primary?).to be false
|
|
35
|
-
expect(context.last_used_connection).to be_nil
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe '#used_connection' do
|
|
40
|
-
it 'sets the last used connection' do
|
|
41
|
-
context = described_class.new
|
|
42
|
-
context.used_connection(:secondary)
|
|
43
|
-
expect(context.last_used_connection).to eq(:secondary)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Janus::Logging::Logger do
|
|
4
|
-
describe '.log' do
|
|
5
|
-
let(:logger) { double('logger') }
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
described_class.logger = logger
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it 'logs the message with the specified format' do
|
|
12
|
-
expect(logger).to receive(:send).with(:info, '[Janus] Test message')
|
|
13
|
-
described_class.log('Test message', :info)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'does not log the message if logger is not set' do
|
|
17
|
-
described_class.logger = nil
|
|
18
|
-
expect(logger).not_to receive(:send)
|
|
19
|
-
described_class.log('Test message', :info)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe '.logger=' do
|
|
24
|
-
let(:logger) { double('logger') }
|
|
25
|
-
|
|
26
|
-
it 'sets the logger' do
|
|
27
|
-
described_class.logger = logger
|
|
28
|
-
expect(described_class.logger).to eq(logger)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe Janus::QueryDirector do
|
|
4
|
-
describe 'Constants' do
|
|
5
|
-
it { expect(described_class::SQL_SKIP_ALL_MATCHERS).to eq [/\A\s*set\s+local\s/i] }
|
|
6
|
-
it {
|
|
7
|
-
expect(described_class::SQL_PRIMARY_MATCHERS).to eq(
|
|
8
|
-
[
|
|
9
|
-
/\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i,
|
|
10
|
-
/\A\s*select.+(nextval|currval|lastval|get_lock|release_lock|pg_advisory_lock|pg_advisory_unlock)\(/i,
|
|
11
|
-
/\A\s*show/i
|
|
12
|
-
]
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
it { expect(described_class::SQL_REPLICA_MATCHERS).to eq([/\A\s*(select|with.+\)\s*select)\s/i]) }
|
|
16
|
-
it { expect(described_class::SQL_ALL_MATCHERS).to eq([/\A\s*set\s/i]) }
|
|
17
|
-
it {
|
|
18
|
-
expect(described_class::WRITE_PREFIXES).to eq %w(INSERT UPDATE DELETE LOCK CREATE GRANT DROP ALTER TRUNCATE BEGIN
|
|
19
|
-
SAVEPOINT FLUSH)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
it { expect(described_class::ALL).to eq :all }
|
|
23
|
-
it { expect(described_class::REPLICA).to eq :replica }
|
|
24
|
-
it { expect(described_class::PRIMARY).to eq :primary }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
describe '#where_to_send?' do
|
|
28
|
-
before(:each) do
|
|
29
|
-
Janus::Context.release_all
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context 'when should send to all' do
|
|
33
|
-
it 'returns :all' do
|
|
34
|
-
sql = 'SET foo = bar'
|
|
35
|
-
open_transactions = 0
|
|
36
|
-
query_director = described_class.new(sql, open_transactions)
|
|
37
|
-
expect(query_director.where_to_send?).to eq(:all)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
context 'when can go to replica' do
|
|
42
|
-
it 'returns :replica' do
|
|
43
|
-
sql = 'SELECT * FROM users'
|
|
44
|
-
open_transactions = 0
|
|
45
|
-
query_director = described_class.new(sql, open_transactions)
|
|
46
|
-
expect(query_director.where_to_send?).to eq(:replica)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
context 'when should go to primary' do
|
|
51
|
-
it 'returns :primary' do
|
|
52
|
-
sql = 'INSERT INTO users (name) VALUES ("John")'
|
|
53
|
-
open_transactions = 0
|
|
54
|
-
query_director = described_class.new(sql, open_transactions)
|
|
55
|
-
expect(query_director.where_to_send?).to eq(:primary)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
RSpec.shared_examples 'a mysql like server' do
|
|
3
|
-
let(:create_test_table) { ActiveRecord::Base.connection.execute("CREATE TABLE `#{table_name}` (id INT);") }
|
|
4
|
-
|
|
5
|
-
before(:each) do
|
|
6
|
-
$query_logger.flush_all
|
|
7
|
-
ActiveRecord::Base.establish_connection(config)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
after(:each) do
|
|
11
|
-
ActiveRecord::Base.connection.execute(<<-SQL
|
|
12
|
-
SELECT CONCAT('DROP TABLE IF EXISTS `', table_name, '`;')
|
|
13
|
-
FROM information_schema.tables
|
|
14
|
-
WHERE table_schema = '#{database}';
|
|
15
|
-
SQL
|
|
16
|
-
).to_a.map { |row| ActiveRecord::Base.connection.execute(row[0]) }
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'can list tables' do
|
|
20
|
-
expect(ActiveRecord::Base.connection.execute('SHOW TABLES;').to_a).to eq []
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'can create table' do
|
|
24
|
-
create_test_table
|
|
25
|
-
expect(ActiveRecord::Base.connection.execute('SHOW TABLES;').to_a).to eq [[table_name]]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
describe 'SELECT' do
|
|
29
|
-
it 'reads from `replica` by default' do
|
|
30
|
-
create_test_table
|
|
31
|
-
Janus::Context.release_all
|
|
32
|
-
$query_logger.flush_all
|
|
33
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
34
|
-
expect($query_logger.queries.first).to include '[replica]'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'will read from primary after a write operation' do
|
|
38
|
-
create_test_table
|
|
39
|
-
$query_logger.flush_all
|
|
40
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
41
|
-
expect($query_logger.queries.first).to include '[primary]'
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
describe 'INSERT' do
|
|
46
|
-
let(:insert_query) { "INSERT INTO `#{table_name}` SET `id` = 5;" }
|
|
47
|
-
|
|
48
|
-
before(:each) do
|
|
49
|
-
create_test_table
|
|
50
|
-
$query_logger.flush_all
|
|
51
|
-
Janus::Context.release_all
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it 'sends INSERT query to primary' do
|
|
55
|
-
ActiveRecord::Base.connection.execute(insert_query)
|
|
56
|
-
expect($query_logger.queries.first).to include '[primary]'
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'ignores case when directing queries' do
|
|
60
|
-
ActiveRecord::Base.connection.execute(insert_query.downcase)
|
|
61
|
-
expect($query_logger.queries.first).to include '[primary]'
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
describe 'UPDATE' do
|
|
66
|
-
before(:each) do
|
|
67
|
-
create_test_table
|
|
68
|
-
5.times { |i| ActiveRecord::Base.connection.execute("INSERT INTO `#{table_name}` SET `id` = #{i};") }
|
|
69
|
-
$query_logger.flush_all
|
|
70
|
-
Janus::Context.release_all
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it 'continues to direct after bulk update' do
|
|
74
|
-
ActiveRecord::Base.connection.execute("UPDATE `#{table_name}` SET `id` = `id` + 2;")
|
|
75
|
-
expect($query_logger.queries.first).to include '[primary]'
|
|
76
|
-
expect(Janus::Context.last_used_connection).to eq :primary
|
|
77
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
78
|
-
expect($query_logger.queries.last).to include '[primary]'
|
|
79
|
-
Janus::Context.release_all
|
|
80
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
81
|
-
expect($query_logger.queries.last).to include '[replica]'
|
|
82
|
-
expect(Janus::Context.last_used_connection).to eq :replica
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'pry'
|
|
4
|
-
|
|
5
|
-
require 'active_record'
|
|
6
|
-
|
|
7
|
-
require './lib/janus-ar'
|
|
8
|
-
require './lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter'
|
|
9
|
-
require './lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter'
|
|
10
|
-
|
|
11
|
-
ActiveRecord::ConnectionAdapters.register("janus_trilogy", "ActiveRecord::ConnectionAdapters::JanusTrilogyAdapter")
|
|
12
|
-
ActiveRecord::ConnectionAdapters.register("janus_mysql2", "ActiveRecord::ConnectionAdapters::JanusMysql2Adapter")
|
|
13
|
-
|
|
14
|
-
require './spec/shared_examples/a_mysql_like_server.rb'
|
|
15
|
-
|
|
16
|
-
class QueryLogger
|
|
17
|
-
def initialize
|
|
18
|
-
@_logs = []
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def flush_all
|
|
22
|
-
@_logs = []
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def log(level, message)
|
|
26
|
-
@_logs << "#{level}: #{message}"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def error(message)
|
|
30
|
-
log('error', message)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def queries
|
|
34
|
-
@_logs
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def debug?
|
|
38
|
-
true
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def debug(message)
|
|
42
|
-
log('debug', message)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
$query_logger = ActiveRecord::Base.logger = QueryLogger.new
|