activerecord-virgodb-adapter 0.1.6 → 0.1.8
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/lib/active_record/tasks/virgodb_database_tasks.rb +54 -17
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b21e3613bde955c3741ba92692bb2465036783609e4d11f9540ce0283ea83732
|
|
4
|
+
data.tar.gz: 34b1d14f797d629a6f09c029d422803353df2d86cb8c0682883bbb90d56fde18
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbafb03b4df28cc059ed39deffd6504916232cb545b4ae2c7bce66e55121837e90cb3a76c8ecc6fd074277665abd6c438042ecce57530a5960b0fc6391a2d314
|
|
7
|
+
data.tar.gz: 79aae8c9a8cbcc419ac83295f371d24122cfddf291d5974c473d23cbafa512b3a177109197b86f090c349af594eb1533d47bea3e2bd84e7a2a28fe835d08c02a
|
|
@@ -74,6 +74,7 @@ module ActiveRecord
|
|
|
74
74
|
super
|
|
75
75
|
strip_null_autoindex_blank_lines!(filename)
|
|
76
76
|
reformat_create_table_statements!(filename)
|
|
77
|
+
separate_create_table_statements_with_blank_lines!(filename)
|
|
77
78
|
annotate_physical_layout!(filename)
|
|
78
79
|
dump_schema_versions!(filename)
|
|
79
80
|
end
|
|
@@ -133,32 +134,45 @@ module ActiveRecord
|
|
|
133
134
|
# history here isn't a correctness requirement. It also isn't a
|
|
134
135
|
# readability win: each version's `columns` re-lists every column from
|
|
135
136
|
# scratch, so N migrations means N near-duplicate JSON blobs, longer
|
|
136
|
-
# every time. The
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
137
|
+
# every time. The migration files themselves (db/migrate_virgodb_*/*.rb,
|
|
138
|
+
# timestamped, under git blame) are already the authoritative "what
|
|
139
|
+
# changed when" record. `register_schema_version`'s additive-only check
|
|
140
|
+
# is unaffected: it only ever compares a new migration's proposed
|
|
141
|
+
# columns against the CURRENT version, which is exactly what's still
|
|
142
|
+
# dumped.
|
|
143
|
+
#
|
|
144
|
+
# `applied_at` is dumped as a fixed `0`, and no per-version history
|
|
145
|
+
# comment is written -- both used to carry real wall-clock data
|
|
146
|
+
# (`Time.now.to_i` at migration time), which made this file diff on
|
|
147
|
+
# every clean rebuild (`db:drop` + `db:migrate`) even when the actual
|
|
148
|
+
# schema hadn't changed at all. Confirmed nothing reads either back:
|
|
149
|
+
# `current_schema_version` only ever selects `version, columns` (see
|
|
150
|
+
# above), and this adapter's own `assert_additive!`/
|
|
151
|
+
# `record_added_column!` only ever read `columns` too. The live
|
|
152
|
+
# manifest's real `schema_versions` table is untouched by this --
|
|
153
|
+
# `applied_at` still gets a real timestamp there at migration time,
|
|
154
|
+
# useful for a human inspecting the live table directly. This only
|
|
155
|
+
# changes what a fresh `structure_load` seeds into a NEW database,
|
|
156
|
+
# where a wall-clock value was never reproducible enough to belong in
|
|
157
|
+
# a checked-in file meant to represent "current schema shape," not
|
|
158
|
+
# "when someone last regenerated this file."
|
|
143
159
|
def dump_schema_versions!(filename)
|
|
144
160
|
return unless connection.data_source_exists?("schema_versions")
|
|
145
161
|
|
|
146
|
-
rows = connection.select_all("SELECT id, table_name, version, columns
|
|
162
|
+
rows = connection.select_all("SELECT id, table_name, version, columns FROM schema_versions ORDER BY table_name, version")
|
|
147
163
|
return if rows.to_a.empty?
|
|
148
164
|
|
|
149
165
|
File.open(filename, "a") do |f|
|
|
150
166
|
f.puts
|
|
151
167
|
rows.to_a.group_by { |r| r["table_name"] }.each do |table_name, versions|
|
|
152
168
|
latest = versions.max_by { |r| r["version"] }
|
|
153
|
-
history = versions.map { |r| "v#{r['version']} (#{Time.at(r['applied_at'].to_i).utc.strftime('%Y-%m-%d')})" }.join(", ")
|
|
154
169
|
|
|
155
|
-
f.puts "-- #{table_name} schema history: #{history} -- only the current version is dumped below; see db/migrate_virgodb_*/ for the rest"
|
|
156
170
|
pretty_columns = JSON.pretty_generate(JSON.parse(latest["columns"]))
|
|
157
171
|
f.puts(
|
|
158
172
|
"INSERT INTO \"schema_versions\" (id, table_name, version, columns, applied_at) VALUES (\n" \
|
|
159
173
|
" #{latest['id']}, #{connection.quote(table_name)}, #{latest['version']},\n" \
|
|
160
174
|
" #{connection.quote(pretty_columns)},\n" \
|
|
161
|
-
"
|
|
175
|
+
" 0\n" \
|
|
162
176
|
");"
|
|
163
177
|
)
|
|
164
178
|
f.puts
|
|
@@ -198,7 +212,7 @@ module ActiveRecord
|
|
|
198
212
|
# `SQLiteDatabaseTasks#structure_dump`'s `ignore_tables`-triggered
|
|
199
213
|
# fallback (used whenever `ActiveRecord::SchemaDumper.ignore_tables` is
|
|
200
214
|
# non-empty, e.g. excluding tables owned by a separate replication/
|
|
201
|
-
# backup mechanism -- exactly
|
|
215
|
+
# backup mechanism -- exactly a host app's own Litestream initializer)
|
|
202
216
|
# runs `SELECT sql || ';' FROM sqlite_master WHERE tbl_name NOT IN
|
|
203
217
|
# (...) ORDER BY tbl_name, type DESC, name` through the `sqlite3` CLI.
|
|
204
218
|
# Any table with a non-INTEGER (so non-rowid-alias) PRIMARY KEY --
|
|
@@ -217,11 +231,11 @@ module ActiveRecord
|
|
|
217
231
|
# `ignore_tables` is empty) already skips these rows itself --
|
|
218
232
|
# confirmed empirically too -- so this is purely a gap in the
|
|
219
233
|
# raw-SQL fallback, not something either path does on purpose.
|
|
220
|
-
# Stripping now, before `reformat_create_table_statements!`
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
224
|
-
#
|
|
234
|
+
# Stripping now, before `reformat_create_table_statements!` and
|
|
235
|
+
# `separate_create_table_statements_with_blank_lines!` (below) touch
|
|
236
|
+
# anything, gives those steps a clean slate -- every blank line in the
|
|
237
|
+
# dump from this point on is one THEY deliberately added, not this
|
|
238
|
+
# accidental one.
|
|
225
239
|
def strip_null_autoindex_blank_lines!(filename)
|
|
226
240
|
content = File.read(filename)
|
|
227
241
|
content.gsub!(/\n\n+/, "\n")
|
|
@@ -268,6 +282,29 @@ module ActiveRecord
|
|
|
268
282
|
File.write(filename, content)
|
|
269
283
|
end
|
|
270
284
|
|
|
285
|
+
# Matches `db/clickhouse_structure.sql` and `db/schema.rb`'s own
|
|
286
|
+
# convention (both, unprompted, separate every top-level table
|
|
287
|
+
# definition with a blank line -- confirmed directly against a real
|
|
288
|
+
# host app's dumps of each, not assumed) rather than inventing a
|
|
289
|
+
# new one here. Only CREATE TABLE gets a leading blank line, not
|
|
290
|
+
# CREATE INDEX/CREATE UNIQUE INDEX -- those stay glued directly under
|
|
291
|
+
# their own table, same as clickhouse_structure.sql has no equivalent
|
|
292
|
+
# to disagree with and virgodb's own tables (e.g. `inline_batches` +
|
|
293
|
+
# `idx_inline_batches_table_name`) already read naturally that way.
|
|
294
|
+
# Runs after `reformat_create_table_statements!` (so every `CREATE
|
|
295
|
+
# TABLE` is unambiguously alone at the start of its own line already,
|
|
296
|
+
# nothing left to normalize first) but before
|
|
297
|
+
# `annotate_physical_layout!` (so a table WITH a physical-layout
|
|
298
|
+
# comment gets the blank line ahead of the comment block, not
|
|
299
|
+
# wedged between the comment and its own `CREATE TABLE`).
|
|
300
|
+
# `(?<!\A)` skips the very first statement in the file, which should
|
|
301
|
+
# start right at the top with no leading blank line.
|
|
302
|
+
def separate_create_table_statements_with_blank_lines!(filename)
|
|
303
|
+
content = File.read(filename)
|
|
304
|
+
content.gsub!(/(?<!\A)^CREATE TABLE /) { |match| "\n#{match}" }
|
|
305
|
+
File.write(filename, content)
|
|
306
|
+
end
|
|
307
|
+
|
|
271
308
|
# Splits a CREATE TABLE column list on commas that are NOT nested
|
|
272
309
|
# inside a type's own parens (e.g. `Decimal(18,2)`) -- a plain
|
|
273
310
|
# `String#split(",")` would wrongly cut `Decimal(18` and `2)` apart.
|