activerecord-spanner-adapter 2.4.0 → 2.5.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/CODEOWNERS +1 -1
- data/.github/workflows/acceptance-tests-on-emulator.yaml +3 -1
- data/.github/workflows/ci.yaml +3 -1
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +3 -1
- data/.github/workflows/nightly-unit-tests.yaml +3 -1
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/README.md +1 -0
- data/acceptance/cases/migration/index_test.rb +2 -2
- data/acceptance/cases/tasks/database_tasks_test.rb +8 -0
- data/acceptance/cases/type/all_types_test.rb +15 -4
- data/acceptance/schema/schema.rb +2 -0
- data/activerecord-spanner-adapter.gemspec +2 -2
- data/lib/active_record/connection_adapters/spanner/column.rb +20 -7
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +32 -12
- data/lib/active_record/connection_adapters/spanner/type_mapping.rb +26 -0
- data/lib/active_record/connection_adapters/spanner_adapter.rb +8 -17
- data/lib/active_record/type/spanner/spanner_active_record_converter.rb +1 -0
- data/lib/active_record/type/spanner/uuid.rb +19 -0
- data/lib/activerecord_spanner_adapter/connection.rb +5 -0
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- metadata +13 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e5132b6ef0337fa324c42c5b61ff6bee8e745352c58c46afc5f583a253fc6571
|
|
4
|
+
data.tar.gz: 699d2b993d739c78fc95fc12b30189e512517111aa9ae787d929b9d3ac828576
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d97e90c71f7dad83a35fc6cfb1921c24989d88b050c88b75ff444dbc58d4c0c2a9abbde2f8197d700dca121dda5c12853e4f6cae6c27bfc0520c7facbff3338
|
|
7
|
+
data.tar.gz: 5dbb5523a45941eff16db888d0af3c5ab7ea3e54af9e94d0f0943cef2a9b6d5e39078df1a1761e05a436910906cd19825f84f298d8e2b9043d79981dff51b4f7
|
data/.github/CODEOWNERS
CHANGED
|
@@ -19,11 +19,13 @@ jobs:
|
|
|
19
19
|
max-parallel: 4
|
|
20
20
|
matrix:
|
|
21
21
|
ruby: ["3.1", "3.2", "3.3", "3.4"]
|
|
22
|
-
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0"]
|
|
22
|
+
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0", "~> 8.1.0"]
|
|
23
23
|
# Exclude combinations that are not supported.
|
|
24
24
|
exclude:
|
|
25
25
|
- ruby: "3.1"
|
|
26
26
|
ar: "~> 8.0.0"
|
|
27
|
+
- ruby: "3.1"
|
|
28
|
+
ar: "~> 8.1.0"
|
|
27
29
|
- ruby: "3.4"
|
|
28
30
|
ar: "~> 7.0.0"
|
|
29
31
|
- ruby: "3.4"
|
data/.github/workflows/ci.yaml
CHANGED
|
@@ -11,11 +11,13 @@ jobs:
|
|
|
11
11
|
max-parallel: 4
|
|
12
12
|
matrix:
|
|
13
13
|
ruby: ["3.1", "3.2", "3.3", "3.4"]
|
|
14
|
-
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0"]
|
|
14
|
+
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0", "~> 8.1.0"]
|
|
15
15
|
# Exclude combinations that are not supported.
|
|
16
16
|
exclude:
|
|
17
17
|
- ruby: "3.1"
|
|
18
18
|
ar: "~> 8.0.0"
|
|
19
|
+
- ruby: "3.1"
|
|
20
|
+
ar: "~> 8.1.0"
|
|
19
21
|
- ruby: "3.4"
|
|
20
22
|
ar: "~> 7.0.0"
|
|
21
23
|
- ruby: "3.4"
|
|
@@ -19,11 +19,13 @@ jobs:
|
|
|
19
19
|
max-parallel: 4
|
|
20
20
|
matrix:
|
|
21
21
|
ruby: ["3.1", "3.2", "3.3", "3.4"]
|
|
22
|
-
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0"]
|
|
22
|
+
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0", "~> 8.1.0"]
|
|
23
23
|
# Exclude combinations that are not supported.
|
|
24
24
|
exclude:
|
|
25
25
|
- ruby: "3.1"
|
|
26
26
|
ar: "~> 8.0.0"
|
|
27
|
+
- ruby: "3.1"
|
|
28
|
+
ar: "~> 8.1.0"
|
|
27
29
|
- ruby: "3.4"
|
|
28
30
|
ar: "~> 7.0.0"
|
|
29
31
|
- ruby: "3.4"
|
|
@@ -12,11 +12,13 @@ jobs:
|
|
|
12
12
|
matrix:
|
|
13
13
|
# Run acceptance tests all supported combinations of Ruby and ActiveRecord.
|
|
14
14
|
ruby: ["3.1", "3.2", "3.3", "3.4"]
|
|
15
|
-
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0"]
|
|
15
|
+
ar: ["~> 7.0.0", "~> 7.1.0", "~> 7.2.0", "~> 8.0.0", "~> 8.1.0"]
|
|
16
16
|
# Exclude combinations that are not supported.
|
|
17
17
|
exclude:
|
|
18
18
|
- ruby: "3.1"
|
|
19
19
|
ar: "~> 8.0.0"
|
|
20
|
+
- ruby: "3.1"
|
|
21
|
+
ar: "~> 8.1.0"
|
|
20
22
|
- ruby: "3.4"
|
|
21
23
|
ar: "~> 7.0.0"
|
|
22
24
|
- ruby: "3.4"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
### 2.5.0 (2026-02-11)
|
|
4
|
+
|
|
5
|
+
#### Features
|
|
6
|
+
|
|
7
|
+
* add support for the UUID data type ([#387](https://github.com/googleapis/ruby-spanner-activerecord/issues/387))
|
|
8
|
+
* support ActiveRecord 8.1.x ([#385](https://github.com/googleapis/ruby-spanner-activerecord/issues/385))
|
|
9
|
+
#### Documentation
|
|
10
|
+
|
|
11
|
+
* update README to reflect support for Rails 8.1.x ([#388](https://github.com/googleapis/ruby-spanner-activerecord/issues/388))
|
|
12
|
+
|
|
3
13
|
### 2.4.0 (2026-02-04)
|
|
4
14
|
|
|
5
15
|
#### Features
|
data/Gemfile
CHANGED
|
@@ -7,7 +7,7 @@ ar_version = ENV.fetch("AR_VERSION", "~> 7.1.0")
|
|
|
7
7
|
gem "activerecord", ar_version
|
|
8
8
|
gem "ostruct"
|
|
9
9
|
gem "minitest", "~> 5.27.0"
|
|
10
|
-
gem "minitest-rg", "~> 5.
|
|
10
|
+
gem "minitest-rg", "~> 5.4.0"
|
|
11
11
|
gem "pry", "~> 0.14.2"
|
|
12
12
|
gem "pry-byebug", "~> 3.11.0"
|
|
13
13
|
gem "mutex_m"
|
data/README.md
CHANGED
|
@@ -15,6 +15,7 @@ This project provides a Spanner adapter for ActiveRecord. It supports the follow
|
|
|
15
15
|
- ActiveRecord 7.1.x with Ruby 3.1 and higher.
|
|
16
16
|
- ActiveRecord 7.2.x with Ruby 3.1 and higher.
|
|
17
17
|
- ActiveRecord 8.0.x with Ruby 3.2 and higher.
|
|
18
|
+
- ActiveRecord 8.1.x with Ruby 3.2 and higher.
|
|
18
19
|
|
|
19
20
|
Known limitations are listed in the [Limitations](#limitations) section.
|
|
20
21
|
Please report any problems that you might encounter by [creating a new issue](https://github.com/googleapis/ruby-spanner-activerecord/issues/new).
|
|
@@ -57,7 +57,7 @@ module ActiveRecord
|
|
|
57
57
|
e = assert_raises(ArgumentError) {
|
|
58
58
|
connection.rename_index(table_name, "old_idx", too_long_index_name)
|
|
59
59
|
}
|
|
60
|
-
assert_match(/too long
|
|
60
|
+
assert_match(/too long/, e.message)
|
|
61
61
|
|
|
62
62
|
assert connection.index_name_exists?(table_name, "old_idx")
|
|
63
63
|
end
|
|
@@ -79,7 +79,7 @@ module ActiveRecord
|
|
|
79
79
|
e = assert_raises(ArgumentError) {
|
|
80
80
|
connection.add_index(table_name, "foo", name: too_long_index_name)
|
|
81
81
|
}
|
|
82
|
-
assert_match(/too long
|
|
82
|
+
assert_match(/too long/, e.message)
|
|
83
83
|
|
|
84
84
|
assert_not connection.index_name_exists?(table_name, too_long_index_name)
|
|
85
85
|
connection.add_index(table_name, "foo", name: good_index_name)
|
|
@@ -129,6 +129,7 @@ module ActiveRecord
|
|
|
129
129
|
col_date DATE,
|
|
130
130
|
col_timestamp TIMESTAMP,
|
|
131
131
|
col_json JSON,
|
|
132
|
+
col_uuid UUID,
|
|
132
133
|
col_array_string ARRAY<STRING(MAX)>,
|
|
133
134
|
col_array_int64 ARRAY<INT64>,
|
|
134
135
|
col_array_float64 ARRAY<FLOAT64>,
|
|
@@ -138,6 +139,7 @@ module ActiveRecord
|
|
|
138
139
|
col_array_date ARRAY<DATE>,
|
|
139
140
|
col_array_timestamp ARRAY<TIMESTAMP>,
|
|
140
141
|
col_array_json ARRAY<JSON>,
|
|
142
|
+
col_array_uuid ARRAY<UUID>,
|
|
141
143
|
) PRIMARY KEY(id);
|
|
142
144
|
CREATE TABLE firms (
|
|
143
145
|
id INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
|
|
@@ -287,6 +289,7 @@ INSERT INTO `schema_migrations` (version) VALUES
|
|
|
287
289
|
col_date DATE,
|
|
288
290
|
col_timestamp TIMESTAMP,
|
|
289
291
|
col_json JSON,
|
|
292
|
+
col_uuid UUID,
|
|
290
293
|
col_array_string ARRAY<STRING(MAX)>,
|
|
291
294
|
col_array_int64 ARRAY<INT64>,
|
|
292
295
|
col_array_float64 ARRAY<FLOAT64>,
|
|
@@ -296,6 +299,7 @@ INSERT INTO `schema_migrations` (version) VALUES
|
|
|
296
299
|
col_array_date ARRAY<DATE>,
|
|
297
300
|
col_array_timestamp ARRAY<TIMESTAMP>,
|
|
298
301
|
col_array_json ARRAY<JSON>,
|
|
302
|
+
col_array_uuid ARRAY<UUID>,
|
|
299
303
|
) PRIMARY KEY(id);
|
|
300
304
|
CREATE TABLE firms (
|
|
301
305
|
id INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
|
|
@@ -463,6 +467,7 @@ CREATE TABLE all_types (
|
|
|
463
467
|
col_date DATE,
|
|
464
468
|
col_timestamp TIMESTAMP,
|
|
465
469
|
col_json JSON,
|
|
470
|
+
col_uuid UUID,
|
|
466
471
|
col_array_string ARRAY<STRING(MAX)>,
|
|
467
472
|
col_array_int64 ARRAY<INT64>,
|
|
468
473
|
col_array_float64 ARRAY<FLOAT64>,
|
|
@@ -472,6 +477,7 @@ CREATE TABLE all_types (
|
|
|
472
477
|
col_array_date ARRAY<DATE>,
|
|
473
478
|
col_array_timestamp ARRAY<TIMESTAMP>,
|
|
474
479
|
col_array_json ARRAY<JSON>,
|
|
480
|
+
col_array_uuid ARRAY<UUID>,
|
|
475
481
|
) PRIMARY KEY(id);
|
|
476
482
|
CREATE TABLE ar_internal_metadata (
|
|
477
483
|
key STRING(MAX) NOT NULL,
|
|
@@ -624,6 +630,7 @@ CREATE TABLE all_types (
|
|
|
624
630
|
col_date DATE,
|
|
625
631
|
col_timestamp TIMESTAMP,
|
|
626
632
|
col_json JSON,
|
|
633
|
+
col_uuid UUID,
|
|
627
634
|
col_array_string ARRAY<STRING(MAX)>,
|
|
628
635
|
col_array_int64 ARRAY<INT64>,
|
|
629
636
|
col_array_float64 ARRAY<FLOAT64>,
|
|
@@ -633,6 +640,7 @@ CREATE TABLE all_types (
|
|
|
633
640
|
col_array_date ARRAY<DATE>,
|
|
634
641
|
col_array_timestamp ARRAY<TIMESTAMP>,
|
|
635
642
|
col_array_json ARRAY<JSON>,
|
|
643
|
+
col_array_uuid ARRAY<UUID>,
|
|
636
644
|
) PRIMARY KEY(id);
|
|
637
645
|
CREATE TABLE ar_internal_metadata (
|
|
638
646
|
key STRING(MAX) NOT NULL,
|
|
@@ -30,7 +30,8 @@ module ActiveRecord
|
|
|
30
30
|
AllTypes.create col_string: "string", col_int64: 100, col_float64: 3.14, col_numeric: 6.626, col_bool: true,
|
|
31
31
|
col_bytes: StringIO.new("bytes"), col_date: ::Date.new(2021, 6, 23),
|
|
32
32
|
col_timestamp: ::Time.new(2021, 6, 23, 17, 8, 21, "+02:00"),
|
|
33
|
-
col_json: { kind: "user_renamed", change: %w[jack john]},
|
|
33
|
+
col_json: { kind: "user_renamed", change: %w[jack john] },
|
|
34
|
+
col_uuid: "3840ba25-55df-4cb7-a210-1fe37278954f",
|
|
34
35
|
col_array_string: ["string1", nil, "string2"],
|
|
35
36
|
col_array_int64: [100, nil, 200, "300"],
|
|
36
37
|
col_array_float64: [3.14, nil, 2.0/3.0, "3.14"],
|
|
@@ -42,7 +43,8 @@ module ActiveRecord
|
|
|
42
43
|
::Time.new(2021, 6, 24, 17, 8, 21, "+02:00"), "2021-06-25 17:08:21 +02:00"],
|
|
43
44
|
col_array_json: [{ kind: "user_renamed", change: %w[jack john]}, nil, \
|
|
44
45
|
{ kind: "user_renamed", change: %w[alice meredith]},
|
|
45
|
-
"{\"kind\":\"user_renamed\",\"change\":[\"bob\",\"carol\"]}"]
|
|
46
|
+
"{\"kind\":\"user_renamed\",\"change\":[\"bob\",\"carol\"]}"],
|
|
47
|
+
col_array_uuid: ["e986c19c-9bf3-44f8-851d-710ad3d0067b", nil, "a02f50b6-2860-48dc-acd6-49b42abc3094"]
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def test_create_record
|
|
@@ -67,6 +69,7 @@ module ActiveRecord
|
|
|
67
69
|
assert_equal ::Time.new(2021, 6, 23, 17, 8, 21, "+02:00").utc, record.col_timestamp.utc
|
|
68
70
|
assert_equal ({"kind" => "user_renamed", "change" => %w[jack john]}),
|
|
69
71
|
record.col_json
|
|
72
|
+
assert_equal "3840ba25-55df-4cb7-a210-1fe37278954f", record.col_uuid
|
|
70
73
|
|
|
71
74
|
assert_equal ["string1", nil, "string2"], record.col_array_string
|
|
72
75
|
assert_equal [100, nil, 200, 300], record.col_array_int64
|
|
@@ -85,6 +88,7 @@ module ActiveRecord
|
|
|
85
88
|
{"kind" => "user_renamed", "change" => %w[alice meredith]}, \
|
|
86
89
|
"{\"kind\":\"user_renamed\",\"change\":[\"bob\",\"carol\"]}"],
|
|
87
90
|
record.col_array_json
|
|
91
|
+
assert_equal ["e986c19c-9bf3-44f8-851d-710ad3d0067b", nil, "a02f50b6-2860-48dc-acd6-49b42abc3094"], record.col_array_uuid
|
|
88
92
|
end
|
|
89
93
|
end
|
|
90
94
|
|
|
@@ -100,6 +104,7 @@ module ActiveRecord
|
|
|
100
104
|
col_date: ::Date.new(2021, 6, 28),
|
|
101
105
|
col_timestamp: ::Time.new(2021, 6, 28, 11, 22, 21, "+02:00"),
|
|
102
106
|
col_json: { kind: "user_created", change: %w[jack alice]},
|
|
107
|
+
col_uuid: "b493579f-f4f6-41f6-a520-8373ecf1cde4",
|
|
103
108
|
col_array_string: ["new string 1", "new string 2"],
|
|
104
109
|
col_array_int64: [300, 200, 100],
|
|
105
110
|
col_array_float64: [1.1, 2.2, 3.3],
|
|
@@ -108,7 +113,8 @@ module ActiveRecord
|
|
|
108
113
|
col_array_bytes: [StringIO.new("new bytes 1"), StringIO.new("new bytes 2")],
|
|
109
114
|
col_array_date: [::Date.new(2021, 6, 28)],
|
|
110
115
|
col_array_timestamp: [::Time.utc(2020, 12, 31, 0, 0, 0)],
|
|
111
|
-
col_array_json: [{ kind: "user_created", change: %w[jack alice]}]
|
|
116
|
+
col_array_json: [{ kind: "user_created", change: %w[jack alice]}],
|
|
117
|
+
col_array_uuid: ["a664b1eb-4dc7-4795-9ed8-28fab6644cea", nil, "1c794d81-bc6d-4771-9c92-a920d28a7aaa"]
|
|
112
118
|
end
|
|
113
119
|
|
|
114
120
|
# Verify that the record was updated.
|
|
@@ -123,6 +129,7 @@ module ActiveRecord
|
|
|
123
129
|
assert_equal ::Time.new(2021, 6, 28, 11, 22, 21, "+02:00").utc, record.col_timestamp.utc
|
|
124
130
|
assert_equal ({"kind" => "user_created", "change" => %w[jack alice]}),
|
|
125
131
|
record.col_json
|
|
132
|
+
assert_equal "b493579f-f4f6-41f6-a520-8373ecf1cde4", record.col_uuid
|
|
126
133
|
|
|
127
134
|
assert_equal ["new string 1", "new string 2"], record.col_array_string
|
|
128
135
|
assert_equal [300, 200, 100], record.col_array_int64
|
|
@@ -135,6 +142,8 @@ module ActiveRecord
|
|
|
135
142
|
assert_equal [::Time.utc(2020, 12, 31, 0, 0, 0)], record.col_array_timestamp.map(&:utc)
|
|
136
143
|
assert_equal [{"kind" => "user_created", "change" => %w[jack alice]}],
|
|
137
144
|
record.col_array_json
|
|
145
|
+
assert_equal ["a664b1eb-4dc7-4795-9ed8-28fab6644cea", nil, "1c794d81-bc6d-4771-9c92-a920d28a7aaa"],
|
|
146
|
+
record.col_array_uuid
|
|
138
147
|
end
|
|
139
148
|
end
|
|
140
149
|
|
|
@@ -151,7 +160,8 @@ module ActiveRecord
|
|
|
151
160
|
col_array_bytes: [],
|
|
152
161
|
col_array_date: [],
|
|
153
162
|
col_array_timestamp: [],
|
|
154
|
-
col_array_json: []
|
|
163
|
+
col_array_json: [],
|
|
164
|
+
col_array_uuid: []
|
|
155
165
|
end
|
|
156
166
|
|
|
157
167
|
record = AllTypes.find record.id
|
|
@@ -164,6 +174,7 @@ module ActiveRecord
|
|
|
164
174
|
assert_equal [], record.col_array_date
|
|
165
175
|
assert_equal [], record.col_array_timestamp
|
|
166
176
|
assert_equal [], record.col_array_json
|
|
177
|
+
assert_equal [], record.col_array_uuid
|
|
167
178
|
end
|
|
168
179
|
end
|
|
169
180
|
end
|
data/acceptance/schema/schema.rb
CHANGED
|
@@ -24,6 +24,7 @@ def create_tables_in_test_schema
|
|
|
24
24
|
t.column :col_date, :date
|
|
25
25
|
t.column :col_timestamp, :datetime
|
|
26
26
|
t.column :col_json, :json
|
|
27
|
+
t.column :col_uuid, :uuid
|
|
27
28
|
|
|
28
29
|
t.column :col_array_string, :string, array: true
|
|
29
30
|
t.column :col_array_int64, :bigint, array: true
|
|
@@ -34,6 +35,7 @@ def create_tables_in_test_schema
|
|
|
34
35
|
t.column :col_array_date, :date, array: true
|
|
35
36
|
t.column :col_array_timestamp, :datetime, array: true
|
|
36
37
|
t.column :col_array_json, :json, array: true
|
|
38
|
+
t.column :col_array_uuid, :uuid, array: true
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
create_table :firms do |t|
|
|
@@ -29,12 +29,12 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_runtime_dependency "activerecord", [">= 7.0", "< 9"]
|
|
30
30
|
|
|
31
31
|
spec.add_development_dependency "autotest-suffix", "~> 1.1"
|
|
32
|
-
spec.add_development_dependency "bundler", "
|
|
32
|
+
spec.add_development_dependency "bundler", [">= 2.0", "< 5.0"]
|
|
33
33
|
spec.add_development_dependency "google-style", "~> 1.31.0"
|
|
34
34
|
spec.add_development_dependency "minitest", "~> 5.10"
|
|
35
35
|
spec.add_development_dependency "minitest-autotest", "~> 1.0"
|
|
36
36
|
spec.add_development_dependency "minitest-focus", "~> 1.1"
|
|
37
|
-
spec.add_development_dependency "minitest-rg", "~> 5.
|
|
37
|
+
spec.add_development_dependency "minitest-rg", "~> 5.4"
|
|
38
38
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
39
39
|
spec.add_development_dependency "redcarpet", "~> 3.0"
|
|
40
40
|
spec.add_development_dependency "simplecov", "~> 0.9"
|
|
@@ -10,13 +10,26 @@ module ActiveRecord
|
|
|
10
10
|
module ConnectionAdapters
|
|
11
11
|
module Spanner
|
|
12
12
|
class Column < ConnectionAdapters::Column
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
VERSION_8_1 = Gem::Version.create "8.1.0"
|
|
14
|
+
|
|
15
|
+
if ActiveRecord.gem_version < VERSION_8_1
|
|
16
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
|
17
|
+
def initialize(name, default, sql_type_metadata = nil, null = true,
|
|
18
|
+
default_function = nil, collation: nil, comment: nil,
|
|
19
|
+
primary_key: false, **)
|
|
20
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
|
21
|
+
super
|
|
22
|
+
@primary_key = primary_key
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
|
26
|
+
def initialize(name, cast_type, default, sql_type_metadata = nil, null = true,
|
|
27
|
+
default_function = nil, collation: nil, comment: nil,
|
|
28
|
+
primary_key: false, **)
|
|
29
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
|
30
|
+
super
|
|
31
|
+
@primary_key = primary_key
|
|
32
|
+
end
|
|
20
33
|
end
|
|
21
34
|
|
|
22
35
|
def auto_incremented_by_db?
|
|
@@ -138,7 +138,11 @@ module ActiveRecord
|
|
|
138
138
|
sql << " NOT NULL"
|
|
139
139
|
end
|
|
140
140
|
if options.key? :default
|
|
141
|
-
sql <<
|
|
141
|
+
sql << if respond_to? :quote_default_expression_for_column_definition, :include_private
|
|
142
|
+
" DEFAULT (#{quote_default_expression_for_column_definition options[:default], column})"
|
|
143
|
+
else
|
|
144
|
+
" DEFAULT (#{quote_default_expression options[:default], column})"
|
|
145
|
+
end
|
|
142
146
|
elsif column.type == :primary_key
|
|
143
147
|
if @connection.use_auto_increment?
|
|
144
148
|
sql << " AUTO_INCREMENT"
|
|
@@ -22,6 +22,7 @@ module ActiveRecord
|
|
|
22
22
|
#
|
|
23
23
|
module SchemaStatements
|
|
24
24
|
VERSION_7_2 = Gem::Version.create "7.2.0"
|
|
25
|
+
VERSION_8_1 = Gem::Version.create "8.1.0"
|
|
25
26
|
|
|
26
27
|
def current_database
|
|
27
28
|
@connection.database_id
|
|
@@ -116,18 +117,37 @@ module ActiveRecord
|
|
|
116
117
|
information_schema { |i| i.table_columns table_name }
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
if ActiveRecord.gem_version < VERSION_8_1
|
|
121
|
+
def new_column_from_field _table_name, field, _definitions = nil
|
|
122
|
+
Spanner::Column.new \
|
|
123
|
+
field.name,
|
|
124
|
+
field.default,
|
|
125
|
+
fetch_type_metadata(field.spanner_type,
|
|
126
|
+
field.ordinal_position,
|
|
127
|
+
field.allow_commit_timestamp,
|
|
128
|
+
field.generated,
|
|
129
|
+
is_identity: field.is_identity),
|
|
130
|
+
field.nullable,
|
|
131
|
+
field.default_function,
|
|
132
|
+
primary_key: field.primary_key
|
|
133
|
+
end
|
|
134
|
+
else
|
|
135
|
+
def new_column_from_field _table_name, field, _definitions = nil
|
|
136
|
+
cast_type = type_map.lookup field.type
|
|
137
|
+
raise ArgumentError, "unknown type: `#{field.type}`" if cast_type.nil?
|
|
138
|
+
Spanner::Column.new \
|
|
139
|
+
field.name,
|
|
140
|
+
cast_type,
|
|
141
|
+
field.default,
|
|
142
|
+
fetch_type_metadata(field.spanner_type,
|
|
143
|
+
field.ordinal_position,
|
|
144
|
+
field.allow_commit_timestamp,
|
|
145
|
+
field.generated,
|
|
146
|
+
is_identity: field.is_identity),
|
|
147
|
+
field.nullable,
|
|
148
|
+
field.default_function,
|
|
149
|
+
primary_key: field.primary_key
|
|
150
|
+
end
|
|
131
151
|
end
|
|
132
152
|
|
|
133
153
|
def fetch_type_metadata sql_type, ordinal_position = nil, allow_commit_timestamp = nil, generated = nil,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Use of this source code is governed by an MIT-style
|
|
4
|
+
# license that can be found in the LICENSE file or at
|
|
5
|
+
# https://opensource.org/licenses/MIT.
|
|
6
|
+
#
|
|
7
|
+
# frozen_string_literal: true
|
|
8
|
+
|
|
9
|
+
NATIVE_DATABASE_TYPES = {
|
|
10
|
+
primary_key: "INT64",
|
|
11
|
+
parent_key: "INT64",
|
|
12
|
+
string: { name: "STRING", limit: "MAX" },
|
|
13
|
+
text: { name: "STRING", limit: "MAX" },
|
|
14
|
+
integer: { name: "INT64" },
|
|
15
|
+
bigint: { name: "INT64" },
|
|
16
|
+
float: { name: "FLOAT64" },
|
|
17
|
+
decimal: { name: "NUMERIC" },
|
|
18
|
+
numeric: { name: "NUMERIC" },
|
|
19
|
+
datetime: { name: "TIMESTAMP" },
|
|
20
|
+
time: { name: "TIMESTAMP" },
|
|
21
|
+
date: { name: "DATE" },
|
|
22
|
+
binary: { name: "BYTES", limit: "MAX" },
|
|
23
|
+
boolean: { name: "BOOL" },
|
|
24
|
+
json: { name: "JSON" },
|
|
25
|
+
uuid: { name: "UUID" }
|
|
26
|
+
}.freeze
|
|
@@ -13,12 +13,14 @@ require "active_record/connection_adapters/spanner/database_statements"
|
|
|
13
13
|
require "active_record/connection_adapters/spanner/schema_statements"
|
|
14
14
|
require "active_record/connection_adapters/spanner/schema_cache"
|
|
15
15
|
require "active_record/connection_adapters/spanner/schema_definitions"
|
|
16
|
+
require "active_record/connection_adapters/spanner/type_mapping"
|
|
16
17
|
require "active_record/connection_adapters/spanner/type_metadata"
|
|
17
18
|
require "active_record/connection_adapters/spanner/quoting"
|
|
18
19
|
require "active_record/type/spanner/array"
|
|
19
20
|
require "active_record/type/spanner/bytes"
|
|
20
21
|
require "active_record/type/spanner/spanner_active_record_converter"
|
|
21
22
|
require "active_record/type/spanner/time"
|
|
23
|
+
require "active_record/type/spanner/uuid"
|
|
22
24
|
require "arel/visitors/spanner"
|
|
23
25
|
require "activerecord_spanner_adapter/base"
|
|
24
26
|
require "activerecord_spanner_adapter/connection"
|
|
@@ -46,23 +48,6 @@ module ActiveRecord
|
|
|
46
48
|
module ConnectionAdapters
|
|
47
49
|
class SpannerAdapter < AbstractAdapter
|
|
48
50
|
ADAPTER_NAME = "spanner".freeze
|
|
49
|
-
NATIVE_DATABASE_TYPES = {
|
|
50
|
-
primary_key: "INT64",
|
|
51
|
-
parent_key: "INT64",
|
|
52
|
-
string: { name: "STRING", limit: "MAX" },
|
|
53
|
-
text: { name: "STRING", limit: "MAX" },
|
|
54
|
-
integer: { name: "INT64" },
|
|
55
|
-
bigint: { name: "INT64" },
|
|
56
|
-
float: { name: "FLOAT64" },
|
|
57
|
-
decimal: { name: "NUMERIC" },
|
|
58
|
-
numeric: { name: "NUMERIC" },
|
|
59
|
-
datetime: { name: "TIMESTAMP" },
|
|
60
|
-
time: { name: "TIMESTAMP" },
|
|
61
|
-
date: { name: "DATE" },
|
|
62
|
-
binary: { name: "BYTES", limit: "MAX" },
|
|
63
|
-
boolean: { name: "BOOL" },
|
|
64
|
-
json: { name: "JSON" }
|
|
65
|
-
}.freeze
|
|
66
51
|
|
|
67
52
|
include Spanner::Quoting
|
|
68
53
|
include Spanner::DatabaseStatements
|
|
@@ -118,6 +103,10 @@ module ActiveRecord
|
|
|
118
103
|
NATIVE_DATABASE_TYPES
|
|
119
104
|
end
|
|
120
105
|
|
|
106
|
+
def self.native_database_types
|
|
107
|
+
NATIVE_DATABASE_TYPES
|
|
108
|
+
end
|
|
109
|
+
|
|
121
110
|
# Database
|
|
122
111
|
|
|
123
112
|
def self.database_exists? config
|
|
@@ -262,6 +251,7 @@ module ActiveRecord
|
|
|
262
251
|
register_class_with_limit m, %r{^STRING}i, Type::String
|
|
263
252
|
m.register_type "TIMESTAMP", ActiveRecord::Type::Spanner::Time.new
|
|
264
253
|
m.register_type "JSON", ActiveRecord::Type::Json.new
|
|
254
|
+
m.register_type "UUID", ActiveRecord::Type::Spanner::Uuid.new
|
|
265
255
|
|
|
266
256
|
register_array_types m
|
|
267
257
|
end
|
|
@@ -277,6 +267,7 @@ module ActiveRecord
|
|
|
277
267
|
m.register_type %r{^ARRAY<STRING\((MAX|d+)\)>}i, Type::Spanner::Array.new(Type::String.new)
|
|
278
268
|
m.register_type %r{^ARRAY<TIMESTAMP>}i, Type::Spanner::Array.new(ActiveRecord::Type::Spanner::Time.new)
|
|
279
269
|
m.register_type %r{^ARRAY<JSON>}i, Type::Spanner::Array.new(ActiveRecord::Type::Json.new)
|
|
270
|
+
m.register_type %r{^ARRAY<UUID>}i, Type::Spanner::Array.new(ActiveRecord::Type::Spanner::Uuid.new)
|
|
280
271
|
end
|
|
281
272
|
|
|
282
273
|
def extract_limit sql_type
|
|
@@ -37,6 +37,7 @@ module ActiveRecord
|
|
|
37
37
|
when ActiveModel::Type::DateTime, ActiveModel::Type::Time, ActiveRecord::Type::Spanner::Time then :TIMESTAMP
|
|
38
38
|
when ActiveModel::Type::Date then :DATE
|
|
39
39
|
when ActiveRecord::Type::Json then :JSON
|
|
40
|
+
when ActiveRecord::Type::Spanner::Uuid then :UUID
|
|
40
41
|
when ActiveRecord::Type::Spanner::Array then [convert_active_model_type_to_spanner(type.element_type)]
|
|
41
42
|
end
|
|
42
43
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Use of this source code is governed by an MIT-style
|
|
4
|
+
# license that can be found in the LICENSE file or at
|
|
5
|
+
# https://opensource.org/licenses/MIT.
|
|
6
|
+
|
|
7
|
+
# frozen_string_literal: true
|
|
8
|
+
|
|
9
|
+
module ActiveRecord
|
|
10
|
+
module Type
|
|
11
|
+
module Spanner
|
|
12
|
+
class Uuid < ActiveModel::Type::Value
|
|
13
|
+
def type
|
|
14
|
+
:uuid
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
require "google/cloud/spanner"
|
|
8
8
|
require "spanner_client_ext"
|
|
9
|
+
require "active_record/connection_adapters/spanner/type_mapping"
|
|
9
10
|
require "activerecord_spanner_adapter/information_schema"
|
|
10
11
|
require_relative "../active_record/connection_adapters/spanner/errors/transaction_mutation_limit_exceeded_error"
|
|
11
12
|
|
|
@@ -43,6 +44,10 @@ module ActiveRecordSpannerAdapter
|
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
|
|
47
|
+
def native_database_types
|
|
48
|
+
NATIVE_DATABASE_TYPES
|
|
49
|
+
end
|
|
50
|
+
|
|
46
51
|
# Clears the cached information about the underlying information schemas.
|
|
47
52
|
# Call this method if you drop and recreate a database with the same name
|
|
48
53
|
# to prevent the cached information to be used for the new database.
|
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.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Google LLC
|
|
@@ -75,16 +75,22 @@ dependencies:
|
|
|
75
75
|
name: bundler
|
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements:
|
|
78
|
-
- - "
|
|
78
|
+
- - ">="
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
80
|
version: '2.0'
|
|
81
|
+
- - "<"
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '5.0'
|
|
81
84
|
type: :development
|
|
82
85
|
prerelease: false
|
|
83
86
|
version_requirements: !ruby/object:Gem::Requirement
|
|
84
87
|
requirements:
|
|
85
|
-
- - "
|
|
88
|
+
- - ">="
|
|
86
89
|
- !ruby/object:Gem::Version
|
|
87
90
|
version: '2.0'
|
|
91
|
+
- - "<"
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '5.0'
|
|
88
94
|
- !ruby/object:Gem::Dependency
|
|
89
95
|
name: google-style
|
|
90
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -147,14 +153,14 @@ dependencies:
|
|
|
147
153
|
requirements:
|
|
148
154
|
- - "~>"
|
|
149
155
|
- !ruby/object:Gem::Version
|
|
150
|
-
version: '5.
|
|
156
|
+
version: '5.4'
|
|
151
157
|
type: :development
|
|
152
158
|
prerelease: false
|
|
153
159
|
version_requirements: !ruby/object:Gem::Requirement
|
|
154
160
|
requirements:
|
|
155
161
|
- - "~>"
|
|
156
162
|
- !ruby/object:Gem::Version
|
|
157
|
-
version: '5.
|
|
163
|
+
version: '5.4'
|
|
158
164
|
- !ruby/object:Gem::Dependency
|
|
159
165
|
name: rake
|
|
160
166
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -553,6 +559,7 @@ files:
|
|
|
553
559
|
- lib/active_record/connection_adapters/spanner/schema_definitions.rb
|
|
554
560
|
- lib/active_record/connection_adapters/spanner/schema_dumper.rb
|
|
555
561
|
- lib/active_record/connection_adapters/spanner/schema_statements.rb
|
|
562
|
+
- lib/active_record/connection_adapters/spanner/type_mapping.rb
|
|
556
563
|
- lib/active_record/connection_adapters/spanner/type_metadata.rb
|
|
557
564
|
- lib/active_record/connection_adapters/spanner_adapter.rb
|
|
558
565
|
- lib/active_record/tasks/spanner_database_tasks.rb
|
|
@@ -560,6 +567,7 @@ files:
|
|
|
560
567
|
- lib/active_record/type/spanner/bytes.rb
|
|
561
568
|
- lib/active_record/type/spanner/spanner_active_record_converter.rb
|
|
562
569
|
- lib/active_record/type/spanner/time.rb
|
|
570
|
+
- lib/active_record/type/spanner/uuid.rb
|
|
563
571
|
- lib/activerecord-spanner-adapter.rb
|
|
564
572
|
- lib/activerecord_spanner_adapter/base.rb
|
|
565
573
|
- lib/activerecord_spanner_adapter/connection.rb
|