activerecord-spanner-adapter 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +8 -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/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 +56 -19
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ad2384bb1890bb224c89a146c42f615f89c6e2892848da5e701a091d90fa95b
|
4
|
+
data.tar.gz: 0e8a9c608068ff30011bc9bca68b10ab0d22b910260a37a6d4a492365adf78b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1894765bbc1e3dfac270d73199a4f235ae95724ca18145d6850cce27c38ef2018b59e9035cf2fa91bc30d3f650e080b8eea58c3e91a66035db3a4d07c35ca1be
|
7
|
+
data.tar.gz: 4a9b93d7990fa78f901864bed816e75ff5d0f9da34a530c7107f475d8fd06dc71817fbf8b2c1e0262e4656bf7ab363917ecf7b7c82315b6d5fa84cce0d22489d
|
@@ -34,12 +34,14 @@ jobs:
|
|
34
34
|
with:
|
35
35
|
bundler-cache: true
|
36
36
|
ruby-version: ${{ matrix.ruby }}
|
37
|
+
- name: Authenticate Google Cloud
|
38
|
+
uses: google-github-actions/auth@v2
|
39
|
+
with:
|
40
|
+
credentials_json: ${{ secrets.GCP_SA_KEY }}
|
37
41
|
- name: Setup GCloud
|
38
|
-
uses: google-github-actions/setup-gcloud@
|
42
|
+
uses: google-github-actions/setup-gcloud@v2
|
39
43
|
with:
|
40
44
|
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
41
|
-
service_account_key: ${{ secrets.GCP_SA_KEY }}
|
42
|
-
export_default_credentials: true
|
43
45
|
- name: Install dependencies
|
44
46
|
run: bundle install
|
45
47
|
- name: Run acceptance tests on production
|
data/.github/workflows/ci.yaml
CHANGED
@@ -20,7 +20,7 @@ jobs:
|
|
20
20
|
matrix:
|
21
21
|
# Run acceptance tests all supported combinations of Ruby and ActiveRecord.
|
22
22
|
ruby: [2.7, 3.0, 3.1, 3.2]
|
23
|
-
ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.0.6, 7.0.7]
|
23
|
+
ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.0.6, 7.0.7, 7.1.0, 7.1.1, 7.1.2]
|
24
24
|
# Exclude combinations that are not supported.
|
25
25
|
exclude:
|
26
26
|
- ruby: 3.0
|
@@ -20,12 +20,14 @@ jobs:
|
|
20
20
|
with:
|
21
21
|
bundler-cache: true
|
22
22
|
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- name: Authenticate Google Cloud
|
24
|
+
uses: google-github-actions/auth@v2
|
25
|
+
with:
|
26
|
+
credentials_json: ${{ secrets.GCP_SA_KEY }}
|
23
27
|
- name: Setup GCloud
|
24
|
-
uses: google-github-actions/setup-gcloud@
|
28
|
+
uses: google-github-actions/setup-gcloud@v2
|
25
29
|
with:
|
26
30
|
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
27
|
-
service_account_key: ${{ secrets.GCP_SA_KEY }}
|
28
|
-
export_default_credentials: true
|
29
31
|
- name: Install dependencies
|
30
32
|
run: bundle install
|
31
33
|
- name: Run acceptance tests on production
|
@@ -12,7 +12,7 @@ jobs:
|
|
12
12
|
matrix:
|
13
13
|
# Run unit tests all supported combinations of Ruby and ActiveRecord.
|
14
14
|
ruby: [2.7, 3.0, 3.1, 3.2]
|
15
|
-
ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5]
|
15
|
+
ar: [6.0.0, 6.0.1, 6.0.2.2, 6.0.3.7, 6.0.4, 6.1.3.2, 6.1.4.7, 6.1.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1, 7.0.4, 7.0.5, 7.1.0, 7.1.1, 7.1.2]
|
16
16
|
# Exclude combinations that are not supported.
|
17
17
|
exclude:
|
18
18
|
- ruby: 3.0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 1.6.0 (2023-12-20)
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* interleaved tables with built-in composite pk ([#282](https://github.com/googleapis/ruby-spanner-activerecord/issues/282))
|
8
|
+
* support Query Logs ([#291](https://github.com/googleapis/ruby-spanner-activerecord/issues/291))
|
9
|
+
* support Rails 7.1 ([#278](https://github.com/googleapis/ruby-spanner-activerecord/issues/278))
|
10
|
+
|
3
11
|
### 1.5.1 (2023-12-12)
|
4
12
|
|
5
13
|
#### Bug Fixes
|
data/Gemfile
CHANGED
@@ -4,12 +4,15 @@ source "https://rubygems.org"
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
gem "activerecord", ENV.fetch("AR_VERSION", "~> 6.1.6.1")
|
7
|
-
gem "minitest", "~> 5.
|
7
|
+
gem "minitest", "~> 5.20.0"
|
8
|
+
gem "minitest-rg", "~> 5.3.0"
|
8
9
|
gem "pry", "~> 0.13.0"
|
9
10
|
gem "pry-byebug", "~> 3.9.0"
|
10
11
|
|
11
12
|
# Required for samples and testing.
|
12
|
-
|
13
|
+
install_if -> { ENV.fetch("AR_VERSION", "~> 6.1.6.1").dup.to_s.sub!("~>", "").strip < "7.1.0" && !ENV["SKIP_COMPOSITE_PK"] } do
|
14
|
+
gem "composite_primary_keys"
|
15
|
+
end
|
13
16
|
|
14
17
|
# Required for samples
|
15
18
|
gem "docker-api"
|
data/README.md
CHANGED
@@ -84,19 +84,19 @@ Some noteworthy examples in the snippets directory:
|
|
84
84
|
for inserting, updating and deleting data in a Cloud Spanner database. Mutations can have a significant performance
|
85
85
|
advantage compared to DML statements, but do not allow read-your-writes semantics during a transaction.
|
86
86
|
- [array-data-type](examples/snippets/array-data-type): Shows how to work with `ARRAY` data types.
|
87
|
-
- [interleaved-tables](examples/snippets/interleaved-tables): Shows how to work with [Interleaved Tables](https://cloud.google.com/spanner/docs/schema-and-data-model#create-interleaved-tables).
|
87
|
+
- [interleaved-tables](examples/snippets/interleaved-tables-before-7.1): Shows how to work with [Interleaved Tables](https://cloud.google.com/spanner/docs/schema-and-data-model#create-interleaved-tables).
|
88
88
|
|
89
89
|
## Limitations
|
90
90
|
|
91
|
-
Limitation|Comment|Resolution
|
92
|
-
|
93
|
-
Interleaved tables require composite primary keys| Cloud Spanner requires composite primary keys for interleaved tables. See {file:examples/snippets/interleaved-tables/README.md this example} for an example on how to use interleaved tables with ActiveRecord
|
94
|
-
Lack of sequential
|
95
|
-
Table without Primary Key| Cloud Spanner support does not support tables without a primary key
|
96
|
-
Table names CANNOT have spaces within them whether back-ticked or not|Cloud Spanner DOES NOT support tables with spaces in them for example `Entity ID
|
97
|
-
Table names CANNOT have punctuation marks and MUST contain valid UTF-8|Cloud Spanner DOES NOT support punctuation marks e.g. periods ".", question marks "?" in table names|Ensure that your table names don't contain punctuation marks.
|
98
|
-
Index with fields length [add_index](https://apidock.com/rails/v5.2.3/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index)|Cloud Spanner does not support index with fields length
|
99
|
-
Only GoogleSQL-dialect databases| Cloud Spanner supports both GoogleSQL- and PostgreSQL-dialect databases. This adapter only supports GoogleSQL-dialect databases.
|
91
|
+
| Limitation | Comment | Resolution |
|
92
|
+
|-----------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
|
93
|
+
| Interleaved tables require composite primary keys | Cloud Spanner requires composite primary keys for interleaved tables. See {file:examples/snippets/interleaved-tables/README.md this example} for an example on how to use interleaved tables with ActiveRecord | Use composite primary keys. |
|
94
|
+
| Lack of sequential IDs | Cloud Spanner uses either using bit-reversed sequences or UUID4 to generated primary keys to avoid [hotspotting](https://cloud.google.com/spanner/docs/schema-design#uuid_primary_key) so you SHOULD NOT rely on IDs being sorted | Use either UUID4s or bit-reversed sequences to automatically generate primary keys. |
|
95
|
+
| Table without Primary Key | Cloud Spanner support does not support tables without a primary key. | Always define a primary key for your table. |
|
96
|
+
| Table names CANNOT have spaces within them whether back-ticked or not | Cloud Spanner DOES NOT support tables with spaces in them for example `Entity ID` | Ensure that your table names don't contain spaces. |
|
97
|
+
| Table names CANNOT have punctuation marks and MUST contain valid UTF-8 | Cloud Spanner DOES NOT support punctuation marks e.g. periods ".", question marks "?" in table names | Ensure that your table names don't contain punctuation marks. |
|
98
|
+
| Index with fields length [add_index](https://apidock.com/rails/v5.2.3/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index) | Cloud Spanner does not support index with fields length | Ensure that your database definition does not include index definitions with field lengths. |
|
99
|
+
| Only GoogleSQL-dialect databases | Cloud Spanner supports both GoogleSQL- and PostgreSQL-dialect databases. This adapter only supports GoogleSQL-dialect databases. | Ensure that your database uses the GoogleSQL dialect. |
|
100
100
|
|
101
101
|
## Contributing
|
102
102
|
|
data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb
CHANGED
@@ -6,6 +6,12 @@
|
|
6
6
|
|
7
7
|
# frozen_string_literal: true
|
8
8
|
|
9
|
+
# ActiveRecord 7.1 introduced native support for composite primary keys.
|
10
|
+
# This deprecates the https://github.com/composite-primary-keys/composite_primary_keys gem that was previously used in
|
11
|
+
# this library to support composite primary keys, which again are needed for interleaved tables. These tests use the
|
12
|
+
# third-party composite primary key gem and are therefore not executed for Rails 7.1 and higher.
|
13
|
+
return if ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
|
14
|
+
|
9
15
|
require "test_helper"
|
10
16
|
require "models/singer"
|
11
17
|
require "models/album"
|
@@ -196,8 +196,14 @@ module ActiveRecord
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
end
|
199
|
+
expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
|
200
|
+
"you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table."
|
201
|
+
else
|
202
|
+
"you can't redefine the primary key column 'id' on 'testings'. To define a custom primary key, pass { id: false } to create_table."
|
203
|
+
end
|
204
|
+
|
199
205
|
|
200
|
-
assert_equal
|
206
|
+
assert_equal expected, error.message
|
201
207
|
end
|
202
208
|
|
203
209
|
def test_create_table_raises_when_redefining_custom_primary_key_column
|
@@ -209,7 +215,12 @@ module ActiveRecord
|
|
209
215
|
end
|
210
216
|
end
|
211
217
|
|
212
|
-
|
218
|
+
expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
|
219
|
+
"you can't redefine the primary key column 'testing_id'. To define a custom primary key, pass { id: false } to create_table."
|
220
|
+
else
|
221
|
+
"you can't redefine the primary key column 'testing_id' on 'testings'. To define a custom primary key, pass { id: false } to create_table."
|
222
|
+
end
|
223
|
+
assert_equal expected, error.message
|
213
224
|
end
|
214
225
|
|
215
226
|
def test_create_table_raises_when_defining_existing_column
|
@@ -222,7 +233,12 @@ module ActiveRecord
|
|
222
233
|
end
|
223
234
|
end
|
224
235
|
|
225
|
-
|
236
|
+
expected = if ActiveRecord::gem_version < Gem::Version.create('7.1.0')
|
237
|
+
"you can't define an already defined column 'testing_column'."
|
238
|
+
else
|
239
|
+
"you can't define an already defined column 'testing_column' on 'testings'."
|
240
|
+
end
|
241
|
+
assert_equal expected, error.message
|
226
242
|
end
|
227
243
|
|
228
244
|
def test_create_table_with_timestamps_should_create_datetime_columns
|
@@ -13,6 +13,10 @@ module ActiveRecord
|
|
13
13
|
class IndexTest < SpannerAdapter::TestCase
|
14
14
|
include SpannerAdapter::Migration::TestHelper
|
15
15
|
|
16
|
+
def is_7_1_or_higher?
|
17
|
+
ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
|
18
|
+
end
|
19
|
+
|
16
20
|
def test_dump_schema_contains_start_batch_ddl
|
17
21
|
connection = ActiveRecord::Base.connection
|
18
22
|
schema = StringIO.new
|
@@ -34,7 +38,12 @@ module ActiveRecord
|
|
34
38
|
connection = ActiveRecord::Base.connection
|
35
39
|
schema = StringIO.new
|
36
40
|
ActiveRecord::SchemaDumper.dump connection, schema
|
37
|
-
|
41
|
+
sql = schema.string
|
42
|
+
if is_7_1_or_higher?
|
43
|
+
assert schema.string.include?("create_table \"albums\", primary_key: [\"singerid\", \"albumid\"]"), sql
|
44
|
+
else
|
45
|
+
assert schema.string.include?("create_table \"albums\", primary_key: \"albumid\""), sql
|
46
|
+
end
|
38
47
|
end
|
39
48
|
|
40
49
|
def test_dump_schema_contains_interleaved_index
|
@@ -6,6 +6,12 @@
|
|
6
6
|
|
7
7
|
# frozen_string_literal: true
|
8
8
|
|
9
|
+
# ActiveRecord 7.1 introduced native support for composite primary keys.
|
10
|
+
# This deprecates the https://github.com/composite-primary-keys/composite_primary_keys gem that was previously used in
|
11
|
+
# this library to support composite primary keys, which again are needed for interleaved tables. These tests use the
|
12
|
+
# third-party composite primary key gem and are therefore not executed for Rails 7.1 and higher.
|
13
|
+
return if ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
|
14
|
+
|
9
15
|
require "test_helper"
|
10
16
|
require "test_helpers/with_separate_database"
|
11
17
|
|
@@ -14,6 +14,10 @@ module ActiveRecord
|
|
14
14
|
class DatabaseTasksTest < SpannerAdapter::TestCase
|
15
15
|
attr_reader :connector_config, :connection
|
16
16
|
|
17
|
+
def is_7_1_or_higher?
|
18
|
+
ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
|
19
|
+
end
|
20
|
+
|
17
21
|
def setup
|
18
22
|
@database_id = "ar-tasks-test-#{SecureRandom.hex 4}"
|
19
23
|
@connector_config = {
|
@@ -87,8 +91,12 @@ module ActiveRecord
|
|
87
91
|
end
|
88
92
|
ActiveRecord::Tasks::DatabaseTasks.dump_schema db_config, :sql
|
89
93
|
sql = File.read(filename)
|
90
|
-
if ENV["SPANNER_EMULATOR_HOST"]
|
94
|
+
if ENV["SPANNER_EMULATOR_HOST"] && is_7_1_or_higher?
|
95
|
+
assert_equal expected_schema_sql_on_emulator_7_1, sql, msg = sql
|
96
|
+
elsif ENV["SPANNER_EMULATOR_HOST"]
|
91
97
|
assert_equal expected_schema_sql_on_emulator, sql, msg = sql
|
98
|
+
elsif is_7_1_or_higher?
|
99
|
+
assert_equal expected_schema_sql_on_production_7_1, sql, msg = sql
|
92
100
|
else
|
93
101
|
assert_equal expected_schema_sql_on_production, sql, msg = sql
|
94
102
|
end
|
@@ -235,6 +243,168 @@ CREATE TABLE tracks (
|
|
235
243
|
) PRIMARY KEY(singerid, albumid, trackid),
|
236
244
|
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
237
245
|
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
246
|
+
CREATE TABLE table_with_sequence (
|
247
|
+
id INT64 NOT NULL DEFAULT (FARM_FINGERPRINT(GENERATE_UUID())),
|
248
|
+
name STRING(MAX) NOT NULL,
|
249
|
+
age INT64 NOT NULL,
|
250
|
+
) PRIMARY KEY(id);
|
251
|
+
CREATE TABLE schema_migrations (
|
252
|
+
version STRING(MAX) NOT NULL,
|
253
|
+
) PRIMARY KEY(version);
|
254
|
+
CREATE TABLE ar_internal_metadata (
|
255
|
+
key STRING(MAX) NOT NULL,
|
256
|
+
value STRING(MAX),
|
257
|
+
created_at TIMESTAMP NOT NULL,
|
258
|
+
updated_at TIMESTAMP NOT NULL,
|
259
|
+
) PRIMARY KEY(key);
|
260
|
+
INSERT INTO `schema_migrations` (version) VALUES
|
261
|
+
('1');
|
262
|
+
|
263
|
+
"
|
264
|
+
end
|
265
|
+
|
266
|
+
def expected_schema_sql_on_emulator_7_1
|
267
|
+
"CREATE TABLE all_types (
|
268
|
+
id INT64 NOT NULL,
|
269
|
+
col_string STRING(MAX),
|
270
|
+
col_int64 INT64,
|
271
|
+
col_float64 FLOAT64,
|
272
|
+
col_numeric NUMERIC,
|
273
|
+
col_bool BOOL,
|
274
|
+
col_bytes BYTES(MAX),
|
275
|
+
col_date DATE,
|
276
|
+
col_timestamp TIMESTAMP,
|
277
|
+
col_json JSON,
|
278
|
+
col_array_string ARRAY<STRING(MAX)>,
|
279
|
+
col_array_int64 ARRAY<INT64>,
|
280
|
+
col_array_float64 ARRAY<FLOAT64>,
|
281
|
+
col_array_numeric ARRAY<NUMERIC>,
|
282
|
+
col_array_bool ARRAY<BOOL>,
|
283
|
+
col_array_bytes ARRAY<BYTES(MAX)>,
|
284
|
+
col_array_date ARRAY<DATE>,
|
285
|
+
col_array_timestamp ARRAY<TIMESTAMP>,
|
286
|
+
col_array_json ARRAY<JSON>,
|
287
|
+
) PRIMARY KEY(id);
|
288
|
+
CREATE TABLE firms (
|
289
|
+
id INT64 NOT NULL,
|
290
|
+
name STRING(MAX),
|
291
|
+
rating INT64,
|
292
|
+
description STRING(MAX),
|
293
|
+
account_id INT64,
|
294
|
+
) PRIMARY KEY(id);
|
295
|
+
CREATE INDEX index_firms_on_account_id ON firms(account_id);
|
296
|
+
CREATE TABLE customers (
|
297
|
+
id INT64 NOT NULL,
|
298
|
+
name STRING(MAX),
|
299
|
+
) PRIMARY KEY(id);
|
300
|
+
CREATE TABLE accounts (
|
301
|
+
id INT64 NOT NULL,
|
302
|
+
customer_id INT64,
|
303
|
+
firm_id INT64,
|
304
|
+
name STRING(MAX),
|
305
|
+
credit_limit INT64,
|
306
|
+
transactions_count INT64,
|
307
|
+
) PRIMARY KEY(id);
|
308
|
+
CREATE TABLE transactions (
|
309
|
+
id INT64 NOT NULL,
|
310
|
+
amount FLOAT64,
|
311
|
+
account_id INT64,
|
312
|
+
) PRIMARY KEY(id);
|
313
|
+
CREATE TABLE departments (
|
314
|
+
id INT64 NOT NULL,
|
315
|
+
name STRING(MAX),
|
316
|
+
resource_type STRING(255),
|
317
|
+
resource_id INT64,
|
318
|
+
) PRIMARY KEY(id);
|
319
|
+
CREATE INDEX index_departments_on_resource ON departments(resource_type, resource_id);
|
320
|
+
CREATE TABLE member_types (
|
321
|
+
id INT64 NOT NULL,
|
322
|
+
name STRING(MAX),
|
323
|
+
) PRIMARY KEY(id);
|
324
|
+
CREATE TABLE members (
|
325
|
+
id INT64 NOT NULL,
|
326
|
+
name STRING(MAX),
|
327
|
+
member_type_id INT64,
|
328
|
+
admittable_type STRING(255),
|
329
|
+
admittable_id INT64,
|
330
|
+
) PRIMARY KEY(id);
|
331
|
+
CREATE TABLE memberships (
|
332
|
+
id INT64 NOT NULL,
|
333
|
+
joined_on TIMESTAMP,
|
334
|
+
club_id INT64,
|
335
|
+
member_id INT64,
|
336
|
+
favourite BOOL,
|
337
|
+
) PRIMARY KEY(id);
|
338
|
+
CREATE TABLE clubs (
|
339
|
+
id INT64 NOT NULL,
|
340
|
+
name STRING(MAX),
|
341
|
+
) PRIMARY KEY(id);
|
342
|
+
CREATE TABLE authors (
|
343
|
+
id INT64 NOT NULL,
|
344
|
+
name STRING(MAX) NOT NULL,
|
345
|
+
registered_date DATE,
|
346
|
+
organization_id INT64,
|
347
|
+
) PRIMARY KEY(id);
|
348
|
+
CREATE TABLE posts (
|
349
|
+
id INT64 NOT NULL,
|
350
|
+
title STRING(MAX),
|
351
|
+
content STRING(MAX),
|
352
|
+
author_id INT64,
|
353
|
+
comments_count INT64,
|
354
|
+
post_date DATE,
|
355
|
+
published_time TIMESTAMP,
|
356
|
+
) PRIMARY KEY(id);
|
357
|
+
CREATE INDEX index_posts_on_author_id ON posts(author_id);
|
358
|
+
CREATE TABLE comments (
|
359
|
+
id INT64 NOT NULL,
|
360
|
+
comment STRING(MAX),
|
361
|
+
post_id INT64,
|
362
|
+
CONSTRAINT fk_rails_2fd19c0db7 FOREIGN KEY(post_id) REFERENCES posts(id),
|
363
|
+
) PRIMARY KEY(id);
|
364
|
+
CREATE TABLE addresses (
|
365
|
+
id INT64 NOT NULL,
|
366
|
+
line1 STRING(MAX),
|
367
|
+
postal_code STRING(MAX),
|
368
|
+
city STRING(MAX),
|
369
|
+
author_id INT64,
|
370
|
+
) PRIMARY KEY(id);
|
371
|
+
CREATE TABLE organizations (
|
372
|
+
id INT64 NOT NULL,
|
373
|
+
name STRING(MAX),
|
374
|
+
last_updated TIMESTAMP OPTIONS (
|
375
|
+
allow_commit_timestamp = true
|
376
|
+
),
|
377
|
+
) PRIMARY KEY(id);
|
378
|
+
CREATE TABLE singers (
|
379
|
+
singerid INT64 NOT NULL,
|
380
|
+
first_name STRING(200),
|
381
|
+
last_name STRING(MAX),
|
382
|
+
tracks_count INT64,
|
383
|
+
lock_version INT64,
|
384
|
+
full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
|
385
|
+
) PRIMARY KEY(singerid);
|
386
|
+
CREATE TABLE albums (
|
387
|
+
singerid INT64 NOT NULL,
|
388
|
+
albumid INT64 NOT NULL,
|
389
|
+
title STRING(MAX),
|
390
|
+
lock_version INT64,
|
391
|
+
) PRIMARY KEY(singerid, albumid),
|
392
|
+
INTERLEAVE IN PARENT singers ON DELETE NO ACTION;
|
393
|
+
CREATE TABLE tracks (
|
394
|
+
singerid INT64 NOT NULL,
|
395
|
+
albumid INT64 NOT NULL,
|
396
|
+
trackid INT64 NOT NULL,
|
397
|
+
title STRING(MAX),
|
398
|
+
duration NUMERIC,
|
399
|
+
lock_version INT64,
|
400
|
+
) PRIMARY KEY(singerid, albumid, trackid),
|
401
|
+
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
402
|
+
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
403
|
+
CREATE TABLE table_with_sequence (
|
404
|
+
id INT64 NOT NULL DEFAULT (FARM_FINGERPRINT(GENERATE_UUID())),
|
405
|
+
name STRING(MAX) NOT NULL,
|
406
|
+
age INT64 NOT NULL,
|
407
|
+
) PRIMARY KEY(id);
|
238
408
|
CREATE TABLE schema_migrations (
|
239
409
|
version STRING(MAX) NOT NULL,
|
240
410
|
) PRIMARY KEY(version);
|
@@ -251,7 +421,10 @@ INSERT INTO `schema_migrations` (version) VALUES
|
|
251
421
|
end
|
252
422
|
|
253
423
|
def expected_schema_sql_on_production
|
254
|
-
"CREATE
|
424
|
+
"CREATE SEQUENCE test_sequence OPTIONS (
|
425
|
+
sequence_kind = 'bit_reversed_positive'
|
426
|
+
);
|
427
|
+
CREATE TABLE accounts (
|
255
428
|
id INT64 NOT NULL,
|
256
429
|
customer_id INT64,
|
257
430
|
firm_id INT64,
|
@@ -391,6 +564,171 @@ CREATE TABLE tracks (
|
|
391
564
|
) PRIMARY KEY(singerid, albumid, trackid),
|
392
565
|
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
393
566
|
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
567
|
+
CREATE TABLE table_with_sequence (
|
568
|
+
id INT64 NOT NULL DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE test_sequence)),
|
569
|
+
name STRING(MAX) NOT NULL,
|
570
|
+
age INT64 NOT NULL,
|
571
|
+
) PRIMARY KEY(id);
|
572
|
+
CREATE TABLE transactions (
|
573
|
+
id INT64 NOT NULL,
|
574
|
+
amount FLOAT64,
|
575
|
+
account_id INT64,
|
576
|
+
) PRIMARY KEY(id);
|
577
|
+
INSERT INTO `schema_migrations` (version) VALUES
|
578
|
+
('1');
|
579
|
+
|
580
|
+
"
|
581
|
+
end
|
582
|
+
|
583
|
+
def expected_schema_sql_on_production_7_1
|
584
|
+
"CREATE SEQUENCE test_sequence OPTIONS (
|
585
|
+
sequence_kind = 'bit_reversed_positive'
|
586
|
+
);
|
587
|
+
CREATE TABLE accounts (
|
588
|
+
id INT64 NOT NULL,
|
589
|
+
customer_id INT64,
|
590
|
+
firm_id INT64,
|
591
|
+
name STRING(MAX),
|
592
|
+
credit_limit INT64,
|
593
|
+
transactions_count INT64,
|
594
|
+
) PRIMARY KEY(id);
|
595
|
+
CREATE TABLE addresses (
|
596
|
+
id INT64 NOT NULL,
|
597
|
+
line1 STRING(MAX),
|
598
|
+
postal_code STRING(MAX),
|
599
|
+
city STRING(MAX),
|
600
|
+
author_id INT64,
|
601
|
+
) PRIMARY KEY(id);
|
602
|
+
CREATE TABLE all_types (
|
603
|
+
id INT64 NOT NULL,
|
604
|
+
col_string STRING(MAX),
|
605
|
+
col_int64 INT64,
|
606
|
+
col_float64 FLOAT64,
|
607
|
+
col_numeric NUMERIC,
|
608
|
+
col_bool BOOL,
|
609
|
+
col_bytes BYTES(MAX),
|
610
|
+
col_date DATE,
|
611
|
+
col_timestamp TIMESTAMP,
|
612
|
+
col_json JSON,
|
613
|
+
col_array_string ARRAY<STRING(MAX)>,
|
614
|
+
col_array_int64 ARRAY<INT64>,
|
615
|
+
col_array_float64 ARRAY<FLOAT64>,
|
616
|
+
col_array_numeric ARRAY<NUMERIC>,
|
617
|
+
col_array_bool ARRAY<BOOL>,
|
618
|
+
col_array_bytes ARRAY<BYTES(MAX)>,
|
619
|
+
col_array_date ARRAY<DATE>,
|
620
|
+
col_array_timestamp ARRAY<TIMESTAMP>,
|
621
|
+
col_array_json ARRAY<JSON>,
|
622
|
+
) PRIMARY KEY(id);
|
623
|
+
CREATE TABLE ar_internal_metadata (
|
624
|
+
key STRING(MAX) NOT NULL,
|
625
|
+
value STRING(MAX),
|
626
|
+
created_at TIMESTAMP NOT NULL,
|
627
|
+
updated_at TIMESTAMP NOT NULL,
|
628
|
+
) PRIMARY KEY(key);
|
629
|
+
CREATE TABLE authors (
|
630
|
+
id INT64 NOT NULL,
|
631
|
+
name STRING(MAX) NOT NULL,
|
632
|
+
registered_date DATE,
|
633
|
+
organization_id INT64,
|
634
|
+
) PRIMARY KEY(id);
|
635
|
+
CREATE TABLE clubs (
|
636
|
+
id INT64 NOT NULL,
|
637
|
+
name STRING(MAX),
|
638
|
+
) PRIMARY KEY(id);
|
639
|
+
CREATE TABLE comments (
|
640
|
+
id INT64 NOT NULL,
|
641
|
+
comment STRING(MAX),
|
642
|
+
post_id INT64,
|
643
|
+
) PRIMARY KEY(id);
|
644
|
+
CREATE TABLE customers (
|
645
|
+
id INT64 NOT NULL,
|
646
|
+
name STRING(MAX),
|
647
|
+
) PRIMARY KEY(id);
|
648
|
+
CREATE TABLE departments (
|
649
|
+
id INT64 NOT NULL,
|
650
|
+
name STRING(MAX),
|
651
|
+
resource_type STRING(255),
|
652
|
+
resource_id INT64,
|
653
|
+
) PRIMARY KEY(id);
|
654
|
+
CREATE INDEX index_departments_on_resource ON departments(resource_type, resource_id);
|
655
|
+
CREATE TABLE firms (
|
656
|
+
id INT64 NOT NULL,
|
657
|
+
name STRING(MAX),
|
658
|
+
rating INT64,
|
659
|
+
description STRING(MAX),
|
660
|
+
account_id INT64,
|
661
|
+
) PRIMARY KEY(id);
|
662
|
+
CREATE INDEX index_firms_on_account_id ON firms(account_id);
|
663
|
+
CREATE TABLE member_types (
|
664
|
+
id INT64 NOT NULL,
|
665
|
+
name STRING(MAX),
|
666
|
+
) PRIMARY KEY(id);
|
667
|
+
CREATE TABLE members (
|
668
|
+
id INT64 NOT NULL,
|
669
|
+
name STRING(MAX),
|
670
|
+
member_type_id INT64,
|
671
|
+
admittable_type STRING(255),
|
672
|
+
admittable_id INT64,
|
673
|
+
) PRIMARY KEY(id);
|
674
|
+
CREATE TABLE memberships (
|
675
|
+
id INT64 NOT NULL,
|
676
|
+
joined_on TIMESTAMP,
|
677
|
+
club_id INT64,
|
678
|
+
member_id INT64,
|
679
|
+
favourite BOOL,
|
680
|
+
) PRIMARY KEY(id);
|
681
|
+
CREATE TABLE organizations (
|
682
|
+
id INT64 NOT NULL,
|
683
|
+
name STRING(MAX),
|
684
|
+
last_updated TIMESTAMP OPTIONS (
|
685
|
+
allow_commit_timestamp = true
|
686
|
+
),
|
687
|
+
) PRIMARY KEY(id);
|
688
|
+
CREATE TABLE posts (
|
689
|
+
id INT64 NOT NULL,
|
690
|
+
title STRING(MAX),
|
691
|
+
content STRING(MAX),
|
692
|
+
author_id INT64,
|
693
|
+
comments_count INT64,
|
694
|
+
post_date DATE,
|
695
|
+
published_time TIMESTAMP,
|
696
|
+
) PRIMARY KEY(id);
|
697
|
+
ALTER TABLE comments ADD CONSTRAINT fk_rails_2fd19c0db7 FOREIGN KEY(post_id) REFERENCES posts(id);
|
698
|
+
CREATE INDEX index_posts_on_author_id ON posts(author_id);
|
699
|
+
CREATE TABLE schema_migrations (
|
700
|
+
version STRING(MAX) NOT NULL,
|
701
|
+
) PRIMARY KEY(version);
|
702
|
+
CREATE TABLE singers (
|
703
|
+
singerid INT64 NOT NULL,
|
704
|
+
first_name STRING(200),
|
705
|
+
last_name STRING(MAX),
|
706
|
+
tracks_count INT64,
|
707
|
+
lock_version INT64,
|
708
|
+
full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
|
709
|
+
) PRIMARY KEY(singerid);
|
710
|
+
CREATE TABLE albums (
|
711
|
+
singerid INT64 NOT NULL,
|
712
|
+
albumid INT64 NOT NULL,
|
713
|
+
title STRING(MAX),
|
714
|
+
lock_version INT64,
|
715
|
+
) PRIMARY KEY(singerid, albumid),
|
716
|
+
INTERLEAVE IN PARENT singers ON DELETE NO ACTION;
|
717
|
+
CREATE TABLE tracks (
|
718
|
+
singerid INT64 NOT NULL,
|
719
|
+
albumid INT64 NOT NULL,
|
720
|
+
trackid INT64 NOT NULL,
|
721
|
+
title STRING(MAX),
|
722
|
+
duration NUMERIC,
|
723
|
+
lock_version INT64,
|
724
|
+
) PRIMARY KEY(singerid, albumid, trackid),
|
725
|
+
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
726
|
+
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
727
|
+
CREATE TABLE table_with_sequence (
|
728
|
+
id INT64 NOT NULL DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE test_sequence)),
|
729
|
+
name STRING(MAX) NOT NULL,
|
730
|
+
age INT64 NOT NULL,
|
731
|
+
) PRIMARY KEY(id);
|
394
732
|
CREATE TABLE transactions (
|
395
733
|
id INT64 NOT NULL,
|
396
734
|
amount FLOAT64,
|
@@ -6,6 +6,12 @@
|
|
6
6
|
|
7
7
|
# frozen_string_literal: true
|
8
8
|
|
9
|
+
# ActiveRecord 7.1 introduced native support for composite primary keys.
|
10
|
+
# This deprecates the https://github.com/composite-primary-keys/composite_primary_keys gem that was previously used in
|
11
|
+
# this library to support composite primary keys, which again are needed for interleaved tables. These tests use the
|
12
|
+
# third-party composite primary key gem and are therefore not executed for Rails 7.1 and higher.
|
13
|
+
return if ActiveRecord::gem_version >= Gem::Version.create('7.1.0')
|
14
|
+
|
9
15
|
require "test_helper"
|
10
16
|
require "models/singer"
|
11
17
|
require "models/album"
|