activerecord-spanner-adapter 2.6.0 → 2.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/acceptance-tests-on-emulator.yaml +9 -13
- data/.github/workflows/acceptance-tests-on-production.yaml +4 -3
- data/.github/workflows/ci.yaml +8 -12
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +9 -13
- data/.github/workflows/nightly-acceptance-tests-on-production.yaml +4 -3
- data/.github/workflows/nightly-unit-tests.yaml +8 -12
- data/.github/workflows/rubocop.yaml +3 -3
- data/.github/workflows/samples.yaml +8 -12
- data/.gitignore +0 -1
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +2 -0
- data/Appraisals +15 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +12 -22
- data/Gemfile.lock +479 -0
- data/acceptance/cases/migration/change_table_test.rb +4 -14
- data/acceptance/cases/models/generated_column_test.rb +8 -26
- data/acceptance/test_helper.rb +10 -22
- data/activerecord-spanner-adapter.gemspec +2 -1
- data/benchmarks/db/migrate/01_create_tables.rb +1 -1
- data/examples/rails/README.md +1 -1
- data/examples/snippets/Rakefile +0 -7
- data/examples/snippets/array-data-type/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/batch-dml/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/bulk-insert/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/commit-timestamp/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/create-records/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/date-data-type/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/generated-column/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/hints/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/interleaved-tables/README.md +2 -5
- data/examples/snippets/isolation-level/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/migrations/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/mutations/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/optimistic-locking/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/partitioned-dml/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/query-logs/application.rb +3 -3
- data/examples/snippets/query-logs/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/quickstart/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/read-only-transactions/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/read-write-transactions/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/stale-reads/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/tags/db/migrate/01_create_tables.rb +1 -1
- data/examples/snippets/timestamp-data-type/db/migrate/01_create_tables.rb +1 -1
- data/gemfiles/7.1.gemfile +18 -0
- data/gemfiles/7.1.gemfile.lock +389 -0
- data/gemfiles/7.2.gemfile +18 -0
- data/gemfiles/7.2.gemfile.lock +479 -0
- data/gemfiles/8.0.gemfile +18 -0
- data/gemfiles/8.0.gemfile.lock +480 -0
- data/gemfiles/8.1.gemfile +18 -0
- data/gemfiles/8.1.gemfile.lock +478 -0
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +62 -95
- data/lib/active_record/connection_adapters/spanner/quoting.rb +0 -22
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +3 -15
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +0 -4
- data/lib/active_record/connection_adapters/spanner_adapter.rb +12 -14
- data/lib/active_record/type/spanner/spanner_active_record_converter.rb +33 -2
- data/lib/activerecord_spanner_adapter/base.rb +5 -27
- data/lib/activerecord_spanner_adapter/connection.rb +0 -20
- data/lib/activerecord_spanner_adapter/information_schema.rb +1 -4
- data/lib/activerecord_spanner_adapter/table.rb +0 -22
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- data/lib/arel/visitors/spanner.rb +12 -15
- data/lib/spanner_client_ext.rb +6 -2
- metadata +27 -17
- data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb +0 -221
- data/acceptance/cases/models/interleave_test.rb +0 -113
- data/acceptance/cases/transactions/optimistic_locking_test.rb +0 -152
- data/acceptance/models/album.rb +0 -15
- data/acceptance/models/track.rb +0 -23
- data/examples/snippets/interleaved-tables-before-7.1/README.md +0 -167
- data/examples/snippets/interleaved-tables-before-7.1/Rakefile +0 -13
- data/examples/snippets/interleaved-tables-before-7.1/application.rb +0 -122
- data/examples/snippets/interleaved-tables-before-7.1/config/database.yml +0 -9
- data/examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb +0 -44
- data/examples/snippets/interleaved-tables-before-7.1/db/seeds.rb +0 -40
- data/examples/snippets/interleaved-tables-before-7.1/models/album.rb +0 -20
- data/examples/snippets/interleaved-tables-before-7.1/models/singer.rb +0 -18
- data/examples/snippets/interleaved-tables-before-7.1/models/track.rb +0 -28
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
# The MIT License (MIT)
|
|
2
|
-
#
|
|
3
|
-
# Copyright (c) 2020 Google LLC.
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
|
13
|
-
# all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
# THE SOFTWARE.
|
|
22
|
-
|
|
23
1
|
# Copyright 2020 Google LLC
|
|
24
2
|
#
|
|
25
3
|
# Use of this source code is governed by an MIT-style
|
|
@@ -21,23 +21,11 @@ module ActiveRecord
|
|
|
21
21
|
create_sql = +"CREATE TABLE #{quote_table_name o.name} "
|
|
22
22
|
statements = o.columns.map { |c| accept c }
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
statements << accept(fk)
|
|
27
|
-
end
|
|
28
|
-
else
|
|
29
|
-
o.foreign_keys.each do |to_table, options|
|
|
30
|
-
statements << foreign_key_in_create(o.name, to_table, options)
|
|
31
|
-
end
|
|
24
|
+
o.foreign_keys.each do |fk|
|
|
25
|
+
statements << accept(fk)
|
|
32
26
|
end
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
statements.concat(o.check_constraints.map { |chk| accept chk })
|
|
36
|
-
elsif ActiveRecord::VERSION::MAJOR == 6 && ActiveRecord::VERSION::MINOR >= 1
|
|
37
|
-
statements.concat(
|
|
38
|
-
o.check_constraints.map { |expression, options| check_constraint_in_create o.name, expression, options }
|
|
39
|
-
)
|
|
40
|
-
end
|
|
28
|
+
statements.concat(o.check_constraints.map { |chk| accept chk })
|
|
41
29
|
|
|
42
30
|
create_sql << "(#{statements.join ', '}) " if statements.any?
|
|
43
31
|
|
|
@@ -473,10 +473,6 @@ module ActiveRecord
|
|
|
473
473
|
TableDefinition.new self, args[0], options: args[1]
|
|
474
474
|
end
|
|
475
475
|
|
|
476
|
-
def able_to_ddl_batch? table_name
|
|
477
|
-
[ActiveRecord::InternalMetadata.table_name, ActiveRecord::SchemaMigration.table_name].exclude? table_name.to_s
|
|
478
|
-
end
|
|
479
|
-
|
|
480
476
|
def _change_column table_name, column_name, type, **options # rubocop:disable Metrics/AbcSize
|
|
481
477
|
column = information_schema do |i|
|
|
482
478
|
i.table_column table_name, column_name
|
|
@@ -208,6 +208,10 @@ module ActiveRecord
|
|
|
208
208
|
true
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
+
def supports_savepoints?
|
|
212
|
+
false
|
|
213
|
+
end
|
|
214
|
+
|
|
211
215
|
# Generate next sequence number for primary key
|
|
212
216
|
def next_sequence_value _sequence_name
|
|
213
217
|
SecureRandom.uuid.gsub("-", "").hex & 0x7FFFFFFFFFFFFFFF
|
|
@@ -278,29 +282,23 @@ module ActiveRecord
|
|
|
278
282
|
end
|
|
279
283
|
end
|
|
280
284
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
end
|
|
285
|
+
class << self
|
|
286
|
+
include TypeMapBuilder
|
|
287
|
+
end
|
|
285
288
|
|
|
286
|
-
|
|
289
|
+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map m }
|
|
287
290
|
|
|
288
|
-
|
|
291
|
+
private
|
|
289
292
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
end
|
|
293
|
-
else
|
|
294
|
-
include TypeMapBuilder
|
|
293
|
+
def type_map
|
|
294
|
+
TYPE_MAP
|
|
295
295
|
end
|
|
296
296
|
|
|
297
297
|
def transform sql
|
|
298
298
|
if ActiveRecord::VERSION::MAJOR >= 8
|
|
299
299
|
preprocess_query sql
|
|
300
|
-
elsif ActiveRecord::VERSION::MAJOR == 7
|
|
301
|
-
transform_query sql
|
|
302
300
|
else
|
|
303
|
-
sql
|
|
301
|
+
transform_query sql
|
|
304
302
|
end
|
|
305
303
|
end
|
|
306
304
|
|
|
@@ -6,10 +6,34 @@
|
|
|
6
6
|
|
|
7
7
|
# frozen_string_literal: true
|
|
8
8
|
|
|
9
|
+
require "active_record/type/spanner/array"
|
|
10
|
+
require "active_record/type/spanner/bytes"
|
|
11
|
+
require "active_record/type/spanner/time"
|
|
12
|
+
require "active_record/type/spanner/uuid"
|
|
13
|
+
|
|
9
14
|
module ActiveRecord
|
|
10
15
|
module Type
|
|
11
16
|
module Spanner
|
|
12
17
|
class SpannerActiveRecordConverter
|
|
18
|
+
TYPE_MAP = {
|
|
19
|
+
ActiveModel::Type::Integer => :INT64,
|
|
20
|
+
ActiveModel::Type::BigInteger => :INT64,
|
|
21
|
+
ActiveModel::Type::Boolean => :BOOL,
|
|
22
|
+
ActiveModel::Type::String => :STRING,
|
|
23
|
+
ActiveModel::Type::ImmutableString => :STRING,
|
|
24
|
+
ActiveModel::Type::Binary => :BYTES,
|
|
25
|
+
ActiveRecord::Type::Spanner::Bytes => :BYTES,
|
|
26
|
+
ActiveModel::Type::Float => :FLOAT64,
|
|
27
|
+
ActiveModel::Type::Decimal => :NUMERIC,
|
|
28
|
+
ActiveModel::Type::DateTime => :TIMESTAMP,
|
|
29
|
+
ActiveModel::Type::Time => :TIMESTAMP,
|
|
30
|
+
ActiveRecord::Type::Spanner::Time => :TIMESTAMP,
|
|
31
|
+
ActiveModel::Type::Date => :DATE,
|
|
32
|
+
ActiveRecord::Type::Json => :JSON,
|
|
33
|
+
ActiveRecord::Type::Spanner::Uuid => :UUID
|
|
34
|
+
}.freeze
|
|
35
|
+
private_constant :TYPE_MAP
|
|
36
|
+
|
|
13
37
|
def self.serialize_with_transaction_isolation_level type, value, isolation_level
|
|
14
38
|
if type.respond_to? :serialize_with_isolation_level
|
|
15
39
|
type.serialize_with_isolation_level value, isolation_level
|
|
@@ -22,12 +46,19 @@ module ActiveRecord
|
|
|
22
46
|
|
|
23
47
|
##
|
|
24
48
|
# Converts an ActiveModel::Type to a Spanner type code.
|
|
25
|
-
def self.convert_active_model_type_to_spanner type
|
|
49
|
+
def self.convert_active_model_type_to_spanner type
|
|
50
|
+
return nil if type.nil?
|
|
51
|
+
|
|
26
52
|
# Unwrap the underlying object if the type is a DelegateClass.
|
|
27
53
|
type = type.__getobj__ if type.respond_to? :__getobj__
|
|
28
54
|
|
|
55
|
+
TYPE_MAP[type.class] || fallback_convert_active_model_type_to_spanner(type)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.fallback_convert_active_model_type_to_spanner type # rubocop:disable Metrics/CyclomaticComplexity
|
|
29
59
|
case type
|
|
30
60
|
when NilClass then nil
|
|
61
|
+
when ActiveRecord::Type::Spanner::Array then [convert_active_model_type_to_spanner(type.element_type)]
|
|
31
62
|
when ActiveModel::Type::Integer, ActiveModel::Type::BigInteger then :INT64
|
|
32
63
|
when ActiveModel::Type::Boolean then :BOOL
|
|
33
64
|
when ActiveModel::Type::String, ActiveModel::Type::ImmutableString then :STRING
|
|
@@ -38,9 +69,9 @@ module ActiveRecord
|
|
|
38
69
|
when ActiveModel::Type::Date then :DATE
|
|
39
70
|
when ActiveRecord::Type::Json then :JSON
|
|
40
71
|
when ActiveRecord::Type::Spanner::Uuid then :UUID
|
|
41
|
-
when ActiveRecord::Type::Spanner::Array then [convert_active_model_type_to_spanner(type.element_type)]
|
|
42
72
|
end
|
|
43
73
|
end
|
|
74
|
+
private_class_method :fallback_convert_active_model_type_to_spanner
|
|
44
75
|
end
|
|
45
76
|
end
|
|
46
77
|
end
|
|
@@ -8,14 +8,7 @@ require "active_record/gem_version"
|
|
|
8
8
|
require "activerecord_spanner_adapter/relation"
|
|
9
9
|
|
|
10
10
|
module ActiveRecord
|
|
11
|
-
class TableMetadata # :nodoc:
|
|
12
|
-
# This attr_reader is private in ActiveRecord 6.0.x and public in 6.1.x. This makes sure it is always available in
|
|
13
|
-
# the Spanner adapter.
|
|
14
|
-
attr_reader :arel_table
|
|
15
|
-
end
|
|
16
|
-
|
|
17
11
|
class Base
|
|
18
|
-
VERSION_7_1 = Gem::Version.create "7.1.0"
|
|
19
12
|
VERSION_7_2 = Gem::Version.create "7.2.0"
|
|
20
13
|
|
|
21
14
|
# Creates an object (or multiple objects) and saves it to the database. This method will use mutations instead
|
|
@@ -88,7 +81,6 @@ module ActiveRecord
|
|
|
88
81
|
end
|
|
89
82
|
|
|
90
83
|
if _should_use_standard_insert_record? values
|
|
91
|
-
return super values if ActiveRecord.gem_version < VERSION_7_1
|
|
92
84
|
return super
|
|
93
85
|
end
|
|
94
86
|
|
|
@@ -108,12 +100,8 @@ module ActiveRecord
|
|
|
108
100
|
|
|
109
101
|
def self._insert_record_dml values, returning
|
|
110
102
|
primary_key_value = _set_primary_key_value values, false
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
im.insert(values.transform_keys { |name| arel_table[name] })
|
|
114
|
-
else
|
|
115
|
-
im = arel_table.compile_insert _substitute_values(values)
|
|
116
|
-
end
|
|
103
|
+
im = Arel::InsertManager.new arel_table
|
|
104
|
+
im.insert(values.transform_keys { |name| arel_table[name] })
|
|
117
105
|
result = connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
|
118
106
|
|
|
119
107
|
_convert_primary_key result, returning
|
|
@@ -131,7 +119,6 @@ module ActiveRecord
|
|
|
131
119
|
# Rails 7.1 and higher supports composite primary keys, and therefore require the provider to return an array
|
|
132
120
|
# instead of a single value in all cases. The order of the values should be equal to the order of the returning
|
|
133
121
|
# columns (or the primary key if no returning columns were specified).
|
|
134
|
-
return primary_key_value if ActiveRecord.gem_version < VERSION_7_1
|
|
135
122
|
return primary_key_value if primary_key_value.is_a?(Array) && primary_key_value.length == 1
|
|
136
123
|
return [primary_key_value] unless primary_key_value.is_a? Array
|
|
137
124
|
|
|
@@ -270,12 +257,7 @@ module ActiveRecord
|
|
|
270
257
|
value = next_sequence_value
|
|
271
258
|
end
|
|
272
259
|
|
|
273
|
-
values[primary_key] =
|
|
274
|
-
if ActiveRecord::VERSION::MAJOR >= 7
|
|
275
|
-
ActiveModel::Attribute.from_database primary_key, value, type
|
|
276
|
-
else
|
|
277
|
-
value
|
|
278
|
-
end
|
|
260
|
+
values[primary_key] = ActiveModel::Attribute.from_database primary_key, value, type
|
|
279
261
|
|
|
280
262
|
value
|
|
281
263
|
end
|
|
@@ -289,12 +271,8 @@ module ActiveRecord
|
|
|
289
271
|
|
|
290
272
|
if primary_key_value.nil?
|
|
291
273
|
primary_key_value = next_sequence_value
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
ActiveModel::Type::BigInteger.new
|
|
295
|
-
else
|
|
296
|
-
values[primary_key] = primary_key_value
|
|
297
|
-
end
|
|
274
|
+
values[primary_key] = ActiveModel::Attribute.from_database primary_key, primary_key_value,
|
|
275
|
+
ActiveModel::Type::BigInteger.new
|
|
298
276
|
end
|
|
299
277
|
|
|
300
278
|
primary_key_value
|
|
@@ -459,25 +459,5 @@ module ActiveRecordSpannerAdapter
|
|
|
459
459
|
raise
|
|
460
460
|
end
|
|
461
461
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
##
|
|
465
|
-
# Retrieves the delay value from Google::Cloud::AbortedError or
|
|
466
|
-
# GRPC::Aborted
|
|
467
|
-
def delay_from_aborted err
|
|
468
|
-
return nil if err.nil?
|
|
469
|
-
if err.respond_to?(:metadata) && err.metadata["google.rpc.retryinfo-bin"]
|
|
470
|
-
retry_info = Google::Rpc::RetryInfo.decode err.metadata["google.rpc.retryinfo-bin"]
|
|
471
|
-
seconds = retry_info["retry_delay"].seconds
|
|
472
|
-
nanos = retry_info["retry_delay"].nanos
|
|
473
|
-
return seconds if nanos.zero?
|
|
474
|
-
return seconds + (nanos / 1_000_000_000.0)
|
|
475
|
-
end
|
|
476
|
-
# No metadata? Try the inner error
|
|
477
|
-
delay_from_aborted err.cause
|
|
478
|
-
rescue StandardError
|
|
479
|
-
# Any error indicates the backoff should be handled elsewhere
|
|
480
|
-
nil
|
|
481
|
-
end
|
|
482
462
|
end
|
|
483
463
|
end
|
|
@@ -15,13 +15,10 @@ module ActiveRecordSpannerAdapter
|
|
|
15
15
|
class InformationSchema
|
|
16
16
|
include ActiveRecord::ConnectionAdapters::Quoting
|
|
17
17
|
|
|
18
|
-
IsRails71OrLater = ActiveRecord.gem_version >= Gem::Version.create("7.1.0")
|
|
19
|
-
|
|
20
18
|
attr_reader :connection
|
|
21
19
|
|
|
22
20
|
def initialize connection
|
|
23
21
|
@connection = connection
|
|
24
|
-
@mutex = Mutex.new
|
|
25
22
|
end
|
|
26
23
|
|
|
27
24
|
def tables table_name: nil, schema_name: "", view: nil
|
|
@@ -128,7 +125,7 @@ module ActiveRecordSpannerAdapter
|
|
|
128
125
|
# ActiveRecord. The parent primary key columns are filtered out by default to allow interleaved tables to be
|
|
129
126
|
# considered as tables with a single-column primary key by ActiveRecord. The actual primary key of the table will
|
|
130
127
|
# include both the parent primary key columns and the 'own' primary key columns of a table.
|
|
131
|
-
def table_primary_keys table_name, include_parent_keys =
|
|
128
|
+
def table_primary_keys table_name, include_parent_keys = true, schema_name: "" # rubocop:disable Style/OptionalBooleanParameter
|
|
132
129
|
sql = +"WITH TABLE_PK_COLS AS ( "
|
|
133
130
|
sql << "SELECT C.TABLE_CATALOG, C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, "
|
|
134
131
|
sql << "C.INDEX_NAME, C.COLUMN_ORDERING, C.ORDINAL_POSITION "
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
# The MIT License (MIT)
|
|
2
|
-
#
|
|
3
|
-
# Copyright (c) 2020 Google LLC.
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
|
13
|
-
# all copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
# THE SOFTWARE.
|
|
22
|
-
|
|
23
1
|
# Copyright 2020 Google LLC
|
|
24
2
|
#
|
|
25
3
|
# Use of this source code is governed by an MIT-style
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
# https://opensource.org/licenses/MIT.
|
|
6
6
|
|
|
7
7
|
module Arel # :nodoc: all
|
|
8
|
+
module Collectors
|
|
9
|
+
class SQLString
|
|
10
|
+
attr_accessor :hints
|
|
11
|
+
attr_accessor :table_hints
|
|
12
|
+
attr_accessor :join_hints
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
8
16
|
module Visitors
|
|
9
17
|
class StalenessHint
|
|
10
18
|
attr_reader :value
|
|
@@ -24,9 +32,9 @@ module Arel # :nodoc: all
|
|
|
24
32
|
|
|
25
33
|
class Spanner < Arel::Visitors::ToSql
|
|
26
34
|
def compile node, collector = Arel::Collectors::SQLString.new
|
|
27
|
-
collector.
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
unless collector.respond_to? :hints=
|
|
36
|
+
collector.class.attr_accessor :hints, :table_hints, :join_hints
|
|
37
|
+
end
|
|
30
38
|
collector.hints = {}
|
|
31
39
|
collector.table_hints = {}
|
|
32
40
|
collector.join_hints = {}
|
|
@@ -137,7 +145,7 @@ module Arel # :nodoc: all
|
|
|
137
145
|
end
|
|
138
146
|
end
|
|
139
147
|
|
|
140
|
-
# For ActiveRecord 7.
|
|
148
|
+
# For ActiveRecord 7.1+
|
|
141
149
|
def visit_ActiveModel_Attribute o, collector
|
|
142
150
|
# Do not generate a query parameter if the value should be set to the PENDING_COMMIT_TIMESTAMP(), as that is
|
|
143
151
|
# not supported as a parameter value by Cloud Spanner.
|
|
@@ -145,17 +153,6 @@ module Arel # :nodoc: all
|
|
|
145
153
|
if o.type.is_a?(ActiveRecord::Type::Spanner::Time) && o.value == :commit_timestamp
|
|
146
154
|
collector.add_bind(o, &bind_block)
|
|
147
155
|
end
|
|
148
|
-
|
|
149
|
-
# For ActiveRecord 6.x
|
|
150
|
-
def visit_Arel_Nodes_BindParam o, collector
|
|
151
|
-
# Do not generate a query parameter if the value should be set to the PENDING_COMMIT_TIMESTAMP(), as that is
|
|
152
|
-
# not supported as a parameter value by Cloud Spanner.
|
|
153
|
-
return collector << "PENDING_COMMIT_TIMESTAMP()" \
|
|
154
|
-
if o.value.respond_to?(:type) \
|
|
155
|
-
&& o.value.type.is_a?(ActiveRecord::Type::Spanner::Time) \
|
|
156
|
-
&& o.value.value == :commit_timestamp
|
|
157
|
-
collector.add_bind(o.value, &bind_block)
|
|
158
|
-
end
|
|
159
156
|
# rubocop:enable Naming/MethodName
|
|
160
157
|
end
|
|
161
158
|
end
|
data/lib/spanner_client_ext.rb
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
|
5
5
|
# https://opensource.org/licenses/MIT.
|
|
6
6
|
|
|
7
|
+
require "google/cloud/spanner"
|
|
7
8
|
|
|
8
9
|
module Google
|
|
9
10
|
module Cloud
|
|
@@ -23,6 +24,10 @@ module Google
|
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
class Session
|
|
27
|
+
def self.snapshot_from_grpc_arity
|
|
28
|
+
@snapshot_from_grpc_arity ||= Snapshot.method(:from_grpc).arity
|
|
29
|
+
end
|
|
30
|
+
|
|
26
31
|
def commit_transaction transaction, mutations = [], commit_options: nil
|
|
27
32
|
ensure_service!
|
|
28
33
|
|
|
@@ -69,8 +74,7 @@ module Google
|
|
|
69
74
|
snp_grpc = service.create_snapshot \
|
|
70
75
|
path, timestamp: timestamp || read_timestamp,
|
|
71
76
|
staleness: staleness || exact_staleness
|
|
72
|
-
|
|
73
|
-
if num_args == 3
|
|
77
|
+
if Session.snapshot_from_grpc_arity == 3
|
|
74
78
|
Snapshot.from_grpc snp_grpc, self, nil
|
|
75
79
|
else
|
|
76
80
|
Snapshot.from_grpc snp_grpc, self
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-spanner-adapter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Google LLC
|
|
@@ -43,7 +43,7 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '7.
|
|
46
|
+
version: '7.1'
|
|
47
47
|
- - "<"
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
49
|
version: '9'
|
|
@@ -53,10 +53,24 @@ dependencies:
|
|
|
53
53
|
requirements:
|
|
54
54
|
- - ">="
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: '7.
|
|
56
|
+
version: '7.1'
|
|
57
57
|
- - "<"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
59
|
version: '9'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: appraisal
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '2.5'
|
|
67
|
+
type: :development
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '2.5'
|
|
60
74
|
- !ruby/object:Gem::Dependency
|
|
61
75
|
name: autotest-suffix
|
|
62
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -261,10 +275,12 @@ files:
|
|
|
261
275
|
- ".toys/release.rb"
|
|
262
276
|
- ".trampolinerc"
|
|
263
277
|
- ".yardopts"
|
|
278
|
+
- Appraisals
|
|
264
279
|
- CHANGELOG.md
|
|
265
280
|
- CODE_OF_CONDUCT.md
|
|
266
281
|
- CONTRIBUTING.md
|
|
267
282
|
- Gemfile
|
|
283
|
+
- Gemfile.lock
|
|
268
284
|
- LICENSE
|
|
269
285
|
- README.md
|
|
270
286
|
- Rakefile
|
|
@@ -273,7 +289,6 @@ files:
|
|
|
273
289
|
- acceptance/cases/associations/has_many_through_associations_test.rb
|
|
274
290
|
- acceptance/cases/associations/has_one_associations_test.rb
|
|
275
291
|
- acceptance/cases/associations/has_one_through_associations_test.rb
|
|
276
|
-
- acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb
|
|
277
292
|
- acceptance/cases/migration/change_schema_test.rb
|
|
278
293
|
- acceptance/cases/migration/change_table_test.rb
|
|
279
294
|
- acceptance/cases/migration/column_attributes_test.rb
|
|
@@ -294,13 +309,11 @@ files:
|
|
|
294
309
|
- acceptance/cases/models/default_value_test.rb
|
|
295
310
|
- acceptance/cases/models/generated_column_test.rb
|
|
296
311
|
- acceptance/cases/models/insert_all_test.rb
|
|
297
|
-
- acceptance/cases/models/interleave_test.rb
|
|
298
312
|
- acceptance/cases/models/logging_test.rb
|
|
299
313
|
- acceptance/cases/models/mutation_test.rb
|
|
300
314
|
- acceptance/cases/models/query_test.rb
|
|
301
315
|
- acceptance/cases/sessions/session_not_found_test.rb
|
|
302
316
|
- acceptance/cases/tasks/database_tasks_test.rb
|
|
303
|
-
- acceptance/cases/transactions/optimistic_locking_test.rb
|
|
304
317
|
- acceptance/cases/transactions/read_only_transactions_test.rb
|
|
305
318
|
- acceptance/cases/transactions/read_write_transactions_test.rb
|
|
306
319
|
- acceptance/cases/type/all_types_test.rb
|
|
@@ -317,7 +330,6 @@ files:
|
|
|
317
330
|
- acceptance/cases/type/time_test.rb
|
|
318
331
|
- acceptance/models/account.rb
|
|
319
332
|
- acceptance/models/address.rb
|
|
320
|
-
- acceptance/models/album.rb
|
|
321
333
|
- acceptance/models/all_types.rb
|
|
322
334
|
- acceptance/models/author.rb
|
|
323
335
|
- acceptance/models/binary_project.rb
|
|
@@ -334,7 +346,6 @@ files:
|
|
|
334
346
|
- acceptance/models/singer.rb
|
|
335
347
|
- acceptance/models/string_io.rb
|
|
336
348
|
- acceptance/models/table_with_sequence.rb
|
|
337
|
-
- acceptance/models/track.rb
|
|
338
349
|
- acceptance/models/transaction.rb
|
|
339
350
|
- acceptance/models/user.rb
|
|
340
351
|
- acceptance/schema/schema.rb
|
|
@@ -435,15 +446,6 @@ files:
|
|
|
435
446
|
- examples/snippets/hints/db/seeds.rb
|
|
436
447
|
- examples/snippets/hints/models/album.rb
|
|
437
448
|
- examples/snippets/hints/models/singer.rb
|
|
438
|
-
- examples/snippets/interleaved-tables-before-7.1/README.md
|
|
439
|
-
- examples/snippets/interleaved-tables-before-7.1/Rakefile
|
|
440
|
-
- examples/snippets/interleaved-tables-before-7.1/application.rb
|
|
441
|
-
- examples/snippets/interleaved-tables-before-7.1/config/database.yml
|
|
442
|
-
- examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb
|
|
443
|
-
- examples/snippets/interleaved-tables-before-7.1/db/seeds.rb
|
|
444
|
-
- examples/snippets/interleaved-tables-before-7.1/models/album.rb
|
|
445
|
-
- examples/snippets/interleaved-tables-before-7.1/models/singer.rb
|
|
446
|
-
- examples/snippets/interleaved-tables-before-7.1/models/track.rb
|
|
447
449
|
- examples/snippets/interleaved-tables/README.md
|
|
448
450
|
- examples/snippets/interleaved-tables/Rakefile
|
|
449
451
|
- examples/snippets/interleaved-tables/application.rb
|
|
@@ -550,6 +552,14 @@ files:
|
|
|
550
552
|
- examples/snippets/timestamp-data-type/db/seeds.rb
|
|
551
553
|
- examples/snippets/timestamp-data-type/models/meeting.rb
|
|
552
554
|
- examples/solidus/README.md
|
|
555
|
+
- gemfiles/7.1.gemfile
|
|
556
|
+
- gemfiles/7.1.gemfile.lock
|
|
557
|
+
- gemfiles/7.2.gemfile
|
|
558
|
+
- gemfiles/7.2.gemfile.lock
|
|
559
|
+
- gemfiles/8.0.gemfile
|
|
560
|
+
- gemfiles/8.0.gemfile.lock
|
|
561
|
+
- gemfiles/8.1.gemfile
|
|
562
|
+
- gemfiles/8.1.gemfile.lock
|
|
553
563
|
- lib/active_record/connection_adapters/spanner/column.rb
|
|
554
564
|
- lib/active_record/connection_adapters/spanner/database_statements.rb
|
|
555
565
|
- lib/active_record/connection_adapters/spanner/errors/transaction_mutation_limit_exceeded_error.rb
|