activerecord-spanner-adapter 0.3.0 → 1.0.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 +49 -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 +55 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +79 -0
- data/Gemfile +9 -4
- data/LICENSE +6 -6
- data/README.md +66 -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 +171 -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 +130 -0
- data/acceptance/cases/transactions/read_write_transactions_test.rb +248 -0
- data/acceptance/cases/type/all_types_test.rb +172 -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/json_test.rb +34 -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 +147 -0
- data/acceptance/test_helper.rb +261 -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/hints/README.md +19 -0
- data/examples/snippets/hints/Rakefile +13 -0
- data/examples/snippets/hints/application.rb +47 -0
- data/examples/snippets/hints/config/database.yml +8 -0
- data/examples/snippets/hints/db/migrate/01_create_tables.rb +23 -0
- data/examples/snippets/hints/db/schema.rb +28 -0
- data/examples/snippets/hints/db/seeds.rb +29 -0
- data/examples/snippets/hints/models/album.rb +9 -0
- data/examples/snippets/hints/models/singer.rb +9 -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/partitioned-dml/README.md +16 -0
- data/examples/snippets/partitioned-dml/Rakefile +13 -0
- data/examples/snippets/partitioned-dml/application.rb +48 -0
- data/examples/snippets/partitioned-dml/config/database.yml +8 -0
- data/examples/snippets/partitioned-dml/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/partitioned-dml/db/schema.rb +26 -0
- data/examples/snippets/partitioned-dml/db/seeds.rb +29 -0
- data/examples/snippets/partitioned-dml/models/album.rb +9 -0
- data/examples/snippets/partitioned-dml/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 +77 -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/stale-reads/README.md +27 -0
- data/examples/snippets/stale-reads/Rakefile +13 -0
- data/examples/snippets/stale-reads/application.rb +63 -0
- data/examples/snippets/stale-reads/config/database.yml +8 -0
- data/examples/snippets/stale-reads/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/stale-reads/db/schema.rb +26 -0
- data/examples/snippets/stale-reads/db/seeds.rb +24 -0
- data/examples/snippets/stale-reads/models/album.rb +9 -0
- data/examples/snippets/stale-reads/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 +244 -266
- 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 +185 -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 +33 -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 +238 -0
- data/lib/activerecord_spanner_adapter/connection.rb +350 -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 +262 -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 +154 -0
- data/lib/activerecord_spanner_adapter/version.rb +9 -0
- data/lib/arel/visitors/spanner.rb +111 -0
- data/lib/spanner_client_ext.rb +107 -0
- data/renovate.json +5 -0
- metadata +405 -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,24 @@
|
|
|
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
|
+
require_relative "../../config/environment.rb"
|
|
8
|
+
require_relative "../models/singer"
|
|
9
|
+
require_relative "../models/album"
|
|
10
|
+
|
|
11
|
+
first_names = ["Pete", "Alice", "John", "Ethel", "Trudy", "Naomi", "Wendy", "Ruben", "Thomas", "Elly"]
|
|
12
|
+
last_names = ["Wendelson", "Allison", "Peterson", "Johnson", "Henderson", "Ericsson", "Aronson", "Tennet", "Courtou"]
|
|
13
|
+
|
|
14
|
+
adjectives = ["daily", "happy", "blue", "generous", "cooked", "bad", "open"]
|
|
15
|
+
nouns = ["windows", "potatoes", "bank", "street", "tree", "glass", "bottle"]
|
|
16
|
+
|
|
17
|
+
5.times do
|
|
18
|
+
Singer.create first_name: first_names.sample, last_name: last_names.sample
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
20.times do
|
|
22
|
+
singer_id = Singer.all.sample.id
|
|
23
|
+
Album.create title: "#{adjectives.sample} #{nouns.sample}", singer_id: singer_id
|
|
24
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Sample - Timestamp Data Type
|
|
2
|
+
|
|
3
|
+
This example shows how to use the `TIMESTAMP` data type with the Spanner ActiveRecord adapter. A `TIMESTAMP` represents
|
|
4
|
+
a specific point in time. Cloud Spanner always stores the timestamp in UTC, and it is not possible to include a
|
|
5
|
+
specific timezone in a timestamp value in Cloud Spanner. Instead, a separate column containing a timezone can be used
|
|
6
|
+
if your application needs to store both a timestamp and a timezone. This sample shows how to do this.
|
|
7
|
+
|
|
8
|
+
## Running the Sample
|
|
9
|
+
|
|
10
|
+
The sample will automatically start a Spanner Emulator in a docker container and execute the sample
|
|
11
|
+
against that emulator. The emulator will automatically be stopped when the application finishes.
|
|
12
|
+
|
|
13
|
+
Run the application with the command
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle exec rake run
|
|
17
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
require_relative "../config/environment"
|
|
8
|
+
require "sinatra/activerecord/rake"
|
|
9
|
+
|
|
10
|
+
desc "Sample showing how to work with the TIMESTAMP data type in ActiveRecord."
|
|
11
|
+
task :run do
|
|
12
|
+
Dir.chdir("..") { sh "bundle exec rake run[timestamp-data-type]" }
|
|
13
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
require "io/console"
|
|
8
|
+
require_relative "../config/environment"
|
|
9
|
+
require_relative "models/meeting"
|
|
10
|
+
|
|
11
|
+
class Application
|
|
12
|
+
def self.run
|
|
13
|
+
# Set the default local timezone.
|
|
14
|
+
Time.zone = "Europe/Lisbon"
|
|
15
|
+
|
|
16
|
+
# Create a meeting using the local timezone. The timezone information will not be stored in the `meeting_time`
|
|
17
|
+
# column in the database, which is why we also include a separate column where we can store the timezone name.
|
|
18
|
+
meeting_time = Time.zone.local 2021, 7, 1, 10, 30, 0
|
|
19
|
+
meeting = Meeting.create title: "Standup", meeting_time: meeting_time, meeting_timezone: Time.zone.name
|
|
20
|
+
|
|
21
|
+
# The meeting_time is saved in UTC in Cloud Spanner. Reloading it will therefore lose the timezone information in
|
|
22
|
+
# the meeting_time attribute. It is however stored in the separate meeting_timezone attribute, and that can be used
|
|
23
|
+
# to reconstruct the meeting_time in the timezone where the meeting was planned.
|
|
24
|
+
# The Meeting model class also contains two helper methods:
|
|
25
|
+
# 1. `local_meeting_time`: Returns the meeting_time in the local timezone.
|
|
26
|
+
# 2. `meeting_time_in_planned_zone`: Returns the meeting_time in the timezone where it is planned.
|
|
27
|
+
meeting.reload
|
|
28
|
+
puts ""
|
|
29
|
+
puts "#{'Meeting time in UTC:'.ljust 60} #{meeting.meeting_time}"
|
|
30
|
+
puts "#{'Meeting time in the timezone where it was planned:'.ljust 60} #{meeting.meeting_time_in_planned_zone}"
|
|
31
|
+
|
|
32
|
+
# Simulate that the application is now running in the timezone America/Los_Angeles.
|
|
33
|
+
Time.zone = "America/Los_Angeles"
|
|
34
|
+
puts "#{'Meeting time in the local timezone (America/Los_Angeles):'.ljust 60} #{meeting.local_meeting_time}"
|
|
35
|
+
|
|
36
|
+
puts ""
|
|
37
|
+
puts "Press any key to end the application"
|
|
38
|
+
STDIN.getch
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Application.run
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
class CreateTables < ActiveRecord::Migration[6.0]
|
|
8
|
+
def change
|
|
9
|
+
connection.ddl_batch do
|
|
10
|
+
create_table :meetings do |t|
|
|
11
|
+
t.string :title
|
|
12
|
+
# A `TIMESTAMP` column in Cloud Spanner contains a date/time value that designates a specific point in time. The
|
|
13
|
+
# value is always stored in UTC. If you specify a date/time value in a different timezone, the value is
|
|
14
|
+
# converted to UTC when saving it to the database. You can use a separate column to store the timezone of the
|
|
15
|
+
# timestamp if that is vital for your application, and use that information when the timestamp is read back.
|
|
16
|
+
t.datetime :meeting_time
|
|
17
|
+
t.string :meeting_timezone
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
|
4
|
+
#
|
|
5
|
+
# This file is the source Rails uses to define your schema when running `rails
|
|
6
|
+
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
|
|
7
|
+
# be faster and is potentially less error prone than running all of your
|
|
8
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
|
9
|
+
# migrations use external dependencies or application code.
|
|
10
|
+
#
|
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
|
12
|
+
|
|
13
|
+
ActiveRecord::Schema.define(version: 1) do
|
|
14
|
+
|
|
15
|
+
create_table "meetings", force: :cascade do |t|
|
|
16
|
+
t.string "title"
|
|
17
|
+
t.time "meeting_time"
|
|
18
|
+
t.string "meeting_timezone"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
class Meeting < ActiveRecord::Base
|
|
8
|
+
# Returns the meeting time in the local timezone.
|
|
9
|
+
def local_meeting_time
|
|
10
|
+
return unless meeting_time && Time.zone
|
|
11
|
+
meeting_time.in_time_zone Time.zone
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the time of the meeting in the timezone where the meeting is planned.
|
|
15
|
+
def meeting_time_in_planned_zone
|
|
16
|
+
return unless meeting_time && meeting_timezone
|
|
17
|
+
meeting_time.in_time_zone meeting_timezone
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
## activerecord-spanner-adapter on Solidus
|
|
2
|
+
|
|
3
|
+
This example shows how to use activerecord-spanner-adapter for Cloud Spanner as a backend database for https://solidus.io.
|
|
4
|
+
|
|
5
|
+
#### Table of contents
|
|
6
|
+
- [Ensure you have a Cloud Spanner database already created](#ensure-you-have-a-Cloud-Spanner-database-already-created)
|
|
7
|
+
- [Create a Rails application and install Solidus](#create-a-rails-application-and-install-solidus)
|
|
8
|
+
- [Update database.yml](#update-database.yml)
|
|
9
|
+
- [Create application database](#create-application-database)
|
|
10
|
+
- [Apply the migrations](#apply-the-migrations)
|
|
11
|
+
- [Go view the results on Cloud Spanner UI](#go-view-the-results-on-Cloud-Spanner-UI)
|
|
12
|
+
- [Run the application](#run-the-application)
|
|
13
|
+
- [References](#references)
|
|
14
|
+
|
|
15
|
+
### Ensure you have a Cloud Spanner database already created
|
|
16
|
+
If you haven't already, please follow the steps to install [Cloud Spanner](https://cloud.google.com/spanner/docs/getting-started/set-up),
|
|
17
|
+
or visit this [codelab](https://opencensus.io/codelabs/spanner/#0)
|
|
18
|
+
|
|
19
|
+
**You'll need to ensure that your Google Application Default Credentials are properly downloaded and saved in your environment.**
|
|
20
|
+
|
|
21
|
+
### Create a Rails application and install Solidus
|
|
22
|
+
|
|
23
|
+
Create a Rails application.
|
|
24
|
+
```shell
|
|
25
|
+
rails new e-store
|
|
26
|
+
cd e-store
|
|
27
|
+
```
|
|
28
|
+
Add `solidus` and `activerecord-spanner-adapter` gem to Gemfile.
|
|
29
|
+
|
|
30
|
+
Gemfile
|
|
31
|
+
```ruby
|
|
32
|
+
gem 'solidus'
|
|
33
|
+
gem 'activerecord-spanner-adapter', git: 'https://github.com/orijtech/activerecord-spanner-adapter.git'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```shell
|
|
37
|
+
bundle install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Use Cloud Spanner adapter in Gemfile
|
|
41
|
+
Edit Gemfile file and add `activerecord-spanner-adapter` gem.
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
gem 'activerecord-spanner-adapter', git: 'https://github.com/orijtech/activerecord-spanner-adapter.git'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Install gems.
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
bundle install
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
After installing gems, you'll have to run the generator to create necessary configuration files and migrations.
|
|
54
|
+
|
|
55
|
+
```shell
|
|
56
|
+
bin/rails g spree:install
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Update database.yml
|
|
60
|
+
|
|
61
|
+
Update `db/database.yml` to use `activerecord-spanner-adapter`
|
|
62
|
+
|
|
63
|
+
After we have a Cloud Spanner database created, we'll need a few variables:
|
|
64
|
+
* Project id
|
|
65
|
+
* Instance id
|
|
66
|
+
* Database name
|
|
67
|
+
* Credential: Credential keyfile path or Export `GOOGLE_CLOUD_KEYFILE`environment variable.
|
|
68
|
+
|
|
69
|
+
Once in, please edit the file `config/database.yml` and make the section `DATABASES` into the following:
|
|
70
|
+
|
|
71
|
+
```yml
|
|
72
|
+
default: &default
|
|
73
|
+
adapter: "spanner"
|
|
74
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 10 } %>
|
|
75
|
+
project: PROJECT_ID
|
|
76
|
+
instance: SPANNER_INSTANCE_ID
|
|
77
|
+
credentials: SPANNER_PROJECT_KEYFILE
|
|
78
|
+
|
|
79
|
+
development:
|
|
80
|
+
<<: *default
|
|
81
|
+
database: e-store-dev
|
|
82
|
+
|
|
83
|
+
test:
|
|
84
|
+
<<: *default
|
|
85
|
+
database: e-store-test
|
|
86
|
+
|
|
87
|
+
production:
|
|
88
|
+
<<: *default
|
|
89
|
+
database: e-store
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
and for example here is a filled in database where:
|
|
93
|
+
|
|
94
|
+
* `PROJECT_ID`: spanner-appdev
|
|
95
|
+
* `SPANNER_INSTANCE_ID`: instance
|
|
96
|
+
* `SPANNER_PROJECT_KEYFILE`: credentials key file path. i.e "/app/keyfile.json".
|
|
97
|
+
|
|
98
|
+
### Create application database
|
|
99
|
+
|
|
100
|
+
Please run:
|
|
101
|
+
```shell
|
|
102
|
+
$ ./bin/rails db:create
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```shell
|
|
106
|
+
Created database e-store-dev
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Apply the migrations
|
|
110
|
+
Please run:
|
|
111
|
+
```shell
|
|
112
|
+
$ ./bin/rails db:migrate
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
and that'll take a while running, it will look like the following
|
|
116
|
+
|
|
117
|
+
<details>
|
|
118
|
+
|
|
119
|
+
```shell
|
|
120
|
+
$ ./bin/rails db:migrate
|
|
121
|
+
== 20200410055855 CreateActiveStorageTables: migrating ========================
|
|
122
|
+
-- create_table(:active_storage_blobs, {})
|
|
123
|
+
-> 0.0011s
|
|
124
|
+
-- create_table(:active_storage_attachments, {})
|
|
125
|
+
-> 0.0010s
|
|
126
|
+
== 20200410055855 CreateActiveStorageTables: migrated (0.0023s) ===============
|
|
127
|
+
|
|
128
|
+
..... MANY MORE MIGRATION LOG LINES
|
|
129
|
+
```
|
|
130
|
+
</details>
|
|
131
|
+
|
|
132
|
+
### Go view the results on Cloud Spanner UI
|
|
133
|
+
|
|
134
|
+
To double check that the respective tables and migrations were performed, please go visit the page with your database on Cloud Spanner's UI. For example it should look like this
|
|
135
|
+
|
|
136
|
+

|
|
137
|
+
|
|
138
|
+
### Run the application
|
|
139
|
+
After those migrations run application server.
|
|
140
|
+
|
|
141
|
+
```shell
|
|
142
|
+
./bin/rails s
|
|
143
|
+
```
|
|
144
|
+
<details>
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
./bin/rails s
|
|
148
|
+
Puma starting in single mode...
|
|
149
|
+
* Version 4.3.3 (ruby 2.6.3-p62), codename: Mysterious Traveller
|
|
150
|
+
* Min threads: 5, max threads: 5
|
|
151
|
+
* Environment: development
|
|
152
|
+
* Listening on tcp://127.0.0.1:3000
|
|
153
|
+
* Listening on tcp://[::1]:3000
|
|
154
|
+
Use Ctrl-C to stop
|
|
155
|
+
Started GET "/" for ::1 at 2020-04-10 11:42:00 +0530
|
|
156
|
+
(563.0ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
|
|
157
|
+
Processing by Spree::HomeController#index as HTML
|
|
158
|
+
Spree::Store Load (507.9ms) SELECT `spree_stores`.* FROM `spree_stores` WHERE (`spree_stores`.`url` = 'localhost' OR `spree_stores`.`default` = TRUE) ORDER BY `spree_stores`.`default` ASC LIMIT 1
|
|
159
|
+
Rendering /Users/jiren/work/spanner_orm/solidus/frontend/app/views/spree/home/index.html.erb within spree/layouts/spree_application
|
|
160
|
+
Spree::Taxonomy Load (571.6ms) SELECT `spree_taxonomies`.* FROM `spree_taxonomies` ORDER BY `spree_taxonomies`.`position` ASC
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
</details>
|
|
164
|
+
|
|
165
|
+
### References
|
|
166
|
+
|
|
167
|
+
Resource|URL
|
|
168
|
+
---|---
|
|
169
|
+
Solidus application|https://solidus.io/
|
|
170
|
+
Solidus application source code|https://github.com/solidusio/solidus
|
|
171
|
+
Cloud Spanner homepage|https://cloud.google.com/spanner/
|
|
172
|
+
activerecord-spanner-adapter project's source code|https://github.com/orijtech/activerecord-spanner-adapter
|