activerecord-spanner-adapter 0.3.0 → 0.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 +5 -5
- data/.github/CODEOWNERS +7 -0
- data/.github/sync-repo-settings.yaml +16 -0
- data/.github/workflows/acceptance-tests-on-emulator.yaml +45 -0
- data/.github/workflows/acceptance-tests-on-production.yaml +36 -0
- data/.github/workflows/ci.yaml +33 -0
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +52 -0
- data/.github/workflows/nightly-acceptance-tests-on-production.yaml +35 -0
- data/.github/workflows/nightly-unit-tests.yaml +40 -0
- data/.github/workflows/release-please-label.yml +25 -0
- data/.github/workflows/release-please.yml +39 -0
- data/.github/workflows/rubocop.yaml +31 -0
- data/.gitignore +67 -5
- data/.kokoro/populate-secrets.sh +77 -0
- data/.kokoro/release.cfg +33 -0
- data/.kokoro/release.sh +15 -0
- data/.kokoro/trampoline_v2.sh +489 -0
- data/.rubocop.yml +46 -0
- data/.toys/release.rb +18 -0
- data/.trampolinerc +48 -0
- data/.yardopts +11 -0
- data/CHANGELOG.md +26 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +79 -0
- data/Gemfile +9 -4
- data/LICENSE +6 -6
- data/README.md +67 -30
- data/Rakefile +79 -3
- data/SECURITY.md +7 -0
- data/acceptance/cases/associations/has_many_associations_test.rb +119 -0
- data/acceptance/cases/associations/has_many_through_associations_test.rb +63 -0
- data/acceptance/cases/associations/has_one_associations_test.rb +79 -0
- data/acceptance/cases/associations/has_one_through_associations_test.rb +98 -0
- data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb +211 -0
- data/acceptance/cases/migration/change_schema_test.rb +433 -0
- data/acceptance/cases/migration/change_table_test.rb +115 -0
- data/acceptance/cases/migration/column_attributes_test.rb +122 -0
- data/acceptance/cases/migration/column_positioning_test.rb +48 -0
- data/acceptance/cases/migration/columns_test.rb +201 -0
- data/acceptance/cases/migration/command_recorder_test.rb +406 -0
- data/acceptance/cases/migration/create_join_table_test.rb +216 -0
- data/acceptance/cases/migration/ddl_batching_test.rb +80 -0
- data/acceptance/cases/migration/foreign_key_test.rb +297 -0
- data/acceptance/cases/migration/index_test.rb +211 -0
- data/acceptance/cases/migration/references_foreign_key_test.rb +259 -0
- data/acceptance/cases/migration/references_index_test.rb +135 -0
- data/acceptance/cases/migration/references_statements_test.rb +166 -0
- data/acceptance/cases/migration/rename_column_test.rb +96 -0
- data/acceptance/cases/models/calculation_query_test.rb +128 -0
- data/acceptance/cases/models/generated_column_test.rb +126 -0
- data/acceptance/cases/models/mutation_test.rb +122 -0
- data/acceptance/cases/models/query_test.rb +147 -0
- data/acceptance/cases/sessions/session_not_found_test.rb +121 -0
- data/acceptance/cases/transactions/optimistic_locking_test.rb +141 -0
- data/acceptance/cases/transactions/read_only_transactions_test.rb +67 -0
- data/acceptance/cases/transactions/read_write_transactions_test.rb +248 -0
- data/acceptance/cases/type/all_types_test.rb +152 -0
- data/acceptance/cases/type/binary_test.rb +59 -0
- data/acceptance/cases/type/boolean_test.rb +31 -0
- data/acceptance/cases/type/date_test.rb +32 -0
- data/acceptance/cases/type/date_time_test.rb +30 -0
- data/acceptance/cases/type/float_test.rb +27 -0
- data/acceptance/cases/type/integer_test.rb +44 -0
- data/acceptance/cases/type/numeric_test.rb +27 -0
- data/acceptance/cases/type/string_test.rb +79 -0
- data/acceptance/cases/type/text_test.rb +30 -0
- data/acceptance/cases/type/time_test.rb +87 -0
- data/acceptance/models/account.rb +13 -0
- data/acceptance/models/address.rb +9 -0
- data/acceptance/models/album.rb +12 -0
- data/acceptance/models/all_types.rb +8 -0
- data/acceptance/models/author.rb +11 -0
- data/acceptance/models/club.rb +12 -0
- data/acceptance/models/comment.rb +9 -0
- data/acceptance/models/customer.rb +9 -0
- data/acceptance/models/department.rb +9 -0
- data/acceptance/models/firm.rb +10 -0
- data/acceptance/models/member.rb +13 -0
- data/acceptance/models/member_type.rb +9 -0
- data/acceptance/models/membership.rb +10 -0
- data/acceptance/models/organization.rb +9 -0
- data/acceptance/models/post.rb +10 -0
- data/acceptance/models/singer.rb +10 -0
- data/acceptance/models/track.rb +20 -0
- data/acceptance/models/transaction.rb +9 -0
- data/acceptance/schema/schema.rb +143 -0
- data/acceptance/test_helper.rb +260 -0
- data/activerecord-spanner-adapter.gemspec +32 -17
- data/assets/solidus-db.png +0 -0
- data/benchmarks/README.md +17 -0
- data/benchmarks/Rakefile +14 -0
- data/benchmarks/application.rb +308 -0
- data/benchmarks/config/database.yml +8 -0
- data/benchmarks/config/environment.rb +12 -0
- data/benchmarks/db/migrate/01_create_tables.rb +25 -0
- data/benchmarks/db/schema.rb +29 -0
- data/benchmarks/models/album.rb +9 -0
- data/benchmarks/models/singer.rb +9 -0
- data/bin/console +6 -7
- data/examples/rails/README.md +262 -0
- data/examples/snippets/README.md +29 -0
- data/examples/snippets/Rakefile +57 -0
- data/examples/snippets/array-data-type/README.md +45 -0
- data/examples/snippets/array-data-type/Rakefile +13 -0
- data/examples/snippets/array-data-type/application.rb +45 -0
- data/examples/snippets/array-data-type/config/database.yml +8 -0
- data/examples/snippets/array-data-type/db/migrate/01_create_tables.rb +24 -0
- data/examples/snippets/array-data-type/db/schema.rb +26 -0
- data/examples/snippets/array-data-type/db/seeds.rb +5 -0
- data/examples/snippets/array-data-type/models/entity_with_array_types.rb +18 -0
- data/examples/snippets/bin/create_emulator_instance.rb +18 -0
- data/examples/snippets/bulk-insert/README.md +21 -0
- data/examples/snippets/bulk-insert/Rakefile +13 -0
- data/examples/snippets/bulk-insert/application.rb +64 -0
- data/examples/snippets/bulk-insert/config/database.yml +8 -0
- data/examples/snippets/bulk-insert/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/bulk-insert/db/schema.rb +26 -0
- data/examples/snippets/bulk-insert/db/seeds.rb +5 -0
- data/examples/snippets/bulk-insert/models/album.rb +9 -0
- data/examples/snippets/bulk-insert/models/singer.rb +9 -0
- data/examples/snippets/commit-timestamp/README.md +18 -0
- data/examples/snippets/commit-timestamp/Rakefile +13 -0
- data/examples/snippets/commit-timestamp/application.rb +53 -0
- data/examples/snippets/commit-timestamp/config/database.yml +8 -0
- data/examples/snippets/commit-timestamp/db/migrate/01_create_tables.rb +26 -0
- data/examples/snippets/commit-timestamp/db/schema.rb +29 -0
- data/examples/snippets/commit-timestamp/db/seeds.rb +5 -0
- data/examples/snippets/commit-timestamp/models/album.rb +9 -0
- data/examples/snippets/commit-timestamp/models/singer.rb +9 -0
- data/examples/snippets/config/environment.rb +21 -0
- data/examples/snippets/create-records/README.md +12 -0
- data/examples/snippets/create-records/Rakefile +13 -0
- data/examples/snippets/create-records/application.rb +42 -0
- data/examples/snippets/create-records/config/database.yml +8 -0
- data/examples/snippets/create-records/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/create-records/db/schema.rb +26 -0
- data/examples/snippets/create-records/db/seeds.rb +5 -0
- data/examples/snippets/create-records/models/album.rb +9 -0
- data/examples/snippets/create-records/models/singer.rb +9 -0
- data/examples/snippets/date-data-type/README.md +19 -0
- data/examples/snippets/date-data-type/Rakefile +13 -0
- data/examples/snippets/date-data-type/application.rb +35 -0
- data/examples/snippets/date-data-type/config/database.yml +8 -0
- data/examples/snippets/date-data-type/db/migrate/01_create_tables.rb +20 -0
- data/examples/snippets/date-data-type/db/schema.rb +21 -0
- data/examples/snippets/date-data-type/db/seeds.rb +16 -0
- data/examples/snippets/date-data-type/models/singer.rb +8 -0
- data/examples/snippets/generated-column/README.md +41 -0
- data/examples/snippets/generated-column/Rakefile +13 -0
- data/examples/snippets/generated-column/application.rb +37 -0
- data/examples/snippets/generated-column/config/database.yml +8 -0
- data/examples/snippets/generated-column/db/migrate/01_create_tables.rb +23 -0
- data/examples/snippets/generated-column/db/schema.rb +21 -0
- data/examples/snippets/generated-column/db/seeds.rb +18 -0
- data/examples/snippets/generated-column/models/singer.rb +8 -0
- data/examples/snippets/interleaved-tables/README.md +152 -0
- data/examples/snippets/interleaved-tables/Rakefile +13 -0
- data/examples/snippets/interleaved-tables/application.rb +109 -0
- data/examples/snippets/interleaved-tables/config/database.yml +8 -0
- data/examples/snippets/interleaved-tables/db/migrate/01_create_tables.rb +44 -0
- data/examples/snippets/interleaved-tables/db/schema.rb +32 -0
- data/examples/snippets/interleaved-tables/db/seeds.rb +40 -0
- data/examples/snippets/interleaved-tables/models/album.rb +15 -0
- data/examples/snippets/interleaved-tables/models/singer.rb +20 -0
- data/examples/snippets/interleaved-tables/models/track.rb +25 -0
- data/examples/snippets/migrations/README.md +43 -0
- data/examples/snippets/migrations/Rakefile +13 -0
- data/examples/snippets/migrations/application.rb +26 -0
- data/examples/snippets/migrations/config/database.yml +8 -0
- data/examples/snippets/migrations/db/migrate/01_create_tables.rb +28 -0
- data/examples/snippets/migrations/db/schema.rb +33 -0
- data/examples/snippets/migrations/db/seeds.rb +5 -0
- data/examples/snippets/migrations/models/album.rb +10 -0
- data/examples/snippets/migrations/models/singer.rb +10 -0
- data/examples/snippets/migrations/models/track.rb +9 -0
- data/examples/snippets/mutations/README.md +34 -0
- data/examples/snippets/mutations/Rakefile +13 -0
- data/examples/snippets/mutations/application.rb +47 -0
- data/examples/snippets/mutations/config/database.yml +8 -0
- data/examples/snippets/mutations/db/migrate/01_create_tables.rb +22 -0
- data/examples/snippets/mutations/db/schema.rb +27 -0
- data/examples/snippets/mutations/db/seeds.rb +25 -0
- data/examples/snippets/mutations/models/album.rb +9 -0
- data/examples/snippets/mutations/models/singer.rb +9 -0
- data/examples/snippets/optimistic-locking/README.md +12 -0
- data/examples/snippets/optimistic-locking/Rakefile +13 -0
- data/examples/snippets/optimistic-locking/application.rb +48 -0
- data/examples/snippets/optimistic-locking/config/database.yml +8 -0
- data/examples/snippets/optimistic-locking/db/migrate/01_create_tables.rb +26 -0
- data/examples/snippets/optimistic-locking/db/schema.rb +29 -0
- data/examples/snippets/optimistic-locking/db/seeds.rb +25 -0
- data/examples/snippets/optimistic-locking/models/album.rb +9 -0
- data/examples/snippets/optimistic-locking/models/singer.rb +9 -0
- data/examples/snippets/quickstart/README.md +26 -0
- data/examples/snippets/quickstart/Rakefile +13 -0
- data/examples/snippets/quickstart/application.rb +51 -0
- data/examples/snippets/quickstart/config/database.yml +8 -0
- data/examples/snippets/quickstart/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/quickstart/db/schema.rb +26 -0
- data/examples/snippets/quickstart/db/seeds.rb +24 -0
- data/examples/snippets/quickstart/models/album.rb +9 -0
- data/examples/snippets/quickstart/models/singer.rb +9 -0
- data/examples/snippets/read-only-transactions/README.md +13 -0
- data/examples/snippets/read-only-transactions/Rakefile +13 -0
- data/examples/snippets/read-only-transactions/application.rb +49 -0
- data/examples/snippets/read-only-transactions/config/database.yml +8 -0
- data/examples/snippets/read-only-transactions/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/read-only-transactions/db/schema.rb +26 -0
- data/examples/snippets/read-only-transactions/db/seeds.rb +24 -0
- data/examples/snippets/read-only-transactions/models/album.rb +9 -0
- data/examples/snippets/read-only-transactions/models/singer.rb +9 -0
- data/examples/snippets/read-write-transactions/README.md +12 -0
- data/examples/snippets/read-write-transactions/Rakefile +13 -0
- data/examples/snippets/read-write-transactions/application.rb +39 -0
- data/examples/snippets/read-write-transactions/config/database.yml +8 -0
- data/examples/snippets/read-write-transactions/db/migrate/01_create_tables.rb +22 -0
- data/examples/snippets/read-write-transactions/db/schema.rb +27 -0
- data/examples/snippets/read-write-transactions/db/seeds.rb +25 -0
- data/examples/snippets/read-write-transactions/models/album.rb +9 -0
- data/examples/snippets/read-write-transactions/models/singer.rb +9 -0
- data/examples/snippets/timestamp-data-type/README.md +17 -0
- data/examples/snippets/timestamp-data-type/Rakefile +13 -0
- data/examples/snippets/timestamp-data-type/application.rb +42 -0
- data/examples/snippets/timestamp-data-type/config/database.yml +8 -0
- data/examples/snippets/timestamp-data-type/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/timestamp-data-type/db/schema.rb +21 -0
- data/examples/snippets/timestamp-data-type/db/seeds.rb +6 -0
- data/examples/snippets/timestamp-data-type/models/meeting.rb +19 -0
- data/examples/solidus/README.md +172 -0
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +224 -269
- data/lib/active_record/connection_adapters/spanner/quoting.rb +42 -50
- data/lib/active_record/connection_adapters/spanner/schema_cache.rb +43 -0
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +125 -9
- data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +122 -0
- data/lib/active_record/connection_adapters/spanner/schema_dumper.rb +19 -0
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +553 -139
- data/lib/active_record/connection_adapters/spanner/type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/spanner_adapter.rb +182 -78
- data/lib/active_record/tasks/spanner_database_tasks.rb +74 -0
- data/lib/active_record/type/spanner/array.rb +32 -0
- data/lib/active_record/type/spanner/bytes.rb +26 -0
- data/lib/active_record/type/spanner/spanner_active_record_converter.rb +32 -0
- data/lib/active_record/type/spanner/time.rb +37 -0
- data/lib/activerecord-spanner-adapter.rb +23 -0
- data/lib/activerecord_spanner_adapter/base.rb +217 -0
- data/lib/activerecord_spanner_adapter/connection.rb +324 -0
- data/lib/activerecord_spanner_adapter/errors.rb +13 -0
- data/lib/activerecord_spanner_adapter/foreign_key.rb +29 -0
- data/lib/activerecord_spanner_adapter/index/column.rb +38 -0
- data/lib/activerecord_spanner_adapter/index.rb +80 -0
- data/lib/activerecord_spanner_adapter/information_schema.rb +261 -0
- data/lib/activerecord_spanner_adapter/primary_key.rb +31 -0
- data/lib/activerecord_spanner_adapter/table/column.rb +59 -0
- data/lib/activerecord_spanner_adapter/table.rb +61 -0
- data/lib/activerecord_spanner_adapter/transaction.rb +113 -0
- data/lib/activerecord_spanner_adapter/version.rb +9 -0
- data/lib/arel/visitors/spanner.rb +35 -0
- data/lib/spanner_client_ext.rb +82 -0
- data/renovate.json +5 -0
- metadata +387 -34
- data/.travis.yml +0 -5
- data/lib/active_record/connection_adapters/spanner/client.rb +0 -190
- data/lib/active_record/connection_adapters/spanner.rb +0 -10
- data/lib/activerecord-spanner-adapter/version.rb +0 -3
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Copyright 2020 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
|
+
|
|
11
|
+
module ActiveRecord
|
|
12
|
+
class Migration
|
|
13
|
+
class TableTest < SpannerAdapter::TestCase
|
|
14
|
+
include SpannerAdapter::Migration::TestHelper
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
skip_test_table_create!
|
|
18
|
+
|
|
19
|
+
super
|
|
20
|
+
@connection = Minitest::Mock.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def teardown
|
|
24
|
+
assert @connection.verify
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def with_change_table
|
|
28
|
+
yield ActiveRecord::Base.connection.update_table_definition(:delete_me, @connection)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_remove_references_column_type_with_polymorphic_removes_type
|
|
32
|
+
with_change_table do |t|
|
|
33
|
+
@connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true]
|
|
34
|
+
t.remove_references :taggable, polymorphic: true
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
|
|
39
|
+
with_change_table do |t|
|
|
40
|
+
@connection.expect :add_reference, nil, [:delete_me, :taggable, polymorphic: true, null: false]
|
|
41
|
+
t.references :taggable, polymorphic: true, null: false
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_remove_references_column_type_with_polymorphic_and_options_null_is_false_removes_table_flag
|
|
46
|
+
with_change_table do |t|
|
|
47
|
+
@connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true, null: false]
|
|
48
|
+
t.remove_references :taggable, polymorphic: true, null: false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_references_column_type_with_polymorphic_and_type
|
|
53
|
+
with_change_table do |t|
|
|
54
|
+
@connection.expect :add_reference, nil, [:delete_me, :taggable, polymorphic: true, type: :string]
|
|
55
|
+
t.references :taggable, polymorphic: true, type: :string
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_remove_references_column_type_with_polymorphic_and_type
|
|
60
|
+
with_change_table do |t|
|
|
61
|
+
@connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true, type: :string]
|
|
62
|
+
t.remove_references :taggable, polymorphic: true, type: :string
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_timestamps_creates_updated_at_and_created_at
|
|
67
|
+
with_change_table do |t|
|
|
68
|
+
@connection.expect :add_timestamps, nil, [:delete_me, null: true]
|
|
69
|
+
t.timestamps null: true
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def test_remove_timestamps_creates_updated_at_and_created_at
|
|
74
|
+
with_change_table do |t|
|
|
75
|
+
@connection.expect :remove_timestamps, nil, [:delete_me, { null: true }]
|
|
76
|
+
t.remove_timestamps(null: true)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_primary_key_creates_primary_key_column
|
|
81
|
+
with_change_table do |t|
|
|
82
|
+
@connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
|
|
83
|
+
t.primary_key :id, first: true
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_index_exists
|
|
88
|
+
with_change_table do |t|
|
|
89
|
+
@connection.expect :index_exists?, nil, [:delete_me, :bar, {}]
|
|
90
|
+
t.index_exists?(:bar)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_index_exists_with_options
|
|
95
|
+
with_change_table do |t|
|
|
96
|
+
@connection.expect :index_exists?, nil, [:delete_me, :bar, { unique: true }]
|
|
97
|
+
t.index_exists?(:bar, unique: true)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_remove_drops_multiple_columns_when_column_options_are_given
|
|
102
|
+
with_change_table do |t|
|
|
103
|
+
@connection.expect :remove_columns, nil, [:delete_me, :bar, :baz, type: :string, null: false]
|
|
104
|
+
t.remove :bar, :baz, type: :string, null: false
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_table_name_set
|
|
109
|
+
with_change_table do |t|
|
|
110
|
+
assert_equal :delete_me, t.name
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Copyright 2020 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 "bigdecimal"
|
|
11
|
+
|
|
12
|
+
module ActiveRecord
|
|
13
|
+
class Migration
|
|
14
|
+
class ColumnAttributesTest < SpannerAdapter::TestCase
|
|
15
|
+
include SpannerAdapter::Migration::TestHelper
|
|
16
|
+
|
|
17
|
+
def test_add_remove_single_field_using_string_arguments
|
|
18
|
+
assert_no_column TestModel, :last_name
|
|
19
|
+
|
|
20
|
+
add_column "test_models", "last_name", :string
|
|
21
|
+
assert_column TestModel, :last_name
|
|
22
|
+
|
|
23
|
+
remove_column "test_models", "last_name"
|
|
24
|
+
assert_no_column TestModel, :last_name
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_add_remove_single_field_using_symbol_arguments
|
|
28
|
+
assert_no_column TestModel, :last_name
|
|
29
|
+
|
|
30
|
+
add_column :test_models, :last_name, :string
|
|
31
|
+
assert_column TestModel, :last_name
|
|
32
|
+
|
|
33
|
+
remove_column :test_models, :last_name
|
|
34
|
+
assert_no_column TestModel, :last_name
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_add_column_without_limit
|
|
38
|
+
add_column :test_models, :description, :string, limit: nil
|
|
39
|
+
TestModel.reset_column_information
|
|
40
|
+
assert_equal "MAX", TestModel.columns_hash["description"].limit
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# We specifically do a manual INSERT here, and then test only the SELECT
|
|
44
|
+
# functionality. This allows us to more easily catch INSERT being broken,
|
|
45
|
+
# but SELECT actually working fine.
|
|
46
|
+
def test_native_float_insert_manual_vs_automatic
|
|
47
|
+
correct_value = "0012345678901234567890.0123456789".to_f
|
|
48
|
+
|
|
49
|
+
connection.add_column "test_models", "wealth", :float
|
|
50
|
+
|
|
51
|
+
# Do a manual insertion
|
|
52
|
+
connection.transaction {
|
|
53
|
+
connection.execute "insert into test_models (id, wealth) values (#{generate_id}, 12345678901234567890.0123456789)"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# SELECT
|
|
57
|
+
row = TestModel.first
|
|
58
|
+
assert_kind_of Float, row.wealth
|
|
59
|
+
|
|
60
|
+
# If this assert fails, that means the SELECT is broken!
|
|
61
|
+
assert_equal correct_value, row.wealth
|
|
62
|
+
|
|
63
|
+
# Reset to old state
|
|
64
|
+
TestModel.delete_all
|
|
65
|
+
|
|
66
|
+
# Now use the Rails insertion
|
|
67
|
+
TestModel.create wealth: BigDecimal("12345678901234567890.0123456789")
|
|
68
|
+
|
|
69
|
+
# SELECT
|
|
70
|
+
row = TestModel.first
|
|
71
|
+
assert_kind_of Float, row.wealth
|
|
72
|
+
|
|
73
|
+
# If these asserts fail, that means the INSERT (create function, or cast to SQL) is broken!
|
|
74
|
+
assert_equal correct_value, row.wealth
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_native_types
|
|
78
|
+
connection.ddl_batch do
|
|
79
|
+
add_column "test_models", "first_name", :string
|
|
80
|
+
add_column "test_models", "last_name", :string
|
|
81
|
+
add_column "test_models", "bio", :text
|
|
82
|
+
add_column "test_models", "age", :integer
|
|
83
|
+
add_column "test_models", "height", :float
|
|
84
|
+
add_column "test_models", "birthday", :datetime
|
|
85
|
+
add_column "test_models", "favorite_day", :date
|
|
86
|
+
add_column "test_models", "moment_of_truth", :datetime
|
|
87
|
+
add_column "test_models", "male", :boolean
|
|
88
|
+
add_column "test_models", "weight", :decimal
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
TestModel.create first_name: "bob", last_name: "bobsen",
|
|
92
|
+
bio: "I was born ....", age: 18, height: 1.78,
|
|
93
|
+
birthday: 18.years.ago, favorite_day: 10.days.ago,
|
|
94
|
+
moment_of_truth: "1782-10-10 21:40:18", male: true, weight: BigDecimal("75.6", 1)
|
|
95
|
+
|
|
96
|
+
bob = TestModel.first
|
|
97
|
+
assert_equal "bob", bob.first_name
|
|
98
|
+
assert_equal "bobsen", bob.last_name
|
|
99
|
+
assert_equal "I was born ....", bob.bio
|
|
100
|
+
assert_equal 18, bob.age
|
|
101
|
+
assert_equal 1.78, bob.height
|
|
102
|
+
assert_equal true, bob.male?
|
|
103
|
+
assert_equal BigDecimal("75.6", 1), bob.weight
|
|
104
|
+
|
|
105
|
+
assert_equal String, bob.first_name.class
|
|
106
|
+
assert_equal String, bob.last_name.class
|
|
107
|
+
assert_equal String, bob.bio.class
|
|
108
|
+
assert_kind_of Integer, bob.age
|
|
109
|
+
assert_equal Float, bob.height.class
|
|
110
|
+
assert_equal Time, bob.birthday.class
|
|
111
|
+
assert_equal Date, bob.favorite_day.class
|
|
112
|
+
assert_instance_of TrueClass, bob.male?
|
|
113
|
+
assert_equal BigDecimal, bob.weight.class
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_add_column_and_ignore_limit
|
|
117
|
+
add_column :test_models, :integer_ignore_limit, :integer, limit: 10
|
|
118
|
+
assert_column TestModel, :integer_ignore_limit
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright 2020 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
|
+
|
|
11
|
+
module ActiveRecord
|
|
12
|
+
class Migration
|
|
13
|
+
class ColumnPositioningTest < SpannerAdapter::TestCase
|
|
14
|
+
include SpannerAdapter::Migration::TestHelper
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
skip_test_table_create!
|
|
18
|
+
super
|
|
19
|
+
|
|
20
|
+
connection.ddl_batch do
|
|
21
|
+
connection.create_table :testing_columns_position, id: false, force: true do |t|
|
|
22
|
+
t.column :first, :integer
|
|
23
|
+
t.column :second, :integer
|
|
24
|
+
t.column :third, :integer
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def teardown
|
|
30
|
+
connection.ddl_batch do
|
|
31
|
+
connection.drop_table :testing_columns_position
|
|
32
|
+
end rescue nil
|
|
33
|
+
ActiveRecord::Base.primary_key_prefix_type = nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_column_positioning
|
|
37
|
+
assert_equal %w(first second third), connection.columns(:testing_columns_position).map(&:name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_add_column_with_positioning
|
|
41
|
+
connection.ddl_batch do
|
|
42
|
+
connection.add_column :testing_columns_position, :fourth, :integer
|
|
43
|
+
end
|
|
44
|
+
assert_equal %w(first second third fourth), connection.columns(:testing_columns_position).map(&:name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Copyright 2020 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
|
+
|
|
11
|
+
module ActiveRecord
|
|
12
|
+
class Migration
|
|
13
|
+
class ColumnsTest < SpannerAdapter::TestCase
|
|
14
|
+
include SpannerAdapter::Migration::TestHelper
|
|
15
|
+
|
|
16
|
+
def test_rename_column
|
|
17
|
+
connection.ddl_batch do
|
|
18
|
+
add_column "test_models", :hat_name, :string
|
|
19
|
+
end
|
|
20
|
+
assert_column TestModel, :hat_name
|
|
21
|
+
|
|
22
|
+
rename_column "test_models", :hat_name, :cap_name
|
|
23
|
+
assert_column TestModel, :cap_name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_change_column_default_value
|
|
27
|
+
error = assert_raise ActiveRecordSpannerAdapter::NotSupportedError do
|
|
28
|
+
change_column_default "test_models", :hat_name, "hat"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
assert_equal "change column with default value not supported.", error.message
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_remove_column_with_index
|
|
35
|
+
connection.ddl_batch do
|
|
36
|
+
add_column "test_models", :hat_name, :string
|
|
37
|
+
add_index :test_models, :hat_name
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
assert_equal 1, connection.indexes("test_models").size
|
|
41
|
+
connection.ddl_batch do
|
|
42
|
+
remove_column "test_models", "hat_name"
|
|
43
|
+
end
|
|
44
|
+
assert_equal 0, connection.indexes("test_models").size
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_remove_column_with_multi_column_index
|
|
48
|
+
connection.ddl_batch do
|
|
49
|
+
add_column "test_models", :hat_size, :integer
|
|
50
|
+
add_column "test_models", :hat_style, :string, limit: 100
|
|
51
|
+
add_index "test_models", ["hat_style", "hat_size"], unique: true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
assert_equal 1, connection.indexes("test_models").size
|
|
55
|
+
connection.ddl_batch do
|
|
56
|
+
remove_column "test_models", "hat_size"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
assert_equal [], connection.indexes("test_models").map(&:name)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_change_type_of_not_null_column
|
|
63
|
+
connection.ddl_batch do
|
|
64
|
+
change_column "test_models", "updated_at", :datetime, null: false
|
|
65
|
+
change_column "test_models", "updated_at", :datetime, null: false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
TestModel.reset_column_information
|
|
69
|
+
assert_equal false, TestModel.columns_hash["updated_at"].null
|
|
70
|
+
ensure
|
|
71
|
+
connection.ddl_batch do
|
|
72
|
+
change_column "test_models", "updated_at", :datetime, null: true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_change_column_nullability
|
|
77
|
+
connection.ddl_batch do
|
|
78
|
+
add_column "test_models", "funny", :boolean
|
|
79
|
+
end
|
|
80
|
+
assert TestModel.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
|
|
81
|
+
|
|
82
|
+
connection.ddl_batch do
|
|
83
|
+
change_column "test_models", "funny", :boolean, null: false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
TestModel.reset_column_information
|
|
87
|
+
assert_not TestModel.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
|
|
88
|
+
|
|
89
|
+
connection.ddl_batch do
|
|
90
|
+
change_column "test_models", "funny", :boolean, null: true
|
|
91
|
+
end
|
|
92
|
+
TestModel.reset_column_information
|
|
93
|
+
assert TestModel.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_change_column
|
|
97
|
+
# Only string and binary allows to change types
|
|
98
|
+
connection.ddl_batch do
|
|
99
|
+
add_column "test_models", "name", :string
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
old_columns = connection.columns TestModel.table_name
|
|
103
|
+
|
|
104
|
+
assert old_columns.find { |c| c.name == "name" && c.type == :string }
|
|
105
|
+
|
|
106
|
+
connection.ddl_batch do
|
|
107
|
+
change_column "test_models", "name", :binary
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
new_columns = connection.columns TestModel.table_name
|
|
111
|
+
|
|
112
|
+
assert_not new_columns.find { |c| c.name == "name" && c.type == :string }
|
|
113
|
+
assert new_columns.find { |c| c.name == "name" && c.type == :binary }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_change_column_with_custom_index_name
|
|
117
|
+
connection.ddl_batch do
|
|
118
|
+
add_column :test_models, :category, :string
|
|
119
|
+
add_index :test_models, :category, name: "test_models_categories_idx", order: { category: :desc}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name)
|
|
123
|
+
connection.ddl_batch do
|
|
124
|
+
change_column "test_models", "category", :string, null: false
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
assert column_exists?(:test_models, :category, :string, null: false)
|
|
128
|
+
indexes = connection.indexes("test_models")
|
|
129
|
+
assert_equal ["test_models_categories_idx"], indexes.map(&:name)
|
|
130
|
+
assert_equal({ category: :desc }, indexes.first.orders)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_change_column_with_long_index_name
|
|
134
|
+
table_name_prefix = "test_models_"
|
|
135
|
+
long_index_name = table_name_prefix + ("x" * (connection.index_name_length - table_name_prefix.length))
|
|
136
|
+
connection.ddl_batch do
|
|
137
|
+
add_column "test_models", "category", :string
|
|
138
|
+
add_index :test_models, :category, name: long_index_name
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
connection.ddl_batch do
|
|
142
|
+
change_column "test_models", "category", :string, null: false
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
assert_equal [long_index_name], connection.indexes("test_models").map(&:name)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_remove_column_no_second_parameter_raises_exception
|
|
149
|
+
assert_raise(ArgumentError) { connection.remove_column("funny") }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def test_removing_column_preserves_custom_primary_key
|
|
153
|
+
connection.ddl_batch do
|
|
154
|
+
connection.create_table "my_table", primary_key: "my_table_id", force: true do |t|
|
|
155
|
+
t.integer "col_one"
|
|
156
|
+
t.string "col_two", limit: 128, null: false
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
connection.ddl_batch do
|
|
161
|
+
remove_column "my_table", "col_two"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
assert_equal "my_table_id", connection.primary_key("my_table")
|
|
165
|
+
|
|
166
|
+
columns = connection.columns "my_table"
|
|
167
|
+
my_table_id = columns.detect { |c| c.name == "my_table_id" }
|
|
168
|
+
assert_equal "INT64", my_table_id.sql_type
|
|
169
|
+
ensure
|
|
170
|
+
connection.ddl_batch do
|
|
171
|
+
connection.drop_table :my_table rescue nil
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_column_with_index
|
|
176
|
+
connection.ddl_batch do
|
|
177
|
+
connection.create_table "my_table", force: true do |t|
|
|
178
|
+
t.string :item_number, index: true
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
assert connection.index_exists?("my_table", :item_number, name: :index_my_table_on_item_number)
|
|
183
|
+
ensure
|
|
184
|
+
connection.ddl_batch do
|
|
185
|
+
connection.drop_table :my_table rescue nil
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def test_add_column_without_column_name
|
|
190
|
+
e = assert_raise ArgumentError do
|
|
191
|
+
connection.create_table "my_table", force: true do |t|
|
|
192
|
+
t.timestamp
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
assert_equal "Missing column name(s) for timestamp", e.message
|
|
196
|
+
ensure
|
|
197
|
+
connection.drop_table :my_table, if_exists: true
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|