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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/blunderbuss.yml +1 -1
  4. data/.github/workflows/acceptance-tests-on-emulator.yaml +8 -8
  5. data/.github/workflows/ci.yaml +6 -4
  6. data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +14 -6
  7. data/.github/workflows/nightly-unit-tests.yaml +14 -6
  8. data/.release-please-manifest.json +1 -1
  9. data/CHANGELOG.md +28 -0
  10. data/Gemfile +1 -1
  11. data/README.md +4 -0
  12. data/acceptance/cases/migration/change_table_test.rb +23 -13
  13. data/acceptance/cases/migration/schema_dumper_test.rb +69 -0
  14. data/acceptance/cases/models/generated_column_test.rb +21 -7
  15. data/acceptance/cases/models/interleave_test.rb +36 -0
  16. data/acceptance/cases/models/logging_test.rb +57 -0
  17. data/acceptance/cases/models/query_test.rb +6 -1
  18. data/acceptance/cases/tasks/database_tasks_test.rb +407 -0
  19. data/acceptance/models/album_partial_disabled.rb +17 -0
  20. data/acceptance/schema/schema.rb +139 -134
  21. data/acceptance/test_helper.rb +2 -0
  22. data/examples/snippets/array-data-type/db/schema.rb +8 -3
  23. data/examples/snippets/bulk-insert/db/schema.rb +9 -4
  24. data/examples/snippets/commit-timestamp/db/schema.rb +11 -6
  25. data/examples/snippets/create-records/db/schema.rb +9 -4
  26. data/examples/snippets/date-data-type/db/schema.rb +8 -3
  27. data/examples/snippets/generated-column/db/schema.rb +6 -1
  28. data/examples/snippets/hints/db/schema.rb +6 -1
  29. data/examples/snippets/interleaved-tables/README.md +2 -2
  30. data/examples/snippets/interleaved-tables/db/schema.rb +5 -0
  31. data/examples/snippets/migrations/db/schema.rb +10 -5
  32. data/examples/snippets/mutations/db/schema.rb +9 -4
  33. data/examples/snippets/optimistic-locking/db/schema.rb +9 -4
  34. data/examples/snippets/partitioned-dml/db/schema.rb +5 -0
  35. data/examples/snippets/quickstart/db/schema.rb +9 -4
  36. data/examples/snippets/read-only-transactions/db/schema.rb +5 -0
  37. data/examples/snippets/read-write-transactions/db/schema.rb +9 -4
  38. data/examples/snippets/stale-reads/db/schema.rb +5 -0
  39. data/examples/snippets/timestamp-data-type/db/schema.rb +8 -3
  40. data/lib/active_record/connection_adapters/spanner/column.rb +23 -0
  41. data/lib/active_record/connection_adapters/spanner/database_statements.rb +7 -4
  42. data/lib/active_record/connection_adapters/spanner/quoting.rb +9 -0
  43. data/lib/active_record/connection_adapters/spanner/schema_creation.rb +17 -4
  44. data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +11 -2
  45. data/lib/active_record/connection_adapters/spanner/schema_dumper.rb +56 -0
  46. data/lib/active_record/connection_adapters/spanner/schema_statements.rb +56 -9
  47. data/lib/active_record/connection_adapters/spanner/type_metadata.rb +19 -4
  48. data/lib/active_record/connection_adapters/spanner_adapter.rb +11 -0
  49. data/lib/active_record/tasks/spanner_database_tasks.rb +18 -4
  50. data/lib/active_record/type/spanner/spanner_active_record_converter.rb +10 -0
  51. data/lib/active_record/type/spanner/time.rb +10 -3
  52. data/lib/activerecord_spanner_adapter/base.rb +41 -27
  53. data/lib/activerecord_spanner_adapter/connection.rb +8 -3
  54. data/lib/activerecord_spanner_adapter/information_schema.rb +52 -3
  55. data/lib/activerecord_spanner_adapter/table/column.rb +7 -2
  56. data/lib/activerecord_spanner_adapter/version.rb +1 -1
  57. data/lib/arel/visitors/spanner.rb +8 -2
  58. metadata +9 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5796cf16ff55f858459e9d87da1cdd362b8b8a097161e3e7bda6283b56f6036a
