latticesql 1.6.0 → 1.6.2
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 +143 -1
- package/dist/index.cjs +143 -1
- package/dist/index.js +143 -1
- package/dist/postgres-worker.js +72 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6226,7 +6226,146 @@ var PostgresAdapter = class {
|
|
|
6226
6226
|
return result;
|
|
6227
6227
|
}
|
|
6228
6228
|
};
|
|
6229
|
-
function
|
|
6229
|
+
function translateDialect(sql) {
|
|
6230
|
+
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
6231
|
+
throw new Error(
|
|
6232
|
+
"PostgresAdapter: 'INSERT OR REPLACE INTO ...' is not auto-translated. Use INSERT INTO ... ON CONFLICT (col) DO UPDATE SET ... in your migration."
|
|
6233
|
+
);
|
|
6234
|
+
}
|
|
6235
|
+
let s = mapCodeRegions(sql, (code) => {
|
|
6236
|
+
let mutated = code;
|
|
6237
|
+
let needsOnConflict = false;
|
|
6238
|
+
mutated = mutated.replace(/INSERT(\s+)OR\s+IGNORE(\s+)INTO/gi, (_m, w1, _w2) => {
|
|
6239
|
+
needsOnConflict = true;
|
|
6240
|
+
return `INSERT${w1}INTO`;
|
|
6241
|
+
});
|
|
6242
|
+
if (needsOnConflict && !/ON\s+CONFLICT/i.test(mutated)) {
|
|
6243
|
+
mutated = mutated.replace(/(\s*;?\s*)$/, " ON CONFLICT DO NOTHING$1");
|
|
6244
|
+
}
|
|
6245
|
+
return mutated;
|
|
6246
|
+
});
|
|
6247
|
+
s = replaceFunction(s, "hex", (arg) => `encode(${arg}, 'hex')`);
|
|
6248
|
+
s = replaceFunction(s, "randomblob", (arg) => `gen_random_bytes(${arg})`);
|
|
6249
|
+
return s;
|
|
6250
|
+
}
|
|
6251
|
+
function mapCodeRegions(sql, xform) {
|
|
6252
|
+
let out = "";
|
|
6253
|
+
let codeStart = 0;
|
|
6254
|
+
let i = 0;
|
|
6255
|
+
const flushCode = (end) => {
|
|
6256
|
+
if (end > codeStart) out += xform(sql.slice(codeStart, end));
|
|
6257
|
+
};
|
|
6258
|
+
while (i < sql.length) {
|
|
6259
|
+
const ch = sql[i];
|
|
6260
|
+
if (ch === "'") {
|
|
6261
|
+
flushCode(i);
|
|
6262
|
+
out += "'";
|
|
6263
|
+
i++;
|
|
6264
|
+
while (i < sql.length) {
|
|
6265
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
6266
|
+
out += "''";
|
|
6267
|
+
i += 2;
|
|
6268
|
+
continue;
|
|
6269
|
+
}
|
|
6270
|
+
out += sql[i];
|
|
6271
|
+
if (sql[i] === "'") {
|
|
6272
|
+
i++;
|
|
6273
|
+
break;
|
|
6274
|
+
}
|
|
6275
|
+
i++;
|
|
6276
|
+
}
|
|
6277
|
+
codeStart = i;
|
|
6278
|
+
continue;
|
|
6279
|
+
}
|
|
6280
|
+
if (ch === '"') {
|
|
6281
|
+
flushCode(i);
|
|
6282
|
+
out += '"';
|
|
6283
|
+
i++;
|
|
6284
|
+
while (i < sql.length) {
|
|
6285
|
+
out += sql[i];
|
|
6286
|
+
if (sql[i] === '"') {
|
|
6287
|
+
i++;
|
|
6288
|
+
break;
|
|
6289
|
+
}
|
|
6290
|
+
i++;
|
|
6291
|
+
}
|
|
6292
|
+
codeStart = i;
|
|
6293
|
+
continue;
|
|
6294
|
+
}
|
|
6295
|
+
if (ch === "-" && sql[i + 1] === "-") {
|
|
6296
|
+
flushCode(i);
|
|
6297
|
+
while (i < sql.length && sql[i] !== "\n") {
|
|
6298
|
+
out += sql[i];
|
|
6299
|
+
i++;
|
|
6300
|
+
}
|
|
6301
|
+
codeStart = i;
|
|
6302
|
+
continue;
|
|
6303
|
+
}
|
|
6304
|
+
if (ch === "/" && sql[i + 1] === "*") {
|
|
6305
|
+
flushCode(i);
|
|
6306
|
+
out += "/*";
|
|
6307
|
+
i += 2;
|
|
6308
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/")) {
|
|
6309
|
+
out += sql[i];
|
|
6310
|
+
i++;
|
|
6311
|
+
}
|
|
6312
|
+
if (i < sql.length) {
|
|
6313
|
+
out += "*/";
|
|
6314
|
+
i += 2;
|
|
6315
|
+
}
|
|
6316
|
+
codeStart = i;
|
|
6317
|
+
continue;
|
|
6318
|
+
}
|
|
6319
|
+
i++;
|
|
6320
|
+
}
|
|
6321
|
+
flushCode(sql.length);
|
|
6322
|
+
return out;
|
|
6323
|
+
}
|
|
6324
|
+
function replaceFunction(sql, name, translate) {
|
|
6325
|
+
const pattern = new RegExp(`\\b${name}\\s*\\(`, "gi");
|
|
6326
|
+
let out = "";
|
|
6327
|
+
let lastIndex = 0;
|
|
6328
|
+
let match;
|
|
6329
|
+
while ((match = pattern.exec(sql)) !== null) {
|
|
6330
|
+
out += sql.slice(lastIndex, match.index);
|
|
6331
|
+
let depth = 1;
|
|
6332
|
+
let i = match.index + match[0].length;
|
|
6333
|
+
const argStart = i;
|
|
6334
|
+
while (i < sql.length && depth > 0) {
|
|
6335
|
+
const ch = sql[i];
|
|
6336
|
+
if (ch === "'") {
|
|
6337
|
+
i++;
|
|
6338
|
+
while (i < sql.length) {
|
|
6339
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
6340
|
+
i += 2;
|
|
6341
|
+
continue;
|
|
6342
|
+
}
|
|
6343
|
+
if (sql[i] === "'") {
|
|
6344
|
+
i++;
|
|
6345
|
+
break;
|
|
6346
|
+
}
|
|
6347
|
+
i++;
|
|
6348
|
+
}
|
|
6349
|
+
continue;
|
|
6350
|
+
}
|
|
6351
|
+
if (ch === "(") depth++;
|
|
6352
|
+
else if (ch === ")") depth--;
|
|
6353
|
+
if (depth > 0) i++;
|
|
6354
|
+
}
|
|
6355
|
+
if (depth !== 0) {
|
|
6356
|
+
out += sql.slice(match.index);
|
|
6357
|
+
lastIndex = sql.length;
|
|
6358
|
+
break;
|
|
6359
|
+
}
|
|
6360
|
+
const arg = sql.slice(argStart, i);
|
|
6361
|
+
out += translate(arg);
|
|
6362
|
+
lastIndex = i + 1;
|
|
6363
|
+
pattern.lastIndex = lastIndex;
|
|
6364
|
+
}
|
|
6365
|
+
out += sql.slice(lastIndex);
|
|
6366
|
+
return out;
|
|
6367
|
+
}
|
|
6368
|
+
function rewriteParams(sql) {
|
|
6230
6369
|
let out = "";
|
|
6231
6370
|
let i = 0;
|
|
6232
6371
|
let n = 1;
|
|
@@ -6293,6 +6432,9 @@ function rewrite(sql) {
|
|
|
6293
6432
|
}
|
|
6294
6433
|
return out;
|
|
6295
6434
|
}
|
|
6435
|
+
function rewrite(sql) {
|
|
6436
|
+
return rewriteParams(translateDialect(sql));
|
|
6437
|
+
}
|
|
6296
6438
|
|
|
6297
6439
|
// src/schema/manager.ts
|
|
6298
6440
|
var SchemaManager = class {
|
package/dist/index.cjs
CHANGED
|
@@ -5969,7 +5969,146 @@ var PostgresAdapter = class {
|
|
|
5969
5969
|
return result;
|
|
5970
5970
|
}
|
|
5971
5971
|
};
|
|
5972
|
-
function
|
|
5972
|
+
function translateDialect(sql) {
|
|
5973
|
+
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
5974
|
+
throw new Error(
|
|
5975
|
+
"PostgresAdapter: 'INSERT OR REPLACE INTO ...' is not auto-translated. Use INSERT INTO ... ON CONFLICT (col) DO UPDATE SET ... in your migration."
|
|
5976
|
+
);
|
|
5977
|
+
}
|
|
5978
|
+
let s = mapCodeRegions(sql, (code) => {
|
|
5979
|
+
let mutated = code;
|
|
5980
|
+
let needsOnConflict = false;
|
|
5981
|
+
mutated = mutated.replace(/INSERT(\s+)OR\s+IGNORE(\s+)INTO/gi, (_m, w1, _w2) => {
|
|
5982
|
+
needsOnConflict = true;
|
|
5983
|
+
return `INSERT${w1}INTO`;
|
|
5984
|
+
});
|
|
5985
|
+
if (needsOnConflict && !/ON\s+CONFLICT/i.test(mutated)) {
|
|
5986
|
+
mutated = mutated.replace(/(\s*;?\s*)$/, " ON CONFLICT DO NOTHING$1");
|
|
5987
|
+
}
|
|
5988
|
+
return mutated;
|
|
5989
|
+
});
|
|
5990
|
+
s = replaceFunction(s, "hex", (arg) => `encode(${arg}, 'hex')`);
|
|
5991
|
+
s = replaceFunction(s, "randomblob", (arg) => `gen_random_bytes(${arg})`);
|
|
5992
|
+
return s;
|
|
5993
|
+
}
|
|
5994
|
+
function mapCodeRegions(sql, xform) {
|
|
5995
|
+
let out = "";
|
|
5996
|
+
let codeStart = 0;
|
|
5997
|
+
let i = 0;
|
|
5998
|
+
const flushCode = (end) => {
|
|
5999
|
+
if (end > codeStart) out += xform(sql.slice(codeStart, end));
|
|
6000
|
+
};
|
|
6001
|
+
while (i < sql.length) {
|
|
6002
|
+
const ch = sql[i];
|
|
6003
|
+
if (ch === "'") {
|
|
6004
|
+
flushCode(i);
|
|
6005
|
+
out += "'";
|
|
6006
|
+
i++;
|
|
6007
|
+
while (i < sql.length) {
|
|
6008
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
6009
|
+
out += "''";
|
|
6010
|
+
i += 2;
|
|
6011
|
+
continue;
|
|
6012
|
+
}
|
|
6013
|
+
out += sql[i];
|
|
6014
|
+
if (sql[i] === "'") {
|
|
6015
|
+
i++;
|
|
6016
|
+
break;
|
|
6017
|
+
}
|
|
6018
|
+
i++;
|
|
6019
|
+
}
|
|
6020
|
+
codeStart = i;
|
|
6021
|
+
continue;
|
|
6022
|
+
}
|
|
6023
|
+
if (ch === '"') {
|
|
6024
|
+
flushCode(i);
|
|
6025
|
+
out += '"';
|
|
6026
|
+
i++;
|
|
6027
|
+
while (i < sql.length) {
|
|
6028
|
+
out += sql[i];
|
|
6029
|
+
if (sql[i] === '"') {
|
|
6030
|
+
i++;
|
|
6031
|
+
break;
|
|
6032
|
+
}
|
|
6033
|
+
i++;
|
|
6034
|
+
}
|
|
6035
|
+
codeStart = i;
|
|
6036
|
+
continue;
|
|
6037
|
+
}
|
|
6038
|
+
if (ch === "-" && sql[i + 1] === "-") {
|
|
6039
|
+
flushCode(i);
|
|
6040
|
+
while (i < sql.length && sql[i] !== "\n") {
|
|
6041
|
+
out += sql[i];
|
|
6042
|
+
i++;
|
|
6043
|
+
}
|
|
6044
|
+
codeStart = i;
|
|
6045
|
+
continue;
|
|
6046
|
+
}
|
|
6047
|
+
if (ch === "/" && sql[i + 1] === "*") {
|
|
6048
|
+
flushCode(i);
|
|
6049
|
+
out += "/*";
|
|
6050
|
+
i += 2;
|
|
6051
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/")) {
|
|
6052
|
+
out += sql[i];
|
|
6053
|
+
i++;
|
|
6054
|
+
}
|
|
6055
|
+
if (i < sql.length) {
|
|
6056
|
+
out += "*/";
|
|
6057
|
+
i += 2;
|
|
6058
|
+
}
|
|
6059
|
+
codeStart = i;
|
|
6060
|
+
continue;
|
|
6061
|
+
}
|
|
6062
|
+
i++;
|
|
6063
|
+
}
|
|
6064
|
+
flushCode(sql.length);
|
|
6065
|
+
return out;
|
|
6066
|
+
}
|
|
6067
|
+
function replaceFunction(sql, name, translate) {
|
|
6068
|
+
const pattern = new RegExp(`\\b${name}\\s*\\(`, "gi");
|
|
6069
|
+
let out = "";
|
|
6070
|
+
let lastIndex = 0;
|
|
6071
|
+
let match;
|
|
6072
|
+
while ((match = pattern.exec(sql)) !== null) {
|
|
6073
|
+
out += sql.slice(lastIndex, match.index);
|
|
6074
|
+
let depth = 1;
|
|
6075
|
+
let i = match.index + match[0].length;
|
|
6076
|
+
const argStart = i;
|
|
6077
|
+
while (i < sql.length && depth > 0) {
|
|
6078
|
+
const ch = sql[i];
|
|
6079
|
+
if (ch === "'") {
|
|
6080
|
+
i++;
|
|
6081
|
+
while (i < sql.length) {
|
|
6082
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
6083
|
+
i += 2;
|
|
6084
|
+
continue;
|
|
6085
|
+
}
|
|
6086
|
+
if (sql[i] === "'") {
|
|
6087
|
+
i++;
|
|
6088
|
+
break;
|
|
6089
|
+
}
|
|
6090
|
+
i++;
|
|
6091
|
+
}
|
|
6092
|
+
continue;
|
|
6093
|
+
}
|
|
6094
|
+
if (ch === "(") depth++;
|
|
6095
|
+
else if (ch === ")") depth--;
|
|
6096
|
+
if (depth > 0) i++;
|
|
6097
|
+
}
|
|
6098
|
+
if (depth !== 0) {
|
|
6099
|
+
out += sql.slice(match.index);
|
|
6100
|
+
lastIndex = sql.length;
|
|
6101
|
+
break;
|
|
6102
|
+
}
|
|
6103
|
+
const arg = sql.slice(argStart, i);
|
|
6104
|
+
out += translate(arg);
|
|
6105
|
+
lastIndex = i + 1;
|
|
6106
|
+
pattern.lastIndex = lastIndex;
|
|
6107
|
+
}
|
|
6108
|
+
out += sql.slice(lastIndex);
|
|
6109
|
+
return out;
|
|
6110
|
+
}
|
|
6111
|
+
function rewriteParams(sql) {
|
|
5973
6112
|
let out = "";
|
|
5974
6113
|
let i = 0;
|
|
5975
6114
|
let n = 1;
|
|
@@ -6036,6 +6175,9 @@ function rewrite(sql) {
|
|
|
6036
6175
|
}
|
|
6037
6176
|
return out;
|
|
6038
6177
|
}
|
|
6178
|
+
function rewrite(sql) {
|
|
6179
|
+
return rewriteParams(translateDialect(sql));
|
|
6180
|
+
}
|
|
6039
6181
|
|
|
6040
6182
|
// src/schema/manager.ts
|
|
6041
6183
|
var SchemaManager = class {
|
package/dist/index.js
CHANGED
|
@@ -5912,7 +5912,146 @@ var PostgresAdapter = class {
|
|
|
5912
5912
|
return result;
|
|
5913
5913
|
}
|
|
5914
5914
|
};
|
|
5915
|
-
function
|
|
5915
|
+
function translateDialect(sql) {
|
|
5916
|
+
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
5917
|
+
throw new Error(
|
|
5918
|
+
"PostgresAdapter: 'INSERT OR REPLACE INTO ...' is not auto-translated. Use INSERT INTO ... ON CONFLICT (col) DO UPDATE SET ... in your migration."
|
|
5919
|
+
);
|
|
5920
|
+
}
|
|
5921
|
+
let s = mapCodeRegions(sql, (code) => {
|
|
5922
|
+
let mutated = code;
|
|
5923
|
+
let needsOnConflict = false;
|
|
5924
|
+
mutated = mutated.replace(/INSERT(\s+)OR\s+IGNORE(\s+)INTO/gi, (_m, w1, _w2) => {
|
|
5925
|
+
needsOnConflict = true;
|
|
5926
|
+
return `INSERT${w1}INTO`;
|
|
5927
|
+
});
|
|
5928
|
+
if (needsOnConflict && !/ON\s+CONFLICT/i.test(mutated)) {
|
|
5929
|
+
mutated = mutated.replace(/(\s*;?\s*)$/, " ON CONFLICT DO NOTHING$1");
|
|
5930
|
+
}
|
|
5931
|
+
return mutated;
|
|
5932
|
+
});
|
|
5933
|
+
s = replaceFunction(s, "hex", (arg) => `encode(${arg}, 'hex')`);
|
|
5934
|
+
s = replaceFunction(s, "randomblob", (arg) => `gen_random_bytes(${arg})`);
|
|
5935
|
+
return s;
|
|
5936
|
+
}
|
|
5937
|
+
function mapCodeRegions(sql, xform) {
|
|
5938
|
+
let out = "";
|
|
5939
|
+
let codeStart = 0;
|
|
5940
|
+
let i = 0;
|
|
5941
|
+
const flushCode = (end) => {
|
|
5942
|
+
if (end > codeStart) out += xform(sql.slice(codeStart, end));
|
|
5943
|
+
};
|
|
5944
|
+
while (i < sql.length) {
|
|
5945
|
+
const ch = sql[i];
|
|
5946
|
+
if (ch === "'") {
|
|
5947
|
+
flushCode(i);
|
|
5948
|
+
out += "'";
|
|
5949
|
+
i++;
|
|
5950
|
+
while (i < sql.length) {
|
|
5951
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
5952
|
+
out += "''";
|
|
5953
|
+
i += 2;
|
|
5954
|
+
continue;
|
|
5955
|
+
}
|
|
5956
|
+
out += sql[i];
|
|
5957
|
+
if (sql[i] === "'") {
|
|
5958
|
+
i++;
|
|
5959
|
+
break;
|
|
5960
|
+
}
|
|
5961
|
+
i++;
|
|
5962
|
+
}
|
|
5963
|
+
codeStart = i;
|
|
5964
|
+
continue;
|
|
5965
|
+
}
|
|
5966
|
+
if (ch === '"') {
|
|
5967
|
+
flushCode(i);
|
|
5968
|
+
out += '"';
|
|
5969
|
+
i++;
|
|
5970
|
+
while (i < sql.length) {
|
|
5971
|
+
out += sql[i];
|
|
5972
|
+
if (sql[i] === '"') {
|
|
5973
|
+
i++;
|
|
5974
|
+
break;
|
|
5975
|
+
}
|
|
5976
|
+
i++;
|
|
5977
|
+
}
|
|
5978
|
+
codeStart = i;
|
|
5979
|
+
continue;
|
|
5980
|
+
}
|
|
5981
|
+
if (ch === "-" && sql[i + 1] === "-") {
|
|
5982
|
+
flushCode(i);
|
|
5983
|
+
while (i < sql.length && sql[i] !== "\n") {
|
|
5984
|
+
out += sql[i];
|
|
5985
|
+
i++;
|
|
5986
|
+
}
|
|
5987
|
+
codeStart = i;
|
|
5988
|
+
continue;
|
|
5989
|
+
}
|
|
5990
|
+
if (ch === "/" && sql[i + 1] === "*") {
|
|
5991
|
+
flushCode(i);
|
|
5992
|
+
out += "/*";
|
|
5993
|
+
i += 2;
|
|
5994
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/")) {
|
|
5995
|
+
out += sql[i];
|
|
5996
|
+
i++;
|
|
5997
|
+
}
|
|
5998
|
+
if (i < sql.length) {
|
|
5999
|
+
out += "*/";
|
|
6000
|
+
i += 2;
|
|
6001
|
+
}
|
|
6002
|
+
codeStart = i;
|
|
6003
|
+
continue;
|
|
6004
|
+
}
|
|
6005
|
+
i++;
|
|
6006
|
+
}
|
|
6007
|
+
flushCode(sql.length);
|
|
6008
|
+
return out;
|
|
6009
|
+
}
|
|
6010
|
+
function replaceFunction(sql, name, translate) {
|
|
6011
|
+
const pattern = new RegExp(`\\b${name}\\s*\\(`, "gi");
|
|
6012
|
+
let out = "";
|
|
6013
|
+
let lastIndex = 0;
|
|
6014
|
+
let match;
|
|
6015
|
+
while ((match = pattern.exec(sql)) !== null) {
|
|
6016
|
+
out += sql.slice(lastIndex, match.index);
|
|
6017
|
+
let depth = 1;
|
|
6018
|
+
let i = match.index + match[0].length;
|
|
6019
|
+
const argStart = i;
|
|
6020
|
+
while (i < sql.length && depth > 0) {
|
|
6021
|
+
const ch = sql[i];
|
|
6022
|
+
if (ch === "'") {
|
|
6023
|
+
i++;
|
|
6024
|
+
while (i < sql.length) {
|
|
6025
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
6026
|
+
i += 2;
|
|
6027
|
+
continue;
|
|
6028
|
+
}
|
|
6029
|
+
if (sql[i] === "'") {
|
|
6030
|
+
i++;
|
|
6031
|
+
break;
|
|
6032
|
+
}
|
|
6033
|
+
i++;
|
|
6034
|
+
}
|
|
6035
|
+
continue;
|
|
6036
|
+
}
|
|
6037
|
+
if (ch === "(") depth++;
|
|
6038
|
+
else if (ch === ")") depth--;
|
|
6039
|
+
if (depth > 0) i++;
|
|
6040
|
+
}
|
|
6041
|
+
if (depth !== 0) {
|
|
6042
|
+
out += sql.slice(match.index);
|
|
6043
|
+
lastIndex = sql.length;
|
|
6044
|
+
break;
|
|
6045
|
+
}
|
|
6046
|
+
const arg = sql.slice(argStart, i);
|
|
6047
|
+
out += translate(arg);
|
|
6048
|
+
lastIndex = i + 1;
|
|
6049
|
+
pattern.lastIndex = lastIndex;
|
|
6050
|
+
}
|
|
6051
|
+
out += sql.slice(lastIndex);
|
|
6052
|
+
return out;
|
|
6053
|
+
}
|
|
6054
|
+
function rewriteParams(sql) {
|
|
5916
6055
|
let out = "";
|
|
5917
6056
|
let i = 0;
|
|
5918
6057
|
let n = 1;
|
|
@@ -5979,6 +6118,9 @@ function rewrite(sql) {
|
|
|
5979
6118
|
}
|
|
5980
6119
|
return out;
|
|
5981
6120
|
}
|
|
6121
|
+
function rewrite(sql) {
|
|
6122
|
+
return rewriteParams(translateDialect(sql));
|
|
6123
|
+
}
|
|
5982
6124
|
|
|
5983
6125
|
// src/schema/manager.ts
|
|
5984
6126
|
var SchemaManager = class {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// src/db/postgres-worker.ts
|
|
4
|
+
var import_synckit = require("synckit");
|
|
5
|
+
var { Client } = require("pg");
|
|
6
|
+
var client = null;
|
|
7
|
+
function ensureClient() {
|
|
8
|
+
if (!client) throw new Error("PostgresAdapter worker: client not opened");
|
|
9
|
+
return client;
|
|
10
|
+
}
|
|
11
|
+
(0, import_synckit.runAsWorker)(async (action) => {
|
|
12
|
+
try {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case "open": {
|
|
15
|
+
if (client) return { ok: true };
|
|
16
|
+
client = new Client({ connectionString: action.connectionString });
|
|
17
|
+
await client.connect();
|
|
18
|
+
try {
|
|
19
|
+
await client.query("CREATE EXTENSION IF NOT EXISTS pgcrypto");
|
|
20
|
+
} catch (extErr) {
|
|
21
|
+
console.warn(
|
|
22
|
+
"[PostgresAdapter] CREATE EXTENSION pgcrypto failed (may already be enabled by your provider):",
|
|
23
|
+
extErr instanceof Error ? extErr.message : extErr
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return { ok: true };
|
|
27
|
+
}
|
|
28
|
+
case "close": {
|
|
29
|
+
if (client) {
|
|
30
|
+
await client.end();
|
|
31
|
+
client = null;
|
|
32
|
+
}
|
|
33
|
+
return { ok: true };
|
|
34
|
+
}
|
|
35
|
+
case "run": {
|
|
36
|
+
const r = await ensureClient().query(action.sql, action.params);
|
|
37
|
+
return { ok: true, rowCount: r.rowCount ?? 0 };
|
|
38
|
+
}
|
|
39
|
+
case "get": {
|
|
40
|
+
const r = await ensureClient().query(action.sql, action.params);
|
|
41
|
+
return { ok: true, rows: r.rows.slice(0, 1) };
|
|
42
|
+
}
|
|
43
|
+
case "all": {
|
|
44
|
+
const r = await ensureClient().query(action.sql, action.params);
|
|
45
|
+
return { ok: true, rows: r.rows };
|
|
46
|
+
}
|
|
47
|
+
case "introspectColumns": {
|
|
48
|
+
const r = await ensureClient().query(
|
|
49
|
+
`SELECT column_name FROM information_schema.columns
|
|
50
|
+
WHERE table_schema = current_schema() AND table_name = $1
|
|
51
|
+
ORDER BY ordinal_position`,
|
|
52
|
+
[action.table]
|
|
53
|
+
);
|
|
54
|
+
return { ok: true, rows: r.rows };
|
|
55
|
+
}
|
|
56
|
+
case "addColumn": {
|
|
57
|
+
const upper = action.typeSpec.toUpperCase();
|
|
58
|
+
if (upper.includes("PRIMARY KEY")) return { ok: true };
|
|
59
|
+
const translated = translateTypeSpec(action.typeSpec);
|
|
60
|
+
await ensureClient().query(
|
|
61
|
+
`ALTER TABLE "${action.table}" ADD COLUMN IF NOT EXISTS "${action.column}" ${translated}`
|
|
62
|
+
);
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
function translateTypeSpec(typeSpec) {
|
|
71
|
+
return typeSpec.replace(/\bBLOB\b/gi, "BYTEA").replace(/\bdatetime\(\s*'now'\s*\)/gi, "NOW()").replace(/\bRANDOM\(\)/gi, "random()");
|
|
72
|
+
}
|
package/package.json
CHANGED