tempest-db-js 0.2.0 → 0.3.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.
- package/README.md +2 -2
- package/dist/bin.cjs +89 -30
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +2 -2
- package/dist/{chunk-QMW4NKMH.js → chunk-OP7FRDI5.js} +199 -34
- package/dist/chunk-OP7FRDI5.js.map +1 -0
- package/dist/{chunk-AGDD7K3F.js → chunk-Q32CBI2A.js} +133 -16
- package/dist/chunk-Q32CBI2A.js.map +1 -0
- package/dist/index.cjs +131 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +1 -1
- package/dist/migrations/index.cjs +196 -30
- package/dist/migrations/index.cjs.map +1 -1
- package/dist/migrations/index.d.cts +42 -5
- package/dist/migrations/index.d.ts +42 -5
- package/dist/migrations/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-AGDD7K3F.js.map +0 -1
- package/dist/chunk-QMW4NKMH.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -288,7 +288,9 @@ var DIALECT_ALIASES = {
|
|
|
288
288
|
sqlite3: "sqlite",
|
|
289
289
|
postgresql: "postgresql",
|
|
290
290
|
postgres: "postgresql",
|
|
291
|
-
pg: "postgresql"
|
|
291
|
+
pg: "postgresql",
|
|
292
|
+
mysql: "mysql",
|
|
293
|
+
mariadb: "mysql"
|
|
292
294
|
};
|
|
293
295
|
function splitScheme(scheme) {
|
|
294
296
|
const plus = scheme.indexOf("+");
|
|
@@ -328,10 +330,10 @@ function parseSqlite(raw, driver, rest) {
|
|
|
328
330
|
raw
|
|
329
331
|
};
|
|
330
332
|
}
|
|
331
|
-
function
|
|
333
|
+
function parseNetworkUrl(raw, driver, rest, dialect) {
|
|
332
334
|
let parsed;
|
|
333
335
|
try {
|
|
334
|
-
parsed = new URL(
|
|
336
|
+
parsed = new URL(`${dialect}:${rest}`);
|
|
335
337
|
} catch {
|
|
336
338
|
throw new InvalidDatabaseUrl(raw, "could not parse host/credentials");
|
|
337
339
|
}
|
|
@@ -339,7 +341,7 @@ function parsePostgres(raw, driver, rest) {
|
|
|
339
341
|
const options = {};
|
|
340
342
|
for (const [key, value] of parsed.searchParams) options[key] = value;
|
|
341
343
|
return {
|
|
342
|
-
dialect
|
|
344
|
+
dialect,
|
|
343
345
|
driver,
|
|
344
346
|
host: parsed.hostname || null,
|
|
345
347
|
port: parsed.port ? Number(parsed.port) : null,
|
|
@@ -364,7 +366,8 @@ function parseDatabaseUrl(url) {
|
|
|
364
366
|
throw new InvalidDatabaseUrl(url, `unknown dialect ${JSON.stringify(base)}`);
|
|
365
367
|
}
|
|
366
368
|
const rest = url.slice(schemeEnd + 1);
|
|
367
|
-
|
|
369
|
+
if (dialect === "sqlite") return parseSqlite(url, driver, rest);
|
|
370
|
+
return parseNetworkUrl(url, driver, rest, dialect);
|
|
368
371
|
}
|
|
369
372
|
function detectDialect(url) {
|
|
370
373
|
return parseDatabaseUrl(url).dialect;
|
|
@@ -663,18 +666,30 @@ var BaseDialect = class _BaseDialect {
|
|
|
663
666
|
const rowsSql = node.values.map(() => `(${columns.map(() => this.placeholder(++position)).join(", ")})`).join(", ");
|
|
664
667
|
let sql2 = `INSERT INTO ${this.quoteId(node.table)} (${colSql}) VALUES ${rowsSql}`;
|
|
665
668
|
if (node.onConflict) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
sql2 += ` ON CONFLICT (${target}) DO UPDATE SET ${assignments}`;
|
|
672
|
-
}
|
|
669
|
+
sql2 += this.renderConflict(
|
|
670
|
+
node.onConflict,
|
|
671
|
+
conflictCols,
|
|
672
|
+
() => this.placeholder(++position)
|
|
673
|
+
);
|
|
673
674
|
}
|
|
674
675
|
sql2 += this.compileReturning(node.returning);
|
|
675
676
|
_BaseDialect.insertTemplates.set(key, sql2);
|
|
676
677
|
return sql2;
|
|
677
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* Render the conflict-handling clause. Standard SQL (SQLite/PostgreSQL) uses
|
|
681
|
+
* `ON CONFLICT (...) DO NOTHING | DO UPDATE SET ...`; MySQL overrides this.
|
|
682
|
+
*
|
|
683
|
+
* @param onConflict The conflict clause from the node.
|
|
684
|
+
* @param conflictCols The columns to overwrite on `DO UPDATE` (empty for nothing).
|
|
685
|
+
* @param nextPlaceholder Yields the next positional placeholder (advances the count).
|
|
686
|
+
*/
|
|
687
|
+
renderConflict(onConflict, conflictCols, nextPlaceholder) {
|
|
688
|
+
const target = onConflict.target.map((c) => this.quoteId(c)).join(", ");
|
|
689
|
+
if (onConflict.update === "nothing") return ` ON CONFLICT (${target}) DO NOTHING`;
|
|
690
|
+
const assignments = conflictCols.map((c) => `${this.quoteId(c)} = ${nextPlaceholder()}`).join(", ");
|
|
691
|
+
return ` ON CONFLICT (${target}) DO UPDATE SET ${assignments}`;
|
|
692
|
+
}
|
|
678
693
|
compileUpdate(node, params) {
|
|
679
694
|
const sets = Object.entries(node.set).map(([col, value]) => `${this.quoteId(col)} = ${params.bind(value)}`).join(", ");
|
|
680
695
|
let sql2 = `UPDATE ${this.quoteId(node.table)} SET ${sets}`;
|
|
@@ -812,8 +827,46 @@ var PostgresDialect = class extends BaseDialect {
|
|
|
812
827
|
return `${column2} ILIKE ${param}`;
|
|
813
828
|
}
|
|
814
829
|
};
|
|
830
|
+
var mysqlQuotedIds = /* @__PURE__ */ new Map();
|
|
831
|
+
var MysqlDialect = class extends BaseDialect {
|
|
832
|
+
name = "mysql";
|
|
833
|
+
placeholder() {
|
|
834
|
+
return "?";
|
|
835
|
+
}
|
|
836
|
+
ilike(column2, param) {
|
|
837
|
+
return `${column2} LIKE ${param}`;
|
|
838
|
+
}
|
|
839
|
+
quoteId(name) {
|
|
840
|
+
const cached = mysqlQuotedIds.get(name);
|
|
841
|
+
if (cached !== void 0) return cached;
|
|
842
|
+
const quoted = `\`${name.replace(/`/g, "``")}\``;
|
|
843
|
+
mysqlQuotedIds.set(name, quoted);
|
|
844
|
+
return quoted;
|
|
845
|
+
}
|
|
846
|
+
renderConflict(onConflict, conflictCols, nextPlaceholder) {
|
|
847
|
+
if (onConflict.update === "nothing") {
|
|
848
|
+
const col = this.quoteId(onConflict.target[0] ?? "id");
|
|
849
|
+
return ` ON DUPLICATE KEY UPDATE ${col} = ${col}`;
|
|
850
|
+
}
|
|
851
|
+
const assignments = conflictCols.map((c) => `${this.quoteId(c)} = ${nextPlaceholder()}`).join(", ");
|
|
852
|
+
return ` ON DUPLICATE KEY UPDATE ${assignments}`;
|
|
853
|
+
}
|
|
854
|
+
compileReturning(returning) {
|
|
855
|
+
if (returning === null) return "";
|
|
856
|
+
throw new Error(
|
|
857
|
+
"RETURNING is not supported on MySQL \u2014 insert, then SELECT by key (e.g. LAST_INSERT_ID())."
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
815
861
|
function getDialect(name) {
|
|
816
|
-
|
|
862
|
+
switch (name) {
|
|
863
|
+
case "sqlite":
|
|
864
|
+
return new SqliteDialect();
|
|
865
|
+
case "postgresql":
|
|
866
|
+
return new PostgresDialect();
|
|
867
|
+
case "mysql":
|
|
868
|
+
return new MysqlDialect();
|
|
869
|
+
}
|
|
817
870
|
}
|
|
818
871
|
|
|
819
872
|
// src/join.ts
|
|
@@ -1576,12 +1629,76 @@ function createEngine(url, options) {
|
|
|
1576
1629
|
options?.onQuery
|
|
1577
1630
|
);
|
|
1578
1631
|
}
|
|
1632
|
+
if (parsed.dialect === "mysql") {
|
|
1633
|
+
return new AsyncEngine(
|
|
1634
|
+
createMysqlDriver(parsed.raw, options?.pool),
|
|
1635
|
+
"mysql",
|
|
1636
|
+
options?.onQuery
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1579
1639
|
return new AsyncEngine(
|
|
1580
1640
|
createPostgresDriver(parsed.raw, options?.pool),
|
|
1581
1641
|
"postgresql",
|
|
1582
1642
|
options?.onQuery
|
|
1583
1643
|
);
|
|
1584
1644
|
}
|
|
1645
|
+
function encodeMysqlParam(value) {
|
|
1646
|
+
if (value === void 0 || value === null) return null;
|
|
1647
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
1648
|
+
if (value instanceof Uint8Array) return value;
|
|
1649
|
+
if (value instanceof Date) return value;
|
|
1650
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
1651
|
+
return value;
|
|
1652
|
+
}
|
|
1653
|
+
function toMysqlResult(rows) {
|
|
1654
|
+
if (Array.isArray(rows)) {
|
|
1655
|
+
return { rows, changes: 0 };
|
|
1656
|
+
}
|
|
1657
|
+
const header = rows;
|
|
1658
|
+
return { rows: [], changes: header.affectedRows ?? 0 };
|
|
1659
|
+
}
|
|
1660
|
+
function createMysqlDriver(url, pool) {
|
|
1661
|
+
let poolHandle;
|
|
1662
|
+
const ensure = async () => {
|
|
1663
|
+
if (poolHandle) return;
|
|
1664
|
+
const moduleName = "mysql2/promise";
|
|
1665
|
+
const mod = await import(
|
|
1666
|
+
/* @vite-ignore */
|
|
1667
|
+
moduleName
|
|
1668
|
+
);
|
|
1669
|
+
const opts = { uri: url };
|
|
1670
|
+
if (pool?.size !== void 0) opts.connectionLimit = pool.size;
|
|
1671
|
+
if (pool?.idleTimeoutMs !== void 0) opts.idleTimeout = pool.idleTimeoutMs;
|
|
1672
|
+
if (pool?.connectTimeoutMs !== void 0) opts.connectTimeout = pool.connectTimeoutMs;
|
|
1673
|
+
poolHandle = mod.createPool(opts);
|
|
1674
|
+
};
|
|
1675
|
+
const runOn = async (queryable, sql2, params) => {
|
|
1676
|
+
const [rows] = await queryable.query(sql2, params.map(encodeMysqlParam));
|
|
1677
|
+
return toMysqlResult(rows);
|
|
1678
|
+
};
|
|
1679
|
+
return {
|
|
1680
|
+
async execute(sql2, params) {
|
|
1681
|
+
await ensure();
|
|
1682
|
+
return runOn(poolHandle, sql2, params);
|
|
1683
|
+
},
|
|
1684
|
+
async reserve() {
|
|
1685
|
+
await ensure();
|
|
1686
|
+
const conn = await poolHandle.getConnection();
|
|
1687
|
+
return {
|
|
1688
|
+
execute: (sql2, params) => runOn(conn, sql2, params),
|
|
1689
|
+
async release() {
|
|
1690
|
+
conn.release();
|
|
1691
|
+
},
|
|
1692
|
+
async close() {
|
|
1693
|
+
conn.release();
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
1696
|
+
},
|
|
1697
|
+
async close() {
|
|
1698
|
+
if (poolHandle) await poolHandle.end();
|
|
1699
|
+
}
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1585
1702
|
function toPostgresResult(rows) {
|
|
1586
1703
|
const arr = rows;
|
|
1587
1704
|
return { rows: Array.from(arr), changes: arr.count ?? arr.length };
|
|
@@ -1785,6 +1902,7 @@ exports.InsertBuilder = InsertBuilder;
|
|
|
1785
1902
|
exports.InvalidDatabaseUrl = InvalidDatabaseUrl;
|
|
1786
1903
|
exports.JoinBuilder = JoinBuilder;
|
|
1787
1904
|
exports.Model = Model;
|
|
1905
|
+
exports.MysqlDialect = MysqlDialect;
|
|
1788
1906
|
exports.NoResultError = NoResultError;
|
|
1789
1907
|
exports.NodeSqliteDriver = NodeSqliteDriver;
|
|
1790
1908
|
exports.OPERATORS = OPERATORS;
|