4
- data.tar.gz: 9e2b8b7f9f4a72b7fe70d139281b82468d019cc46065368bd9fc0dc9e687a722
3
+ metadata.gz: 499376d85989274623aa1cda4cb9197e14636b42cd5cf5d5bda4b3fbdb2a6494
4
+ data.tar.gz: 4e0f7e384b4450b28581523a79540416567aa44745e44377a1f7744e11ff95e7
5
5
  SHA512:
6
- metadata.gz: 4899a089f30648b42a68386da0c43553c560c620178ff5609153cc67c42a08ada041b2dba565870c1b63cc067d3bbcd2208f97f290db93cda4dc2ba8c0dccb6a
7
- data.tar.gz: f3f3fca35b1e83a02fbd073cf5a8d969d411ac93588cb41c828e5a596d74cb8485f8bc23956e205ea1737a30bada65f65812ca0b24c8f02bb1287ed2106c6134
6
+ metadata.gz: a3d5ff8b79e774c6eb6c74431162366543d2476a8f2e7eb3f3f2d81dac249b0493a773b09cd787cdf5a8dd5b287d85170021b2e7c47c2aba9d06f76a77c2b9d6
7
+ data.tar.gz: 28bebd4c40535b80239992f66aed5030744623c21c00f875b548fac2c0318280871e83c294e8b87681a2376d34446050cee60283da469ff4fe175b2ad78685a6
data/.github/CODEOWNERS CHANGED
@@ -4,4 +4,4 @@
4
4
  # For syntax help see:
5
5
  # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
6
6
 
7
- * @googleapis/ruby-team @skuruppu @hengfengli @olavloite @xiangshen-dk
7
+ * @googleapis/ruby-team @olavloite @rahul2393 @ansh0l
@@ -1,2 +1,2 @@
1
1
  assign_issues:
2
- - hengfengli
2
+ - olavloite
@@ -18,16 +18,16 @@ jobs:
18
18
  strategy:
19
19
  max-parallel: 4
20
20
  matrix:
21
- ruby: [2.6, 2.7, 3.0]
22
- ar: [6.0.5.1, 6.1.6.1, 7.0.2.4, 7.0.3.1]
21
+ ruby: ["2.6", "2.7", "3.0", "3.1"]
22
+ ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4"]
23
23
  # Exclude combinations that are not supported.
24
24
  exclude:
25
- - ruby: 3.0
26
- ar: 6.0.5.1
27
- - ruby: 2.6
28
- ar: 7.0.2.4
29
- - ruby: 2.6
30
- ar: 7.0.3.1
25
+ - ruby: "3.0"
26
+ ar: "~> 6.0.6"
27
+ - ruby: "3.1"
28
+ ar: "~> 6.0.6"
29
+ - ruby: "2.6"
30
+ ar: "~> 7.0.4"
31
31
  env:
32
32
  AR_VERSION: ${{ matrix.ar }}
33
33
  steps:
@@ -10,14 +10,16 @@ jobs:
10
10
  strategy:
11
11
  max-parallel: 4
12
12
  matrix:
13
- ruby: ["2.6", "2.7", "3.0"]
14
- ar: ["6.0.4", "6.1.4", "7.0.2.4"]
13
+ ruby: ["2.6", "2.7", "3.0", "3.1"]
14
+ ar: ["~> 6.0.6", "~> 6.1.7", "~> 7.0.4"]
15
15
  # Exclude combinations that are not supported.
16
16
  exclude:
17
17
  - ruby: "3.0"
18
- ar: "6.0.4"
18
+ ar: "~> 6.0.6"
19
+ - ruby: "3.1"
20
+ ar: "~> 6.0.6"
19
21
  - ruby: "2.6"
20
- ar: "7.0.2.4"
22
+ ar: "~> 7.0.4"
21
23
  env:
22
24
  AR_VERSION: ${{ matrix.ar }}
23
25
  steps:
