activerecord-spanner-adapter 1.6.3 → 2.0.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 +3 -7
- data/.github/workflows/acceptance-tests-on-production.yaml +1 -1
- data/.github/workflows/ci.yaml +3 -7
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +4 -33
- data/.github/workflows/nightly-acceptance-tests-on-production.yaml +1 -1
- data/.github/workflows/nightly-unit-tests.yaml +5 -33
- data/.github/workflows/rubocop.yaml +1 -1
- data/.github/workflows/samples.yaml +30 -0
- data/.kokoro/populate-secrets.sh +5 -1
- data/.kokoro/release.cfg +22 -12
- data/.kokoro/release.sh +1 -3
- data/.kokoro/trampoline_v2.sh +19 -11
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +2 -2
- data/.trampolinerc +6 -1
- data/CHANGELOG.md +37 -0
- data/Gemfile +7 -5
- data/README.md +11 -9
- data/Rakefile +2 -2
- data/acceptance/cases/migration/command_recorder_test.rb +7 -38
- data/acceptance/cases/migration/references_index_test.rb +2 -11
- data/acceptance/cases/migration/schema_dumper_test.rb +21 -9
- data/acceptance/cases/models/binary_identifiers.rb +97 -0
- data/acceptance/cases/models/insert_all_test.rb +22 -7
- data/acceptance/cases/sessions/session_not_found_test.rb +2 -0
- data/acceptance/cases/tasks/database_tasks_test.rb +1 -0
- data/acceptance/models/binary_project.rb +20 -0
- data/acceptance/models/string_io.rb +28 -0
- data/acceptance/models/user.rb +20 -0
- data/acceptance/test_helper.rb +6 -1
- data/activerecord-spanner-adapter.gemspec +3 -3
- data/benchmarks/application.rb +3 -7
- data/examples/snippets/Rakefile +27 -5
- data/examples/snippets/array-data-type/application.rb +1 -5
- data/examples/snippets/array-data-type/config/database.yml +1 -0
- data/examples/snippets/bit-reversed-sequence/application.rb +0 -4
- data/examples/snippets/bit-reversed-sequence/config/database.yml +1 -0
- data/examples/snippets/bit-reversed-sequence/db/seeds.rb +2 -2
- data/examples/snippets/bulk-insert/application.rb +1 -5
- data/examples/snippets/bulk-insert/config/database.yml +1 -0
- data/examples/snippets/commit-timestamp/application.rb +0 -4
- data/examples/snippets/commit-timestamp/config/database.yml +1 -0
- data/examples/snippets/config/environment.rb +5 -0
- data/examples/snippets/create-records/application.rb +1 -5
- data/examples/snippets/create-records/config/database.yml +1 -0
- data/examples/snippets/date-data-type/application.rb +1 -5
- data/examples/snippets/date-data-type/config/database.yml +1 -0
- data/examples/snippets/date-data-type/db/seeds.rb +1 -1
- data/examples/snippets/generated-column/application.rb +0 -4
- data/examples/snippets/generated-column/config/database.yml +1 -0
- data/examples/snippets/generated-column/db/seeds.rb +1 -1
- data/examples/snippets/hints/application.rb +0 -4
- data/examples/snippets/hints/config/database.yml +1 -0
- data/examples/snippets/hints/db/seeds.rb +1 -1
- data/examples/snippets/interleaved-tables/application.rb +1 -5
- data/examples/snippets/interleaved-tables/config/database.yml +1 -0
- data/examples/snippets/interleaved-tables/db/seeds.rb +1 -1
- data/examples/snippets/interleaved-tables/models/album.rb +6 -2
- data/examples/snippets/interleaved-tables/models/track.rb +5 -1
- data/examples/snippets/interleaved-tables-before-7.1/application.rb +1 -5
- data/examples/snippets/interleaved-tables-before-7.1/config/database.yml +1 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/seeds.rb +1 -1
- data/examples/snippets/migrations/application.rb +0 -4
- data/examples/snippets/migrations/config/database.yml +1 -0
- data/examples/snippets/mutations/application.rb +1 -5
- data/examples/snippets/mutations/config/database.yml +1 -0
- data/examples/snippets/mutations/db/seeds.rb +1 -1
- data/examples/snippets/optimistic-locking/application.rb +0 -4
- data/examples/snippets/optimistic-locking/config/database.yml +1 -0
- data/examples/snippets/optimistic-locking/db/seeds.rb +1 -1
- data/examples/snippets/partitioned-dml/application.rb +0 -4
- data/examples/snippets/partitioned-dml/config/database.yml +1 -0
- data/examples/snippets/partitioned-dml/db/seeds.rb +1 -1
- data/examples/snippets/query-logs/application.rb +15 -13
- data/examples/snippets/query-logs/config/database.yml +1 -0
- data/examples/snippets/query-logs/db/seeds.rb +1 -1
- data/examples/snippets/quickstart/application.rb +0 -4
- data/examples/snippets/quickstart/config/database.yml +1 -0
- data/examples/snippets/quickstart/db/seeds.rb +1 -1
- data/examples/snippets/read-only-transactions/application.rb +0 -4
- data/examples/snippets/read-only-transactions/config/database.yml +1 -0
- data/examples/snippets/read-only-transactions/db/seeds.rb +1 -1
- data/examples/snippets/read-write-transactions/application.rb +2 -6
- data/examples/snippets/read-write-transactions/config/database.yml +1 -0
- data/examples/snippets/read-write-transactions/db/seeds.rb +1 -1
- data/examples/snippets/stale-reads/application.rb +0 -4
- data/examples/snippets/stale-reads/config/database.yml +1 -0
- data/examples/snippets/stale-reads/db/seeds.rb +1 -1
- data/examples/snippets/tags/application.rb +0 -4
- data/examples/snippets/tags/config/database.yml +1 -0
- data/examples/snippets/tags/db/seeds.rb +1 -1
- data/examples/snippets/timestamp-data-type/application.rb +0 -4
- data/examples/snippets/timestamp-data-type/config/database.yml +1 -0
- data/lib/active_record/connection_adapters/spanner/column.rb +3 -3
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +37 -23
- data/lib/active_record/connection_adapters/spanner/quoting.rb +19 -6
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +7 -9
- data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +12 -2
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +28 -46
- data/lib/active_record/connection_adapters/spanner/type_metadata.rb +4 -6
- data/lib/active_record/connection_adapters/spanner_adapter.rb +54 -27
- data/lib/active_record/tasks/spanner_database_tasks.rb +4 -4
- data/lib/active_record/type/spanner/array.rb +4 -0
- data/lib/active_record/type/spanner/bytes.rb +10 -0
- data/lib/activerecord-spanner-adapter.rb +5 -1
- data/lib/activerecord_spanner_adapter/base.rb +58 -30
- data/lib/activerecord_spanner_adapter/connection.rb +9 -5
- data/lib/activerecord_spanner_adapter/foreign_key.rb +9 -2
- data/lib/activerecord_spanner_adapter/index/column.rb +6 -1
- data/lib/activerecord_spanner_adapter/index.rb +10 -2
- data/lib/activerecord_spanner_adapter/information_schema.rb +1 -1
- data/lib/activerecord_spanner_adapter/primary_key.rb +2 -2
- data/lib/activerecord_spanner_adapter/table/column.rb +12 -3
- data/lib/activerecord_spanner_adapter/table.rb +8 -2
- data/lib/activerecord_spanner_adapter/transaction.rb +1 -1
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- data/lib/arel/visitors/spanner.rb +16 -11
- data/lib/spanner_client_ext.rb +4 -3
- metadata +15 -34
- data/examples/snippets/array-data-type/db/schema.rb +0 -31
- data/examples/snippets/bit-reversed-sequence/db/schema.rb +0 -31
- data/examples/snippets/bulk-insert/db/schema.rb +0 -31
- data/examples/snippets/commit-timestamp/db/schema.rb +0 -34
- data/examples/snippets/create-records/db/schema.rb +0 -31
- data/examples/snippets/date-data-type/db/schema.rb +0 -26
- data/examples/snippets/generated-column/db/schema.rb +0 -26
- data/examples/snippets/hints/db/schema.rb +0 -33
- data/examples/snippets/interleaved-tables/db/schema.rb +0 -39
- data/examples/snippets/interleaved-tables-before-7.1/db/schema.rb +0 -37
- data/examples/snippets/migrations/db/schema.rb +0 -38
- data/examples/snippets/mutations/db/schema.rb +0 -32
- data/examples/snippets/optimistic-locking/db/schema.rb +0 -34
- data/examples/snippets/partitioned-dml/db/schema.rb +0 -31
- data/examples/snippets/query-logs/db/schema.rb +0 -31
- data/examples/snippets/quickstart/db/schema.rb +0 -31
- data/examples/snippets/read-only-transactions/db/schema.rb +0 -31
- data/examples/snippets/read-write-transactions/db/schema.rb +0 -32
- data/examples/snippets/stale-reads/db/schema.rb +0 -31
- data/examples/snippets/tags/db/schema.rb +0 -31
- data/examples/snippets/timestamp-data-type/db/schema.rb +0 -26
|
@@ -16,6 +16,7 @@ module ActiveRecord
|
|
|
16
16
|
|
|
17
17
|
class Base
|
|
18
18
|
VERSION_7_1 = Gem::Version.create "7.1.0"
|
|
19
|
+
VERSION_7_2 = Gem::Version.create "7.2.0"
|
|
19
20
|
|
|
20
21
|
# Creates an object (or multiple objects) and saves it to the database. This method will use mutations instead
|
|
21
22
|
# of DML if there is no active transaction, or if the active transaction has been created with the option
|
|
@@ -48,8 +49,26 @@ module ActiveRecord
|
|
|
48
49
|
spanner_adapter? && connection&.current_spanner_transaction&.isolation == :buffered_mutations
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
def self.
|
|
52
|
-
|
|
52
|
+
def self._should_use_standard_insert_record? values
|
|
53
|
+
!(buffered_mutations? || (primary_key && values.is_a?(Hash))) || !spanner_adapter?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self._internal_insert_record values
|
|
57
|
+
if ActiveRecord.gem_version < VERSION_7_2
|
|
58
|
+
_insert_record values
|
|
59
|
+
else
|
|
60
|
+
_insert_record nil, values
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self._insert_record *args
|
|
65
|
+
if ActiveRecord.gem_version < VERSION_7_2
|
|
66
|
+
values, returning = args
|
|
67
|
+
else
|
|
68
|
+
_connection, values, returning = args
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if _should_use_standard_insert_record? values
|
|
53
72
|
return super values if ActiveRecord.gem_version < VERSION_7_1
|
|
54
73
|
return super
|
|
55
74
|
end
|
|
@@ -57,7 +76,7 @@ module ActiveRecord
|
|
|
57
76
|
# Mutations cannot be used in combination with a sequence, as mutations do not support a THEN RETURN clause.
|
|
58
77
|
if buffered_mutations? && sequence_name
|
|
59
78
|
raise StatementInvalid, "Mutations cannot be used to create records that use a sequence " \
|
|
60
|
-
|
|
79
|
+
"to generate the primary key. #{self} uses #{sequence_name}."
|
|
61
80
|
end
|
|
62
81
|
|
|
63
82
|
return _buffer_record values, :insert, returning if buffered_mutations?
|
|
@@ -99,20 +118,30 @@ module ActiveRecord
|
|
|
99
118
|
keys = returning || primary_key
|
|
100
119
|
return primary_key_value if keys == primary_key
|
|
101
120
|
|
|
102
|
-
primary_key_values_hash =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
values.append primary_key_values_hash[column]
|
|
121
|
+
primary_key_values_hash = primary_key.zip(primary_key_value).to_h
|
|
122
|
+
keys.map do |column|
|
|
123
|
+
primary_key_values_hash[column]
|
|
106
124
|
end
|
|
107
|
-
values
|
|
108
125
|
end
|
|
109
126
|
|
|
110
127
|
def self._upsert_record values, returning
|
|
111
128
|
_buffer_record values, :insert_or_update, returning
|
|
112
129
|
end
|
|
113
130
|
|
|
114
|
-
def self.insert_all
|
|
115
|
-
|
|
131
|
+
def self.insert_all attributes, returning: nil, **_kwargs
|
|
132
|
+
if active_transaction? && buffered_mutations?
|
|
133
|
+
raise NotImplementedError,
|
|
134
|
+
"Spanner does not support skip_duplicates for mutations. " \
|
|
135
|
+
"Use a transaction that uses DML, or use insert! or upsert instead."
|
|
136
|
+
end
|
|
137
|
+
super
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.insert! attributes, returning: nil, **kwargs
|
|
141
|
+
return super unless spanner_adapter?
|
|
142
|
+
return super if active_transaction? && !buffered_mutations?
|
|
143
|
+
|
|
144
|
+
insert_all! [attributes], returning: returning, **kwargs
|
|
116
145
|
end
|
|
117
146
|
|
|
118
147
|
def self.insert_all! attributes, returning: nil, **_kwargs
|
|
@@ -123,24 +152,27 @@ module ActiveRecord
|
|
|
123
152
|
# The mutations will be sent as one batch when the transaction is committed.
|
|
124
153
|
if active_transaction?
|
|
125
154
|
attributes.each do |record|
|
|
126
|
-
|
|
155
|
+
_internal_insert_record record
|
|
127
156
|
end
|
|
128
157
|
else
|
|
129
158
|
transaction isolation: :buffered_mutations do
|
|
130
159
|
attributes.each do |record|
|
|
131
|
-
|
|
160
|
+
_internal_insert_record record
|
|
132
161
|
end
|
|
133
162
|
end
|
|
134
163
|
end
|
|
135
164
|
end
|
|
136
165
|
|
|
137
|
-
def self.
|
|
166
|
+
def self.upsert attributes, returning: nil, **kwargs
|
|
138
167
|
return super unless spanner_adapter?
|
|
139
|
-
if active_transaction? && !buffered_mutations?
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
168
|
+
return super if active_transaction? && !buffered_mutations?
|
|
169
|
+
|
|
170
|
+
upsert_all [attributes], returning: returning, **kwargs
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def self.upsert_all attributes, returning: nil, unique_by: nil, **kwargs
|
|
174
|
+
return super unless spanner_adapter?
|
|
175
|
+
return super if active_transaction? && !buffered_mutations?
|
|
144
176
|
|
|
145
177
|
# This might seem inefficient, but is actually not, as it is only buffering a mutation locally.
|
|
146
178
|
# The mutations will be sent as one batch when the transaction is committed.
|
|
@@ -182,11 +214,9 @@ module ActiveRecord
|
|
|
182
214
|
end
|
|
183
215
|
|
|
184
216
|
def self._set_composite_primary_key_values primary_key, values
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
primary_key_value.append _set_composite_primary_key_value col, values
|
|
217
|
+
primary_key.map do |col|
|
|
218
|
+
_set_composite_primary_key_value col, values
|
|
188
219
|
end
|
|
189
|
-
primary_key_value
|
|
190
220
|
end
|
|
191
221
|
|
|
192
222
|
def self._set_composite_primary_key_value primary_key, values
|
|
@@ -385,14 +415,12 @@ module ActiveRecord
|
|
|
385
415
|
end
|
|
386
416
|
|
|
387
417
|
def serialize_keys metadata, keys
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
:mutation)
|
|
418
|
+
keys.map do |key|
|
|
419
|
+
ActiveRecord::Type::Spanner::SpannerActiveRecordConverter
|
|
420
|
+
.serialize_with_transaction_isolation_level(metadata.type(key),
|
|
421
|
+
attribute_in_database(key),
|
|
422
|
+
:mutation)
|
|
394
423
|
end
|
|
395
|
-
serialized_values
|
|
396
424
|
end
|
|
397
425
|
|
|
398
426
|
def _execute_version_check attempted_action # rubocop:disable Metrics/AbcSize
|
|
@@ -422,7 +450,7 @@ module ActiveRecord
|
|
|
422
450
|
|
|
423
451
|
# We need to check the version using a SELECT query, as a mutation cannot include a WHERE clause.
|
|
424
452
|
sql = "SELECT 1 FROM `#{self.class.arel_table.name}` " \
|
|
425
|
-
|
|
453
|
+
"WHERE #{pk_sql} AND `#{locking_column}` = @lock_version"
|
|
426
454
|
locked_row = self.class.connection.raw_connection.execute_query sql, params: params, types: param_types
|
|
427
455
|
raise ActiveRecord::StaleObjectError.new(self, attempted_action) unless locked_row.rows.any?
|
|
428
456
|
end
|
|
@@ -10,7 +10,9 @@ require "activerecord_spanner_adapter/information_schema"
|
|
|
10
10
|
|
|
11
11
|
module ActiveRecordSpannerAdapter
|
|
12
12
|
class Connection
|
|
13
|
-
attr_reader :instance_id
|
|
13
|
+
attr_reader :instance_id
|
|
14
|
+
attr_reader :database_id
|
|
15
|
+
attr_reader :spanner
|
|
14
16
|
attr_accessor :current_transaction
|
|
15
17
|
|
|
16
18
|
def initialize config
|
|
@@ -45,7 +47,7 @@ module ActiveRecordSpannerAdapter
|
|
|
45
47
|
|
|
46
48
|
def self.information_schema config
|
|
47
49
|
@information_schemas ||= {}
|
|
48
|
-
@information_schemas[database_path(config)] ||=
|
|
50
|
+
@information_schemas[database_path(config)] ||=
|
|
49
51
|
ActiveRecordSpannerAdapter::InformationSchema.new new(config)
|
|
50
52
|
end
|
|
51
53
|
|
|
@@ -202,7 +204,7 @@ module ActiveRecordSpannerAdapter
|
|
|
202
204
|
|
|
203
205
|
def execute_query sql, params: nil, types: nil, single_use_selector: nil, request_options: nil
|
|
204
206
|
if params
|
|
205
|
-
converted_params, types =
|
|
207
|
+
converted_params, types =
|
|
206
208
|
Google::Cloud::Spanner::Convert.to_input_params_and_types(
|
|
207
209
|
params, types
|
|
208
210
|
)
|
|
@@ -217,6 +219,7 @@ module ActiveRecordSpannerAdapter
|
|
|
217
219
|
execute_sql_request sql, converted_params, types, selector, request_options
|
|
218
220
|
end
|
|
219
221
|
|
|
222
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
220
223
|
def execute_sql_request sql, converted_params, types, selector, request_options = nil
|
|
221
224
|
res = session.execute_query \
|
|
222
225
|
sql,
|
|
@@ -224,7 +227,7 @@ module ActiveRecordSpannerAdapter
|
|
|
224
227
|
types: types,
|
|
225
228
|
transaction: selector,
|
|
226
229
|
request_options: request_options,
|
|
227
|
-
seqno:
|
|
230
|
+
seqno: current_transaction&.next_sequence_number
|
|
228
231
|
current_transaction.grpc_transaction = res.metadata.transaction \
|
|
229
232
|
if current_transaction && res&.metadata&.transaction
|
|
230
233
|
res
|
|
@@ -252,6 +255,7 @@ module ActiveRecordSpannerAdapter
|
|
|
252
255
|
# It was not the first statement, so propagate the error.
|
|
253
256
|
raise
|
|
254
257
|
end
|
|
258
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
255
259
|
|
|
256
260
|
# Creates a transaction using a BeginTransaction RPC. This is used if the first statement of a
|
|
257
261
|
# transaction fails, as that also means that no transaction id was returned.
|
|
@@ -283,7 +287,7 @@ module ActiveRecordSpannerAdapter
|
|
|
283
287
|
end
|
|
284
288
|
|
|
285
289
|
def transaction_selector
|
|
286
|
-
|
|
290
|
+
current_transaction&.transaction_selector if current_transaction&.active?
|
|
287
291
|
end
|
|
288
292
|
|
|
289
293
|
def truncate table_name
|
|
@@ -6,8 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
module ActiveRecordSpannerAdapter
|
|
8
8
|
class ForeignKey
|
|
9
|
-
attr_accessor :table_schema
|
|
10
|
-
|
|
9
|
+
attr_accessor :table_schema
|
|
10
|
+
attr_accessor :table_name
|
|
11
|
+
attr_accessor :name
|
|
12
|
+
attr_accessor :columns
|
|
13
|
+
attr_accessor :ref_schema
|
|
14
|
+
attr_accessor :ref_table
|
|
15
|
+
attr_accessor :ref_columns
|
|
16
|
+
attr_accessor :on_delete
|
|
17
|
+
attr_accessor :on_update
|
|
11
18
|
|
|
12
19
|
def initialize \
|
|
13
20
|
table_name,
|
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
module ActiveRecordSpannerAdapter
|
|
8
8
|
class Index
|
|
9
9
|
class Column
|
|
10
|
-
attr_accessor :table_name
|
|
10
|
+
attr_accessor :table_name
|
|
11
|
+
attr_accessor :schema_name
|
|
12
|
+
attr_accessor :index_name
|
|
13
|
+
attr_accessor :name
|
|
14
|
+
attr_accessor :order
|
|
15
|
+
attr_accessor :ordinal_position
|
|
11
16
|
|
|
12
17
|
def initialize \
|
|
13
18
|
table_name,
|
|
@@ -8,8 +8,16 @@ require "activerecord_spanner_adapter/index/column"
|
|
|
8
8
|
|
|
9
9
|
module ActiveRecordSpannerAdapter
|
|
10
10
|
class Index
|
|
11
|
-
attr_accessor :schema
|
|
12
|
-
|
|
11
|
+
attr_accessor :schema
|
|
12
|
+
attr_accessor :table
|
|
13
|
+
attr_accessor :name
|
|
14
|
+
attr_accessor :columns
|
|
15
|
+
attr_accessor :type
|
|
16
|
+
attr_accessor :unique
|
|
17
|
+
attr_accessor :null_filtered
|
|
18
|
+
attr_accessor :interleave_in
|
|
19
|
+
attr_accessor :storing
|
|
20
|
+
attr_accessor :state
|
|
13
21
|
|
|
14
22
|
def initialize \
|
|
15
23
|
table,
|
|
@@ -18,8 +18,8 @@ module ActiveRecord
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def fetch_primary_and_parent_key
|
|
21
|
-
|
|
22
|
-
if ActiveRecord::Base
|
|
21
|
+
connection.spanner_schema_cache.primary_and_parent_keys table_name \
|
|
22
|
+
if self != ActiveRecord::Base && table_exists?
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def primary_and_parent_key= value
|
|
@@ -7,9 +7,18 @@
|
|
|
7
7
|
module ActiveRecordSpannerAdapter
|
|
8
8
|
class Table
|
|
9
9
|
class Column
|
|
10
|
-
attr_accessor :schema_name
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
attr_accessor :schema_name
|
|
11
|
+
attr_accessor :table_name
|
|
12
|
+
attr_accessor :name
|
|
13
|
+
attr_accessor :type
|
|
14
|
+
attr_accessor :limit
|
|
15
|
+
attr_accessor :ordinal_position
|
|
16
|
+
attr_accessor :allow_commit_timestamp
|
|
17
|
+
attr_accessor :default
|
|
18
|
+
attr_accessor :default_function
|
|
19
|
+
attr_accessor :generated
|
|
20
|
+
attr_accessor :primary_key
|
|
21
|
+
attr_accessor :nullable
|
|
13
22
|
|
|
14
23
|
def initialize \
|
|
15
24
|
table_name,
|
|
@@ -30,8 +30,14 @@ require "activerecord_spanner_adapter/table/column"
|
|
|
30
30
|
|
|
31
31
|
module ActiveRecordSpannerAdapter
|
|
32
32
|
class Table
|
|
33
|
-
attr_accessor :name
|
|
34
|
-
|
|
33
|
+
attr_accessor :name
|
|
34
|
+
attr_accessor :on_delete
|
|
35
|
+
attr_accessor :parent_table
|
|
36
|
+
attr_accessor :schema_name
|
|
37
|
+
attr_accessor :catalog
|
|
38
|
+
attr_accessor :indexes
|
|
39
|
+
attr_accessor :columns
|
|
40
|
+
attr_accessor :foreign_keys
|
|
35
41
|
|
|
36
42
|
# parent_table == interleave_in
|
|
37
43
|
def initialize \
|
|
@@ -123,7 +123,7 @@ module ActiveRecordSpannerAdapter
|
|
|
123
123
|
|
|
124
124
|
def shoot_and_forget_rollback
|
|
125
125
|
@connection.session.rollback @grpc_transaction.transaction_id if @committable
|
|
126
|
-
rescue StandardError
|
|
126
|
+
rescue StandardError
|
|
127
127
|
# Ignored
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -35,9 +35,7 @@ module Arel # :nodoc: all
|
|
|
35
35
|
sql = collector.hints[:statement_hint].value + sql if collector.hints[:statement_hint]
|
|
36
36
|
|
|
37
37
|
if binds
|
|
38
|
-
|
|
39
|
-
binds << collector.hints[:request_options] if collector.hints[:request_options]
|
|
40
|
-
[sql, binds]
|
|
38
|
+
compile_with_binds collector, sql, binds
|
|
41
39
|
else
|
|
42
40
|
sql
|
|
43
41
|
end
|
|
@@ -45,6 +43,12 @@ module Arel # :nodoc: all
|
|
|
45
43
|
|
|
46
44
|
private
|
|
47
45
|
|
|
46
|
+
def compile_with_binds collector, sql, binds
|
|
47
|
+
binds << collector.hints[:staleness] if collector.hints[:staleness]
|
|
48
|
+
binds << collector.hints[:request_options] if collector.hints[:request_options]
|
|
49
|
+
[sql, binds]
|
|
50
|
+
end
|
|
51
|
+
|
|
48
52
|
BIND_BLOCK = proc { |i| "@p#{i}" }
|
|
49
53
|
private_constant :BIND_BLOCK
|
|
50
54
|
|
|
@@ -62,43 +66,44 @@ module Arel # :nodoc: all
|
|
|
62
66
|
end
|
|
63
67
|
|
|
64
68
|
def visit_statement_hint v, collector
|
|
65
|
-
collector.hints[:statement_hint] =
|
|
69
|
+
collector.hints[:statement_hint] =
|
|
66
70
|
StatementHint.new v.delete_prefix("statement_hint:")
|
|
67
71
|
end
|
|
68
72
|
|
|
69
|
-
# rubocop:disable Naming/MethodName
|
|
73
|
+
# rubocop:disable Naming/MethodName, Metrics/AbcSize
|
|
70
74
|
def visit_Arel_Nodes_OptimizerHints o, collector
|
|
71
75
|
o.expr.each do |v|
|
|
72
76
|
visit_table_hint v, collector if v.start_with? "table_hint:"
|
|
73
77
|
visit_statement_hint v, collector if v.start_with? "statement_hint:"
|
|
74
78
|
if v.start_with? "max_staleness:"
|
|
75
|
-
collector.hints[:staleness] =
|
|
79
|
+
collector.hints[:staleness] =
|
|
76
80
|
StalenessHint.new max_staleness: v.delete_prefix("max_staleness:").to_f
|
|
77
81
|
next
|
|
78
82
|
end
|
|
79
83
|
if v.start_with? "exact_staleness:"
|
|
80
|
-
collector.hints[:staleness] =
|
|
84
|
+
collector.hints[:staleness] =
|
|
81
85
|
StalenessHint.new exact_staleness: v.delete_prefix("exact_staleness:").to_f
|
|
82
86
|
next
|
|
83
87
|
end
|
|
84
88
|
if v.start_with? "min_read_timestamp:"
|
|
85
89
|
time = Time.xmlschema v.delete_prefix("min_read_timestamp:")
|
|
86
|
-
collector.hints[:staleness] =
|
|
90
|
+
collector.hints[:staleness] =
|
|
87
91
|
StalenessHint.new min_read_timestamp: time
|
|
88
92
|
next
|
|
89
93
|
end
|
|
90
94
|
next unless v.start_with? "read_timestamp:"
|
|
91
95
|
time = Time.xmlschema v.delete_prefix("read_timestamp:")
|
|
92
|
-
collector.hints[:staleness] =
|
|
96
|
+
collector.hints[:staleness] =
|
|
93
97
|
StalenessHint.new read_timestamp: time
|
|
94
98
|
end
|
|
95
99
|
collector
|
|
96
100
|
end
|
|
101
|
+
# rubocop:enable Metrics/AbcSize
|
|
97
102
|
|
|
98
103
|
def visit_Arel_Nodes_Comment o, collector
|
|
99
|
-
o.values.each do |v|
|
|
104
|
+
o.values.each do |v| # rubocop:disable Style/HashEachMethods
|
|
100
105
|
if v.start_with?("request_tag:") || v.start_with?("transaction_tag:")
|
|
101
|
-
collector.hints[:request_options] ||=
|
|
106
|
+
collector.hints[:request_options] ||=
|
|
102
107
|
Google::Cloud::Spanner::V1::RequestOptions.new
|
|
103
108
|
end
|
|
104
109
|
|
data/lib/spanner_client_ext.rb
CHANGED
|
@@ -66,8 +66,8 @@ module Google
|
|
|
66
66
|
ensure_service!
|
|
67
67
|
|
|
68
68
|
snp_grpc = service.create_snapshot \
|
|
69
|
-
path, timestamp:
|
|
70
|
-
staleness:
|
|
69
|
+
path, timestamp: timestamp || read_timestamp,
|
|
70
|
+
staleness: staleness || exact_staleness
|
|
71
71
|
num_args = Snapshot.method(:from_grpc).arity
|
|
72
72
|
if num_args == 3
|
|
73
73
|
Snapshot.from_grpc snp_grpc, self, nil
|
|
@@ -105,7 +105,8 @@ module Google
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
class Transaction
|
|
108
|
-
attr_accessor :seqno
|
|
108
|
+
attr_accessor :seqno
|
|
109
|
+
attr_accessor :commit
|
|
109
110
|
end
|
|
110
111
|
end
|
|
111
112
|
end
|