janus-ar 8.0.1 → 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 +24 -24
- data/README.md +24 -1
- data/janus-ar.gemspec +6 -4
- data/lib/janus-ar/adapter_extensions.rb +5 -0
- data/lib/janus-ar/client.rb +6 -6
- 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 +9 -3
- data/lib/janus-ar/version.rb +2 -2
- metadata +8 -31
- data/.bundle/config +0 -5
- data/.github/dependabot.yml +0 -7
- data/.github/workflows/ci.yml +0 -68
- data/.github/workflows/publish.yml +0 -25
- data/.gitignore +0 -3
- data/.rspec +0 -3
- data/.rubocop.yml +0 -29
- data/assets/.gitkeep +0 -1
- data/assets/janus-logo.png +0 -0
- data/bin/release.sh +0 -4
- data/gemfiles/activerecord_8_0.gemfile +0 -7
- data/gemfiles/activerecord_8_1.gemfile +0 -7
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb +0 -78
- data/spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb +0 -77
- data/spec/lib/janus-ar/client_spec.rb +0 -7
- data/spec/lib/janus-ar/context_spec.rb +0 -118
- data/spec/lib/janus-ar/db_console_config_spec.rb +0 -28
- data/spec/lib/janus-ar/logging/logger_spec.rb +0 -31
- data/spec/lib/janus-ar/logging/subscriber_spec.rb +0 -58
- data/spec/lib/janus-ar/query_director_spec.rb +0 -141
- data/spec/shared_examples/a_mysql_like_server.rb +0 -155
- data/spec/spec_helper.rb +0 -46
|
@@ -1,155 +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
|
-
|
|
86
|
-
describe 'ActiveRecord compatibility' do
|
|
87
|
-
before(:each) do
|
|
88
|
-
create_test_table
|
|
89
|
-
Janus::Context.release_all
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
it 'accepts the optional name argument on #execute' do
|
|
93
|
-
expect do
|
|
94
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;", 'CustomName')
|
|
95
|
-
end.not_to raise_error
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it 'returns a usable result through the exec_query read path' do
|
|
99
|
-
ActiveRecord::Base.connection.execute("INSERT INTO `#{table_name}` SET `id` = 7;")
|
|
100
|
-
Janus::Context.release_all
|
|
101
|
-
$query_logger.flush_all
|
|
102
|
-
|
|
103
|
-
result = ActiveRecord::Base.connection.exec_query("SELECT `id` FROM `#{table_name}`")
|
|
104
|
-
|
|
105
|
-
expect(result.rows).to eq [[7]]
|
|
106
|
-
expect($query_logger.queries.first).to include '[replica]'
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
describe 'Transactions' do
|
|
111
|
-
before(:each) do
|
|
112
|
-
create_test_table
|
|
113
|
-
Janus::Context.release_all
|
|
114
|
-
$query_logger.flush_all
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it 'routes reads inside a transaction to the primary' do
|
|
118
|
-
ActiveRecord::Base.transaction do
|
|
119
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
selects = $query_logger.queries.select { |q| q.downcase.include?("select * from `#{table_name}`") }
|
|
123
|
-
expect(selects).not_to be_empty
|
|
124
|
-
expect(selects).to all(include('[primary]'))
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it 'keeps later reads on the primary until the context is released' do
|
|
128
|
-
ActiveRecord::Base.transaction do
|
|
129
|
-
ActiveRecord::Base.connection.execute("INSERT INTO `#{table_name}` SET `id` = 1;")
|
|
130
|
-
end
|
|
131
|
-
$query_logger.flush_all
|
|
132
|
-
|
|
133
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
134
|
-
expect($query_logger.queries.last).to include '[primary]'
|
|
135
|
-
|
|
136
|
-
Janus::Context.release_all
|
|
137
|
-
ActiveRecord::Base.connection.execute("SELECT * FROM `#{table_name}`;")
|
|
138
|
-
expect($query_logger.queries.last).to include '[replica]'
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
describe 'SET statements' do
|
|
143
|
-
before(:each) { Janus::Context.release_all }
|
|
144
|
-
|
|
145
|
-
it 'sends a session SET down the broadcast (:all) path without error' do
|
|
146
|
-
expect do
|
|
147
|
-
ActiveRecord::Base.connection.execute("SET SESSION time_zone = '+00:00'")
|
|
148
|
-
end.not_to raise_error
|
|
149
|
-
|
|
150
|
-
# `:all` means the statement ran against the replica connection too, not
|
|
151
|
-
# just the primary - a write would have been marked `:primary`.
|
|
152
|
-
expect(Janus::Context.last_used_connection).to eq :all
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
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
|