@@ -19,8 +19,8 @@ jobs:
19
19
  max-parallel: 4
20
20
  matrix:
21
21
  # Run acceptance tests all supported combinations of Ruby and ActiveRecord.
22
- ruby: [2.5, 2.6, 2.7, 3.0]
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]
22
+ ruby: [2.6, 2.7, 3.0, 3.1]
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]
24
24
  # Exclude combinations that are not supported.
25
25
  exclude:
26
26
  - ruby: 3.0
@@ -33,14 +33,22 @@ jobs:
33
33
  ar: 6.0.3.7
34
34
  - ruby: 3.0
35
35
  ar: 6.0.4
36
- - ruby: 2.5
37
- ar: 7.0.2.4
36
+ - ruby: 3.1
37
+ ar: 6.0.0
38
+ - ruby: 3.1
39
+ ar: 6.0.1
40
+ - ruby: 3.1
41
+ ar: 6.0.2.2
42
+ - ruby: 3.1
43
+ ar: 6.0.3.7
44
+ - ruby: 3.1
45
+ ar: 6.0.4
38
46
  - ruby: 2.6
39
47
  ar: 7.0.2.4
40
- - ruby: 2.5
41
- ar: 7.0.3.1
42
48
  - ruby: 2.6
43
49
  ar: 7.0.3.1
50
+ - ruby: 2.6
51
+ ar: 7.0.4
44
52
  env:
45
53
  AR_VERSION: ${{ matrix.ar }}
46
54
  steps:
@@ -11,8 +11,8 @@ jobs:
11
11
  max-parallel: 4
12
12
  matrix:
13
13
  # Run unit tests all supported combinations of Ruby and ActiveRecord.
14
- ruby: [2.5, 2.6, 2.7, 3.0]
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]
14
+ ruby: [2.6, 2.7, 3.0, 3.1]
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]
16
16
  # Exclude combinations that are not supported.
17
17
  exclude:
18
18
  - ruby: 3.0
@@ -25,14 +25,22 @@ jobs:
25
25
  ar: 6.0.3.7
26
26
  - ruby: 3.0
27
27
  ar: 6.0.4
28
- - ruby: 2.5
29
- ar: 7.0.2.4
28
+ - ruby: 3.1
29
+ ar: 6.0.0
30
+ - ruby: 3.1
31
+ ar: 6.0.1
32
+ - ruby: 3.1
33
+ ar: 6.0.2.2
34
+ - ruby: 3.1
35
+ ar: 6.0.3.7
36
+ - ruby: 3.1
37
+ ar: 6.0.4
30
38
  - ruby: 2.6
31
39
  ar: 7.0.2.4
32
- - ruby: 2.5
33
- ar: 7.0.3.1
34
40
  - ruby: 2.6
35
41
  ar: 7.0.3.1
42
+ - ruby: 2.6
43
+ ar: 7.0.4
36
44
  env:
37
45
  AR_VERSION: ${{ matrix.ar }}
