activerecord-spanner-adapter 1.2.2 → 1.4.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/blunderbuss.yml +1 -1
- data/.github/workflows/acceptance-tests-on-emulator.yaml +8 -8
- data/.github/workflows/ci.yaml +6 -4
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +14 -6
- data/.github/workflows/nightly-unit-tests.yaml +14 -6
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +28 -0
- data/Gemfile +1 -1
- data/README.md +4 -0
- data/acceptance/cases/migration/change_table_test.rb +23 -13
- data/acceptance/cases/migration/schema_dumper_test.rb +69 -0
- data/acceptance/cases/models/generated_column_test.rb +21 -7
- data/acceptance/cases/models/interleave_test.rb +36 -0
- data/acceptance/cases/models/logging_test.rb +57 -0
- data/acceptance/cases/models/query_test.rb +6 -1
- data/acceptance/cases/tasks/database_tasks_test.rb +407 -0
- data/acceptance/models/album_partial_disabled.rb +17 -0
- data/acceptance/schema/schema.rb +139 -134
- data/acceptance/test_helper.rb +2 -0
- data/examples/snippets/array-data-type/db/schema.rb +8 -3
- data/examples/snippets/bulk-insert/db/schema.rb +9 -4
- data/examples/snippets/commit-timestamp/db/schema.rb +11 -6
- data/examples/snippets/create-records/db/schema.rb +9 -4
- data/examples/snippets/date-data-type/db/schema.rb +8 -3
- data/examples/snippets/generated-column/db/schema.rb +6 -1
- data/examples/snippets/hints/db/schema.rb +6 -1
- data/examples/snippets/interleaved-tables/README.md +2 -2
- data/examples/snippets/interleaved-tables/db/schema.rb +5 -0
- data/examples/snippets/migrations/db/schema.rb +10 -5
- data/examples/snippets/mutations/db/schema.rb +9 -4
- data/examples/snippets/optimistic-locking/db/schema.rb +9 -4
- data/examples/snippets/partitioned-dml/db/schema.rb +5 -0
- data/examples/snippets/quickstart/db/schema.rb +9 -4
- data/examples/snippets/read-only-transactions/db/schema.rb +5 -0
- data/examples/snippets/read-write-transactions/db/schema.rb +9 -4
- data/examples/snippets/stale-reads/db/schema.rb +5 -0
- data/examples/snippets/timestamp-data-type/db/schema.rb +8 -3
- data/lib/active_record/connection_adapters/spanner/column.rb +23 -0
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +7 -4
- data/lib/active_record/connection_adapters/spanner/quoting.rb +9 -0
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +17 -4
- data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +11 -2
- data/lib/active_record/connection_adapters/spanner/schema_dumper.rb +56 -0
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +56 -9
- data/lib/active_record/connection_adapters/spanner/type_metadata.rb +19 -4
- data/lib/active_record/connection_adapters/spanner_adapter.rb +11 -0
- data/lib/active_record/tasks/spanner_database_tasks.rb +18 -4
- data/lib/active_record/type/spanner/spanner_active_record_converter.rb +10 -0
- data/lib/active_record/type/spanner/time.rb +10 -3
- data/lib/activerecord_spanner_adapter/base.rb +41 -27
- data/lib/activerecord_spanner_adapter/connection.rb +8 -3
- data/lib/activerecord_spanner_adapter/information_schema.rb +52 -3
- data/lib/activerecord_spanner_adapter/table/column.rb +7 -2
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- data/lib/arel/visitors/spanner.rb +8 -2
- metadata +9 -3
@@ -0,0 +1,407 @@
|
|
1
|
+
# Copyright 2022 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
|
+
require "test_helper"
|
10
|
+
require "active_record/tasks/spanner_database_tasks"
|
11
|
+
|
12
|
+
module ActiveRecord
|
13
|
+
module Tasks
|
14
|
+
class DatabaseTasksTest < SpannerAdapter::TestCase
|
15
|
+
attr_reader :connector_config, :connection
|
16
|
+
|
17
|
+
def setup
|
18
|
+
@database_id = "ar-tasks-test-#{SecureRandom.hex 4}"
|
19
|
+
@connector_config = {
|
20
|
+
"adapter" => "spanner",
|
21
|
+
"emulator_host" => ENV["SPANNER_EMULATOR_HOST"],
|
22
|
+
"project" => ENV["SPANNER_TEST_PROJECT"],
|
23
|
+
"instance" => ENV["SPANNER_TEST_INSTANCE"],
|
24
|
+
"credentials" => ENV["SPANNER_TEST_KEYFILE"],
|
25
|
+
"database" => @database_id
|
26
|
+
}
|
27
|
+
|
28
|
+
create_database
|
29
|
+
ActiveRecord::Base.establish_connection connector_config
|
30
|
+
@connection = ActiveRecord::Base.connection
|
31
|
+
|
32
|
+
begin
|
33
|
+
@original_db_dir = ActiveRecord::Tasks::DatabaseTasks.db_dir
|
34
|
+
@original_env = ActiveRecord::Tasks::DatabaseTasks.env
|
35
|
+
rescue NameError
|
36
|
+
# ignore `NameError: uninitialized constant primary::Rails`
|
37
|
+
end
|
38
|
+
|
39
|
+
db_dir = File.expand_path "./db", __dir__
|
40
|
+
ActiveRecord::Tasks::DatabaseTasks.db_dir = db_dir
|
41
|
+
FileUtils.mkdir db_dir
|
42
|
+
|
43
|
+
ActiveRecord::Tasks::DatabaseTasks.env = "test"
|
44
|
+
end
|
45
|
+
|
46
|
+
def teardown
|
47
|
+
ActiveRecord::Base.connection_pool.disconnect!
|
48
|
+
FileUtils.rm_rf ActiveRecord::Tasks::DatabaseTasks.db_dir
|
49
|
+
ActiveRecord::Tasks::DatabaseTasks.db_dir = @original_db_dir
|
50
|
+
ActiveRecord::Tasks::DatabaseTasks.env = @original_env
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_database
|
54
|
+
job = spanner_instance.create_database @database_id
|
55
|
+
job.wait_until_done!
|
56
|
+
if job.error?
|
57
|
+
raise "Error in creating database. Error code#{job.error.message}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def drop_database
|
62
|
+
ActiveRecord::Base.connection_pool.disconnect!
|
63
|
+
ActiveRecordSpannerAdapter::Connection.reset_information_schemas!
|
64
|
+
spanner_instance.database(@database_id)&.drop
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_structure_dump_and_load
|
68
|
+
require_relative "../../schema/schema"
|
69
|
+
create_tables_in_test_schema
|
70
|
+
|
71
|
+
db_config =
|
72
|
+
if ActiveRecord.version >= Gem::Version.new("6.1")
|
73
|
+
ActiveRecord::DatabaseConfigurations::HashConfig.new "test",
|
74
|
+
"primary",
|
75
|
+
connector_config
|
76
|
+
else
|
77
|
+
connector_config
|
78
|
+
end
|
79
|
+
|
80
|
+
tables = connection.tables.sort
|
81
|
+
config_name = "primary"
|
82
|
+
config_name = db_config.name if db_config.respond_to?(:name)
|
83
|
+
if ActiveRecord::Tasks::DatabaseTasks.respond_to?(:dump_filename)
|
84
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(config_name, :sql)
|
85
|
+
elsif ActiveRecord::Tasks::DatabaseTasks.respond_to?(:schema_dump_path)
|
86
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(db_config, :sql)
|
87
|
+
end
|
88
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema db_config, :sql
|
89
|
+
sql = File.read(filename)
|
90
|
+
if ENV["SPANNER_EMULATOR_HOST"]
|
91
|
+
assert_equal expected_schema_sql_on_emulator, sql, msg = sql
|
92
|
+
else
|
93
|
+
assert_equal expected_schema_sql_on_production, sql, msg = sql
|
94
|
+
end
|
95
|
+
drop_database
|
96
|
+
create_database
|
97
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema db_config, :sql
|
98
|
+
assert_equal tables, connection.tables.sort
|
99
|
+
end
|
100
|
+
|
101
|
+
def expected_schema_sql_on_emulator
|
102
|
+
"CREATE TABLE all_types (
|
103
|
+
id INT64 NOT NULL,
|
104
|
+
col_string STRING(MAX),
|
105
|
+
col_int64 INT64,
|
106
|
+
col_float64 FLOAT64,
|
107
|
+
col_numeric NUMERIC,
|
108
|
+
col_bool BOOL,
|
109
|
+
col_bytes BYTES(MAX),
|
110
|
+
col_date DATE,
|
111
|
+
col_timestamp TIMESTAMP,
|
112
|
+
col_json JSON,
|
113
|
+
col_array_string ARRAY<STRING(MAX)>,
|
114
|
+
col_array_int64 ARRAY<INT64>,
|
115
|
+
col_array_float64 ARRAY<FLOAT64>,
|
116
|
+
col_array_numeric ARRAY<NUMERIC>,
|
117
|
+
col_array_bool ARRAY<BOOL>,
|
118
|
+
col_array_bytes ARRAY<BYTES(MAX)>,
|
119
|
+
col_array_date ARRAY<DATE>,
|
120
|
+
col_array_timestamp ARRAY<TIMESTAMP>,
|
121
|
+
col_array_json ARRAY<JSON>,
|
122
|
+
) PRIMARY KEY(id);
|
123
|
+
CREATE TABLE firms (
|
124
|
+
id INT64 NOT NULL,
|
125
|
+
name STRING(MAX),
|
126
|
+
rating INT64,
|
127
|
+
description STRING(MAX),
|
128
|
+
account_id INT64,
|
129
|
+
) PRIMARY KEY(id);
|
130
|
+
CREATE INDEX index_firms_on_account_id ON firms(account_id);
|
131
|
+
CREATE TABLE customers (
|
132
|
+
id INT64 NOT NULL,
|
133
|
+
name STRING(MAX),
|
134
|
+
) PRIMARY KEY(id);
|
135
|
+
CREATE TABLE accounts (
|
136
|
+
id INT64 NOT NULL,
|
137
|
+
customer_id INT64,
|
138
|
+
firm_id INT64,
|
139
|
+
name STRING(MAX),
|
140
|
+
credit_limit INT64,
|
141
|
+
transactions_count INT64,
|
142
|
+
) PRIMARY KEY(id);
|
143
|
+
CREATE TABLE transactions (
|
144
|
+
id INT64 NOT NULL,
|
145
|
+
amount FLOAT64,
|
146
|
+
account_id INT64,
|
147
|
+
) PRIMARY KEY(id);
|
148
|
+
CREATE TABLE departments (
|
149
|
+
id INT64 NOT NULL,
|
150
|
+
name STRING(MAX),
|
151
|
+
resource_type STRING(255),
|
152
|
+
resource_id INT64,
|
153
|
+
) PRIMARY KEY(id);
|
154
|
+
CREATE INDEX index_departments_on_resource ON departments(resource_type, resource_id);
|
155
|
+
CREATE TABLE member_types (
|
156
|
+
id INT64 NOT NULL,
|
157
|
+
name STRING(MAX),
|
158
|
+
) PRIMARY KEY(id);
|
159
|
+
CREATE TABLE members (
|
160
|
+
id INT64 NOT NULL,
|
161
|
+
name STRING(MAX),
|
162
|
+
member_type_id INT64,
|
163
|
+
admittable_type STRING(255),
|
164
|
+
admittable_id INT64,
|
165
|
+
) PRIMARY KEY(id);
|
166
|
+
CREATE TABLE memberships (
|
167
|
+
id INT64 NOT NULL,
|
168
|
+
joined_on TIMESTAMP,
|
169
|
+
club_id INT64,
|
170
|
+
member_id INT64,
|
171
|
+
favourite BOOL,
|
172
|
+
) PRIMARY KEY(id);
|
173
|
+
CREATE TABLE clubs (
|
174
|
+
id INT64 NOT NULL,
|
175
|
+
name STRING(MAX),
|
176
|
+
) PRIMARY KEY(id);
|
177
|
+
CREATE TABLE authors (
|
178
|
+
id INT64 NOT NULL,
|
179
|
+
name STRING(MAX) NOT NULL,
|
180
|
+
registered_date DATE,
|
181
|
+
organization_id INT64,
|
182
|
+
) PRIMARY KEY(id);
|
183
|
+
CREATE TABLE posts (
|
184
|
+
id INT64 NOT NULL,
|
185
|
+
title STRING(MAX),
|
186
|
+
content STRING(MAX),
|
187
|
+
author_id INT64,
|
188
|
+
comments_count INT64,
|
189
|
+
post_date DATE,
|
190
|
+
published_time TIMESTAMP,
|
191
|
+
) PRIMARY KEY(id);
|
192
|
+
CREATE INDEX index_posts_on_author_id ON posts(author_id);
|
193
|
+
CREATE TABLE comments (
|
194
|
+
id INT64 NOT NULL,
|
195
|
+
comment STRING(MAX),
|
196
|
+
post_id INT64,
|
197
|
+
CONSTRAINT fk_rails_2fd19c0db7 FOREIGN KEY(post_id) REFERENCES posts(id),
|
198
|
+
) PRIMARY KEY(id);
|
199
|
+
CREATE TABLE addresses (
|
200
|
+
id INT64 NOT NULL,
|
201
|
+
line1 STRING(MAX),
|
202
|
+
postal_code STRING(MAX),
|
203
|
+
city STRING(MAX),
|
204
|
+
author_id INT64,
|
205
|
+
) PRIMARY KEY(id);
|
206
|
+
CREATE TABLE organizations (
|
207
|
+
id INT64 NOT NULL,
|
208
|
+
name STRING(MAX),
|
209
|
+
last_updated TIMESTAMP OPTIONS (
|
210
|
+
allow_commit_timestamp = true
|
211
|
+
),
|
212
|
+
) PRIMARY KEY(id);
|
213
|
+
CREATE TABLE singers (
|
214
|
+
singerid INT64 NOT NULL,
|
215
|
+
first_name STRING(200),
|
216
|
+
last_name STRING(MAX),
|
217
|
+
tracks_count INT64,
|
218
|
+
lock_version INT64,
|
219
|
+
full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
|
220
|
+
) PRIMARY KEY(singerid);
|
221
|
+
CREATE TABLE albums (
|
222
|
+
albumid INT64 NOT NULL,
|
223
|
+
singerid INT64 NOT NULL,
|
224
|
+
title STRING(MAX),
|
225
|
+
lock_version INT64,
|
226
|
+
) PRIMARY KEY(singerid, albumid),
|
227
|
+
INTERLEAVE IN PARENT singers ON DELETE NO ACTION;
|
228
|
+
CREATE TABLE tracks (
|
229
|
+
trackid INT64 NOT NULL,
|
230
|
+
singerid INT64 NOT NULL,
|
231
|
+
albumid INT64 NOT NULL,
|
232
|
+
title STRING(MAX),
|
233
|
+
duration NUMERIC,
|
234
|
+
lock_version INT64,
|
235
|
+
) PRIMARY KEY(singerid, albumid, trackid),
|
236
|
+
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
237
|
+
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
238
|
+
CREATE TABLE schema_migrations (
|
239
|
+
version STRING(MAX) NOT NULL,
|
240
|
+
) PRIMARY KEY(version);
|
241
|
+
CREATE TABLE ar_internal_metadata (
|
242
|
+
key STRING(MAX) NOT NULL,
|
243
|
+
value STRING(MAX),
|
244
|
+
created_at TIMESTAMP NOT NULL,
|
245
|
+
updated_at TIMESTAMP NOT NULL,
|
246
|
+
) PRIMARY KEY(key);
|
247
|
+
INSERT INTO `schema_migrations` (version) VALUES
|
248
|
+
('1');
|
249
|
+
|
250
|
+
"
|
251
|
+
end
|
252
|
+
|
253
|
+
def expected_schema_sql_on_production
|
254
|
+
"CREATE TABLE accounts (
|
255
|
+
id INT64 NOT NULL,
|
256
|
+
customer_id INT64,
|
257
|
+
firm_id INT64,
|
258
|
+
name STRING(MAX),
|
259
|
+
credit_limit INT64,
|
260
|
+
transactions_count INT64,
|
261
|
+
) PRIMARY KEY(id);
|
262
|
+
CREATE TABLE addresses (
|
263
|
+
id INT64 NOT NULL,
|
264
|
+
line1 STRING(MAX),
|
265
|
+
postal_code STRING(MAX),
|
266
|
+
city STRING(MAX),
|
267
|
+
author_id INT64,
|
268
|
+
) PRIMARY KEY(id);
|
269
|
+
CREATE TABLE all_types (
|
270
|
+
id INT64 NOT NULL,
|
271
|
+
col_string STRING(MAX),
|
272
|
+
col_int64 INT64,
|
273
|
+
col_float64 FLOAT64,
|
274
|
+
col_numeric NUMERIC,
|
275
|
+
col_bool BOOL,
|
276
|
+
col_bytes BYTES(MAX),
|
277
|
+
col_date DATE,
|
278
|
+
col_timestamp TIMESTAMP,
|
279
|
+
col_json JSON,
|
280
|
+
col_array_string ARRAY<STRING(MAX)>,
|
281
|
+
col_array_int64 ARRAY<INT64>,
|
282
|
+
col_array_float64 ARRAY<FLOAT64>,
|
283
|
+
col_array_numeric ARRAY<NUMERIC>,
|
284
|
+
col_array_bool ARRAY<BOOL>,
|
285
|
+
col_array_bytes ARRAY<BYTES(MAX)>,
|
286
|
+
col_array_date ARRAY<DATE>,
|
287
|
+
col_array_timestamp ARRAY<TIMESTAMP>,
|
288
|
+
col_array_json ARRAY<JSON>,
|
289
|
+
) PRIMARY KEY(id);
|
290
|
+
CREATE TABLE ar_internal_metadata (
|
291
|
+
key STRING(MAX) NOT NULL,
|
292
|
+
value STRING(MAX),
|
293
|
+
created_at TIMESTAMP NOT NULL,
|
294
|
+
updated_at TIMESTAMP NOT NULL,
|
295
|
+
) PRIMARY KEY(key);
|
296
|
+
CREATE TABLE authors (
|
297
|
+
id INT64 NOT NULL,
|
298
|
+
name STRING(MAX) NOT NULL,
|
299
|
+
registered_date DATE,
|
300
|
+
organization_id INT64,
|
301
|
+
) PRIMARY KEY(id);
|
302
|
+
CREATE TABLE clubs (
|
303
|
+
id INT64 NOT NULL,
|
304
|
+
name STRING(MAX),
|
305
|
+
) PRIMARY KEY(id);
|
306
|
+
CREATE TABLE comments (
|
307
|
+
id INT64 NOT NULL,
|
308
|
+
comment STRING(MAX),
|
309
|
+
post_id INT64,
|
310
|
+
) PRIMARY KEY(id);
|
311
|
+
CREATE TABLE customers (
|
312
|
+
id INT64 NOT NULL,
|
313
|
+
name STRING(MAX),
|
314
|
+
) PRIMARY KEY(id);
|
315
|
+
CREATE TABLE departments (
|
316
|
+
id INT64 NOT NULL,
|
317
|
+
name STRING(MAX),
|
318
|
+
resource_type STRING(255),
|
319
|
+
resource_id INT64,
|
320
|
+
) PRIMARY KEY(id);
|
321
|
+
CREATE INDEX index_departments_on_resource ON departments(resource_type, resource_id);
|
322
|
+
CREATE TABLE firms (
|
323
|
+
id INT64 NOT NULL,
|
324
|
+
name STRING(MAX),
|
325
|
+
rating INT64,
|
326
|
+
description STRING(MAX),
|
327
|
+
account_id INT64,
|
328
|
+
) PRIMARY KEY(id);
|
329
|
+
CREATE INDEX index_firms_on_account_id ON firms(account_id);
|
330
|
+
CREATE TABLE member_types (
|
331
|
+
id INT64 NOT NULL,
|
332
|
+
name STRING(MAX),
|
333
|
+
) PRIMARY KEY(id);
|
334
|
+
CREATE TABLE members (
|
335
|
+
id INT64 NOT NULL,
|
336
|
+
name STRING(MAX),
|
337
|
+
member_type_id INT64,
|
338
|
+
admittable_type STRING(255),
|
339
|
+
admittable_id INT64,
|
340
|
+
) PRIMARY KEY(id);
|
341
|
+
CREATE TABLE memberships (
|
342
|
+
id INT64 NOT NULL,
|
343
|
+
joined_on TIMESTAMP,
|
344
|
+
club_id INT64,
|
345
|
+
member_id INT64,
|
346
|
+
favourite BOOL,
|
347
|
+
) PRIMARY KEY(id);
|
348
|
+
CREATE TABLE organizations (
|
349
|
+
id INT64 NOT NULL,
|
350
|
+
name STRING(MAX),
|
351
|
+
last_updated TIMESTAMP OPTIONS (
|
352
|
+
allow_commit_timestamp = true
|
353
|
+
),
|
354
|
+
) PRIMARY KEY(id);
|
355
|
+
CREATE TABLE posts (
|
356
|
+
id INT64 NOT NULL,
|
357
|
+
title STRING(MAX),
|
358
|
+
content STRING(MAX),
|
359
|
+
author_id INT64,
|
360
|
+
comments_count INT64,
|
361
|
+
post_date DATE,
|
362
|
+
published_time TIMESTAMP,
|
363
|
+
) PRIMARY KEY(id);
|
364
|
+
ALTER TABLE comments ADD CONSTRAINT fk_rails_2fd19c0db7 FOREIGN KEY(post_id) REFERENCES posts(id);
|
365
|
+
CREATE INDEX index_posts_on_author_id ON posts(author_id);
|
366
|
+
CREATE TABLE schema_migrations (
|
367
|
+
version STRING(MAX) NOT NULL,
|
368
|
+
) PRIMARY KEY(version);
|
369
|
+
CREATE TABLE singers (
|
370
|
+
singerid INT64 NOT NULL,
|
371
|
+
first_name STRING(200),
|
372
|
+
last_name STRING(MAX),
|
373
|
+
tracks_count INT64,
|
374
|
+
lock_version INT64,
|
375
|
+
full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
|
376
|
+
) PRIMARY KEY(singerid);
|
377
|
+
CREATE TABLE albums (
|
378
|
+
albumid INT64 NOT NULL,
|
379
|
+
singerid INT64 NOT NULL,
|
380
|
+
title STRING(MAX),
|
381
|
+
lock_version INT64,
|
382
|
+
) PRIMARY KEY(singerid, albumid),
|
383
|
+
INTERLEAVE IN PARENT singers ON DELETE NO ACTION;
|
384
|
+
CREATE TABLE tracks (
|
385
|
+
trackid INT64 NOT NULL,
|
386
|
+
singerid INT64 NOT NULL,
|
387
|
+
albumid INT64 NOT NULL,
|
388
|
+
title STRING(MAX),
|
389
|
+
duration NUMERIC,
|
390
|
+
lock_version INT64,
|
391
|
+
) PRIMARY KEY(singerid, albumid, trackid),
|
392
|
+
INTERLEAVE IN PARENT albums ON DELETE CASCADE;
|
393
|
+
CREATE NULL_FILTERED INDEX index_tracks_on_singerid_and_albumid_and_title ON tracks(singerid, albumid, title), INTERLEAVE IN albums;
|
394
|
+
CREATE TABLE transactions (
|
395
|
+
id INT64 NOT NULL,
|
396
|
+
amount FLOAT64,
|
397
|
+
account_id INT64,
|
398
|
+
) PRIMARY KEY(id);
|
399
|
+
INSERT INTO `schema_migrations` (version) VALUES
|
400
|
+
('1');
|
401
|
+
|
402
|
+
"
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Copyright 2021 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
|
+
require "models/album"
|
10
|
+
|
11
|
+
class AlbumPartialDisabled < Album
|
12
|
+
self.table_name = :albums
|
13
|
+
|
14
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
15
|
+
self.partial_inserts = false
|
16
|
+
end
|
17
|
+
end
|