activerecord-spanner-adapter 1.5.0 → 1.6.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 +1 -1
- data/.github/workflows/acceptance-tests-on-production.yaml +5 -3
- data/.github/workflows/ci.yaml +1 -1
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +1 -1
- data/.github/workflows/nightly-acceptance-tests-on-production.yaml +5 -3
- data/.github/workflows/nightly-unit-tests.yaml +1 -1
- data/.github/workflows/release-please-label.yml +1 -1
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile +5 -2
- data/README.md +10 -10
- data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb +6 -0
- data/acceptance/cases/migration/change_schema_test.rb +19 -3
- data/acceptance/cases/migration/schema_dumper_test.rb +10 -1
- data/acceptance/cases/models/insert_all_test.rb +22 -0
- data/acceptance/cases/models/interleave_test.rb +6 -0
- data/acceptance/cases/tasks/database_tasks_test.rb +340 -2
- data/acceptance/cases/transactions/optimistic_locking_test.rb +6 -0
- data/acceptance/cases/transactions/read_write_transactions_test.rb +24 -0
- data/acceptance/models/table_with_sequence.rb +10 -0
- data/acceptance/schema/schema.rb +65 -19
- data/acceptance/test_helper.rb +1 -1
- data/activerecord-spanner-adapter.gemspec +1 -1
- data/examples/snippets/bit-reversed-sequence/README.md +103 -0
- data/examples/snippets/bit-reversed-sequence/Rakefile +13 -0
- data/examples/snippets/bit-reversed-sequence/application.rb +68 -0
- data/examples/snippets/bit-reversed-sequence/config/database.yml +8 -0
- data/examples/snippets/bit-reversed-sequence/db/migrate/01_create_tables.rb +33 -0
- data/examples/snippets/bit-reversed-sequence/db/schema.rb +31 -0
- data/examples/snippets/bit-reversed-sequence/db/seeds.rb +31 -0
- data/examples/snippets/bit-reversed-sequence/models/album.rb +11 -0
- data/examples/snippets/bit-reversed-sequence/models/singer.rb +15 -0
- data/examples/snippets/interleaved-tables/README.md +44 -53
- data/examples/snippets/interleaved-tables/Rakefile +2 -2
- data/examples/snippets/interleaved-tables/application.rb +2 -2
- data/examples/snippets/interleaved-tables/db/migrate/01_create_tables.rb +12 -18
- data/examples/snippets/interleaved-tables/db/schema.rb +9 -7
- data/examples/snippets/interleaved-tables/db/seeds.rb +1 -1
- data/examples/snippets/interleaved-tables/models/album.rb +3 -7
- data/examples/snippets/interleaved-tables/models/singer.rb +1 -1
- data/examples/snippets/interleaved-tables/models/track.rb +6 -7
- data/examples/snippets/interleaved-tables-before-7.1/README.md +167 -0
- data/examples/snippets/interleaved-tables-before-7.1/Rakefile +13 -0
- data/examples/snippets/interleaved-tables-before-7.1/application.rb +126 -0
- data/examples/snippets/interleaved-tables-before-7.1/config/database.yml +8 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb +44 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/schema.rb +37 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/seeds.rb +40 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/album.rb +20 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/singer.rb +18 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/track.rb +28 -0
- data/examples/snippets/query-logs/README.md +43 -0
- data/examples/snippets/query-logs/Rakefile +13 -0
- data/examples/snippets/query-logs/application.rb +63 -0
- data/examples/snippets/query-logs/config/database.yml +8 -0
- data/examples/snippets/query-logs/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/query-logs/db/schema.rb +31 -0
- data/examples/snippets/query-logs/db/seeds.rb +24 -0
- data/examples/snippets/query-logs/models/album.rb +9 -0
- data/examples/snippets/query-logs/models/singer.rb +9 -0
- data/lib/active_record/connection_adapters/spanner/column.rb +13 -0
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +144 -35
- data/lib/active_record/connection_adapters/spanner/schema_cache.rb +3 -21
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +11 -0
- data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +4 -0
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +3 -2
- data/lib/active_record/connection_adapters/spanner_adapter.rb +28 -9
- data/lib/activerecord_spanner_adapter/base.rb +58 -21
- data/lib/activerecord_spanner_adapter/information_schema.rb +33 -24
- data/lib/activerecord_spanner_adapter/primary_key.rb +1 -1
- data/lib/activerecord_spanner_adapter/table/column.rb +4 -9
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- data/lib/arel/visitors/spanner.rb +3 -1
- metadata +33 -4
@@ -15,6 +15,8 @@ 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
|
+
|
18
20
|
attr_reader :connection
|
19
21
|
|
20
22
|
def initialize connection
|
@@ -62,6 +64,7 @@ module ActiveRecordSpannerAdapter
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def table_columns table_name, column_name: nil
|
67
|
+
primary_keys = table_primary_keys(table_name).map(&:name)
|
65
68
|
sql = +"SELECT COLUMN_NAME, SPANNER_TYPE, IS_NULLABLE, GENERATION_EXPRESSION,"
|
66
69
|
sql << " CAST(COLUMN_DEFAULT AS STRING) AS COLUMN_DEFAULT, ORDINAL_POSITION"
|
67
70
|
sql << " FROM INFORMATION_SCHEMA.COLUMNS"
|
@@ -75,34 +78,40 @@ module ActiveRecordSpannerAdapter
|
|
75
78
|
table_name: table_name,
|
76
79
|
column_name: column_name
|
77
80
|
).map do |row|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
+
_create_column table_name, row, primary_keys, column_options
|
82
|
+
end
|
83
|
+
end
|
81
84
|
|
82
|
-
|
83
|
-
|
85
|
+
def _create_column table_name, row, primary_keys, column_options
|
86
|
+
type, limit = parse_type_and_limit row["SPANNER_TYPE"]
|
87
|
+
column_name = row["COLUMN_NAME"]
|
88
|
+
options = column_options[column_name]
|
89
|
+
primary_key = primary_keys.include? column_name
|
84
90
|
|
85
|
-
|
86
|
-
|
87
|
-
default = nil
|
88
|
-
end
|
91
|
+
default = row["COLUMN_DEFAULT"]
|
92
|
+
default_function = row["GENERATION_EXPRESSION"]
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
|
94
|
+
if default && default.length < 200 && /\w+\(.*\)/.match?(default)
|
95
|
+
default_function ||= default
|
96
|
+
default = nil
|
97
|
+
end
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
column_name,
|
97
|
-
type,
|
98
|
-
limit: limit,
|
99
|
-
allow_commit_timestamp: options["allow_commit_timestamp"],
|
100
|
-
ordinal_position: row["ORDINAL_POSITION"],
|
101
|
-
nullable: row["IS_NULLABLE"] == "YES",
|
102
|
-
default: default,
|
103
|
-
default_function: default_function,
|
104
|
-
generated: row["GENERATION_EXPRESSION"].present?
|
99
|
+
if default && type == "STRING"
|
100
|
+
default = unquote_string default
|
105
101
|
end
|
102
|
+
|
103
|
+
Table::Column.new \
|
104
|
+
table_name,
|
105
|
+
column_name,
|
106
|
+
type,
|
107
|
+
limit: limit,
|
108
|
+
allow_commit_timestamp: options["allow_commit_timestamp"],
|
109
|
+
ordinal_position: row["ORDINAL_POSITION"],
|
110
|
+
nullable: row["IS_NULLABLE"] == "YES",
|
111
|
+
default: default,
|
112
|
+
default_function: default_function,
|
113
|
+
generated: row["GENERATION_EXPRESSION"].present?,
|
114
|
+
primary_key: primary_key
|
106
115
|
end
|
107
116
|
|
108
117
|
def table_column table_name, column_name
|
@@ -114,7 +123,7 @@ module ActiveRecordSpannerAdapter
|
|
114
123
|
# ActiveRecord. The parent primary key columns are filtered out by default to allow interleaved tables to be
|
115
124
|
# considered as tables with a single-column primary key by ActiveRecord. The actual primary key of the table will
|
116
125
|
# include both the parent primary key columns and the 'own' primary key columns of a table.
|
117
|
-
def table_primary_keys table_name, include_parent_keys =
|
126
|
+
def table_primary_keys table_name, include_parent_keys = IsRails71OrLater
|
118
127
|
sql = +"WITH TABLE_PK_COLS AS ( "
|
119
128
|
sql << "SELECT C.TABLE_NAME, C.COLUMN_NAME, C.INDEX_NAME, C.COLUMN_ORDERING, C.ORDINAL_POSITION "
|
120
129
|
sql << "FROM INFORMATION_SCHEMA.INDEX_COLUMNS C "
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def fetch_primary_and_parent_key
|
21
|
-
return connection.
|
21
|
+
return connection.spanner_schema_cache.primary_and_parent_keys table_name \
|
22
22
|
if ActiveRecord::Base != self && table_exists?
|
23
23
|
end
|
24
24
|
|
@@ -9,8 +9,7 @@ module ActiveRecordSpannerAdapter
|
|
9
9
|
class Column
|
10
10
|
attr_accessor :table_name, :name, :type, :limit, :ordinal_position,
|
11
11
|
:allow_commit_timestamp, :default, :default_function, :generated,
|
12
|
-
:primary_key
|
13
|
-
attr_writer :nullable
|
12
|
+
:primary_key, :nullable
|
14
13
|
|
15
14
|
def initialize \
|
16
15
|
table_name,
|
@@ -22,7 +21,8 @@ module ActiveRecordSpannerAdapter
|
|
22
21
|
allow_commit_timestamp: nil,
|
23
22
|
default: nil,
|
24
23
|
default_function: nil,
|
25
|
-
generated: nil
|
24
|
+
generated: nil,
|
25
|
+
primary_key: false
|
26
26
|
@table_name = table_name.to_s
|
27
27
|
@name = name.to_s
|
28
28
|
@type = type
|
@@ -33,12 +33,7 @@ module ActiveRecordSpannerAdapter
|
|
33
33
|
@default = default
|
34
34
|
@default_function = default_function
|
35
35
|
@generated = generated == true
|
36
|
-
@primary_key =
|
37
|
-
end
|
38
|
-
|
39
|
-
def nullable
|
40
|
-
return false if primary_key
|
41
|
-
@nullable
|
36
|
+
@primary_key = primary_key
|
42
37
|
end
|
43
38
|
|
44
39
|
def spanner_type
|
@@ -139,7 +139,9 @@ module Arel # :nodoc: all
|
|
139
139
|
# Do not generate a query parameter if the value should be set to the PENDING_COMMIT_TIMESTAMP(), as that is
|
140
140
|
# not supported as a parameter value by Cloud Spanner.
|
141
141
|
return collector << "PENDING_COMMIT_TIMESTAMP()" \
|
142
|
-
|
142
|
+
if o.value.respond_to?(:type) \
|
143
|
+
&& o.value.type.is_a?(ActiveRecord::Type::Spanner::Time) \
|
144
|
+
&& o.value.value == :commit_timestamp
|
143
145
|
collector.add_bind(o.value, &bind_block)
|
144
146
|
end
|
145
147
|
# rubocop:enable Naming/MethodName
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-spanner-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Google LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-spanner
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 6.0.0
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '7.
|
36
|
+
version: '7.2'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 6.0.0
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '7.
|
46
|
+
version: '7.2'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: autotest-suffix
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -312,6 +312,7 @@ files:
|
|
312
312
|
- acceptance/models/organization.rb
|
313
313
|
- acceptance/models/post.rb
|
314
314
|
- acceptance/models/singer.rb
|
315
|
+
- acceptance/models/table_with_sequence.rb
|
315
316
|
- acceptance/models/track.rb
|
316
317
|
- acceptance/models/transaction.rb
|
317
318
|
- acceptance/schema/schema.rb
|
@@ -342,6 +343,15 @@ files:
|
|
342
343
|
- examples/snippets/array-data-type/db/seeds.rb
|
343
344
|
- examples/snippets/array-data-type/models/entity_with_array_types.rb
|
344
345
|
- examples/snippets/bin/create_emulator_instance.rb
|
346
|
+
- examples/snippets/bit-reversed-sequence/README.md
|
347
|
+
- examples/snippets/bit-reversed-sequence/Rakefile
|
348
|
+
- examples/snippets/bit-reversed-sequence/application.rb
|
349
|
+
- examples/snippets/bit-reversed-sequence/config/database.yml
|
350
|
+
- examples/snippets/bit-reversed-sequence/db/migrate/01_create_tables.rb
|
351
|
+
- examples/snippets/bit-reversed-sequence/db/schema.rb
|
352
|
+
- examples/snippets/bit-reversed-sequence/db/seeds.rb
|
353
|
+
- examples/snippets/bit-reversed-sequence/models/album.rb
|
354
|
+
- examples/snippets/bit-reversed-sequence/models/singer.rb
|
345
355
|
- examples/snippets/bulk-insert/README.md
|
346
356
|
- examples/snippets/bulk-insert/Rakefile
|
347
357
|
- examples/snippets/bulk-insert/application.rb
|
@@ -395,6 +405,16 @@ files:
|
|
395
405
|
- examples/snippets/hints/db/seeds.rb
|
396
406
|
- examples/snippets/hints/models/album.rb
|
397
407
|
- examples/snippets/hints/models/singer.rb
|
408
|
+
- examples/snippets/interleaved-tables-before-7.1/README.md
|
409
|
+
- examples/snippets/interleaved-tables-before-7.1/Rakefile
|
410
|
+
- examples/snippets/interleaved-tables-before-7.1/application.rb
|
411
|
+
- examples/snippets/interleaved-tables-before-7.1/config/database.yml
|
412
|
+
- examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb
|
413
|
+
- examples/snippets/interleaved-tables-before-7.1/db/schema.rb
|
414
|
+
- examples/snippets/interleaved-tables-before-7.1/db/seeds.rb
|
415
|
+
- examples/snippets/interleaved-tables-before-7.1/models/album.rb
|
416
|
+
- examples/snippets/interleaved-tables-before-7.1/models/singer.rb
|
417
|
+
- examples/snippets/interleaved-tables-before-7.1/models/track.rb
|
398
418
|
- examples/snippets/interleaved-tables/README.md
|
399
419
|
- examples/snippets/interleaved-tables/Rakefile
|
400
420
|
- examples/snippets/interleaved-tables/application.rb
|
@@ -442,6 +462,15 @@ files:
|
|
442
462
|
- examples/snippets/partitioned-dml/db/seeds.rb
|
443
463
|
- examples/snippets/partitioned-dml/models/album.rb
|
444
464
|
- examples/snippets/partitioned-dml/models/singer.rb
|
465
|
+
- examples/snippets/query-logs/README.md
|
466
|
+
- examples/snippets/query-logs/Rakefile
|
467
|
+
- examples/snippets/query-logs/application.rb
|
468
|
+
- examples/snippets/query-logs/config/database.yml
|
469
|
+
- examples/snippets/query-logs/db/migrate/01_create_tables.rb
|
470
|
+
- examples/snippets/query-logs/db/schema.rb
|
471
|
+
- examples/snippets/query-logs/db/seeds.rb
|
472
|
+
- examples/snippets/query-logs/models/album.rb
|
473
|
+
- examples/snippets/query-logs/models/singer.rb
|
445
474
|
- examples/snippets/quickstart/README.md
|
446
475
|
- examples/snippets/quickstart/Rakefile
|
447
476
|
- examples/snippets/quickstart/application.rb
|