activerecord-spanner-adapter 1.6.1 → 1.6.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 931e6b17bf3e6d6b068c57ca879bc0dbb06933790101aa05415514c6448fd004
4
- data.tar.gz: c4981e814899be433830e0380f69060dfa589ec39dfa7e831aad616e224030ec
3
+ metadata.gz: 2c2a9a0a36a471ac93bdb0d59e50cc9b8e5c6647655487dc55a1d9e398abcf46
4
+ data.tar.gz: de680bcac6cf0f491bd0007d80d48496cf5e74b5eddf17d13b58353f06b818da
5
5
  SHA512:
6
- metadata.gz: a989bdd8195d98206802a05294b09a53fe76c0684fba781d22dc15aaa5a38106ee3f193555cbe83e5f65254e3b39d95ed1cfb6445ded245ad80683d9752fdfd2
7
- data.tar.gz: 0dbe1209ccad8da313fafb110bbb4fb2c1ef9ff9209230e88673f031ad02c0c372a13422fd2a5756fb0bc97a2318c003433350e071f64bcef37ba5a7754e868e
6
+ metadata.gz: '0658d456b4d6377bf5f95f44296869404ac9ac1c65aaa25360080bab1df7c122c4b7aba28992f5030e6465e51fefa1b6630a4e79547c65446edd29c40954ca61'
7
+ data.tar.gz: 470e026052a753f08d59f2824044894afe84d5601735270250c09368c7541ef98d5356a6ca6810c10755033a81601afb40826656967bdf8cda132563a2e9b267
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.6.1"
2
+ ".": "1.6.3"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ### 1.6.3 (2024-08-31)
4
+
5
+ #### Bug Fixes
6
+
7
+ * a few Ruby DSL schema dump bug fixes ([#308](https://github.com/googleapis/ruby-spanner-activerecord/issues/308))
8
+ #### Documentation
9
+
10
+ * update bit-reversed sequence sample ([#303](https://github.com/googleapis/ruby-spanner-activerecord/issues/303))
11
+
12
+ ### 1.6.2 (2024-02-19)
13
+
14
+ #### Bug Fixes
15
+
16
+ * failed to convert active model type to spanner type under certain condition ([#299](https://github.com/googleapis/ruby-spanner-activerecord/issues/299))
17
+
3
18
  ### 1.6.1 (2024-02-05)
4
19
 
5
20
  #### Bug Fixes
data/Gemfile CHANGED
@@ -4,12 +4,12 @@ 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.20.0"
7
+ gem "minitest", "~> 5.25.0"
8
8
  gem "minitest-rg", "~> 5.3.0"
9
9
  gem "pry", "~> 0.13.0"
10
10
  gem "pry-byebug", "~> 3.9.0"
11
11
  # Add sqlite3 for testing for compatibility with other adapters.
12
- gem "sqlite3"
12
+ gem 'sqlite3', '~> 1.4'
13
13
 
14
14
  # Required for samples and testing.
15
15
  install_if -> { ENV.fetch("AR_VERSION", "~> 6.1.6.1").dup.to_s.sub("~>", "").strip < "7.1.0" && !ENV["SKIP_COMPOSITE_PK"] } do
data/README.md CHANGED
@@ -77,6 +77,7 @@ __NOTE__: You do need to have [Docker](https://docs.docker.com/get-docker/) inst
77
77
  Some noteworthy examples in the snippets directory:
78
78
  - [quickstart](examples/snippets/quickstart): A simple application that shows how to create and query a simple database containing two tables.
79
79
  - [migrations](examples/snippets/migrations): Shows a best-practice for executing migrations on Cloud Spanner.
80
+ - [bit-reversed-sequences](examples/snippets/bit-reversed-sequence): Shows how to use bit-reversed sequences for primary keys.
80
81
  - [read-write-transactions](examples/snippets/read-write-transactions): Shows how to execute transactions on Cloud Spanner.
81
82
  - [read-only-transactions](examples/snippets/read-only-transactions): Shows how to execute read-only transactions on Cloud Spanner.
82
83
  - [bulk-insert](examples/snippets/bulk-insert): Shows the best way to insert a large number of new records.
@@ -73,6 +73,20 @@ module ActiveRecord
73
73
  ActiveRecord::SchemaDumper.dump connection, schema
74
74
  assert schema.string.include?("t.virtual \"full_name\", type: :string, as: \"COALESCE(first_name || ' ', '') || last_name\", stored: true"), schema.string
75
75
  end
76
+
77
+ def test_dump_schema_contains_string_array
78
+ connection = ActiveRecord::Base.connection
79
+ schema = StringIO.new
80
+ ActiveRecord::SchemaDumper.dump connection, schema
81
+ assert schema.string.include?("t.string \"col_array_string\", array: true"), schema.string
82
+ end
83
+
84
+ def test_dump_schema_index_storing
85
+ connection = ActiveRecord::Base.connection
86
+ schema = StringIO.new
87
+ ActiveRecord::SchemaDumper.dump connection, schema
88
+ assert schema.string.include?("t.index [\"last_name\"], name: \"index_singers_on_last_name\", order: { last_name: :asc }, storing: [\"first_name\", \"tracks_count\"]"), schema.string
89
+ end
76
90
  end
77
91
  end
78
92
  end
@@ -226,6 +226,7 @@ CREATE TABLE singers (
226
226
  lock_version INT64,
227
227
  full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
228
228
  ) PRIMARY KEY(singerid);
229
+ CREATE INDEX index_singers_on_last_name ON singers(last_name) STORING (tracks_count, first_name);
229
230
  CREATE TABLE albums (
230
231
  albumid INT64 NOT NULL,
231
232
  singerid INT64 NOT NULL,
@@ -383,6 +384,7 @@ CREATE TABLE singers (
383
384
  lock_version INT64,
384
385
  full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
385
386
  ) PRIMARY KEY(singerid);
387
+ CREATE INDEX index_singers_on_last_name ON singers(last_name) STORING (tracks_count, first_name);
386
388
  CREATE TABLE albums (
387
389
  singerid INT64 NOT NULL,
388
390
  albumid INT64 NOT NULL,
@@ -547,6 +549,7 @@ CREATE TABLE singers (
547
549
  lock_version INT64,
548
550
  full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
549
551
  ) PRIMARY KEY(singerid);
552
+ CREATE INDEX index_singers_on_last_name ON singers(last_name) STORING (tracks_count, first_name);
550
553
  CREATE TABLE albums (
551
554
  albumid INT64 NOT NULL,
552
555
  singerid INT64 NOT NULL,
@@ -707,6 +710,7 @@ CREATE TABLE singers (
707
710
  lock_version INT64,
708
711
  full_name STRING(MAX) AS (COALESCE(first_name || ' ', '') || last_name) STORED,
709
712
  ) PRIMARY KEY(singerid);
713
+ CREATE INDEX index_singers_on_last_name ON singers(last_name) STORING (tracks_count, first_name);
710
714
  CREATE TABLE albums (
711
715
  singerid INT64 NOT NULL,
712
716
  albumid INT64 NOT NULL,
@@ -126,6 +126,7 @@ def create_tables_in_test_schema
126
126
  t.integer :lock_version
127
127
  t.virtual :full_name, type: :string, as: "COALESCE(first_name || ' ', '') || last_name", stored: true
128
128
  end
129
+ add_index :singers, :last_name, storing: %i[tracks_count first_name]
129
130
 
130
131
  if is_7_1_or_higher?
131
132
  create_table :albums, primary_key: [:singerid, :albumid] do |t|
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
25
25
  spec.required_ruby_version = ">= 2.7"
26
26
 
27
27
  spec.add_dependency "google-cloud-spanner", "~> 2.18"
28
+ # Pin gRPC to 1.64.3, as 1.65 and 1.66 cause test runs to hang randomly.
29
+ spec.add_dependency "grpc", "1.64.3"
28
30
  spec.add_runtime_dependency "activerecord", [">= 6.0.0", "< 7.2"]
29
31
 
30
32
  spec.add_development_dependency "autotest-suffix", "~> 1.1"
@@ -5,6 +5,12 @@ This example shows how to use a bit-reversed sequence to generate the primary ke
5
5
  See https://cloud.google.com/spanner/docs/primary-key-default-value#bit-reversed-sequence for more information
6
6
  about bit-reversed sequences in Cloud Spanner.
7
7
 
8
+ ## Requirements
9
+ Using bit-reversed sequences for generating primary key values in ActiveRecord has the following requirements:
10
+ 1. You must use __ActiveRecord version 7.1 or higher__.
11
+ 2. Your models must include a sequence name like this: `self.sequence_name = :singer_sequence`
12
+ 3. You must create the bit-reversed sequence using a SQL statement in your migrations.
13
+
8
14
  ## Creating Tables with Bit-Reversed Sequences in ActiveRecord
9
15
  You can create bit-reversed sequences using migrations in ActiveRecord by executing a SQL statement using the underlying
10
16
  connection.
@@ -8,15 +8,12 @@ class CreateTables < ActiveRecord::Migration[7.1]
8
8
  def change
9
9
  # Execute the entire migration as one DDL batch.
10
10
  connection.ddl_batch do
11
- # TODO: Uncomment when bit-reversed sequences are supported in the emulator.
12
- # connection.execute "create sequence singer_sequence OPTIONS (sequence_kind = 'bit_reversed_positive')"
11
+ connection.execute "create sequence singer_sequence OPTIONS (sequence_kind = 'bit_reversed_positive')"
13
12
 
14
13
  # Explicitly define the primary key.
15
14
  create_table :singers, id: false, primary_key: :singerid do |t|
16
- # TODO: Uncomment when bit-reversed sequences are supported in the emulator.
17
- # t.integer :singerid, primary_key: true, null: false,
18
- # default: -> { "GET_NEXT_SEQUENCE_VALUE(SEQUENCE singer_sequence)" }
19
- t.integer :singerid, primary_key: true, null: false, default: -> { "FARM_FINGERPRINT(GENERATE_UUID())" }
15
+ t.integer :singerid, primary_key: true, null: false,
16
+ default: -> { "GET_NEXT_SEQUENCE_VALUE(SEQUENCE singer_sequence)" }
20
17
  t.string :first_name
21
18
  t.string :last_name
22
19
  end
@@ -19,7 +19,7 @@ ActiveRecord::Schema[7.1].define(version: 1) do
19
19
  t.string "title"
20
20
  end
21
21
 
22
- create_table "singers", primary_key: "singerid", default: -> { "FARM_FINGERPRINT(GENERATE_UUID())" }, force: :cascade do |t|
22
+ create_table "singers", primary_key: "singerid", default: -> { "GET_NEXT_SEQUENCE_VALUE(SEQUENCE singer_sequence)" }, force: :cascade do |t|
23
23
  t.string "first_name"
24
24
  t.string "last_name"
25
25
  end
@@ -27,6 +27,8 @@ module ActiveRecord
27
27
  spec = { type: schema_type(column).inspect }.merge! spec
28
28
  end
29
29
 
30
+ spec[:array] = true if column.sql_type.start_with? "ARRAY<"
31
+
30
32
  spec
31
33
  end
32
34
 
@@ -54,7 +56,7 @@ module ActiveRecord
54
56
  index_parts = super
55
57
  index_parts << "null_filtered: #{index.null_filtered.inspect}" if index.null_filtered
56
58
  index_parts << "interleave_in: #{index.interleave_in.inspect}" if index.interleave_in
57
- index_parts << "storing: #{format_index_parts index.storing}" if index.storing.present?
59
+ index_parts << "storing: #{format_index_parts index.storing.sort}" if index.storing.present?
58
60
  index_parts
59
61
  end
60
62
 
@@ -23,6 +23,9 @@ module ActiveRecord
23
23
  ##
24
24
  # Converts an ActiveModel::Type to a Spanner type code.
25
25
  def self.convert_active_model_type_to_spanner type # rubocop:disable Metrics/CyclomaticComplexity
26
+ # Unwrap the underlying object if the type is a DelegateClass.
27
+ type = type.__getobj__ if type.respond_to? :__getobj__
28
+
26
29
  case type
27
30
  when NilClass then nil
28
31
  when ActiveModel::Type::Integer, ActiveModel::Type::BigInteger then :INT64
@@ -5,5 +5,5 @@
5
5
  # https://opensource.org/licenses/MIT.
6
6
 
7
7
  module ActiveRecordSpannerAdapter
8
- VERSION = "1.6.1".freeze
8
+ VERSION = "1.6.3".freeze
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-spanner-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google LLC
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-06 00:00:00.000000000 Z
11
+ date: 2024-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-spanner
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: grpc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.64.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.64.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: activerecord
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -230,8 +244,6 @@ files:
230
244
  - ".github/workflows/nightly-acceptance-tests-on-emulator.yaml"
231
245
  - ".github/workflows/nightly-acceptance-tests-on-production.yaml"
232
246
  - ".github/workflows/nightly-unit-tests.yaml"
233
- - ".github/workflows/release-please-label.yml"
234
- - ".github/workflows/release-please.yml"
235
247
  - ".github/workflows/rubocop.yaml"
236
248
  - ".gitignore"
237
249
  - ".kokoro/populate-secrets.sh"
@@ -577,7 +589,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
577
589
  - !ruby/object:Gem::Version
578
590
  version: '0'
579
591
  requirements: []
580
- rubygems_version: 3.5.3
592
+ rubygems_version: 3.5.6
581
593
  signing_key:
582
594
  specification_version: 4
583
595
  summary: Rails ActiveRecord connector for Google Spanner Database
@@ -1,25 +0,0 @@
1
- name: release-please-label
2
- on:
3
- pull_request_target:
4
- branches:
5
- - main
6
- types:
7
- - opened
8
- jobs:
9
- release-please-label:
10
- if: "${{ github.event.sender.login == 'yoshi-code-bot' && startsWith(github.event.pull_request.title, 'chore(main): release ') }}"
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: ReleaseLabel
14
- uses: actions/github-script@v7
15
- with:
16
- github-token: ${{secrets.YOSHI_APPROVER_TOKEN}}
17
- script: |
18
- core.info('Labeling release');
19
- await github.rest.issues.addLabels({
20
- owner: context.repo.owner,
21
- repo: context.repo.repo,
22
- issue_number: context.payload.pull_request.number,
23
- labels: ['autorelease: pending']
24
- });
25
- core.info('Labeled');
@@ -1,38 +0,0 @@
1
- name: Release-Please
2
- on:
3
- workflow_dispatch:
4
- inputs:
5
- gem:
6
- description: "Name of single gem to release. Leave blank to check all gems."
7
- required: false
8
- args:
9
- description: "Extra command line arguments."
10
- required: false
11
-
12
- jobs:
13
- release-please:
14
- if: ${{ github.repository == 'googleapis/ruby-spanner-activerecord' }}
15
- runs-on: ubuntu-latest
16
- env:
17
- GITHUB_TOKEN: ${{ secrets.YOSHI_CODE_BOT_TOKEN }}
18
- RELEASE_PLEASE_DISABLE: ${{ secrets.RELEASE_PLEASE_DISABLE }}
19
- steps:
20
- - name: Checkout repo
21
- uses: actions/checkout@v4
22
- - name: Install Ruby 3.0
23
- uses: ruby/setup-ruby@v1
24
- with:
25
- ruby-version: "3.0"
26
- - name: Install NodeJS 16.x
27
- uses: actions/setup-node@v4
28
- with:
29
- node-version: "16.x"
30
- - name: Install tools
31
- run: "gem install --no-document toys"
32
- - name: execute
33
- run: |
34
- toys release manifest -v \
35
- --fork --skip-labeling \
36
- --github-event-name=${{ github.event_name }} \
37
- ${{ github.event.inputs.args }} \
38
- -- ${{ github.event.inputs.gem }}