38
46
  steps:
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.2.2"
2
+ ".": "1.4.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ### 1.4.0 (2023-01-18)
4
+
5
+ #### Features
6
+
7
+ * dropped support for Ruby 2.5 ([#236](https://github.com/googleapis/ruby-spanner-activerecord/issues/236))
8
+
9
+ ### 1.3.1 (2022-12-15)
10
+
11
+ #### Bug Fixes
12
+
13
+ * build error for ruby 2.5 ([#216](https://github.com/googleapis/ruby-spanner-activerecord/issues/216))
14
+
15
+ ### 1.3.0 (2022-12-08)
16
+
17
+ #### Features
18
+
19
+ * add check constraint support to migrations ([#205](https://github.com/googleapis/ruby-spanner-activerecord/issues/205))
20
+ * allows passing of type parameter when creating parent_key column ([#195](https://github.com/googleapis/ruby-spanner-activerecord/issues/195))
21
+ * include index options in the output of SchemaDumper ([#203](https://github.com/googleapis/ruby-spanner-activerecord/issues/203))
22
+ * schema_dumper should use DDL batch ([#207](https://github.com/googleapis/ruby-spanner-activerecord/issues/207))
23
+ * support column DEFAULT expressions in migrations ([#196](https://github.com/googleapis/ruby-spanner-activerecord/issues/196))
24
+ #### Bug Fixes
25
+
26
+ * ignore no database when recreating ([#208](https://github.com/googleapis/ruby-spanner-activerecord/issues/208))
27
+ #### Documentation
28
+
29
+ * fix typo in example of interleaved-tables ([#209](https://github.com/googleapis/ruby-spanner-activerecord/issues/209))
30
+
3
31
  ### 1.2.2 (2022-08-29)
4
32
 
5
33
  #### Documentation
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ 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.15.0"
7
+ gem "minitest", "~> 5.16.3"
8
8
  gem "pry", "~> 0.13.0"
9
9
  gem "pry-byebug", "~> 3.9.0"
10
10
 
data/README.md CHANGED
@@ -13,6 +13,9 @@ This project provides a Cloud Spanner adapter for ActiveRecord. It supports the
13
13
  Known limitations are listed in the [Limitations](#limitations) section.
14
14
  Please report any problems that you might encounter by [creating a new issue](https://github.com/googleapis/ruby-spanner-activerecord/issues/new).
15
15
 
16
+ This adapter only supports GoogleSQL-dialect Cloud Spanner databases. PostgreSQL-dialect
17
+ databases are not supported.
18
+
16
19
  ## Installation
17
20
 
18
21
  Add this line to your application's Gemfile:
@@ -83,6 +86,7 @@ Table without Primary Key| Cloud Spanner support does not support tables without
83
86
  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.
84
87
  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.
85
88
  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.
89
+ 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.
86
90
 
87
91
  ## Contributing
88
92
 
@@ -30,77 +30,87 @@ module ActiveRecord
30
30
 
31
31
  def test_remove_references_column_type_with_polymorphic_removes_type
32
32
  with_change_table do |t|
33
- @connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true]
33
+ @connection.expect :remove_reference, nil, [:delete_me, :taggable], polymorphic: true
34
34
  t.remove_references :taggable, polymorphic: true
35
35
  end
36
36
  end
37
37
 
38
38
  def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
39
39
  with_change_table do |t|
40
- @connection.expect :add_reference, nil, [:delete_me, :taggable, polymorphic: true, null: false]
40
+ @connection.expect :add_reference, nil, [:delete_me, :taggable], polymorphic: true, null: false
41
41
  t.references :taggable, polymorphic: true, null: false
42
42
  end
43
43
  end
44
44
 
45
45
  def test_remove_references_column_type_with_polymorphic_and_options_null_is_false_removes_table_flag
46
46
  with_change_table do |t|
47
- @connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true, null: false]
47
+ @connection.expect :remove_reference, nil, [:delete_me, :taggable], polymorphic: true, null: false
48
48
  t.remove_references :taggable, polymorphic: true, null: false
49
49
  end
50
50
  end
51
51
 
52
52
  def test_references_column_type_with_polymorphic_and_type
53
53
  with_change_table do |t|
54
- @connection.expect :add_reference, nil, [:delete_me, :taggable, polymorphic: true, type: :string]
54
+ @connection.expect :add_reference, nil, [:delete_me, :taggable], polymorphic: true, type: :string
55
55
  t.references :taggable, polymorphic: true, type: :string
56
56
  end
57
57
  end
58
58
 
59
59
  def test_remove_references_column_type_with_polymorphic_and_type
60
60
  with_change_table do |t|
61
- @connection.expect :remove_reference, nil, [:delete_me, :taggable, polymorphic: true, type: :string]
61
+ @connection.expect :remove_reference, nil, [:delete_me, :taggable], polymorphic: true, type: :string
62
62
  t.remove_references :taggable, polymorphic: true, type: :string
63
63
  end
64
64
  end
65
65
 
66
66
  def test_timestamps_creates_updated_at_and_created_at
67
67
  with_change_table do |t|
68
- @connection.expect :add_timestamps, nil, [:delete_me, null: true]
68
+ @connection.expect :add_timestamps, nil, [:delete_me], null: true
69
69
  t.timestamps null: true
70
70
  end
71
71
  end
72
72
 
73
73
  def test_remove_timestamps_creates_updated_at_and_created_at
74
74
  with_change_table do |t|
75
- @connection.expect :remove_timestamps, nil, [:delete_me, { null: true }]
75
+ @connection.expect :remove_timestamps, nil, [:delete_me], null: true
76
76
  t.remove_timestamps(null: true)
77
77
  end
78
78
  end
79
79
 
80
80
  def test_primary_key_creates_primary_key_column
81
81
  with_change_table do |t|
82
- @connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
82
+ @connection.expect :add_column, nil, [:delete_me, :id, :primary_key], primary_key: true, first: true
83
83
  t.primary_key :id, first: true
84
84
  end
85
85
  end
86
86
 
87
87
  def test_index_exists
88
88
  with_change_table do |t|
89
- @connection.expect :index_exists?, nil, [:delete_me, :bar, {}]
90
- t.index_exists?(:bar)
89
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3")
90
+ @connection.expect :index_exists?, nil, [:delete_me, :bar, {}]
91
+ t.index_exists?(:bar, {})
92
+ else
93
+ @connection.expect :index_exists?, nil, [:delete_me, :bar]
94
+ t.index_exists?(:bar)
95
+ end
91
96
  end
92
97
  end
93
98
 
94
99
  def test_index_exists_with_options
95
100
  with_change_table do |t|
96
- @connection.expect :index_exists?, nil, [:delete_me, :bar, { unique: true }]
97
- t.index_exists?(:bar, unique: true)
101
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3")
102
+ @connection.expect :index_exists?, nil, [:delete_me, :bar, {unique: true}]
103
+ t.index_exists?(:bar, {unique: true})
104
+ else
105
+ @connection.expect :index_exists?, nil, [:delete_me, :bar], unique: true
106
+ t.index_exists?(:bar, unique: true)
107
+ end
98
108
  end
99
109
  end
100
110
 
101
111
  def test_remove_drops_multiple_columns_when_column_options_are_given
102
112
  with_change_table do |t|
103
- @connection.expect :remove_columns, nil, [:delete_me, :bar, :baz, type: :string, null: false]
113
+ @connection.expect :remove_columns, nil, [:delete_me, :bar, :baz], type: :string, null: false
104
114
  t.remove :bar, :baz, type: :string, null: false
105
115
  end
106
116
  end
@@ -0,0 +1,69 @@
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
+
11
+ module ActiveRecord
12
+ class Migration
13
+ class IndexTest < SpannerAdapter::TestCase
14
+ include SpannerAdapter::Migration::TestHelper
15
+
16
+ def test_dump_schema_contains_start_batch_ddl
17
+ connection = ActiveRecord::Base.connection
18
+ schema = StringIO.new
19
+ ActiveRecord::SchemaDumper.dump connection, schema
20
+ assert schema.string.include?("connection.start_batch_ddl")
21
+ end
22
+
23
+ def test_dump_schema_contains_run_batch
24
+ connection = ActiveRecord::Base.connection
25
+ schema = StringIO.new
26
+ ActiveRecord::SchemaDumper.dump connection, schema
27
+ assert schema.string.include?(" connection.run_batch\n"\
28
+ "rescue\n"\
29
+ " abort_batch\n"\
30
+ " raise")
31
+ end
32
+
33
+ def test_dump_schema_contains_albums_table
34
+ connection = ActiveRecord::Base.connection
35
+ schema = StringIO.new
36
+ ActiveRecord::SchemaDumper.dump connection, schema
37
+ assert schema.string.include?("create_table \"albums\", primary_key: \"albumid\"")
38
+ end
39
+
40
+ def test_dump_schema_contains_interleaved_index
41
+ connection = ActiveRecord::Base.connection
42
+ schema = StringIO.new
43
+ ActiveRecord::SchemaDumper.dump connection, schema
44
+ assert schema.string.include?("t.index [\"singerid\", \"albumid\", \"title\"], name: \"index_tracks_on_singerid_and_albumid_and_title\", order: { singerid: :asc, albumid: :asc, title: :asc }, null_filtered: true, interleave_in: \"albums\""), schema.string
45
+ end
46
+
47
+ def test_dump_schema_should_not_contain_id_limit
48
+ connection = ActiveRecord::Base.connection
49
+ schema = StringIO.new
50
+ ActiveRecord::SchemaDumper.dump connection, schema
51
+ assert !schema.string.include?("id: { limit: 8 }")
52
+ end
53
+
54
+ def test_dump_schema_contains_commit_timestamp
55
+ connection = ActiveRecord::Base.connection
56
+ schema = StringIO.new
57
+ ActiveRecord::SchemaDumper.dump connection, schema
58
+ assert schema.string.include?("t.time \"last_updated\", allow_commit_timestamp: true"), schema.string
59
+ end
60
+
61
+ def test_dump_schema_contains_virtual_column
62
+ connection = ActiveRecord::Base.connection
63
+ schema = StringIO.new
64
+ ActiveRecord::SchemaDumper.dump connection, schema
65
+ assert schema.string.include?("t.virtual \"full_name\", type: :string, as: \"COALESCE(first_name || ' ', '') || last_name\", stored: true"), schema.string
66
+ end
67
+ end
68
+ end
69
+ end
@@ -76,13 +76,24 @@ module ActiveRecord
76
76
  end
77
77
  end
78
78
 
79
+ VERSION_7 = ActiveRecord.gem_version >= Gem::Version.create("7.0.0")
80
+
81
+ def assert_raises_below_ar_7(ex, &test)
82
+ if VERSION_7
83
+ assert_nothing_raised &test
84
+ else
85
+ assert_raises ex, &test
86
+ end
87
+ end
88
+
79
89
  def test_create_with_value_for_generated_column
80
90
  # Note: The statement itself will not fail for an explicit transaction that uses buffered transactions.
81
91
  # Instead, the commit will fail. That is tested in a separate test case.
82
92
  [nil, :serializable].each do |isolation|
83
93
  run_in_transaction isolation do
84
- assert_raises ActiveRecord::StatementInvalid do
85
- Singer.create first_name: "Pete", last_name: "Allison", full_name: "Alice Peterson"
94
+ assert_raises_below_ar_7 ActiveRecord::StatementInvalid do
95
+ singer = Singer.create first_name: "Pete", last_name: "Allison", full_name: "Alice Peterson"
96
+ assert_equal "Pete Allison", singer.reload.full_name
86
97
  end
87
98
  end
88
99
  end
@@ -90,10 +101,11 @@ module ActiveRecord
90
101
 
91
102
  def test_create_with_value_for_generated_column_buffered_mutations
92
103
  # The transaction itself will raise an error, as the failure occurs during the commit.
93
- assert_raises ActiveRecord::StatementInvalid do
94
- Singer.transaction isolation: :buffered_mutations do
104
+ assert_raises_below_ar_7 ActiveRecord::StatementInvalid do
105
+ singer = run_in_transaction :buffered_mutations do
95
106
  Singer.create first_name: "Pete", last_name: "Allison", full_name: "Alice Peterson"
96
107
  end
108
+ assert_equal "Pete Allison", singer.reload.full_name
97
109
  end
98
110
  end
99
111
 
@@ -104,10 +116,11 @@ module ActiveRecord
104
116
  singer = Singer.create first_name: "Pete", last_name: "Allison"
105
117
  singer.reload # reload to ensure the full_name attribute is populated.
106
118
  run_in_transaction isolation do
107
- assert_raises ActiveRecord::StatementInvalid do
119
+ assert_raises_below_ar_7 ActiveRecord::StatementInvalid do
108
120
  Singer.update full_name: "Alice Peterson"
109
121
  end
110
122
  end
123
+ assert_equal "Pete Allison", singer.reload.full_name
111
124
  end
112
125
  end
113
126
 
@@ -115,11 +128,12 @@ module ActiveRecord
115
128
  singer = Singer.create first_name: "Pete", last_name: "Allison"
116
129
  singer.reload # reload to ensure the full_name attribute is populated.
117
130
  # The transaction itself will raise an error, as the failure occurs during the commit.
118
- assert_raises ActiveRecord::StatementInvalid do
119
- Singer.transaction isolation: :buffered_mutations do
131
+ assert_raises_below_ar_7 ActiveRecord::StatementInvalid do
132
+ run_in_transaction :buffered_mutations do
120
133
  Singer.update full_name: "Alice Peterson"
121
134
  end
122
135
  end
136
+ assert_equal "Pete Allison", singer.reload.full_name
123
137
  end
124
138
  end
125
139
  end
@@ -0,0 +1,36 @@
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 "test_helper"
10
+ require "models/singer"
11
+ require "models/album_partial_disabled"
12
+
13
+ module ActiveRecord
14
+ module Model
15
+ class InterleaveTest < SpannerAdapter::TestCase
16
+ include SpannerAdapter::Associations::TestHelper
17
+
18
+ attr_accessor :singer
19
+
20
+ def setup
21
+ super
22
+
23
+ @singer = Singer.create first_name: "FirstName", last_name: "LastName"
24
+ end
25
+
26
+ def teardown
27
+ Album.destroy_all
28
+ Singer.destroy_all
29
+ end
30
+
31
+ def test_with_partial_inserts_disabled
32
+ AlbumPartialDisabled.create! title: "Title3", singer: singer
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,57 @@
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 "active_support/log_subscriber/test_helper"
10
+ require "test_helper"
11
+ require "models/post"
12
+
13
+ module ActiveRecord
14
+ module Model
15
+ class LoggingTest < SpannerAdapter::TestCase
16
+ include ActiveSupport::LogSubscriber::TestHelper
17
+
18
+ setup do
19
+ ActiveRecord::LogSubscriber.attach_to(:active_record)
20
+ end
21
+
22
+ def test_logs_without_binds
23
+ skip "This test sometimes fails because nothing is logged (or marked as logged by the test logger)"
24
+
25
+ published_time = Time.new(2016, 05, 11, 19, 0, 0)
26
+ Post.where(published_time: published_time, title: 'Title - 1').first
27
+
28
+ wait
29
+ assert @logger.logged(:debug).length >= 1
30
+ assert_no_match "[[\"published_time\", \"#{published_time.utc.iso8601(9)}\"], [\"title\", \"Title - 1\"]",
31
+ @logger.logged(:debug).last
32
+ end
33
+
34
+ def test_logs_with_binds
35
+ skip "This test sometimes fails because nothing is logged (or marked as logged by the test logger)"
36
+
37
+ ActiveRecord::ConnectionAdapters::SpannerAdapter.log_statement_binds = true
38
+
39
+ published_time = Time.new(2016, 05, 11, 19, 0, 0)
40
+ Post.where(published_time: published_time, title: 'Title - 1').first
41
+
42
+ wait
43
+ assert @logger.logged(:debug).length >= 1
44
+ assert_match "[[\"published_time\", \"#{published_time.utc.iso8601(9)}\"], [\"title\", \"Title - 1\"]",
45
+ @logger.logged(:debug).last
46
+ ensure
47
+ ActiveRecord::ConnectionAdapters::SpannerAdapter.log_statement_binds = false
48
+ end
49
+
50
+ private
51
+
52
+ def set_logger(logger)
53
+ ActiveRecord::Base.logger = logger
54
+ end
55
+ end
56
+ end
57
+ end
@@ -166,6 +166,11 @@ module ActiveRecord
166
166
  assert_nil post.id
167
167
  assert_equal "Title - 1", post.title
168
168
  end
169
+
170
+ def test_to_sql
171
+ assert_equal "SELECT `comments`.* FROM `comments` WHERE `comments`.`comment` = 'Comment - 2'",
172
+ Comment.where(comment: 'Comment - 2').to_sql
173
+ end
169
174
  end
170
175
  end
171
- end
176
+ end