activerecord-trilogy-adapter 2.2.0 → 3.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 065e502503fb93e0e951b03e67c43b8ea257a01c681c077b5b904a95ddcb0c90
|
4
|
+
data.tar.gz: 2a85e79e0654196e0dba708f7bbc4146c413bf0f0b135894357bc174374c76fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ed2509f2e8593d3d1b73c56b403875a1751f50c5e5ae99fc405fead7020ec43c5b9e0510e196b3818a5cc1335480062a8c75e2cfebb757ca19c46fa9d1404be
|
7
|
+
data.tar.gz: 45d9e001bee0aa227b2e7a7ac2f3b009d009f312cc2af128d5be0275c5f9ff2ce7b496ebde2ca7df1fedfd7a9a6b235df9fef1cfaf2309ca374357ba14d0a485
|
data/README.md
CHANGED
@@ -1,23 +1,34 @@
|
|
1
1
|
# Trilogy Adapter
|
2
2
|
|
3
|
-
Active Record database adapter for [Trilogy](https://github.com/
|
3
|
+
Ruby on Rails Active Record database adapter for [Trilogy](https://github.com/trilogy-libraries/trilogy), a client library for MySQL-compatible database servers, designed for performance, flexibility, and ease of embedding.
|
4
|
+
|
5
|
+
This gem offers Trilogy support for versions of Active Record prior to v7.1. Currently supports:
|
6
|
+
|
7
|
+
- ⚠️ Rails v7.1+ includes Trilogy support by default making this gem unnecessary
|
8
|
+
- ✅ Rails v7.0.x
|
9
|
+
- ✅ Rails v6.1.x
|
10
|
+
- ✅ Rails v6.0.x
|
4
11
|
|
5
12
|
## Requirements
|
6
13
|
|
7
|
-
- [Ruby](https://www.ruby-lang.org)
|
8
|
-
- [Active Record](https://github.com/rails/rails)
|
9
|
-
- [Trilogy](https://github.com/
|
14
|
+
- [Ruby](https://www.ruby-lang.org) v2.7 or higher
|
15
|
+
- [Active Record](https://github.com/rails/rails) v6.0.x or higher
|
16
|
+
- [Trilogy](https://github.com/trilogy-libraries/trilogy) v2.4.0 or higher, which is included as a dependency of this gem.
|
10
17
|
|
11
18
|
## Setup
|
12
19
|
|
13
|
-
|
20
|
+
1. Add the following to your `Gemfile` and run `bundle install`:
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
```rb
|
23
|
+
# Gemfile
|
24
|
+
gem "activerecord-trilogy-adapter"
|
25
|
+
```
|
26
|
+
2. Update your application's database configuration to use `trilogy` as the adapter:
|
18
27
|
|
19
|
-
|
20
|
-
|
28
|
+
```yaml
|
29
|
+
# config/database.yml
|
30
|
+
adapter: trilogy
|
31
|
+
```
|
21
32
|
|
22
33
|
## Versioning
|
23
34
|
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Trilogy
|
6
|
+
module DatabaseStatements
|
7
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
8
|
+
:desc, :describe, :set, :show, :use
|
9
|
+
) # :nodoc:
|
10
|
+
private_constant :READ_QUERY
|
11
|
+
|
12
|
+
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP(6)").freeze # :nodoc:
|
13
|
+
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
|
14
|
+
|
15
|
+
def write_query?(sql) # :nodoc:
|
16
|
+
!READ_QUERY.match?(sql)
|
17
|
+
rescue ArgumentError # Invalid encoding
|
18
|
+
!READ_QUERY.match?(sql.b)
|
19
|
+
end
|
20
|
+
|
21
|
+
def explain(arel, binds = [])
|
22
|
+
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
23
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
24
|
+
result = internal_exec_query(sql, "EXPLAIN", binds)
|
25
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
26
|
+
|
27
|
+
MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
|
28
|
+
end
|
29
|
+
|
30
|
+
def select_all(*, **) # :nodoc:
|
31
|
+
result = super
|
32
|
+
with_trilogy_connection do |conn|
|
33
|
+
conn.next_result while conn.more_results_exist?
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false, **kwargs)
|
39
|
+
internal_exec_query(sql, name, binds, prepare: prepare, **kwargs)
|
40
|
+
end
|
41
|
+
|
42
|
+
def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false) # :nodoc:
|
43
|
+
sql = transform_query(sql)
|
44
|
+
check_if_write_query(sql)
|
45
|
+
mark_transaction_written_if_write(sql)
|
46
|
+
|
47
|
+
result = raw_execute(sql, name, async: async)
|
48
|
+
ActiveRecord::Result.new(result.fields, result.to_a)
|
49
|
+
end
|
50
|
+
|
51
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil, returning: nil) # :nodoc:
|
52
|
+
sql = transform_query(sql)
|
53
|
+
check_if_write_query(sql)
|
54
|
+
mark_transaction_written_if_write(sql)
|
55
|
+
|
56
|
+
raw_execute(to_sql(sql, binds), name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def exec_delete(sql, name = nil, binds = []) # :nodoc:
|
60
|
+
sql = transform_query(sql)
|
61
|
+
check_if_write_query(sql)
|
62
|
+
mark_transaction_written_if_write(sql)
|
63
|
+
|
64
|
+
result = raw_execute(to_sql(sql, binds), name)
|
65
|
+
result.affected_rows
|
66
|
+
end
|
67
|
+
|
68
|
+
alias :exec_update :exec_delete # :nodoc:
|
69
|
+
|
70
|
+
def high_precision_current_timestamp
|
71
|
+
HIGH_PRECISION_CURRENT_TIMESTAMP
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
if ActiveRecord.version < ::Gem::Version.new('7.0.a') # ActiveRecord <= 6.1 support
|
76
|
+
def raw_execute(sql, name, uses_transaction: true, **_kwargs)
|
77
|
+
# Same as mark_transaction_written_if_write(sql)
|
78
|
+
transaction = current_transaction
|
79
|
+
if transaction.respond_to?(:written) && transaction.open?
|
80
|
+
transaction.written ||= write_query?(sql)
|
81
|
+
end
|
82
|
+
|
83
|
+
log(sql, name) do
|
84
|
+
with_trilogy_connection(uses_transaction: uses_transaction) do |conn|
|
85
|
+
sync_timezone_changes(conn)
|
86
|
+
conn.query(sql)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def transform_query(sql); sql; end
|
92
|
+
def check_if_write_query(*args); end
|
93
|
+
|
94
|
+
if ActiveRecord.version < ::Gem::Version.new('6.1.a') # ActiveRecord <= 6.0 support
|
95
|
+
def mark_transaction_written_if_write(*args); end
|
96
|
+
end
|
97
|
+
else # ActiveRecord 7.0 support
|
98
|
+
def raw_execute(sql, name, uses_transaction: true, async: false, allow_retry: false)
|
99
|
+
mark_transaction_written_if_write(sql)
|
100
|
+
log(sql, name, async: async) do
|
101
|
+
with_trilogy_connection(uses_transaction: uses_transaction, allow_retry: allow_retry) do |conn|
|
102
|
+
sync_timezone_changes(conn)
|
103
|
+
conn.query(sql)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def last_inserted_id(result)
|
110
|
+
result.last_insert_id
|
111
|
+
end
|
112
|
+
|
113
|
+
def sync_timezone_changes(conn)
|
114
|
+
# Sync any changes since connection last established.
|
115
|
+
if default_timezone == :local
|
116
|
+
conn.query_flags |= ::Trilogy::QUERY_FLAGS_LOCAL_TIMEZONE
|
117
|
+
else
|
118
|
+
conn.query_flags &= ~::Trilogy::QUERY_FLAGS_LOCAL_TIMEZONE
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -4,76 +4,82 @@ require "trilogy"
|
|
4
4
|
require "active_record/connection_adapters/abstract_mysql_adapter"
|
5
5
|
|
6
6
|
require "active_record/tasks/trilogy_database_tasks"
|
7
|
+
require "active_record/connection_adapters/trilogy/database_statements"
|
7
8
|
require "trilogy_adapter/lost_connection_exception_translator"
|
8
9
|
|
9
10
|
module ActiveRecord
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
private_constant :READ_QUERY
|
17
|
-
|
18
|
-
def write_query?(sql) # :nodoc:
|
19
|
-
!READ_QUERY.match?(sql)
|
20
|
-
rescue ArgumentError # Invalid encoding
|
21
|
-
!READ_QUERY.match?(sql.b)
|
22
|
-
end
|
23
|
-
|
24
|
-
def explain(arel, binds = [])
|
25
|
-
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
26
|
-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
27
|
-
result = exec_query(sql, "EXPLAIN", binds)
|
28
|
-
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
11
|
+
# ActiveRecord <= 6.1 support
|
12
|
+
if ActiveRecord.version < ::Gem::Version.new('7.0.a')
|
13
|
+
class DatabaseConnectionError < ConnectionNotEstablished
|
14
|
+
def initialize(message = nil)
|
15
|
+
super(message || "Database connection error")
|
16
|
+
end
|
29
17
|
|
30
|
-
|
18
|
+
class << self
|
19
|
+
def hostname_error(hostname)
|
20
|
+
DatabaseConnectionError.new(<<~MSG)
|
21
|
+
There is an issue connecting with your hostname: #{hostname}.\n
|
22
|
+
Please check your database configuration and ensure there is a valid connection to your database.
|
23
|
+
MSG
|
31
24
|
end
|
32
25
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
26
|
+
def username_error(username)
|
27
|
+
DatabaseConnectionError.new(<<~MSG)
|
28
|
+
There is an issue connecting to your database with your username/password, username: #{username}.\n
|
29
|
+
Please check your database configuration to ensure the username/password are valid.
|
30
|
+
MSG
|
36
31
|
end
|
32
|
+
end
|
33
|
+
end
|
37
34
|
|
38
|
-
|
35
|
+
NoDatabaseError.class_exec do
|
36
|
+
def self.db_error(db_name)
|
37
|
+
NoDatabaseError.new(<<~MSG)
|
38
|
+
We could not find your database: #{db_name}. Available database configurations can be found in config/database.yml file.
|
39
39
|
|
40
|
-
|
41
|
-
execute(to_sql(sql, binds), name)
|
42
|
-
end
|
40
|
+
To resolve this error:
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
result.affected_rows
|
47
|
-
end
|
42
|
+
- Did you create the database for this app, or delete it? You may need to create your database.
|
43
|
+
- Has the database name changed? Check your database.yml config has the correct database name.
|
48
44
|
|
49
|
-
|
45
|
+
To create your database, run:\n\n bin/rails db:create
|
46
|
+
MSG
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
if ActiveRecord.version < ::Gem::Version.new('6.1.a') # ActiveRecord <= 6.0 support
|
52
|
+
require "active_record/database_configurations"
|
53
|
+
DatabaseConfigurations.class_exec do
|
54
|
+
def resolve(config) # :nodoc:
|
55
|
+
@resolver ||= ::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(::ActiveRecord::Base.configurations)
|
56
|
+
@resolver.resolve(config)
|
55
57
|
end
|
58
|
+
end
|
59
|
+
end
|
56
60
|
|
61
|
+
module ConnectionAdapters
|
62
|
+
class TrilogyAdapter < ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
|
57
63
|
ER_BAD_DB_ERROR = 1049
|
58
64
|
ER_ACCESS_DENIED_ERROR = 1045
|
59
65
|
|
60
66
|
ADAPTER_NAME = "Trilogy"
|
61
67
|
|
62
|
-
include DatabaseStatements
|
68
|
+
include Trilogy::DatabaseStatements
|
63
69
|
|
64
70
|
SSL_MODES = {
|
65
|
-
SSL_MODE_DISABLED: Trilogy::SSL_DISABLED,
|
66
|
-
SSL_MODE_PREFERRED: Trilogy::SSL_PREFERRED_NOVERIFY,
|
67
|
-
SSL_MODE_REQUIRED: Trilogy::SSL_REQUIRED_NOVERIFY,
|
68
|
-
SSL_MODE_VERIFY_CA: Trilogy::SSL_VERIFY_CA,
|
69
|
-
SSL_MODE_VERIFY_IDENTITY: Trilogy::SSL_VERIFY_IDENTITY
|
71
|
+
SSL_MODE_DISABLED: ::Trilogy::SSL_DISABLED,
|
72
|
+
SSL_MODE_PREFERRED: ::Trilogy::SSL_PREFERRED_NOVERIFY,
|
73
|
+
SSL_MODE_REQUIRED: ::Trilogy::SSL_REQUIRED_NOVERIFY,
|
74
|
+
SSL_MODE_VERIFY_CA: ::Trilogy::SSL_VERIFY_CA,
|
75
|
+
SSL_MODE_VERIFY_IDENTITY: ::Trilogy::SSL_VERIFY_IDENTITY
|
70
76
|
}.freeze
|
71
77
|
|
72
78
|
class << self
|
73
79
|
def new_client(config)
|
74
80
|
config[:ssl_mode] = parse_ssl_mode(config[:ssl_mode]) if config[:ssl_mode]
|
75
81
|
::Trilogy.new(config)
|
76
|
-
rescue Trilogy::ConnectionError, Trilogy::ProtocolError => error
|
82
|
+
rescue ::Trilogy::ConnectionError, ::Trilogy::ProtocolError => error
|
77
83
|
raise translate_connect_error(config, error)
|
78
84
|
end
|
79
85
|
|
@@ -81,7 +87,6 @@ module ActiveRecord
|
|
81
87
|
return mode if mode.is_a? Integer
|
82
88
|
|
83
89
|
m = mode.to_s.upcase
|
84
|
-
# enable Mysql2 client compatibility
|
85
90
|
m = "SSL_MODE_#{m}" unless m.start_with? "SSL_MODE_"
|
86
91
|
|
87
92
|
SSL_MODES.fetch(m.to_sym, mode)
|
@@ -94,15 +99,38 @@ module ActiveRecord
|
|
94
99
|
when ER_ACCESS_DENIED_ERROR
|
95
100
|
ActiveRecord::DatabaseConnectionError.username_error(config[:username])
|
96
101
|
else
|
97
|
-
if error.message.
|
102
|
+
if error.message.include?("TRILOGY_DNS_ERROR")
|
98
103
|
ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
|
99
104
|
else
|
100
105
|
ActiveRecord::ConnectionNotEstablished.new(error.message)
|
101
106
|
end
|
102
107
|
end
|
103
108
|
end
|
109
|
+
|
110
|
+
private
|
111
|
+
def initialize_type_map(m)
|
112
|
+
super if ActiveRecord.version >= ::Gem::Version.new('7.0.a')
|
113
|
+
|
114
|
+
m.register_type(%r(char)i) do |sql_type|
|
115
|
+
limit = extract_limit(sql_type)
|
116
|
+
Type.lookup(:string, adapter: :trilogy, limit: limit)
|
117
|
+
end
|
118
|
+
|
119
|
+
m.register_type %r(^enum)i, Type.lookup(:string, adapter: :trilogy)
|
120
|
+
m.register_type %r(^set)i, Type.lookup(:string, adapter: :trilogy)
|
121
|
+
end
|
104
122
|
end
|
105
123
|
|
124
|
+
def initialize(connection, logger, connection_options, config)
|
125
|
+
super
|
126
|
+
# Ensure that we're treating prepared_statements in the same way that Rails 7.1 does
|
127
|
+
@prepared_statements = self.class.type_cast_config_to_boolean(
|
128
|
+
@config.fetch(:prepared_statements) { default_prepared_statements }
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
133
|
+
|
106
134
|
def supports_json?
|
107
135
|
!mariadb? && database_version >= "5.7.8"
|
108
136
|
end
|
@@ -128,12 +156,41 @@ module ActiveRecord
|
|
128
156
|
end
|
129
157
|
|
130
158
|
def quote_string(string)
|
131
|
-
|
159
|
+
with_trilogy_connection(allow_retry: true, uses_transaction: false) do |conn|
|
132
160
|
conn.escape(string)
|
133
161
|
end
|
134
162
|
end
|
135
163
|
|
164
|
+
def connect!
|
165
|
+
verify!
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
def reconnect!
|
170
|
+
@lock.synchronize do
|
171
|
+
disconnect!
|
172
|
+
connect
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def with_trilogy_connection(uses_transaction: true, **_kwargs)
|
177
|
+
@lock.synchronize do
|
178
|
+
verify!
|
179
|
+
materialize_transactions if uses_transaction
|
180
|
+
yield connection
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def execute(sql, name = nil, allow_retry: false, **kwargs)
|
185
|
+
sql = transform_query(sql)
|
186
|
+
check_if_write_query(sql)
|
187
|
+
|
188
|
+
raw_execute(sql, name, allow_retry: allow_retry, **kwargs)
|
189
|
+
end
|
190
|
+
|
136
191
|
def active?
|
192
|
+
return false if connection&.closed?
|
193
|
+
|
137
194
|
connection&.ping || false
|
138
195
|
rescue ::Trilogy::Error
|
139
196
|
false
|
@@ -150,39 +207,41 @@ module ActiveRecord
|
|
150
207
|
end
|
151
208
|
|
152
209
|
def discard!
|
153
|
-
|
210
|
+
super
|
211
|
+
unless connection.nil?
|
212
|
+
connection.discard!
|
213
|
+
self.connection = nil
|
214
|
+
end
|
154
215
|
end
|
155
216
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
keys = result.fields.map(&:to_sym)
|
160
|
-
result.rows.each do |row|
|
161
|
-
hash = {}
|
162
|
-
idx = 0
|
163
|
-
row.each do |value|
|
164
|
-
hash[keys[idx]] = value
|
165
|
-
idx += 1
|
166
|
-
end
|
167
|
-
yield hash
|
217
|
+
private
|
218
|
+
def text_type?(type)
|
219
|
+
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
|
168
220
|
end
|
169
221
|
|
170
|
-
|
171
|
-
|
222
|
+
def each_hash(result)
|
223
|
+
return to_enum(:each_hash, result) unless block_given?
|
172
224
|
|
173
|
-
|
174
|
-
|
175
|
-
|
225
|
+
keys = result.fields.map(&:to_sym)
|
226
|
+
result.rows.each do |row|
|
227
|
+
hash = {}
|
228
|
+
idx = 0
|
229
|
+
row.each do |value|
|
230
|
+
hash[keys[idx]] = value
|
231
|
+
idx += 1
|
232
|
+
end
|
233
|
+
yield hash
|
234
|
+
end
|
176
235
|
|
177
|
-
|
178
|
-
def connection
|
179
|
-
@raw_connection
|
236
|
+
nil
|
180
237
|
end
|
181
238
|
|
182
|
-
def
|
183
|
-
|
239
|
+
def error_number(exception)
|
240
|
+
exception.error_code if exception.respond_to?(:error_code)
|
184
241
|
end
|
185
242
|
|
243
|
+
attr_accessor :connection
|
244
|
+
|
186
245
|
def connect
|
187
246
|
self.connection = self.class.new_client(@config)
|
188
247
|
end
|
@@ -193,26 +252,85 @@ module ActiveRecord
|
|
193
252
|
connect
|
194
253
|
end
|
195
254
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
255
|
+
def execute_batch(statements, name = nil)
|
256
|
+
statements = statements.map { |sql| transform_query(sql) } if respond_to?(:transform_query)
|
257
|
+
combine_multi_statements(statements).each do |statement|
|
258
|
+
with_trilogy_connection do |conn|
|
259
|
+
raw_execute(statement, name)
|
260
|
+
conn.next_result while conn.more_results_exist?
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def multi_statements_enabled?
|
266
|
+
!!@config[:multi_statement]
|
267
|
+
end
|
268
|
+
|
269
|
+
def with_multi_statements
|
270
|
+
if multi_statements_enabled?
|
271
|
+
return yield
|
272
|
+
end
|
273
|
+
|
274
|
+
with_trilogy_connection do |conn|
|
275
|
+
conn.set_server_option(::Trilogy::SET_SERVER_MULTI_STATEMENTS_ON)
|
276
|
+
|
277
|
+
yield
|
278
|
+
ensure
|
279
|
+
conn.set_server_option(::Trilogy::SET_SERVER_MULTI_STATEMENTS_OFF)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def combine_multi_statements(total_sql)
|
284
|
+
total_sql.each_with_object([]) do |sql, total_sql_chunks|
|
285
|
+
previous_packet = total_sql_chunks.last
|
286
|
+
if max_allowed_packet_reached?(sql, previous_packet)
|
287
|
+
total_sql_chunks << +sql
|
288
|
+
else
|
289
|
+
previous_packet << ";\n"
|
290
|
+
previous_packet << sql
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def max_allowed_packet_reached?(current_packet, previous_packet)
|
296
|
+
if current_packet.bytesize > max_allowed_packet
|
297
|
+
raise ActiveRecordError,
|
298
|
+
"Fixtures set is too large #{current_packet.bytesize}. Consider increasing the max_allowed_packet variable."
|
299
|
+
elsif previous_packet.nil?
|
300
|
+
true
|
200
301
|
else
|
201
|
-
|
302
|
+
(current_packet.bytesize + previous_packet.bytesize + 2) > max_allowed_packet
|
202
303
|
end
|
203
304
|
end
|
204
305
|
|
306
|
+
def max_allowed_packet
|
307
|
+
@max_allowed_packet ||= show_variable("max_allowed_packet")
|
308
|
+
end
|
309
|
+
|
205
310
|
def full_version
|
206
311
|
schema_cache.database_version.full_version_string
|
207
312
|
end
|
208
313
|
|
209
314
|
def get_full_version
|
210
|
-
|
315
|
+
with_trilogy_connection(allow_retry: true, uses_transaction: false) do |conn|
|
211
316
|
conn.server_info[:version]
|
212
317
|
end
|
213
318
|
end
|
214
319
|
|
320
|
+
if ActiveRecord.version < ::Gem::Version.new('7.0.a') # For ActiveRecord <= 6.1
|
321
|
+
def default_timezone
|
322
|
+
ActiveRecord::Base.default_timezone
|
323
|
+
end
|
324
|
+
else # For ActiveRecord 7.0
|
325
|
+
def default_timezone
|
326
|
+
ActiveRecord.default_timezone
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
215
330
|
def translate_exception(exception, message:, sql:, binds:)
|
331
|
+
if exception.is_a?(::Trilogy::TimeoutError) && !exception.error_code
|
332
|
+
return ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds)
|
333
|
+
end
|
216
334
|
error_code = exception.error_code if exception.respond_to?(:error_code)
|
217
335
|
|
218
336
|
::TrilogyAdapter::LostConnectionExceptionTranslator.
|
@@ -222,6 +340,61 @@ module ActiveRecord
|
|
222
340
|
def default_prepared_statements
|
223
341
|
false
|
224
342
|
end
|
343
|
+
|
344
|
+
if ActiveRecord.version < ::Gem::Version.new('6.1.a') # For ActiveRecord <= 6.0
|
345
|
+
def prepared_statements?
|
346
|
+
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
ActiveRecord::Type.register(:immutable_string, adapter: :trilogy) do |_, **args|
|
351
|
+
Type::ImmutableString.new(true: "1", false: "0", **args)
|
352
|
+
end
|
353
|
+
|
354
|
+
ActiveRecord::Type.register(:string, adapter: :trilogy) do |_, **args|
|
355
|
+
Type::String.new(true: "1", false: "0", **args)
|
356
|
+
end
|
357
|
+
|
358
|
+
ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :trilogy)
|
359
|
+
end
|
360
|
+
|
361
|
+
if ActiveRecord.version < ::Gem::Version.new('6.1.a') # For ActiveRecord <= 6.0
|
362
|
+
class PoolConfig < ConnectionSpecification
|
363
|
+
def initialize(connection_class, db_config, *args)
|
364
|
+
super("primary", db_config, "#{db_config[:adapter]}_connection")
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
SchemaCache.class_exec do
|
369
|
+
def self.load_from(filename)
|
370
|
+
return unless File.file?(filename)
|
371
|
+
|
372
|
+
read(filename) do |file|
|
373
|
+
if filename.include?(".dump")
|
374
|
+
Marshal.load(file)
|
375
|
+
else
|
376
|
+
if YAML.respond_to?(:unsafe_load)
|
377
|
+
YAML.unsafe_load(file)
|
378
|
+
else
|
379
|
+
YAML.load(file)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def self.read(filename, &block)
|
386
|
+
if File.extname(filename) == ".gz"
|
387
|
+
Zlib::GzipReader.open(filename) { |gz|
|
388
|
+
yield gz.read
|
389
|
+
}
|
390
|
+
else
|
391
|
+
yield File.read(filename)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
private_class_method :read
|
395
|
+
end
|
225
396
|
end
|
397
|
+
|
398
|
+
ActiveSupport.run_load_hooks(:active_record_trilogyadapter, TrilogyAdapter)
|
226
399
|
end
|
227
400
|
end
|
@@ -1,45 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
if ActiveRecord.version < ::Gem::Version.new('6.1.a') # ActiveRecord <= 6.0 support
|
4
|
+
module ::ActiveRecord
|
5
|
+
class QueryAborted < ::ActiveRecord::StatementInvalid
|
6
|
+
end
|
7
|
+
class AdapterTimeout < ::ActiveRecord::QueryAborted
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
module TrilogyAdapter
|
4
13
|
module Errors
|
5
14
|
# ServerShutdown will be raised when the database server was shutdown.
|
6
|
-
class ServerShutdown < ActiveRecord::
|
15
|
+
class ServerShutdown < ::ActiveRecord::QueryAborted
|
7
16
|
end
|
8
17
|
|
9
18
|
# ServerLost will be raised when the database connection was lost.
|
10
|
-
class ServerLost < ActiveRecord::
|
19
|
+
class ServerLost < ::ActiveRecord::QueryAborted
|
11
20
|
end
|
12
21
|
|
13
22
|
# ServerGone will be raised when the database connection is gone.
|
14
|
-
class ServerGone < ActiveRecord::
|
23
|
+
class ServerGone < ::ActiveRecord::QueryAborted
|
15
24
|
end
|
16
25
|
|
17
26
|
# BrokenPipe will be raised when a system process connection fails.
|
18
|
-
class BrokenPipe < ActiveRecord::
|
27
|
+
class BrokenPipe < ::ActiveRecord::QueryAborted
|
19
28
|
end
|
20
29
|
|
21
30
|
# SocketError will be raised when Ruby encounters a network error.
|
22
|
-
class SocketError < ActiveRecord::
|
31
|
+
class SocketError < ::ActiveRecord::QueryAborted
|
23
32
|
end
|
24
33
|
|
25
34
|
# ConnectionResetByPeer will be raised when a network connection is closed
|
26
35
|
# outside the sytstem process.
|
27
|
-
class ConnectionResetByPeer < ActiveRecord::
|
36
|
+
class ConnectionResetByPeer < ::ActiveRecord::QueryAborted
|
28
37
|
end
|
29
38
|
|
30
39
|
# ClosedConnection will be raised when the Trilogy encounters a closed
|
31
40
|
# connection.
|
32
|
-
class ClosedConnection < ActiveRecord::
|
41
|
+
class ClosedConnection < ::ActiveRecord::QueryAborted
|
33
42
|
end
|
34
43
|
|
35
44
|
# InvalidSequenceId will be raised when Trilogy ecounters an invalid sequence
|
36
45
|
# id.
|
37
|
-
class InvalidSequenceId < ActiveRecord::
|
46
|
+
class InvalidSequenceId < ::ActiveRecord::QueryAborted
|
38
47
|
end
|
39
48
|
|
40
49
|
# UnexpectedPacket will be raised when Trilogy ecounters an unexpected
|
41
50
|
# response packet.
|
42
|
-
class UnexpectedPacket < ActiveRecord::
|
51
|
+
class UnexpectedPacket < ::ActiveRecord::QueryAborted
|
43
52
|
end
|
44
53
|
end
|
45
54
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-trilogy-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trilogy
|
@@ -16,26 +16,32 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.4.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: 2.4.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 6.0.a
|
34
|
+
- - "<"
|
32
35
|
- !ruby/object:Gem::Version
|
33
36
|
version: 7.1.a
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- - "
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 6.0.a
|
44
|
+
- - "<"
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: 7.1.a
|
41
47
|
- !ruby/object:Gem::Dependency
|
@@ -105,6 +111,7 @@ extra_rdoc_files:
|
|
105
111
|
files:
|
106
112
|
- LICENSE.md
|
107
113
|
- README.md
|
114
|
+
- lib/active_record/connection_adapters/trilogy/database_statements.rb
|
108
115
|
- lib/active_record/connection_adapters/trilogy_adapter.rb
|
109
116
|
- lib/active_record/tasks/trilogy_database_tasks.rb
|
110
117
|
- lib/activerecord-trilogy-adapter.rb
|
@@ -113,13 +120,13 @@ files:
|
|
113
120
|
- lib/trilogy_adapter/lost_connection_exception_translator.rb
|
114
121
|
- lib/trilogy_adapter/railtie.rb
|
115
122
|
- lib/trilogy_adapter/version.rb
|
116
|
-
homepage: https://github.com/
|
123
|
+
homepage: https://github.com/trilogy-libraries/activerecord-trilogy-adapter
|
117
124
|
licenses:
|
118
125
|
- MIT
|
119
126
|
metadata:
|
120
|
-
source_code_uri: https://github.com/
|
121
|
-
changelog_uri: https://github.com/
|
122
|
-
bug_tracker_uri: https://github.com/
|
127
|
+
source_code_uri: https://github.com/trilogy-libraries/activerecord-trilogy-adapter
|
128
|
+
changelog_uri: https://github.com/trilogy-libraries/activerecord-trilogy-adapter/blob/master/CHANGELOG.md
|
129
|
+
bug_tracker_uri: https://github.com/trilogy-libraries/activerecord-trilogy-adapter/issues
|
123
130
|
post_install_message:
|
124
131
|
rdoc_options: []
|
125
132
|
require_paths:
|
@@ -138,5 +145,5 @@ requirements: []
|
|
138
145
|
rubygems_version: 3.2.33
|
139
146
|
signing_key:
|
140
147
|
specification_version: 4
|
141
|
-
summary: Active Record adapter for https://github.com/
|
148
|
+
summary: Active Record adapter for https://github.com/trilogy-libraries/trilogy.
|
142
149
|
test_files: []
|