latticesql 4.3.6 → 4.3.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.
- package/dist/cli.js +51 -20
- package/dist/desktop-entry.js +51 -20
- package/dist/index.cjs +50 -19
- package/dist/index.js +50 -19
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -58419,8 +58419,18 @@ init_adapter();
|
|
|
58419
58419
|
var DELETED_AT_SENTINEL = "internal:upgrade:deleted-at-empty-to-null:v1";
|
|
58420
58420
|
var FILES_PATH_SENTINEL = "internal:upgrade:files-path-to-local-ref:v1";
|
|
58421
58421
|
async function upgradeLegacyData(db) {
|
|
58422
|
-
await normalizeEmptyDeletedAt(db);
|
|
58423
|
-
await backfillFilesPath(db);
|
|
58422
|
+
await runUpgradeStep("deleted_at normalization", () => normalizeEmptyDeletedAt(db));
|
|
58423
|
+
await runUpgradeStep("files path backfill", () => backfillFilesPath(db));
|
|
58424
|
+
}
|
|
58425
|
+
async function runUpgradeStep(name, fn) {
|
|
58426
|
+
try {
|
|
58427
|
+
await fn();
|
|
58428
|
+
} catch (err) {
|
|
58429
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
58430
|
+
console.warn(
|
|
58431
|
+
`[lattice] open-time data upgrade step "${name}" skipped (will retry on next open): ${msg}`
|
|
58432
|
+
);
|
|
58433
|
+
}
|
|
58424
58434
|
}
|
|
58425
58435
|
async function tablesWithDeletedAt(db) {
|
|
58426
58436
|
if (db.getDialect() === "postgres") {
|
|
@@ -58444,14 +58454,40 @@ async function normalizeEmptyDeletedAt(db) {
|
|
|
58444
58454
|
await db.migrate([
|
|
58445
58455
|
{
|
|
58446
58456
|
version: `${DELETED_AT_SENTINEL}:all`,
|
|
58457
|
+
// TYPE-AWARE: only a text-like deleted_at column can hold the legacy ''
|
|
58458
|
+
// sentinel. A column that is a real `timestamptz` (some clouds' deleted_at
|
|
58459
|
+
// is) MUST be skipped: the predicate `deleted_at = ''` forces Postgres to
|
|
58460
|
+
// parse `''::timestamptz` at PLAN time — invalid input that throws regardless
|
|
58461
|
+
// of data (a timestamptz column can't even hold ''), which aborted the entire
|
|
58462
|
+
// workspace open. We BLACKLIST the non-text types (timestamp/date/time,
|
|
58463
|
+
// numeric, boolean, json, uuid, bytea, xml) rather than allow-list text — so
|
|
58464
|
+
// text-like columns we don't enumerate (citext, a DOMAIN over text, a custom
|
|
58465
|
+
// text type) are still normalized instead of silently leaving '' rows that
|
|
58466
|
+
// 4.x's `deleted_at IS NULL` predicate would read as DELETED. PER-TABLE FAULT
|
|
58467
|
+
// ISOLATION is the backstop: each table's UPDATE runs in its own
|
|
58468
|
+
// subtransaction, so an exotic type that still errors on `= ''` (enum, inet,
|
|
58469
|
+
// interval, array) — or a blocking trigger/lock — is warned + skipped, never
|
|
58470
|
+
// fatal to the open.
|
|
58447
58471
|
sql: `DO $LATTICE_DAU$
|
|
58448
58472
|
DECLARE r record;
|
|
58449
58473
|
BEGIN
|
|
58450
58474
|
FOR r IN
|
|
58451
58475
|
SELECT table_name FROM information_schema.columns
|
|
58452
|
-
WHERE table_schema = current_schema()
|
|
58476
|
+
WHERE table_schema = current_schema()
|
|
58477
|
+
AND column_name = 'deleted_at'
|
|
58478
|
+
AND data_type NOT IN (
|
|
58479
|
+
'timestamp with time zone', 'timestamp without time zone',
|
|
58480
|
+
'date', 'time with time zone', 'time without time zone',
|
|
58481
|
+
'integer', 'bigint', 'smallint', 'numeric', 'decimal',
|
|
58482
|
+
'real', 'double precision', 'boolean', 'json', 'jsonb',
|
|
58483
|
+
'bytea', 'uuid', 'xml'
|
|
58484
|
+
)
|
|
58453
58485
|
LOOP
|
|
58454
|
-
|
|
58486
|
+
BEGIN
|
|
58487
|
+
EXECUTE format('UPDATE %I SET deleted_at = NULL WHERE deleted_at = ''''', r.table_name);
|
|
58488
|
+
EXCEPTION WHEN others THEN
|
|
58489
|
+
RAISE WARNING 'lattice: skipped deleted_at normalization for %: %', r.table_name, SQLERRM;
|
|
58490
|
+
END;
|
|
58455
58491
|
END LOOP;
|
|
58456
58492
|
END $LATTICE_DAU$;`
|
|
58457
58493
|
}
|
|
@@ -58467,23 +58503,18 @@ END $LATTICE_DAU$;`
|
|
|
58467
58503
|
});
|
|
58468
58504
|
if (migrations.length > 0) await db.migrate(migrations);
|
|
58469
58505
|
}
|
|
58470
|
-
async function
|
|
58471
|
-
|
|
58472
|
-
|
|
58473
|
-
|
|
58474
|
-
|
|
58475
|
-
WHERE table_schema = current_schema() AND table_name = 'files' AND column_name = 'path'`
|
|
58476
|
-
);
|
|
58477
|
-
return rows2.length > 0;
|
|
58478
|
-
}
|
|
58479
|
-
const rows = await allAsyncOrSync(
|
|
58480
|
-
db.adapter,
|
|
58481
|
-
`SELECT 1 AS x FROM pragma_table_info('files') WHERE name = 'path'`
|
|
58482
|
-
);
|
|
58483
|
-
return rows.length > 0;
|
|
58506
|
+
async function filesColumns(db) {
|
|
58507
|
+
const sql = db.getDialect() === "postgres" ? `SELECT column_name AS name FROM information_schema.columns
|
|
58508
|
+
WHERE table_schema = current_schema() AND table_name = 'files'` : `SELECT name FROM pragma_table_info('files')`;
|
|
58509
|
+
const rows = await allAsyncOrSync(db.adapter, sql);
|
|
58510
|
+
return new Set(rows.map((r6) => r6.name));
|
|
58484
58511
|
}
|
|
58485
58512
|
async function backfillFilesPath(db) {
|
|
58486
|
-
|
|
58513
|
+
const cols = await filesColumns(db);
|
|
58514
|
+
if (!cols.has("path")) return;
|
|
58515
|
+
for (const col of ["ref_kind", "ref_uri", "ref_provider", "blob_path"]) {
|
|
58516
|
+
if (!cols.has(col)) await addColumnAsyncOrSync(db.adapter, "files", col, "TEXT");
|
|
58517
|
+
}
|
|
58487
58518
|
await db.migrate([
|
|
58488
58519
|
{
|
|
58489
58520
|
version: FILES_PATH_SENTINEL,
|
|
@@ -82106,7 +82137,7 @@ function printHelp() {
|
|
|
82106
82137
|
);
|
|
82107
82138
|
}
|
|
82108
82139
|
function getVersion() {
|
|
82109
|
-
if (true) return "4.3.
|
|
82140
|
+
if (true) return "4.3.8";
|
|
82110
82141
|
try {
|
|
82111
82142
|
const pkgPath = new URL("../package.json", import.meta.url).pathname;
|
|
82112
82143
|
const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
|
package/dist/desktop-entry.js
CHANGED
|
@@ -58113,8 +58113,18 @@ init_adapter();
|
|
|
58113
58113
|
var DELETED_AT_SENTINEL = "internal:upgrade:deleted-at-empty-to-null:v1";
|
|
58114
58114
|
var FILES_PATH_SENTINEL = "internal:upgrade:files-path-to-local-ref:v1";
|
|
58115
58115
|
async function upgradeLegacyData(db) {
|
|
58116
|
-
await normalizeEmptyDeletedAt(db);
|
|
58117
|
-
await backfillFilesPath(db);
|
|
58116
|
+
await runUpgradeStep("deleted_at normalization", () => normalizeEmptyDeletedAt(db));
|
|
58117
|
+
await runUpgradeStep("files path backfill", () => backfillFilesPath(db));
|
|
58118
|
+
}
|
|
58119
|
+
async function runUpgradeStep(name, fn) {
|
|
58120
|
+
try {
|
|
58121
|
+
await fn();
|
|
58122
|
+
} catch (err) {
|
|
58123
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
58124
|
+
console.warn(
|
|
58125
|
+
`[lattice] open-time data upgrade step "${name}" skipped (will retry on next open): ${msg}`
|
|
58126
|
+
);
|
|
58127
|
+
}
|
|
58118
58128
|
}
|
|
58119
58129
|
async function tablesWithDeletedAt(db) {
|
|
58120
58130
|
if (db.getDialect() === "postgres") {
|
|
@@ -58138,14 +58148,40 @@ async function normalizeEmptyDeletedAt(db) {
|
|
|
58138
58148
|
await db.migrate([
|
|
58139
58149
|
{
|
|
58140
58150
|
version: `${DELETED_AT_SENTINEL}:all`,
|
|
58151
|
+
// TYPE-AWARE: only a text-like deleted_at column can hold the legacy ''
|
|
58152
|
+
// sentinel. A column that is a real `timestamptz` (some clouds' deleted_at
|
|
58153
|
+
// is) MUST be skipped: the predicate `deleted_at = ''` forces Postgres to
|
|
58154
|
+
// parse `''::timestamptz` at PLAN time — invalid input that throws regardless
|
|
58155
|
+
// of data (a timestamptz column can't even hold ''), which aborted the entire
|
|
58156
|
+
// workspace open. We BLACKLIST the non-text types (timestamp/date/time,
|
|
58157
|
+
// numeric, boolean, json, uuid, bytea, xml) rather than allow-list text — so
|
|
58158
|
+
// text-like columns we don't enumerate (citext, a DOMAIN over text, a custom
|
|
58159
|
+
// text type) are still normalized instead of silently leaving '' rows that
|
|
58160
|
+
// 4.x's `deleted_at IS NULL` predicate would read as DELETED. PER-TABLE FAULT
|
|
58161
|
+
// ISOLATION is the backstop: each table's UPDATE runs in its own
|
|
58162
|
+
// subtransaction, so an exotic type that still errors on `= ''` (enum, inet,
|
|
58163
|
+
// interval, array) — or a blocking trigger/lock — is warned + skipped, never
|
|
58164
|
+
// fatal to the open.
|
|
58141
58165
|
sql: `DO $LATTICE_DAU$
|
|
58142
58166
|
DECLARE r record;
|
|
58143
58167
|
BEGIN
|
|
58144
58168
|
FOR r IN
|
|
58145
58169
|
SELECT table_name FROM information_schema.columns
|
|
58146
|
-
WHERE table_schema = current_schema()
|
|
58170
|
+
WHERE table_schema = current_schema()
|
|
58171
|
+
AND column_name = 'deleted_at'
|
|
58172
|
+
AND data_type NOT IN (
|
|
58173
|
+
'timestamp with time zone', 'timestamp without time zone',
|
|
58174
|
+
'date', 'time with time zone', 'time without time zone',
|
|
58175
|
+
'integer', 'bigint', 'smallint', 'numeric', 'decimal',
|
|
58176
|
+
'real', 'double precision', 'boolean', 'json', 'jsonb',
|
|
58177
|
+
'bytea', 'uuid', 'xml'
|
|
58178
|
+
)
|
|
58147
58179
|
LOOP
|
|
58148
|
-
|
|
58180
|
+
BEGIN
|
|
58181
|
+
EXECUTE format('UPDATE %I SET deleted_at = NULL WHERE deleted_at = ''''', r.table_name);
|
|
58182
|
+
EXCEPTION WHEN others THEN
|
|
58183
|
+
RAISE WARNING 'lattice: skipped deleted_at normalization for %: %', r.table_name, SQLERRM;
|
|
58184
|
+
END;
|
|
58149
58185
|
END LOOP;
|
|
58150
58186
|
END $LATTICE_DAU$;`
|
|
58151
58187
|
}
|
|
@@ -58161,23 +58197,18 @@ END $LATTICE_DAU$;`
|
|
|
58161
58197
|
});
|
|
58162
58198
|
if (migrations.length > 0) await db.migrate(migrations);
|
|
58163
58199
|
}
|
|
58164
|
-
async function
|
|
58165
|
-
|
|
58166
|
-
|
|
58167
|
-
|
|
58168
|
-
|
|
58169
|
-
WHERE table_schema = current_schema() AND table_name = 'files' AND column_name = 'path'`
|
|
58170
|
-
);
|
|
58171
|
-
return rows2.length > 0;
|
|
58172
|
-
}
|
|
58173
|
-
const rows = await allAsyncOrSync(
|
|
58174
|
-
db.adapter,
|
|
58175
|
-
`SELECT 1 AS x FROM pragma_table_info('files') WHERE name = 'path'`
|
|
58176
|
-
);
|
|
58177
|
-
return rows.length > 0;
|
|
58200
|
+
async function filesColumns(db) {
|
|
58201
|
+
const sql = db.getDialect() === "postgres" ? `SELECT column_name AS name FROM information_schema.columns
|
|
58202
|
+
WHERE table_schema = current_schema() AND table_name = 'files'` : `SELECT name FROM pragma_table_info('files')`;
|
|
58203
|
+
const rows = await allAsyncOrSync(db.adapter, sql);
|
|
58204
|
+
return new Set(rows.map((r6) => r6.name));
|
|
58178
58205
|
}
|
|
58179
58206
|
async function backfillFilesPath(db) {
|
|
58180
|
-
|
|
58207
|
+
const cols = await filesColumns(db);
|
|
58208
|
+
if (!cols.has("path")) return;
|
|
58209
|
+
for (const col of ["ref_kind", "ref_uri", "ref_provider", "blob_path"]) {
|
|
58210
|
+
if (!cols.has(col)) await addColumnAsyncOrSync(db.adapter, "files", col, "TEXT");
|
|
58211
|
+
}
|
|
58181
58212
|
await db.migrate([
|
|
58182
58213
|
{
|
|
58183
58214
|
version: FILES_PATH_SENTINEL,
|
|
@@ -81684,7 +81715,7 @@ ${e6.stack ?? ""}`
|
|
|
81684
81715
|
}
|
|
81685
81716
|
|
|
81686
81717
|
// src/desktop-entry.ts
|
|
81687
|
-
var VERSION2 = true ? "4.3.
|
|
81718
|
+
var VERSION2 = true ? "4.3.8" : "unknown";
|
|
81688
81719
|
export {
|
|
81689
81720
|
VERSION2 as VERSION,
|
|
81690
81721
|
ensureRootForGui,
|
package/dist/index.cjs
CHANGED
|
@@ -62650,8 +62650,18 @@ init_adapter();
|
|
|
62650
62650
|
var DELETED_AT_SENTINEL = "internal:upgrade:deleted-at-empty-to-null:v1";
|
|
62651
62651
|
var FILES_PATH_SENTINEL = "internal:upgrade:files-path-to-local-ref:v1";
|
|
62652
62652
|
async function upgradeLegacyData(db) {
|
|
62653
|
-
await normalizeEmptyDeletedAt(db);
|
|
62654
|
-
await backfillFilesPath(db);
|
|
62653
|
+
await runUpgradeStep("deleted_at normalization", () => normalizeEmptyDeletedAt(db));
|
|
62654
|
+
await runUpgradeStep("files path backfill", () => backfillFilesPath(db));
|
|
62655
|
+
}
|
|
62656
|
+
async function runUpgradeStep(name, fn) {
|
|
62657
|
+
try {
|
|
62658
|
+
await fn();
|
|
62659
|
+
} catch (err) {
|
|
62660
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62661
|
+
console.warn(
|
|
62662
|
+
`[lattice] open-time data upgrade step "${name}" skipped (will retry on next open): ${msg}`
|
|
62663
|
+
);
|
|
62664
|
+
}
|
|
62655
62665
|
}
|
|
62656
62666
|
async function tablesWithDeletedAt(db) {
|
|
62657
62667
|
if (db.getDialect() === "postgres") {
|
|
@@ -62675,14 +62685,40 @@ async function normalizeEmptyDeletedAt(db) {
|
|
|
62675
62685
|
await db.migrate([
|
|
62676
62686
|
{
|
|
62677
62687
|
version: `${DELETED_AT_SENTINEL}:all`,
|
|
62688
|
+
// TYPE-AWARE: only a text-like deleted_at column can hold the legacy ''
|
|
62689
|
+
// sentinel. A column that is a real `timestamptz` (some clouds' deleted_at
|
|
62690
|
+
// is) MUST be skipped: the predicate `deleted_at = ''` forces Postgres to
|
|
62691
|
+
// parse `''::timestamptz` at PLAN time — invalid input that throws regardless
|
|
62692
|
+
// of data (a timestamptz column can't even hold ''), which aborted the entire
|
|
62693
|
+
// workspace open. We BLACKLIST the non-text types (timestamp/date/time,
|
|
62694
|
+
// numeric, boolean, json, uuid, bytea, xml) rather than allow-list text — so
|
|
62695
|
+
// text-like columns we don't enumerate (citext, a DOMAIN over text, a custom
|
|
62696
|
+
// text type) are still normalized instead of silently leaving '' rows that
|
|
62697
|
+
// 4.x's `deleted_at IS NULL` predicate would read as DELETED. PER-TABLE FAULT
|
|
62698
|
+
// ISOLATION is the backstop: each table's UPDATE runs in its own
|
|
62699
|
+
// subtransaction, so an exotic type that still errors on `= ''` (enum, inet,
|
|
62700
|
+
// interval, array) — or a blocking trigger/lock — is warned + skipped, never
|
|
62701
|
+
// fatal to the open.
|
|
62678
62702
|
sql: `DO $LATTICE_DAU$
|
|
62679
62703
|
DECLARE r record;
|
|
62680
62704
|
BEGIN
|
|
62681
62705
|
FOR r IN
|
|
62682
62706
|
SELECT table_name FROM information_schema.columns
|
|
62683
|
-
WHERE table_schema = current_schema()
|
|
62707
|
+
WHERE table_schema = current_schema()
|
|
62708
|
+
AND column_name = 'deleted_at'
|
|
62709
|
+
AND data_type NOT IN (
|
|
62710
|
+
'timestamp with time zone', 'timestamp without time zone',
|
|
62711
|
+
'date', 'time with time zone', 'time without time zone',
|
|
62712
|
+
'integer', 'bigint', 'smallint', 'numeric', 'decimal',
|
|
62713
|
+
'real', 'double precision', 'boolean', 'json', 'jsonb',
|
|
62714
|
+
'bytea', 'uuid', 'xml'
|
|
62715
|
+
)
|
|
62684
62716
|
LOOP
|
|
62685
|
-
|
|
62717
|
+
BEGIN
|
|
62718
|
+
EXECUTE format('UPDATE %I SET deleted_at = NULL WHERE deleted_at = ''''', r.table_name);
|
|
62719
|
+
EXCEPTION WHEN others THEN
|
|
62720
|
+
RAISE WARNING 'lattice: skipped deleted_at normalization for %: %', r.table_name, SQLERRM;
|
|
62721
|
+
END;
|
|
62686
62722
|
END LOOP;
|
|
62687
62723
|
END $LATTICE_DAU$;`
|
|
62688
62724
|
}
|
|
@@ -62698,23 +62734,18 @@ END $LATTICE_DAU$;`
|
|
|
62698
62734
|
});
|
|
62699
62735
|
if (migrations.length > 0) await db.migrate(migrations);
|
|
62700
62736
|
}
|
|
62701
|
-
async function
|
|
62702
|
-
|
|
62703
|
-
|
|
62704
|
-
|
|
62705
|
-
|
|
62706
|
-
WHERE table_schema = current_schema() AND table_name = 'files' AND column_name = 'path'`
|
|
62707
|
-
);
|
|
62708
|
-
return rows2.length > 0;
|
|
62709
|
-
}
|
|
62710
|
-
const rows = await allAsyncOrSync(
|
|
62711
|
-
db.adapter,
|
|
62712
|
-
`SELECT 1 AS x FROM pragma_table_info('files') WHERE name = 'path'`
|
|
62713
|
-
);
|
|
62714
|
-
return rows.length > 0;
|
|
62737
|
+
async function filesColumns(db) {
|
|
62738
|
+
const sql = db.getDialect() === "postgres" ? `SELECT column_name AS name FROM information_schema.columns
|
|
62739
|
+
WHERE table_schema = current_schema() AND table_name = 'files'` : `SELECT name FROM pragma_table_info('files')`;
|
|
62740
|
+
const rows = await allAsyncOrSync(db.adapter, sql);
|
|
62741
|
+
return new Set(rows.map((r6) => r6.name));
|
|
62715
62742
|
}
|
|
62716
62743
|
async function backfillFilesPath(db) {
|
|
62717
|
-
|
|
62744
|
+
const cols = await filesColumns(db);
|
|
62745
|
+
if (!cols.has("path")) return;
|
|
62746
|
+
for (const col of ["ref_kind", "ref_uri", "ref_provider", "blob_path"]) {
|
|
62747
|
+
if (!cols.has(col)) await addColumnAsyncOrSync(db.adapter, "files", col, "TEXT");
|
|
62748
|
+
}
|
|
62718
62749
|
await db.migrate([
|
|
62719
62750
|
{
|
|
62720
62751
|
version: FILES_PATH_SENTINEL,
|
package/dist/index.js
CHANGED
|
@@ -62350,8 +62350,18 @@ init_adapter();
|
|
|
62350
62350
|
var DELETED_AT_SENTINEL = "internal:upgrade:deleted-at-empty-to-null:v1";
|
|
62351
62351
|
var FILES_PATH_SENTINEL = "internal:upgrade:files-path-to-local-ref:v1";
|
|
62352
62352
|
async function upgradeLegacyData(db) {
|
|
62353
|
-
await normalizeEmptyDeletedAt(db);
|
|
62354
|
-
await backfillFilesPath(db);
|
|
62353
|
+
await runUpgradeStep("deleted_at normalization", () => normalizeEmptyDeletedAt(db));
|
|
62354
|
+
await runUpgradeStep("files path backfill", () => backfillFilesPath(db));
|
|
62355
|
+
}
|
|
62356
|
+
async function runUpgradeStep(name, fn) {
|
|
62357
|
+
try {
|
|
62358
|
+
await fn();
|
|
62359
|
+
} catch (err) {
|
|
62360
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62361
|
+
console.warn(
|
|
62362
|
+
`[lattice] open-time data upgrade step "${name}" skipped (will retry on next open): ${msg}`
|
|
62363
|
+
);
|
|
62364
|
+
}
|
|
62355
62365
|
}
|
|
62356
62366
|
async function tablesWithDeletedAt(db) {
|
|
62357
62367
|
if (db.getDialect() === "postgres") {
|
|
@@ -62375,14 +62385,40 @@ async function normalizeEmptyDeletedAt(db) {
|
|
|
62375
62385
|
await db.migrate([
|
|
62376
62386
|
{
|
|
62377
62387
|
version: `${DELETED_AT_SENTINEL}:all`,
|
|
62388
|
+
// TYPE-AWARE: only a text-like deleted_at column can hold the legacy ''
|
|
62389
|
+
// sentinel. A column that is a real `timestamptz` (some clouds' deleted_at
|
|
62390
|
+
// is) MUST be skipped: the predicate `deleted_at = ''` forces Postgres to
|
|
62391
|
+
// parse `''::timestamptz` at PLAN time — invalid input that throws regardless
|
|
62392
|
+
// of data (a timestamptz column can't even hold ''), which aborted the entire
|
|
62393
|
+
// workspace open. We BLACKLIST the non-text types (timestamp/date/time,
|
|
62394
|
+
// numeric, boolean, json, uuid, bytea, xml) rather than allow-list text — so
|
|
62395
|
+
// text-like columns we don't enumerate (citext, a DOMAIN over text, a custom
|
|
62396
|
+
// text type) are still normalized instead of silently leaving '' rows that
|
|
62397
|
+
// 4.x's `deleted_at IS NULL` predicate would read as DELETED. PER-TABLE FAULT
|
|
62398
|
+
// ISOLATION is the backstop: each table's UPDATE runs in its own
|
|
62399
|
+
// subtransaction, so an exotic type that still errors on `= ''` (enum, inet,
|
|
62400
|
+
// interval, array) — or a blocking trigger/lock — is warned + skipped, never
|
|
62401
|
+
// fatal to the open.
|
|
62378
62402
|
sql: `DO $LATTICE_DAU$
|
|
62379
62403
|
DECLARE r record;
|
|
62380
62404
|
BEGIN
|
|
62381
62405
|
FOR r IN
|
|
62382
62406
|
SELECT table_name FROM information_schema.columns
|
|
62383
|
-
WHERE table_schema = current_schema()
|
|
62407
|
+
WHERE table_schema = current_schema()
|
|
62408
|
+
AND column_name = 'deleted_at'
|
|
62409
|
+
AND data_type NOT IN (
|
|
62410
|
+
'timestamp with time zone', 'timestamp without time zone',
|
|
62411
|
+
'date', 'time with time zone', 'time without time zone',
|
|
62412
|
+
'integer', 'bigint', 'smallint', 'numeric', 'decimal',
|
|
62413
|
+
'real', 'double precision', 'boolean', 'json', 'jsonb',
|
|
62414
|
+
'bytea', 'uuid', 'xml'
|
|
62415
|
+
)
|
|
62384
62416
|
LOOP
|
|
62385
|
-
|
|
62417
|
+
BEGIN
|
|
62418
|
+
EXECUTE format('UPDATE %I SET deleted_at = NULL WHERE deleted_at = ''''', r.table_name);
|
|
62419
|
+
EXCEPTION WHEN others THEN
|
|
62420
|
+
RAISE WARNING 'lattice: skipped deleted_at normalization for %: %', r.table_name, SQLERRM;
|
|
62421
|
+
END;
|
|
62386
62422
|
END LOOP;
|
|
62387
62423
|
END $LATTICE_DAU$;`
|
|
62388
62424
|
}
|
|
@@ -62398,23 +62434,18 @@ END $LATTICE_DAU$;`
|
|
|
62398
62434
|
});
|
|
62399
62435
|
if (migrations.length > 0) await db.migrate(migrations);
|
|
62400
62436
|
}
|
|
62401
|
-
async function
|
|
62402
|
-
|
|
62403
|
-
|
|
62404
|
-
|
|
62405
|
-
|
|
62406
|
-
WHERE table_schema = current_schema() AND table_name = 'files' AND column_name = 'path'`
|
|
62407
|
-
);
|
|
62408
|
-
return rows2.length > 0;
|
|
62409
|
-
}
|
|
62410
|
-
const rows = await allAsyncOrSync(
|
|
62411
|
-
db.adapter,
|
|
62412
|
-
`SELECT 1 AS x FROM pragma_table_info('files') WHERE name = 'path'`
|
|
62413
|
-
);
|
|
62414
|
-
return rows.length > 0;
|
|
62437
|
+
async function filesColumns(db) {
|
|
62438
|
+
const sql = db.getDialect() === "postgres" ? `SELECT column_name AS name FROM information_schema.columns
|
|
62439
|
+
WHERE table_schema = current_schema() AND table_name = 'files'` : `SELECT name FROM pragma_table_info('files')`;
|
|
62440
|
+
const rows = await allAsyncOrSync(db.adapter, sql);
|
|
62441
|
+
return new Set(rows.map((r6) => r6.name));
|
|
62415
62442
|
}
|
|
62416
62443
|
async function backfillFilesPath(db) {
|
|
62417
|
-
|
|
62444
|
+
const cols = await filesColumns(db);
|
|
62445
|
+
if (!cols.has("path")) return;
|
|
62446
|
+
for (const col of ["ref_kind", "ref_uri", "ref_provider", "blob_path"]) {
|
|
62447
|
+
if (!cols.has(col)) await addColumnAsyncOrSync(db.adapter, "files", col, "TEXT");
|
|
62448
|
+
}
|
|
62418
62449
|
await db.migrate([
|
|
62419
62450
|
{
|
|
62420
62451
|
version: FILES_PATH_SENTINEL,
|
package/package.json
CHANGED