activerecord-spanner-adapter 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/acceptance-tests-on-emulator.yaml +1 -1
- data/.github/workflows/acceptance-tests-on-production.yaml +5 -3
- data/.github/workflows/ci.yaml +1 -1
- data/.github/workflows/nightly-acceptance-tests-on-emulator.yaml +1 -1
- data/.github/workflows/nightly-acceptance-tests-on-production.yaml +5 -3
- data/.github/workflows/nightly-unit-tests.yaml +1 -1
- data/.github/workflows/release-please-label.yml +1 -1
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +8 -0
- data/Gemfile +5 -2
- data/README.md +10 -10
- data/acceptance/cases/interleaved_associations/has_many_associations_using_interleaved_test.rb +6 -0
- data/acceptance/cases/migration/change_schema_test.rb +19 -3
- data/acceptance/cases/migration/schema_dumper_test.rb +10 -1
- data/acceptance/cases/models/interleave_test.rb +6 -0
- data/acceptance/cases/tasks/database_tasks_test.rb +340 -2
- data/acceptance/cases/transactions/optimistic_locking_test.rb +6 -0
- data/acceptance/cases/transactions/read_write_transactions_test.rb +24 -0
- data/acceptance/models/table_with_sequence.rb +10 -0
- data/acceptance/schema/schema.rb +65 -19
- data/acceptance/test_helper.rb +1 -1
- data/activerecord-spanner-adapter.gemspec +1 -1
- data/examples/snippets/bit-reversed-sequence/README.md +103 -0
- data/examples/snippets/bit-reversed-sequence/Rakefile +13 -0
- data/examples/snippets/bit-reversed-sequence/application.rb +68 -0
- data/examples/snippets/bit-reversed-sequence/config/database.yml +8 -0
- data/examples/snippets/bit-reversed-sequence/db/migrate/01_create_tables.rb +33 -0
- data/examples/snippets/bit-reversed-sequence/db/schema.rb +31 -0
- data/examples/snippets/bit-reversed-sequence/db/seeds.rb +31 -0
- data/examples/snippets/bit-reversed-sequence/models/album.rb +11 -0
- data/examples/snippets/bit-reversed-sequence/models/singer.rb +15 -0
- data/examples/snippets/interleaved-tables/README.md +44 -53
- data/examples/snippets/interleaved-tables/Rakefile +2 -2
- data/examples/snippets/interleaved-tables/application.rb +2 -2
- data/examples/snippets/interleaved-tables/db/migrate/01_create_tables.rb +12 -18
- data/examples/snippets/interleaved-tables/db/schema.rb +9 -7
- data/examples/snippets/interleaved-tables/db/seeds.rb +1 -1
- data/examples/snippets/interleaved-tables/models/album.rb +3 -7
- data/examples/snippets/interleaved-tables/models/singer.rb +1 -1
- data/examples/snippets/interleaved-tables/models/track.rb +6 -7
- data/examples/snippets/interleaved-tables-before-7.1/README.md +167 -0
- data/examples/snippets/interleaved-tables-before-7.1/Rakefile +13 -0
- data/examples/snippets/interleaved-tables-before-7.1/application.rb +126 -0
- data/examples/snippets/interleaved-tables-before-7.1/config/database.yml +8 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb +44 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/schema.rb +37 -0
- data/examples/snippets/interleaved-tables-before-7.1/db/seeds.rb +40 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/album.rb +20 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/singer.rb +18 -0
- data/examples/snippets/interleaved-tables-before-7.1/models/track.rb +28 -0
- data/examples/snippets/query-logs/README.md +43 -0
- data/examples/snippets/query-logs/Rakefile +13 -0
- data/examples/snippets/query-logs/application.rb +63 -0
- data/examples/snippets/query-logs/config/database.yml +8 -0
- data/examples/snippets/query-logs/db/migrate/01_create_tables.rb +21 -0
- data/examples/snippets/query-logs/db/schema.rb +31 -0
- data/examples/snippets/query-logs/db/seeds.rb +24 -0
- data/examples/snippets/query-logs/models/album.rb +9 -0
- data/examples/snippets/query-logs/models/singer.rb +9 -0
- data/lib/active_record/connection_adapters/spanner/column.rb +13 -0
- data/lib/active_record/connection_adapters/spanner/database_statements.rb +144 -35
- data/lib/active_record/connection_adapters/spanner/schema_cache.rb +3 -21
- data/lib/active_record/connection_adapters/spanner/schema_creation.rb +11 -0
- data/lib/active_record/connection_adapters/spanner/schema_definitions.rb +4 -0
- data/lib/active_record/connection_adapters/spanner/schema_statements.rb +3 -2
- data/lib/active_record/connection_adapters/spanner_adapter.rb +28 -9
- data/lib/activerecord_spanner_adapter/base.rb +56 -19
- data/lib/activerecord_spanner_adapter/information_schema.rb +33 -24
- data/lib/activerecord_spanner_adapter/primary_key.rb +1 -1
- data/lib/activerecord_spanner_adapter/table/column.rb +4 -9
- data/lib/activerecord_spanner_adapter/version.rb +1 -1
- data/lib/arel/visitors/spanner.rb +3 -1
- metadata +33 -4
@@ -4,6 +4,7 @@
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
5
5
|
# https://opensource.org/licenses/MIT.
|
6
6
|
|
7
|
+
require "active_record/gem_version"
|
7
8
|
require "activerecord_spanner_adapter/relation"
|
8
9
|
|
9
10
|
module ActiveRecord
|
@@ -14,6 +15,8 @@ module ActiveRecord
|
|
14
15
|
end
|
15
16
|
|
16
17
|
class Base
|
18
|
+
VERSION_7_1 = Gem::Version.create "7.1.0"
|
19
|
+
|
17
20
|
# Creates an object (or multiple objects) and saves it to the database. This method will use mutations instead
|
18
21
|
# of DML if there is no active transaction, or if the active transaction has been created with the option
|
19
22
|
# isolation: :buffered_mutations.
|
@@ -30,7 +33,9 @@ module ActiveRecord
|
|
30
33
|
return super unless spanner_adapter?
|
31
34
|
return super if active_transaction?
|
32
35
|
|
33
|
-
|
36
|
+
# Only use mutations to create new records if the primary key is generated client-side.
|
37
|
+
isolation = sequence_name ? nil : :buffered_mutations
|
38
|
+
transaction isolation: isolation do
|
34
39
|
return super
|
35
40
|
end
|
36
41
|
end
|
@@ -43,35 +48,67 @@ module ActiveRecord
|
|
43
48
|
spanner_adapter? && connection&.current_spanner_transaction&.isolation == :buffered_mutations
|
44
49
|
end
|
45
50
|
|
46
|
-
def self._insert_record values
|
51
|
+
def self._insert_record values, returning = []
|
47
52
|
return super unless buffered_mutations? || (primary_key && values.is_a?(Hash))
|
48
53
|
|
49
|
-
|
54
|
+
# Mutations cannot be used in combination with a sequence, as mutations do not support a THEN RETURN clause.
|
55
|
+
if buffered_mutations? && sequence_name
|
56
|
+
raise StatementInvalid, "Mutations cannot be used to create records that use a sequence " \
|
57
|
+
"to generate the primary key. #{self} uses #{sequence_name}."
|
58
|
+
end
|
50
59
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
_set_single_primary_key_value primary_key, values
|
56
|
-
end
|
60
|
+
return _buffer_record values, :insert, returning if buffered_mutations?
|
61
|
+
|
62
|
+
primary_key_value = _set_primary_key_value values
|
57
63
|
if ActiveRecord::VERSION::MAJOR >= 7
|
58
64
|
im = Arel::InsertManager.new arel_table
|
59
65
|
im.insert(values.transform_keys { |name| arel_table[name] })
|
60
66
|
else
|
61
67
|
im = arel_table.compile_insert _substitute_values(values)
|
62
68
|
end
|
63
|
-
connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
69
|
+
result = connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
|
70
|
+
|
71
|
+
_convert_primary_key result, returning
|
64
72
|
end
|
65
73
|
|
66
|
-
def self.
|
67
|
-
|
74
|
+
def self._set_primary_key_value values
|
75
|
+
if primary_key.is_a? Array
|
76
|
+
_set_composite_primary_key_values primary_key, values
|
77
|
+
else
|
78
|
+
_set_single_primary_key_value primary_key, values
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self._convert_primary_key primary_key_value, returning
|
83
|
+
# Rails 7.1 and higher supports composite primary keys, and therefore require the provider to return an array
|
84
|
+
# instead of a single value in all cases. The order of the values should be equal to the order of the returning
|
85
|
+
# columns (or the primary key if no returning columns were specified).
|
86
|
+
return primary_key_value if ActiveRecord.gem_version < VERSION_7_1
|
87
|
+
return primary_key_value if primary_key_value.is_a?(Array) && primary_key_value.length == 1
|
88
|
+
return [primary_key_value] unless primary_key_value.is_a? Array
|
89
|
+
|
90
|
+
# Re-order the returned values according to the returning columns if it is not equal to the primary key of the
|
91
|
+
# table.
|
92
|
+
keys = returning || primary_key
|
93
|
+
return primary_key_value if keys == primary_key
|
94
|
+
|
95
|
+
primary_key_values_hash = Hash[primary_key.zip(primary_key_value)]
|
96
|
+
values = []
|
97
|
+
keys.each do |column|
|
98
|
+
values.append primary_key_values_hash[column]
|
99
|
+
end
|
100
|
+
values
|
101
|
+
end
|
102
|
+
|
103
|
+
def self._upsert_record values, returning
|
104
|
+
_buffer_record values, :insert_or_update, returning
|
68
105
|
end
|
69
106
|
|
70
107
|
def self.insert_all _attributes, **_kwargs
|
71
108
|
raise NotImplementedError, "Cloud Spanner does not support skip_duplicates. Use insert! or upsert instead."
|
72
109
|
end
|
73
110
|
|
74
|
-
def self.insert_all! attributes, **_kwargs
|
111
|
+
def self.insert_all! attributes, returning: nil, **_kwargs
|
75
112
|
return super unless spanner_adapter?
|
76
113
|
return super if active_transaction? && !buffered_mutations?
|
77
114
|
|
@@ -90,7 +127,7 @@ module ActiveRecord
|
|
90
127
|
end
|
91
128
|
end
|
92
129
|
|
93
|
-
def self.upsert_all attributes, **_kwargs
|
130
|
+
def self.upsert_all attributes, returning: nil, unique_by: nil, **_kwargs
|
94
131
|
return super unless spanner_adapter?
|
95
132
|
if active_transaction? && !buffered_mutations?
|
96
133
|
raise NotImplementedError, "Cloud Spanner does not support upsert using DML. " \
|
@@ -102,18 +139,18 @@ module ActiveRecord
|
|
102
139
|
# The mutations will be sent as one batch when the transaction is committed.
|
103
140
|
if active_transaction?
|
104
141
|
attributes.each do |record|
|
105
|
-
_upsert_record record
|
142
|
+
_upsert_record record, returning
|
106
143
|
end
|
107
144
|
else
|
108
145
|
transaction isolation: :buffered_mutations do
|
109
146
|
attributes.each do |record|
|
110
|
-
_upsert_record record
|
147
|
+
_upsert_record record, returning
|
111
148
|
end
|
112
149
|
end
|
113
150
|
end
|
114
151
|
end
|
115
152
|
|
116
|
-
def self._buffer_record values, method
|
153
|
+
def self._buffer_record values, method, returning
|
117
154
|
primary_key_value =
|
118
155
|
if primary_key.is_a? Array
|
119
156
|
_set_composite_primary_key_values primary_key, values
|
@@ -132,10 +169,9 @@ module ActiveRecord
|
|
132
169
|
mutation = Google::Cloud::Spanner::V1::Mutation.new(
|
133
170
|
"#{method}": write
|
134
171
|
)
|
135
|
-
|
136
172
|
connection.current_spanner_transaction.buffer mutation
|
137
173
|
|
138
|
-
primary_key_value
|
174
|
+
_convert_primary_key primary_key_value, returning
|
139
175
|
end
|
140
176
|
|
141
177
|
def self._set_composite_primary_key_values primary_key, values
|
@@ -174,6 +210,7 @@ module ActiveRecord
|
|
174
210
|
def self._set_single_primary_key_value primary_key, values
|
175
211
|
primary_key_value = values[primary_key] || values[primary_key.to_sym]
|
176
212
|
|
213
|
+
return primary_key_value if sequence_name
|
177
214
|
return primary_key_value unless prefetch_primary_key?
|
178
215
|
|
179
216
|
if primary_key_value.nil?
|
@@ -15,6 +15,8 @@ module ActiveRecordSpannerAdapter
|
|
15
15
|
class InformationSchema
|
16
16
|
include ActiveRecord::ConnectionAdapters::Quoting
|
17
17
|
|
18
|
+
IsRails71OrLater = ActiveRecord.gem_version >= Gem::Version.create("7.1.0")
|
19
|
+
|
18
20
|
attr_reader :connection
|
19
21
|
|
20
22
|
def initialize connection
|
@@ -62,6 +64,7 @@ module ActiveRecordSpannerAdapter
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def table_columns table_name, column_name: nil
|
67
|
+
primary_keys = table_primary_keys(table_name).map(&:name)
|
65
68
|
sql = +"SELECT COLUMN_NAME, SPANNER_TYPE, IS_NULLABLE, GENERATION_EXPRESSION,"
|
66
69
|
sql << " CAST(COLUMN_DEFAULT AS STRING) AS COLUMN_DEFAULT, ORDINAL_POSITION"
|
67
70
|
sql << " FROM INFORMATION_SCHEMA.COLUMNS"
|
@@ -75,34 +78,40 @@ module ActiveRecordSpannerAdapter
|
|
75
78
|
table_name: table_name,
|
76
79
|
column_name: column_name
|
77
80
|
).map do |row|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
+
_create_column table_name, row, primary_keys, column_options
|
82
|
+
end
|
83
|
+
end
|
81
84
|
|
82
|
-
|
83
|
-
|
85
|
+
def _create_column table_name, row, primary_keys, column_options
|
86
|
+
type, limit = parse_type_and_limit row["SPANNER_TYPE"]
|
87
|
+
column_name = row["COLUMN_NAME"]
|
88
|
+
options = column_options[column_name]
|
89
|
+
primary_key = primary_keys.include? column_name
|
84
90
|
|
85
|
-
|
86
|
-
|
87
|
-
default = nil
|
88
|
-
end
|
91
|
+
default = row["COLUMN_DEFAULT"]
|
92
|
+
default_function = row["GENERATION_EXPRESSION"]
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
|
94
|
+
if default && default.length < 200 && /\w+\(.*\)/.match?(default)
|
95
|
+
default_function ||= default
|
96
|
+
default = nil
|
97
|
+
end
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
column_name,
|
97
|
-
type,
|
98
|
-
limit: limit,
|
99
|
-
allow_commit_timestamp: options["allow_commit_timestamp"],
|
100
|
-
ordinal_position: row["ORDINAL_POSITION"],
|
101
|
-
nullable: row["IS_NULLABLE"] == "YES",
|
102
|
-
default: default,
|
103
|
-
default_function: default_function,
|
104
|
-
generated: row["GENERATION_EXPRESSION"].present?
|
99
|
+
if default && type == "STRING"
|
100
|
+
default = unquote_string default
|
105
101
|
end
|
102
|
+
|
103
|
+
Table::Column.new \
|
104
|
+
table_name,
|
105
|
+
column_name,
|
106
|
+
type,
|
107
|
+
limit: limit,
|
108
|
+
allow_commit_timestamp: options["allow_commit_timestamp"],
|
109
|
+
ordinal_position: row["ORDINAL_POSITION"],
|
110
|
+
nullable: row["IS_NULLABLE"] == "YES",
|
111
|
+
default: default,
|
112
|
+
default_function: default_function,
|
113
|
+
generated: row["GENERATION_EXPRESSION"].present?,
|
114
|
+
primary_key: primary_key
|
106
115
|
end
|
107
116
|
|
108
117
|
def table_column table_name, column_name
|
@@ -114,7 +123,7 @@ module ActiveRecordSpannerAdapter
|
|
114
123
|
# ActiveRecord. The parent primary key columns are filtered out by default to allow interleaved tables to be
|
115
124
|
# considered as tables with a single-column primary key by ActiveRecord. The actual primary key of the table will
|
116
125
|
# include both the parent primary key columns and the 'own' primary key columns of a table.
|
117
|
-
def table_primary_keys table_name, include_parent_keys =
|
126
|
+
def table_primary_keys table_name, include_parent_keys = IsRails71OrLater
|
118
127
|
sql = +"WITH TABLE_PK_COLS AS ( "
|
119
128
|
sql << "SELECT C.TABLE_NAME, C.COLUMN_NAME, C.INDEX_NAME, C.COLUMN_ORDERING, C.ORDINAL_POSITION "
|
120
129
|
sql << "FROM INFORMATION_SCHEMA.INDEX_COLUMNS C "
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def fetch_primary_and_parent_key
|
21
|
-
return connection.
|
21
|
+
return connection.spanner_schema_cache.primary_and_parent_keys table_name \
|
22
22
|
if ActiveRecord::Base != self && table_exists?
|
23
23
|
end
|
24
24
|
|
@@ -9,8 +9,7 @@ module ActiveRecordSpannerAdapter
|
|
9
9
|
class Column
|
10
10
|
attr_accessor :table_name, :name, :type, :limit, :ordinal_position,
|
11
11
|
:allow_commit_timestamp, :default, :default_function, :generated,
|
12
|
-
:primary_key
|
13
|
-
attr_writer :nullable
|
12
|
+
:primary_key, :nullable
|
14
13
|
|
15
14
|
def initialize \
|
16
15
|
table_name,
|
@@ -22,7 +21,8 @@ module ActiveRecordSpannerAdapter
|
|
22
21
|
allow_commit_timestamp: nil,
|
23
22
|
default: nil,
|
24
23
|
default_function: nil,
|
25
|
-
generated: nil
|
24
|
+
generated: nil,
|
25
|
+
primary_key: false
|
26
26
|
@table_name = table_name.to_s
|
27
27
|
@name = name.to_s
|
28
28
|
@type = type
|
@@ -33,12 +33,7 @@ module ActiveRecordSpannerAdapter
|
|
33
33
|
@default = default
|
34
34
|
@default_function = default_function
|
35
35
|
@generated = generated == true
|
36
|
-
@primary_key =
|
37
|
-
end
|
38
|
-
|
39
|
-
def nullable
|
40
|
-
return false if primary_key
|
41
|
-
@nullable
|
36
|
+
@primary_key = primary_key
|
42
37
|
end
|
43
38
|
|
44
39
|
def spanner_type
|
@@ -139,7 +139,9 @@ module Arel # :nodoc: all
|
|
139
139
|
# Do not generate a query parameter if the value should be set to the PENDING_COMMIT_TIMESTAMP(), as that is
|
140
140
|
# not supported as a parameter value by Cloud Spanner.
|
141
141
|
return collector << "PENDING_COMMIT_TIMESTAMP()" \
|
142
|
-
|
142
|
+
if o.value.respond_to?(:type) \
|
143
|
+
&& o.value.type.is_a?(ActiveRecord::Type::Spanner::Time) \
|
144
|
+
&& o.value.value == :commit_timestamp
|
143
145
|
collector.add_bind(o.value, &bind_block)
|
144
146
|
end
|
145
147
|
# rubocop:enable Naming/MethodName
|
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.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Google LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-spanner
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 6.0.0
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '7.
|
36
|
+
version: '7.2'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 6.0.0
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '7.
|
46
|
+
version: '7.2'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: autotest-suffix
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -312,6 +312,7 @@ files:
|
|
312
312
|
- acceptance/models/organization.rb
|
313
313
|
- acceptance/models/post.rb
|
314
314
|
- acceptance/models/singer.rb
|
315
|
+
- acceptance/models/table_with_sequence.rb
|
315
316
|
- acceptance/models/track.rb
|
316
317
|
- acceptance/models/transaction.rb
|
317
318
|
- acceptance/schema/schema.rb
|
@@ -342,6 +343,15 @@ files:
|
|
342
343
|
- examples/snippets/array-data-type/db/seeds.rb
|
343
344
|
- examples/snippets/array-data-type/models/entity_with_array_types.rb
|
344
345
|
- examples/snippets/bin/create_emulator_instance.rb
|
346
|
+
- examples/snippets/bit-reversed-sequence/README.md
|
347
|
+
- examples/snippets/bit-reversed-sequence/Rakefile
|
348
|
+
- examples/snippets/bit-reversed-sequence/application.rb
|
349
|
+
- examples/snippets/bit-reversed-sequence/config/database.yml
|
350
|
+
- examples/snippets/bit-reversed-sequence/db/migrate/01_create_tables.rb
|
351
|
+
- examples/snippets/bit-reversed-sequence/db/schema.rb
|
352
|
+
- examples/snippets/bit-reversed-sequence/db/seeds.rb
|
353
|
+
- examples/snippets/bit-reversed-sequence/models/album.rb
|
354
|
+
- examples/snippets/bit-reversed-sequence/models/singer.rb
|
345
355
|
- examples/snippets/bulk-insert/README.md
|
346
356
|
- examples/snippets/bulk-insert/Rakefile
|
347
357
|
- examples/snippets/bulk-insert/application.rb
|
@@ -395,6 +405,16 @@ files:
|
|
395
405
|
- examples/snippets/hints/db/seeds.rb
|
396
406
|
- examples/snippets/hints/models/album.rb
|
397
407
|
- examples/snippets/hints/models/singer.rb
|
408
|
+
- examples/snippets/interleaved-tables-before-7.1/README.md
|
409
|
+
- examples/snippets/interleaved-tables-before-7.1/Rakefile
|
410
|
+
- examples/snippets/interleaved-tables-before-7.1/application.rb
|
411
|
+
- examples/snippets/interleaved-tables-before-7.1/config/database.yml
|
412
|
+
- examples/snippets/interleaved-tables-before-7.1/db/migrate/01_create_tables.rb
|
413
|
+
- examples/snippets/interleaved-tables-before-7.1/db/schema.rb
|
414
|
+
- examples/snippets/interleaved-tables-before-7.1/db/seeds.rb
|
415
|
+
- examples/snippets/interleaved-tables-before-7.1/models/album.rb
|
416
|
+
- examples/snippets/interleaved-tables-before-7.1/models/singer.rb
|
417
|
+
- examples/snippets/interleaved-tables-before-7.1/models/track.rb
|
398
418
|
- examples/snippets/interleaved-tables/README.md
|
399
419
|
- examples/snippets/interleaved-tables/Rakefile
|
400
420
|
- examples/snippets/interleaved-tables/application.rb
|
@@ -442,6 +462,15 @@ files:
|
|
442
462
|
- examples/snippets/partitioned-dml/db/seeds.rb
|
443
463
|
- examples/snippets/partitioned-dml/models/album.rb
|
444
464
|
- examples/snippets/partitioned-dml/models/singer.rb
|
465
|
+
- examples/snippets/query-logs/README.md
|
466
|
+
- examples/snippets/query-logs/Rakefile
|
467
|
+
- examples/snippets/query-logs/application.rb
|
468
|
+
- examples/snippets/query-logs/config/database.yml
|
469
|
+
- examples/snippets/query-logs/db/migrate/01_create_tables.rb
|
470
|
+
- examples/snippets/query-logs/db/schema.rb
|
471
|
+
- examples/snippets/query-logs/db/seeds.rb
|
472
|
+
- examples/snippets/query-logs/models/album.rb
|
473
|
+
- examples/snippets/query-logs/models/singer.rb
|
445
474
|
- examples/snippets/quickstart/README.md
|
446
475
|
- examples/snippets/quickstart/Rakefile
|
447
476
|
- examples/snippets/quickstart/application.rb
|