activerecord-beagle-turso 0.1.3 → 0.1.4
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 954e05b945781cc01a630306c4cb5d9368ef5dcc54876269229afed57f3a56d1
|
|
4
|
+
data.tar.gz: e512726ed37adeeee5ce7fe6268d3ecda615c079a4b041cca7a1677cce9d55fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e48728f8d4c61291db44090aab87067f31b76ef0503db34cdfcab18cb66e4d204a35b2ab7cdc3d6114ce555a49b347fdf88cc6406f5a08acb6cbc43e97d748e8
|
|
7
|
+
data.tar.gz: 70b9fb0e606a6e8e844a737d250016b800fdf21eb47e29ab3ead567821a5250ba95ff90a2e3dbaeb9283e1673624b3a8d31ed506bb0ce9e4217e5d5751e24965
|
|
@@ -223,6 +223,65 @@ module ActiveRecord
|
|
|
223
223
|
"#{super} AND name NOT LIKE '\\_\\_turso\\_internal\\_%' ESCAPE '\\'"
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
+
# A column definition in the DDL that carries a parenthesised type
|
|
227
|
+
# argument: `"price" decimal (10, 2) NOT NULL`, `a varchar (50)`. The
|
|
228
|
+
# name may be bare or quoted with ", ` or []; the type may be several
|
|
229
|
+
# words ("double precision"); the argument is one or two integers.
|
|
230
|
+
DECLARED_TYPE_REGEX = /
|
|
231
|
+
\A\s*
|
|
232
|
+
(?:"(?<name>[^"]*)" | `(?<name>[^`]*)` | \[(?<name>[^\]]*)\] | (?<name>\w+))
|
|
233
|
+
\s+
|
|
234
|
+
(?<type>[A-Za-z_][A-Za-z0-9_\ ]*?)
|
|
235
|
+
\s*\(\s*(?<args>\d+\s*(?:,\s*\d+)?)\s*\)
|
|
236
|
+
/x
|
|
237
|
+
private_constant :DECLARED_TYPE_REGEX
|
|
238
|
+
|
|
239
|
+
# Restore type arguments that beagle_turso's `PRAGMA table_info` drops.
|
|
240
|
+
#
|
|
241
|
+
# turso reports a column's declared type as the bare type name: a
|
|
242
|
+
# `decimal(10,2)` column comes back as `decimal`, `varchar(50)` as
|
|
243
|
+
# `varchar`, `datetime(6)` as `datetime`. Rails derives precision,
|
|
244
|
+
# scale and limit by parsing exactly that string, so all three silently
|
|
245
|
+
# become nil. Real SQLite returns the full declared type here, and the
|
|
246
|
+
# information is not lost on disk -- the CREATE TABLE in sqlite_master
|
|
247
|
+
# still says `decimal (10, 2)` -- so recover it from there.
|
|
248
|
+
#
|
|
249
|
+
# Left alone this is worse than cosmetic schema.rb churn: a dump emits
|
|
250
|
+
# `t.decimal "price"` with no precision/scale, and loading that dump
|
|
251
|
+
# builds a column whose values are no longer rounded to 2 decimal
|
|
252
|
+
# places. `super` already splits the DDL into per-column strings to
|
|
253
|
+
# recover COLLATE, AUTOINCREMENT and GENERATED ALWAYS AS for the same
|
|
254
|
+
# reason; this is the same trick for the type itself.
|
|
255
|
+
#
|
|
256
|
+
# Only fills in a missing argument -- a type that already arrived with
|
|
257
|
+
# one is left untouched, so this becomes an automatic no-op if turso
|
|
258
|
+
# starts reporting declared types in full.
|
|
259
|
+
def table_structure_with_collation(table_name, basic_structure)
|
|
260
|
+
columns = super
|
|
261
|
+
return columns unless columns.any? { |column| !column["type"].to_s.include?("(") }
|
|
262
|
+
|
|
263
|
+
declared = declared_column_types(table_name, columns.filter_map { |c| c["name"] })
|
|
264
|
+
return columns if declared.empty?
|
|
265
|
+
|
|
266
|
+
columns.each do |column|
|
|
267
|
+
next if column["type"].to_s.include?("(")
|
|
268
|
+
|
|
269
|
+
full_type = declared[column["name"]]
|
|
270
|
+
column["type"] = full_type if full_type
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Maps column name -> declared type with its argument normalised back
|
|
275
|
+
# to Rails' own spelling (`decimal (10, 2)` -> `decimal(10,2)`), which
|
|
276
|
+
# is what Rails' precision/scale/limit extraction expects to see.
|
|
277
|
+
def declared_column_types(table_name, column_names)
|
|
278
|
+
table_structure_sql(table_name, column_names).each_with_object({}) do |column_string, declared|
|
|
279
|
+
next unless (match = DECLARED_TYPE_REGEX.match(column_string))
|
|
280
|
+
|
|
281
|
+
declared[match[:name]] = "#{match[:type]}(#{match[:args].gsub(/\s+/, '')})"
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
226
285
|
# The single seam. AbstractAdapter#raw_execute funnels every statement
|
|
227
286
|
# here and expects an ActiveRecord::Result back, with the notification
|
|
228
287
|
# payload's affected_rows/row_count filled in. cast_result (inherited)
|