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/lib/janus-ar/context.rb
CHANGED
|
@@ -1,80 +1,79 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def
|
|
35
|
-
@
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def
|
|
46
|
-
current.
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def
|
|
50
|
-
current.
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def
|
|
54
|
-
current.
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def
|
|
58
|
-
current.
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/isolated_execution_state'
|
|
4
|
+
|
|
5
|
+
module Janus
|
|
6
|
+
# Per-execution state that records whether the current unit of work has been
|
|
7
|
+
# pinned to the primary (e.g. after a write, so subsequent reads stay
|
|
8
|
+
# consistent). State is stored in ActiveSupport::IsolatedExecutionState so it
|
|
9
|
+
# follows the application's configured isolation level (thread or fiber),
|
|
10
|
+
# matching ActiveRecord itself.
|
|
11
|
+
#
|
|
12
|
+
# Because pooled threads/fibers are reused across requests and jobs, the
|
|
13
|
+
# context MUST be released between units of work or a thread that performed a
|
|
14
|
+
# single write would keep routing every later read to the primary. The Rails
|
|
15
|
+
# integration (see Janus::Railtie) does this automatically; outside Rails,
|
|
16
|
+
# call Janus::Context.release_all yourself (e.g. in a Sidekiq middleware).
|
|
17
|
+
class Context
|
|
18
|
+
STATE_KEY = :janus_ar_context
|
|
19
|
+
|
|
20
|
+
def initialize(primary: false)
|
|
21
|
+
@primary = primary
|
|
22
|
+
@last_used_connection = :primary
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def stick_to_primary
|
|
26
|
+
@primary = true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def release_all
|
|
30
|
+
@primary = false
|
|
31
|
+
@last_used_connection = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def use_primary?
|
|
35
|
+
@primary
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def used_connection(connection)
|
|
39
|
+
@last_used_connection = connection
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
attr_reader :last_used_connection
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
def stick_to_primary
|
|
46
|
+
current.stick_to_primary
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def release_all
|
|
50
|
+
current.release_all
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def used_connection(connection)
|
|
54
|
+
current.used_connection(connection)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def use_primary?
|
|
58
|
+
current.use_primary?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def last_used_connection
|
|
62
|
+
current.last_used_connection
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Release the context at the start of every unit of work wrapped by the
|
|
66
|
+
# given ActiveSupport executor (web requests, ActiveJob and
|
|
67
|
+
# Sidekiq-on-Rails jobs all run inside it).
|
|
68
|
+
def install_reset_hook(executor)
|
|
69
|
+
executor.to_run { Janus::Context.release_all }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
def current
|
|
75
|
+
ActiveSupport::IsolatedExecutionState[STATE_KEY] ||= new
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Janus
|
|
4
|
-
class DbConsoleConfig
|
|
5
|
-
def initialize(config)
|
|
6
|
-
@_config = config.configuration_hash
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def configuration_hash
|
|
10
|
-
@_config[:janus]['replica'].symbolize_keys
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def database
|
|
14
|
-
@_config[:database]
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Janus
|
|
4
|
+
class DbConsoleConfig
|
|
5
|
+
def initialize(config)
|
|
6
|
+
@_config = config.configuration_hash
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def configuration_hash
|
|
10
|
+
@_config[:janus]['replica'].symbolize_keys
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def database
|
|
14
|
+
@_config[:database]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Janus
|
|
4
|
-
module Logging
|
|
5
|
-
class Logger
|
|
6
|
-
class << self
|
|
7
|
-
def log(message, format = :info)
|
|
8
|
-
logger&.send(format, "[Janus] #{message}")
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
attr_accessor :logger
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Janus
|
|
4
|
+
module Logging
|
|
5
|
+
class Logger
|
|
6
|
+
class << self
|
|
7
|
+
def log(message, format = :info)
|
|
8
|
+
logger&.send(format, "[Janus] #{message}")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_accessor :logger
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Janus
|
|
4
|
-
module Logging
|
|
5
|
-
module Subscriber
|
|
6
|
-
IGNORE_PAYLOAD_NAMES = %w(SCHEMA EXPLAIN).freeze
|
|
7
|
-
|
|
8
|
-
def sql(event)
|
|
9
|
-
name = event.payload[:name]
|
|
10
|
-
unless IGNORE_PAYLOAD_NAMES.include?(name)
|
|
11
|
-
name = [current_wrapper_name(event), name].compact.join(' ')
|
|
12
|
-
event.payload[:name] = name
|
|
13
|
-
end
|
|
14
|
-
super(event)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
protected
|
|
18
|
-
|
|
19
|
-
def current_wrapper_name(_event)
|
|
20
|
-
connection = Janus::Context.last_used_connection
|
|
21
|
-
return nil unless connection
|
|
22
|
-
|
|
23
|
-
"[#{connection}]"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Janus
|
|
4
|
+
module Logging
|
|
5
|
+
module Subscriber
|
|
6
|
+
IGNORE_PAYLOAD_NAMES = %w(SCHEMA EXPLAIN).freeze
|
|
7
|
+
|
|
8
|
+
def sql(event)
|
|
9
|
+
name = event.payload[:name]
|
|
10
|
+
unless IGNORE_PAYLOAD_NAMES.include?(name)
|
|
11
|
+
name = [current_wrapper_name(event), name].compact.join(' ')
|
|
12
|
+
event.payload[:name] = name
|
|
13
|
+
end
|
|
14
|
+
super(event)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
|
|
19
|
+
def current_wrapper_name(_event)
|
|
20
|
+
connection = Janus::Context.last_used_connection
|
|
21
|
+
return nil unless connection
|
|
22
|
+
|
|
23
|
+
"[#{connection}]"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,54 +1,87 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
module Janus
|
|
3
|
-
class QueryDirector
|
|
4
|
-
ALL = :all
|
|
5
|
-
REPLICA = :replica
|
|
6
|
-
PRIMARY = :primary
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Janus
|
|
3
|
+
class QueryDirector
|
|
4
|
+
ALL = :all
|
|
5
|
+
REPLICA = :replica
|
|
6
|
+
PRIMARY = :primary
|
|
7
|
+
|
|
8
|
+
LOCK_FUNCTIONS = %w(
|
|
9
|
+
nextval currval lastval get_lock release_lock is_free_lock is_used_lock
|
|
10
|
+
pg_advisory_lock pg_advisory_unlock
|
|
11
|
+
).freeze
|
|
12
|
+
|
|
13
|
+
SQL_PRIMARY_MATCHERS = [
|
|
14
|
+
/\A\s*select\b.*\bfor\s+(update|share)\b/im,
|
|
15
|
+
/\A\s*select\b.*\block\s+in\s+share\s+mode\b/im,
|
|
16
|
+
/\A\s*select\b.*\b(#{LOCK_FUNCTIONS.join('|')})\s*\(/im,
|
|
17
|
+
/\A\s*show\b/i,
|
|
18
|
+
].freeze
|
|
19
|
+
SQL_REPLICA_MATCHERS = [/\A\s*(select|with.+\)\s*select)\s/i].freeze
|
|
20
|
+
SQL_ALL_MATCHERS = [/\A\s*set\s/i].freeze
|
|
21
|
+
SQL_SKIP_ALL_MATCHERS = [/\A\s*set\s+local\s/i].freeze
|
|
22
|
+
|
|
23
|
+
# Leading whitespace and SQL comments are stripped before matching so that an
|
|
24
|
+
# annotated statement (e.g. `/* app:web */ INSERT ...`) is classified by the
|
|
25
|
+
# statement itself rather than by the comment.
|
|
26
|
+
LEADING_NOISE = %r{\A(?:\s+|/\*.*?\*/|--[^\n]*(?:\n|\z)|\#[^\n]*(?:\n|\z))+}m
|
|
27
|
+
|
|
28
|
+
def initialize(sql, open_transactions)
|
|
29
|
+
@_sql = sql
|
|
30
|
+
@_open_transactions = open_transactions
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def where_to_send?
|
|
34
|
+
if should_send_to_all?
|
|
35
|
+
ALL
|
|
36
|
+
elsif can_go_to_replica?
|
|
37
|
+
REPLICA
|
|
38
|
+
else
|
|
39
|
+
PRIMARY
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def should_send_to_all?
|
|
46
|
+
match_any?(SQL_ALL_MATCHERS) && !match_any?(SQL_SKIP_ALL_MATCHERS)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# A replica may only serve a statement we positively recognise as a read and
|
|
50
|
+
# that nothing else forces onto the primary. Everything we do not recognise
|
|
51
|
+
# as a read defaults to the primary, which is the safe direction for a
|
|
52
|
+
# write/read proxy: a misrouted read only costs a little primary load, while
|
|
53
|
+
# a misrouted write is an error (or worse) against a read-only replica.
|
|
54
|
+
#
|
|
55
|
+
# Because this is only reached for a confirmed read, there is no need to also
|
|
56
|
+
# test for a write here.
|
|
57
|
+
def can_go_to_replica?
|
|
58
|
+
read_query? && !should_go_to_primary?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def read_query?
|
|
62
|
+
match_any?(SQL_REPLICA_MATCHERS)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def should_go_to_primary?
|
|
66
|
+
Janus::Context.use_primary? ||
|
|
67
|
+
@_open_transactions.positive? ||
|
|
68
|
+
match_any?(SQL_PRIMARY_MATCHERS)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def match_any?(matchers)
|
|
72
|
+
matchers.any? { |matcher| normalized_sql.match?(matcher) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Avoid copying the statement when there is no leading comment/whitespace to
|
|
76
|
+
# strip, which is the common case for ActiveRecord-generated SQL.
|
|
77
|
+
def normalized_sql
|
|
78
|
+
@normalized_sql ||= strip_leading_noise
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def strip_leading_noise
|
|
82
|
+
return @_sql unless LEADING_NOISE.match?(@_sql)
|
|
83
|
+
|
|
84
|
+
@_sql.sub(LEADING_NOISE, '')
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/railtie'
|
|
4
|
+
|
|
5
|
+
module Janus
|
|
6
|
+
class Railtie < ::Rails::Railtie
|
|
7
|
+
# Clear Janus' per-request primary stickiness at the start of every unit of
|
|
8
|
+
# work wrapped by the Rails executor (web requests, ActiveJob and
|
|
9
|
+
# Sidekiq-on-Rails jobs). Without this, a pooled thread that performs a
|
|
10
|
+
# write keeps routing reads to the primary for the rest of its life.
|
|
11
|
+
initializer 'janus.clear_context_per_execution' do |app|
|
|
12
|
+
Janus::Context.install_reset_hook(app.executor)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/janus-ar/version.rb
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Janus
|
|
4
|
-
unless defined?(::Janus::VERSION)
|
|
5
|
-
module VERSION
|
|
6
|
-
MAJOR = 8
|
|
7
|
-
MINOR =
|
|
8
|
-
PATCH = 0
|
|
9
|
-
PRE = nil
|
|
10
|
-
|
|
11
|
-
def self.to_s
|
|
12
|
-
[MAJOR, MINOR, PATCH, PRE].compact.join('.')
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
::Janus::VERSION
|
|
17
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Janus
|
|
4
|
+
unless defined?(::Janus::VERSION)
|
|
5
|
+
module VERSION
|
|
6
|
+
MAJOR = 8
|
|
7
|
+
MINOR = 1
|
|
8
|
+
PATCH = 0
|
|
9
|
+
PRE = nil
|
|
10
|
+
|
|
11
|
+
def self.to_s
|
|
12
|
+
[MAJOR, MINOR, PATCH, PRE].compact.join('.')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
::Janus::VERSION
|
|
17
|
+
end
|
data/lib/janus-ar.rb
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'active_support'
|
|
4
|
-
|
|
5
|
-
module Janus
|
|
6
|
-
autoload :Context, 'janus-ar/context'
|
|
7
|
-
autoload :Client, 'janus-ar/client'
|
|
8
|
-
autoload :QueryDirector, 'janus-ar/query_director'
|
|
9
|
-
autoload :VERSION, 'janus-ar/version'
|
|
10
|
-
autoload :DbConsoleConfig, 'janus-ar/db_console_config'
|
|
11
|
-
|
|
12
|
-
module Logging
|
|
13
|
-
autoload :Subscriber, 'janus-ar/logging/subscriber'
|
|
14
|
-
autoload :Logger, 'janus-ar/logging/logger'
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
ActiveSupport.on_load(:active_record) do
|
|
19
|
-
ActiveRecord::LogSubscriber.log_subscribers.each do |subscriber|
|
|
20
|
-
subscriber.extend Janus::Logging::Subscriber
|
|
21
|
-
end
|
|
22
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
|
|
5
|
+
module Janus
|
|
6
|
+
autoload :Context, 'janus-ar/context'
|
|
7
|
+
autoload :Client, 'janus-ar/client'
|
|
8
|
+
autoload :QueryDirector, 'janus-ar/query_director'
|
|
9
|
+
autoload :VERSION, 'janus-ar/version'
|
|
10
|
+
autoload :DbConsoleConfig, 'janus-ar/db_console_config'
|
|
11
|
+
|
|
12
|
+
module Logging
|
|
13
|
+
autoload :Subscriber, 'janus-ar/logging/subscriber'
|
|
14
|
+
autoload :Logger, 'janus-ar/logging/logger'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
ActiveSupport.on_load(:active_record) do
|
|
19
|
+
ActiveRecord::LogSubscriber.log_subscribers.each do |subscriber|
|
|
20
|
+
subscriber.extend Janus::Logging::Subscriber
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require 'janus-ar/railtie' if defined?(Rails::Railtie)
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: janus-ar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lloyd Watkin
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -120,28 +119,28 @@ dependencies:
|
|
|
120
119
|
requirements:
|
|
121
120
|
- - "~>"
|
|
122
121
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: 1.
|
|
122
|
+
version: 1.90.0
|
|
124
123
|
type: :development
|
|
125
124
|
prerelease: false
|
|
126
125
|
version_requirements: !ruby/object:Gem::Requirement
|
|
127
126
|
requirements:
|
|
128
127
|
- - "~>"
|
|
129
128
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: 1.
|
|
129
|
+
version: 1.90.0
|
|
131
130
|
- !ruby/object:Gem::Dependency
|
|
132
131
|
name: rubocop-rails
|
|
133
132
|
requirement: !ruby/object:Gem::Requirement
|
|
134
133
|
requirements:
|
|
135
134
|
- - "~>"
|
|
136
135
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: 2.
|
|
136
|
+
version: 2.37.0
|
|
138
137
|
type: :development
|
|
139
138
|
prerelease: false
|
|
140
139
|
version_requirements: !ruby/object:Gem::Requirement
|
|
141
140
|
requirements:
|
|
142
141
|
- - "~>"
|
|
143
142
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: 2.
|
|
143
|
+
version: 2.37.0
|
|
145
144
|
- !ruby/object:Gem::Dependency
|
|
146
145
|
name: rubocop-rspec
|
|
147
146
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -187,52 +186,34 @@ dependencies:
|
|
|
187
186
|
description: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
188
187
|
email:
|
|
189
188
|
- lloyd@olioex.com
|
|
190
|
-
executables:
|
|
191
|
-
- release.sh
|
|
189
|
+
executables: []
|
|
192
190
|
extensions: []
|
|
193
191
|
extra_rdoc_files: []
|
|
194
192
|
files:
|
|
195
|
-
- ".bundle/config"
|
|
196
|
-
- ".github/dependabot.yml"
|
|
197
|
-
- ".github/workflows/ci.yml"
|
|
198
|
-
- ".github/workflows/publish.yml"
|
|
199
|
-
- ".gitignore"
|
|
200
|
-
- ".rspec"
|
|
201
|
-
- ".rubocop.yml"
|
|
202
193
|
- CODE_OF_CONDUCT.md
|
|
203
194
|
- Gemfile
|
|
204
195
|
- Gemfile.lock
|
|
205
196
|
- LICENSE
|
|
206
197
|
- README.md
|
|
207
198
|
- Rakefile
|
|
208
|
-
- assets/.gitkeep
|
|
209
|
-
- assets/janus-logo.png
|
|
210
|
-
- bin/release.sh
|
|
211
199
|
- janus-ar.gemspec
|
|
212
200
|
- lib/janus-ar.rb
|
|
213
201
|
- lib/janus-ar/active_record/connection_adapters/janus_mysql2_adapter.rb
|
|
214
202
|
- lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter.rb
|
|
203
|
+
- lib/janus-ar/adapter_extensions.rb
|
|
215
204
|
- lib/janus-ar/client.rb
|
|
216
205
|
- lib/janus-ar/context.rb
|
|
217
206
|
- lib/janus-ar/db_console_config.rb
|
|
218
207
|
- lib/janus-ar/logging/logger.rb
|
|
219
208
|
- lib/janus-ar/logging/subscriber.rb
|
|
220
209
|
- lib/janus-ar/query_director.rb
|
|
210
|
+
- lib/janus-ar/railtie.rb
|
|
221
211
|
- lib/janus-ar/version.rb
|
|
222
|
-
- spec/lib/janus-ar/active_record/connection_adapters/janus_mysql_adapter_spec.rb
|
|
223
|
-
- spec/lib/janus-ar/active_record/connection_adapters/janus_trilogy_adapter_spec.rb
|
|
224
|
-
- spec/lib/janus-ar/client_spec.rb
|
|
225
|
-
- spec/lib/janus-ar/context_spec.rb
|
|
226
|
-
- spec/lib/janus-ar/logging/logger_spec.rb
|
|
227
|
-
- spec/lib/janus-ar/query_director_spec.rb
|
|
228
|
-
- spec/shared_examples/a_mysql_like_server.rb
|
|
229
|
-
- spec/spec_helper.rb
|
|
230
212
|
homepage: https://github.com/olioex/janus-ar
|
|
231
213
|
licenses:
|
|
232
214
|
- MIT
|
|
233
215
|
metadata:
|
|
234
216
|
source_code_uri: https://github.com/olioex/janus-ar
|
|
235
|
-
post_install_message:
|
|
236
217
|
rdoc_options: []
|
|
237
218
|
require_paths:
|
|
238
219
|
- lib
|
|
@@ -247,8 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
247
228
|
- !ruby/object:Gem::Version
|
|
248
229
|
version: '0'
|
|
249
230
|
requirements: []
|
|
250
|
-
rubygems_version: 3.
|
|
251
|
-
signing_key:
|
|
231
|
+
rubygems_version: 3.6.9
|
|
252
232
|
specification_version: 4
|
|
253
233
|
summary: Read/Write proxy for ActiveRecord using primary/replica databases
|
|
254
234
|
test_files: []
|
data/.bundle/config
DELETED