litedbmodel 2.2.6 → 2.2.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/README.md +146 -86
- package/dist/Column.d.ts +30 -6
- package/dist/Column.d.ts.map +1 -1
- package/dist/Column.js +30 -10
- package/dist/Column.js.map +1 -1
- package/dist/DBModel.d.ts +28 -16
- package/dist/DBModel.d.ts.map +1 -1
- package/dist/DBModel.js +60 -46
- package/dist/DBModel.js.map +1 -1
- package/dist/LazyRelation.d.ts +2 -2
- package/dist/LazyRelation.js +2 -2
- package/dist/TypeCast.d.ts +2 -2
- package/dist/TypeCast.d.ts.map +1 -1
- package/dist/TypeCast.js +7 -9
- package/dist/TypeCast.js.map +1 -1
- package/dist/decorators.d.ts +128 -60
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +393 -251
- package/dist/decorators.js.map +1 -1
- package/dist/drivers/MysqlHelper.d.ts +3 -3
- package/dist/drivers/MysqlHelper.d.ts.map +1 -1
- package/dist/drivers/MysqlHelper.js +3 -17
- package/dist/drivers/MysqlHelper.js.map +1 -1
- package/dist/drivers/MysqlSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/MysqlSqlBuilder.js +2 -13
- package/dist/drivers/MysqlSqlBuilder.js.map +1 -1
- package/dist/drivers/PostgresHelper.d.ts +3 -2
- package/dist/drivers/PostgresHelper.d.ts.map +1 -1
- package/dist/drivers/PostgresHelper.js +3 -16
- package/dist/drivers/PostgresHelper.js.map +1 -1
- package/dist/drivers/PostgresSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/PostgresSqlBuilder.js +2 -14
- package/dist/drivers/PostgresSqlBuilder.js.map +1 -1
- package/dist/drivers/SqliteHelper.d.ts +4 -2
- package/dist/drivers/SqliteHelper.d.ts.map +1 -1
- package/dist/drivers/SqliteHelper.js +4 -2
- package/dist/drivers/SqliteHelper.js.map +1 -1
- package/dist/drivers/SqliteSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/SqliteSqlBuilder.js +2 -13
- package/dist/drivers/SqliteSqlBuilder.js.map +1 -1
- package/dist/index.cjs +861 -816
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scp/coltype.d.ts +14 -5
- package/dist/scp/coltype.d.ts.map +1 -1
- package/dist/scp/coltype.js +35 -36
- package/dist/scp/coltype.js.map +1 -1
- package/dist/scp/decorator-adapter.d.ts +12 -15
- package/dist/scp/decorator-adapter.d.ts.map +1 -1
- package/dist/scp/decorator-adapter.js +13 -15
- package/dist/scp/decorator-adapter.js.map +1 -1
- package/dist/scp/index.cjs +237 -233
- package/dist/scp/index.mjs +237 -233
- package/dist/scp/makesql/json-array.d.ts +6 -0
- package/dist/scp/makesql/json-array.d.ts.map +1 -1
- package/dist/scp/makesql/json-array.js +17 -2
- package/dist/scp/makesql/json-array.js.map +1 -1
- package/dist/scp/makesql/tx.d.ts.map +1 -1
- package/dist/scp/makesql/tx.js +1 -3
- package/dist/scp/makesql/tx.js.map +1 -1
- package/dist/scp/relation.d.ts.map +1 -1
- package/dist/scp/relation.js +8 -10
- package/dist/scp/relation.js.map +1 -1
- package/docs/BENCHMARK.md +3 -3
- package/docs/COMPARISON.md +7 -7
- package/docs/api/README.md +18 -18
- package/docs/api/classes/Conditions.md +10 -10
- package/docs/api/classes/DBHandler.md +1 -1
- package/docs/api/classes/DBModel.md +84 -84
- package/docs/api/classes/LimitExceededError.md +1 -1
- package/docs/api/classes/Middleware.md +1 -1
- package/docs/api/classes/SqlRaw.md +1 -1
- package/docs/api/classes/SqlRef.md +1 -1
- package/docs/api/classes/Values.md +6 -6
- package/docs/api/classes/WriteInReadOnlyContextError.md +1 -1
- package/docs/api/classes/WriteOutsideTransactionError.md +1 -1
- package/docs/api/functions/belongsTo.md +10 -4
- package/docs/api/functions/closeAllPools.md +1 -1
- package/docs/api/functions/condsToRecord.md +4 -3
- package/docs/api/functions/createMiddleware.md +1 -1
- package/docs/api/functions/createPostgresDriver.md +1 -1
- package/docs/api/functions/createSqliteDriver.md +1 -1
- package/docs/api/functions/dbCast.md +1 -1
- package/docs/api/functions/dbCastIn.md +1 -1
- package/docs/api/functions/dbDynamic.md +1 -1
- package/docs/api/functions/dbFalse.md +1 -1
- package/docs/api/functions/dbImmediate.md +1 -1
- package/docs/api/functions/dbIn.md +1 -1
- package/docs/api/functions/dbNotNull.md +1 -1
- package/docs/api/functions/dbNow.md +1 -1
- package/docs/api/functions/dbNull.md +1 -1
- package/docs/api/functions/dbRaw.md +1 -1
- package/docs/api/functions/dbTrue.md +1 -1
- package/docs/api/functions/dbUuid.md +1 -1
- package/docs/api/functions/dbUuidIn.md +1 -1
- package/docs/api/functions/formatLocalDate.md +2 -2
- package/docs/api/functions/formatUTCDate.md +2 -2
- package/docs/api/functions/getDBConfig.md +1 -1
- package/docs/api/functions/getDBHandler.md +1 -1
- package/docs/api/functions/getTransactionConnection.md +2 -2
- package/docs/api/functions/getTransactionContext.md +2 -2
- package/docs/api/functions/hasMany.md +11 -5
- package/docs/api/functions/hasOne.md +10 -4
- package/docs/api/functions/initDBHandler.md +1 -1
- package/docs/api/functions/isAnySqlFragment.md +1 -1
- package/docs/api/functions/isConnectionError.md +1 -1
- package/docs/api/functions/isSqlCondition.md +1 -1
- package/docs/api/functions/isSqlFragment.md +1 -1
- package/docs/api/functions/isSqlRaw.md +1 -1
- package/docs/api/functions/isSqlRef.md +1 -1
- package/docs/api/functions/isSqlTypedFragment.md +1 -1
- package/docs/api/functions/model.md +8 -155
- package/docs/api/functions/parentRef.md +1 -1
- package/docs/api/functions/sql.md +1 -1
- package/docs/api/globals.md +99 -58
- package/docs/api/interfaces/Column.md +32 -31
- package/docs/api/interfaces/ColumnDecorator.md +81 -0
- package/docs/api/interfaces/ColumnOptions.md +6 -10
- package/docs/api/interfaces/CreatedMiddlewareClass.md +1 -1
- package/docs/api/interfaces/DBConfig.md +1 -1
- package/docs/api/interfaces/DBConfigOptions.md +1 -1
- package/docs/api/interfaces/DeleteOptions.md +1 -1
- package/docs/api/interfaces/InsertOptions.md +1 -1
- package/docs/api/interfaces/LimitConfig.md +1 -1
- package/docs/api/interfaces/MiddlewareConfig.md +1 -1
- package/docs/api/interfaces/ModelClassDecorator.md +64 -0
- package/docs/api/interfaces/ModelOptions.md +1 -1
- package/docs/api/interfaces/PkeyResult.md +1 -1
- package/docs/api/interfaces/RelationDecorator.md +72 -0
- package/docs/api/interfaces/SelectOptions.md +1 -1
- package/docs/api/interfaces/SqlCondition.md +1 -1
- package/docs/api/interfaces/SqlFragment.md +1 -1
- package/docs/api/interfaces/SqlTypedFragment.md +1 -1
- package/docs/api/interfaces/TransactionOptions.md +1 -1
- package/docs/api/interfaces/UpdateManyOptions.md +1 -1
- package/docs/api/interfaces/UpdateOptions.md +1 -1
- package/docs/api-guide.md +17 -17
- package/docs/architecture.md +14 -10
- package/docs/sql-tagged-template.md +5 -5
- package/eslint-plugin/rules/require-declare-for-relations.js +59 -4
- package/package.json +8 -7
package/dist/index.cjs
CHANGED
|
@@ -1158,14 +1158,14 @@ __export(index_exports, {
|
|
|
1158
1158
|
_legacyOr: () => or,
|
|
1159
1159
|
and: () => and,
|
|
1160
1160
|
belongsTo: () => belongsTo,
|
|
1161
|
-
castToBoolean: () =>
|
|
1162
|
-
castToBooleanArray: () =>
|
|
1163
|
-
castToDatetime: () =>
|
|
1164
|
-
castToDatetimeArray: () =>
|
|
1165
|
-
castToIntegerArray: () =>
|
|
1166
|
-
castToJson: () =>
|
|
1167
|
-
castToNumericArray: () =>
|
|
1168
|
-
castToStringArray: () =>
|
|
1161
|
+
castToBoolean: () => castToBoolean2,
|
|
1162
|
+
castToBooleanArray: () => castToBooleanArray2,
|
|
1163
|
+
castToDatetime: () => castToDatetime2,
|
|
1164
|
+
castToDatetimeArray: () => castToDatetimeArray2,
|
|
1165
|
+
castToIntegerArray: () => castToIntegerArray2,
|
|
1166
|
+
castToJson: () => castToJson2,
|
|
1167
|
+
castToNumericArray: () => castToNumericArray2,
|
|
1168
|
+
castToStringArray: () => castToStringArray2,
|
|
1169
1169
|
closeAllPools: () => closeAllPools2,
|
|
1170
1170
|
column: () => column,
|
|
1171
1171
|
columnsToNames: () => columnsToNames,
|
|
@@ -1595,6 +1595,166 @@ var defaultLogger = {
|
|
|
1595
1595
|
error: console.error
|
|
1596
1596
|
};
|
|
1597
1597
|
|
|
1598
|
+
// src/drivers/PostgresHelper.ts
|
|
1599
|
+
function castToDatetime(val) {
|
|
1600
|
+
if (val === null || val === void 0) {
|
|
1601
|
+
return null;
|
|
1602
|
+
}
|
|
1603
|
+
if (val instanceof Date) {
|
|
1604
|
+
return val;
|
|
1605
|
+
}
|
|
1606
|
+
if (typeof val === "string" || typeof val === "number") {
|
|
1607
|
+
const date = new Date(val);
|
|
1608
|
+
return isNaN(date.getTime()) ? null : date;
|
|
1609
|
+
}
|
|
1610
|
+
return null;
|
|
1611
|
+
}
|
|
1612
|
+
function castToBoolean(val) {
|
|
1613
|
+
if (val === null || val === void 0) {
|
|
1614
|
+
return null;
|
|
1615
|
+
}
|
|
1616
|
+
if (typeof val === "boolean") {
|
|
1617
|
+
return val;
|
|
1618
|
+
}
|
|
1619
|
+
if (typeof val === "string") {
|
|
1620
|
+
const lower = val.toLowerCase();
|
|
1621
|
+
if (lower === "true" || lower === "t" || lower === "1") {
|
|
1622
|
+
return true;
|
|
1623
|
+
}
|
|
1624
|
+
if (lower === "false" || lower === "f" || lower === "0") {
|
|
1625
|
+
return false;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
if (typeof val === "number") {
|
|
1629
|
+
return val !== 0;
|
|
1630
|
+
}
|
|
1631
|
+
return null;
|
|
1632
|
+
}
|
|
1633
|
+
function castToIntegerArray(val) {
|
|
1634
|
+
if (val === null || val === void 0) {
|
|
1635
|
+
return [];
|
|
1636
|
+
}
|
|
1637
|
+
if (Array.isArray(val)) {
|
|
1638
|
+
return val.map((v) => {
|
|
1639
|
+
if (typeof v === "number") return v;
|
|
1640
|
+
const n = parseInt(String(v), 10);
|
|
1641
|
+
return isNaN(n) ? 0 : n;
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
if (typeof val === "string") {
|
|
1645
|
+
return pgArrayParse(val).map((v) => {
|
|
1646
|
+
const n = parseInt(v, 10);
|
|
1647
|
+
return isNaN(n) ? 0 : n;
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
return [];
|
|
1651
|
+
}
|
|
1652
|
+
function castToNumericArray(val) {
|
|
1653
|
+
if (val === null || val === void 0) {
|
|
1654
|
+
return [];
|
|
1655
|
+
}
|
|
1656
|
+
if (Array.isArray(val)) {
|
|
1657
|
+
return val.map((v) => {
|
|
1658
|
+
if (v === null || v === void 0) return null;
|
|
1659
|
+
if (typeof v === "number") return v;
|
|
1660
|
+
const n = parseFloat(String(v));
|
|
1661
|
+
return isNaN(n) ? null : n;
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
if (typeof val === "string") {
|
|
1665
|
+
return pgArrayParse(val).map((v) => {
|
|
1666
|
+
if (v === "NULL" || v === "") return null;
|
|
1667
|
+
const n = parseFloat(v);
|
|
1668
|
+
return isNaN(n) ? null : n;
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
return [];
|
|
1672
|
+
}
|
|
1673
|
+
function castToStringArray(val) {
|
|
1674
|
+
if (val === null || val === void 0) {
|
|
1675
|
+
return [];
|
|
1676
|
+
}
|
|
1677
|
+
if (Array.isArray(val)) {
|
|
1678
|
+
return val.map((v) => String(v));
|
|
1679
|
+
}
|
|
1680
|
+
if (typeof val === "string") {
|
|
1681
|
+
return pgArrayParse(val);
|
|
1682
|
+
}
|
|
1683
|
+
return [];
|
|
1684
|
+
}
|
|
1685
|
+
function castToBooleanArray(val) {
|
|
1686
|
+
if (val === null || val === void 0) {
|
|
1687
|
+
return [];
|
|
1688
|
+
}
|
|
1689
|
+
if (Array.isArray(val)) {
|
|
1690
|
+
return val.map((v) => castToBoolean(v));
|
|
1691
|
+
}
|
|
1692
|
+
if (typeof val === "string") {
|
|
1693
|
+
return pgArrayParse(val).map((v) => castToBoolean(v));
|
|
1694
|
+
}
|
|
1695
|
+
return [];
|
|
1696
|
+
}
|
|
1697
|
+
function castToDatetimeArray(val) {
|
|
1698
|
+
if (val === null || val === void 0) {
|
|
1699
|
+
return [];
|
|
1700
|
+
}
|
|
1701
|
+
if (Array.isArray(val)) {
|
|
1702
|
+
return val.map((v) => castToDatetime(v));
|
|
1703
|
+
}
|
|
1704
|
+
if (typeof val === "string") {
|
|
1705
|
+
return pgArrayParse(val).map((v) => castToDatetime(v));
|
|
1706
|
+
}
|
|
1707
|
+
return [];
|
|
1708
|
+
}
|
|
1709
|
+
function castToJson(val) {
|
|
1710
|
+
return val ?? null;
|
|
1711
|
+
}
|
|
1712
|
+
function pgArrayParse(literal) {
|
|
1713
|
+
if (!literal || literal === "{}") {
|
|
1714
|
+
return [];
|
|
1715
|
+
}
|
|
1716
|
+
let content = literal.trim();
|
|
1717
|
+
if (content.startsWith("{") && content.endsWith("}")) {
|
|
1718
|
+
content = content.slice(1, -1);
|
|
1719
|
+
}
|
|
1720
|
+
if (content === "") {
|
|
1721
|
+
return [];
|
|
1722
|
+
}
|
|
1723
|
+
const result = [];
|
|
1724
|
+
let current = "";
|
|
1725
|
+
let inQuotes = false;
|
|
1726
|
+
let escaped = false;
|
|
1727
|
+
for (let i = 0; i < content.length; i++) {
|
|
1728
|
+
const char = content[i];
|
|
1729
|
+
if (escaped) {
|
|
1730
|
+
current += char;
|
|
1731
|
+
escaped = false;
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1734
|
+
if (char === "\\") {
|
|
1735
|
+
escaped = true;
|
|
1736
|
+
continue;
|
|
1737
|
+
}
|
|
1738
|
+
if (char === '"') {
|
|
1739
|
+
inQuotes = !inQuotes;
|
|
1740
|
+
continue;
|
|
1741
|
+
}
|
|
1742
|
+
if (char === "," && !inQuotes) {
|
|
1743
|
+
result.push(current);
|
|
1744
|
+
current = "";
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
current += char;
|
|
1748
|
+
}
|
|
1749
|
+
if (current !== "" || result.length > 0) {
|
|
1750
|
+
result.push(current);
|
|
1751
|
+
}
|
|
1752
|
+
return result;
|
|
1753
|
+
}
|
|
1754
|
+
function formatSqlCast(placeholder, sqlCast) {
|
|
1755
|
+
return `${placeholder}::${sqlCast}`;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1598
1758
|
// src/TypeCast.ts
|
|
1599
1759
|
var defaultTypeCast = {
|
|
1600
1760
|
castToDatetime(val) {
|
|
@@ -1719,17 +1879,15 @@ var defaultTypeCast = {
|
|
|
1719
1879
|
}
|
|
1720
1880
|
return [];
|
|
1721
1881
|
},
|
|
1882
|
+
// A string is JSON text to decode; any other value is already a JSON value
|
|
1722
1883
|
castToJson(val) {
|
|
1723
1884
|
if (val === null || val === void 0) return null;
|
|
1724
|
-
if (typeof val
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
return null;
|
|
1730
|
-
}
|
|
1885
|
+
if (typeof val !== "string") return val;
|
|
1886
|
+
try {
|
|
1887
|
+
return JSON.parse(val);
|
|
1888
|
+
} catch {
|
|
1889
|
+
return null;
|
|
1731
1890
|
}
|
|
1732
|
-
return null;
|
|
1733
1891
|
}
|
|
1734
1892
|
};
|
|
1735
1893
|
function parsePostgresArray(literal) {
|
|
@@ -1780,28 +1938,28 @@ function resetTypeCastImpl() {
|
|
|
1780
1938
|
function getTypeCast() {
|
|
1781
1939
|
return currentTypeCast;
|
|
1782
1940
|
}
|
|
1783
|
-
function
|
|
1941
|
+
function castToDatetime2(val) {
|
|
1784
1942
|
return currentTypeCast.castToDatetime(val);
|
|
1785
1943
|
}
|
|
1786
|
-
function
|
|
1944
|
+
function castToBoolean2(val) {
|
|
1787
1945
|
return currentTypeCast.castToBoolean(val);
|
|
1788
1946
|
}
|
|
1789
|
-
function
|
|
1947
|
+
function castToIntegerArray2(val) {
|
|
1790
1948
|
return currentTypeCast.castToIntegerArray(val);
|
|
1791
1949
|
}
|
|
1792
|
-
function
|
|
1950
|
+
function castToNumericArray2(val) {
|
|
1793
1951
|
return currentTypeCast.castToNumericArray(val);
|
|
1794
1952
|
}
|
|
1795
|
-
function
|
|
1953
|
+
function castToStringArray2(val) {
|
|
1796
1954
|
return currentTypeCast.castToStringArray(val);
|
|
1797
1955
|
}
|
|
1798
|
-
function
|
|
1956
|
+
function castToBooleanArray2(val) {
|
|
1799
1957
|
return currentTypeCast.castToBooleanArray(val);
|
|
1800
1958
|
}
|
|
1801
|
-
function
|
|
1959
|
+
function castToDatetimeArray2(val) {
|
|
1802
1960
|
return currentTypeCast.castToDatetimeArray(val);
|
|
1803
1961
|
}
|
|
1804
|
-
function
|
|
1962
|
+
function castToJson2(val) {
|
|
1805
1963
|
return currentTypeCast.castToJson(val);
|
|
1806
1964
|
}
|
|
1807
1965
|
function formatLocalDate(d) {
|
|
@@ -1845,16 +2003,7 @@ var postgresTypeCast = {
|
|
|
1845
2003
|
return JSON.stringify(val);
|
|
1846
2004
|
},
|
|
1847
2005
|
deserializeJson(val) {
|
|
1848
|
-
|
|
1849
|
-
if (typeof val === "object") return val;
|
|
1850
|
-
if (typeof val === "string") {
|
|
1851
|
-
try {
|
|
1852
|
-
return JSON.parse(val);
|
|
1853
|
-
} catch {
|
|
1854
|
-
return null;
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
return null;
|
|
2006
|
+
return castToJson(val);
|
|
1858
2007
|
},
|
|
1859
2008
|
serializeBooleanArray(val) {
|
|
1860
2009
|
if (val === null || val === void 0) return null;
|
|
@@ -2158,73 +2307,151 @@ var postgresSqlBuilder = {
|
|
|
2158
2307
|
inferPgType
|
|
2159
2308
|
};
|
|
2160
2309
|
|
|
2161
|
-
// src/drivers/
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
serializeArray(val) {
|
|
2165
|
-
if (val === null || val === void 0) return null;
|
|
2166
|
-
return JSON.stringify(val);
|
|
2167
|
-
},
|
|
2168
|
-
deserializeArray(val) {
|
|
2169
|
-
if (val === null || val === void 0) return null;
|
|
2170
|
-
if (Array.isArray(val)) return val;
|
|
2171
|
-
if (typeof val === "string") {
|
|
2172
|
-
try {
|
|
2173
|
-
const parsed = JSON.parse(val);
|
|
2174
|
-
return Array.isArray(parsed) ? parsed : null;
|
|
2175
|
-
} catch {
|
|
2176
|
-
return null;
|
|
2177
|
-
}
|
|
2178
|
-
}
|
|
2179
|
-
return null;
|
|
2180
|
-
},
|
|
2181
|
-
serializeJson(val) {
|
|
2182
|
-
if (val === null || val === void 0) return null;
|
|
2183
|
-
return JSON.stringify(val);
|
|
2184
|
-
},
|
|
2185
|
-
deserializeJson(val) {
|
|
2186
|
-
if (val === null || val === void 0) return null;
|
|
2187
|
-
if (typeof val === "object") return val;
|
|
2188
|
-
if (typeof val === "string") {
|
|
2189
|
-
try {
|
|
2190
|
-
return JSON.parse(val);
|
|
2191
|
-
} catch {
|
|
2192
|
-
return null;
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
|
-
return null;
|
|
2196
|
-
},
|
|
2197
|
-
serializeBooleanArray(val) {
|
|
2198
|
-
if (val === null || val === void 0) return null;
|
|
2199
|
-
return JSON.stringify(val);
|
|
2200
|
-
},
|
|
2201
|
-
deserializeBooleanArray(val) {
|
|
2202
|
-
if (val === null || val === void 0) return null;
|
|
2203
|
-
if (Array.isArray(val)) return val;
|
|
2204
|
-
if (typeof val === "string") {
|
|
2205
|
-
try {
|
|
2206
|
-
const parsed = JSON.parse(val);
|
|
2207
|
-
return Array.isArray(parsed) ? parsed : null;
|
|
2208
|
-
} catch {
|
|
2209
|
-
return null;
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2310
|
+
// src/drivers/MysqlHelper.ts
|
|
2311
|
+
function castToDatetime3(val) {
|
|
2312
|
+
if (val === null || val === void 0) {
|
|
2212
2313
|
return null;
|
|
2213
|
-
}
|
|
2214
|
-
|
|
2215
|
-
* MySQL: return Date object as-is, let mysql2 driver handle conversion
|
|
2216
|
-
* Note: MySQL DATETIME has no timezone - values stored/retrieved in server timezone
|
|
2217
|
-
*/
|
|
2218
|
-
serializeDatetime(val) {
|
|
2219
|
-
return val;
|
|
2220
|
-
},
|
|
2221
|
-
/**
|
|
2222
|
-
* MySQL: return Date object as-is, let mysql2 driver handle conversion
|
|
2223
|
-
*/
|
|
2224
|
-
serializeDate(val) {
|
|
2314
|
+
}
|
|
2315
|
+
if (val instanceof Date) {
|
|
2225
2316
|
return val;
|
|
2226
2317
|
}
|
|
2227
|
-
|
|
2318
|
+
if (typeof val === "string" || typeof val === "number") {
|
|
2319
|
+
const date = new Date(val);
|
|
2320
|
+
return isNaN(date.getTime()) ? null : date;
|
|
2321
|
+
}
|
|
2322
|
+
return null;
|
|
2323
|
+
}
|
|
2324
|
+
function castToBoolean3(val) {
|
|
2325
|
+
if (val === null || val === void 0) {
|
|
2326
|
+
return null;
|
|
2327
|
+
}
|
|
2328
|
+
if (typeof val === "boolean") {
|
|
2329
|
+
return val;
|
|
2330
|
+
}
|
|
2331
|
+
if (typeof val === "number") {
|
|
2332
|
+
return val !== 0;
|
|
2333
|
+
}
|
|
2334
|
+
if (typeof val === "string") {
|
|
2335
|
+
const lower = val.toLowerCase();
|
|
2336
|
+
if (lower === "true" || lower === "1") {
|
|
2337
|
+
return true;
|
|
2338
|
+
}
|
|
2339
|
+
if (lower === "false" || lower === "0") {
|
|
2340
|
+
return false;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
if (Buffer.isBuffer(val)) {
|
|
2344
|
+
return val[0] !== 0;
|
|
2345
|
+
}
|
|
2346
|
+
return null;
|
|
2347
|
+
}
|
|
2348
|
+
function castToIntegerArray3(val) {
|
|
2349
|
+
if (val === null || val === void 0) {
|
|
2350
|
+
return [];
|
|
2351
|
+
}
|
|
2352
|
+
if (Array.isArray(val)) {
|
|
2353
|
+
return val.map((v) => {
|
|
2354
|
+
const n = parseInt(String(v), 10);
|
|
2355
|
+
return isNaN(n) ? 0 : n;
|
|
2356
|
+
});
|
|
2357
|
+
}
|
|
2358
|
+
if (typeof val === "string") {
|
|
2359
|
+
try {
|
|
2360
|
+
const parsed = JSON.parse(val);
|
|
2361
|
+
if (Array.isArray(parsed)) {
|
|
2362
|
+
return parsed.map((v) => {
|
|
2363
|
+
const n = parseInt(String(v), 10);
|
|
2364
|
+
return isNaN(n) ? 0 : n;
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
} catch {
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return [];
|
|
2371
|
+
}
|
|
2372
|
+
function castToStringArray3(val) {
|
|
2373
|
+
if (val === null || val === void 0) {
|
|
2374
|
+
return [];
|
|
2375
|
+
}
|
|
2376
|
+
if (Array.isArray(val)) {
|
|
2377
|
+
return val.map((v) => String(v));
|
|
2378
|
+
}
|
|
2379
|
+
if (typeof val === "string") {
|
|
2380
|
+
try {
|
|
2381
|
+
const parsed = JSON.parse(val);
|
|
2382
|
+
if (Array.isArray(parsed)) {
|
|
2383
|
+
return parsed.map((v) => String(v));
|
|
2384
|
+
}
|
|
2385
|
+
} catch {
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
return [];
|
|
2389
|
+
}
|
|
2390
|
+
function castToJson3(val) {
|
|
2391
|
+
return val ?? null;
|
|
2392
|
+
}
|
|
2393
|
+
function formatSqlCast2(placeholder, _sqlCast) {
|
|
2394
|
+
return placeholder;
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
// src/drivers/MysqlSqlBuilder.ts
|
|
2398
|
+
var mysqlTypeCast = {
|
|
2399
|
+
driverName: "mysql",
|
|
2400
|
+
serializeArray(val) {
|
|
2401
|
+
if (val === null || val === void 0) return null;
|
|
2402
|
+
return JSON.stringify(val);
|
|
2403
|
+
},
|
|
2404
|
+
deserializeArray(val) {
|
|
2405
|
+
if (val === null || val === void 0) return null;
|
|
2406
|
+
if (Array.isArray(val)) return val;
|
|
2407
|
+
if (typeof val === "string") {
|
|
2408
|
+
try {
|
|
2409
|
+
const parsed = JSON.parse(val);
|
|
2410
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
2411
|
+
} catch {
|
|
2412
|
+
return null;
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
return null;
|
|
2416
|
+
},
|
|
2417
|
+
serializeJson(val) {
|
|
2418
|
+
if (val === null || val === void 0) return null;
|
|
2419
|
+
return JSON.stringify(val);
|
|
2420
|
+
},
|
|
2421
|
+
deserializeJson(val) {
|
|
2422
|
+
return castToJson3(val);
|
|
2423
|
+
},
|
|
2424
|
+
serializeBooleanArray(val) {
|
|
2425
|
+
if (val === null || val === void 0) return null;
|
|
2426
|
+
return JSON.stringify(val);
|
|
2427
|
+
},
|
|
2428
|
+
deserializeBooleanArray(val) {
|
|
2429
|
+
if (val === null || val === void 0) return null;
|
|
2430
|
+
if (Array.isArray(val)) return val;
|
|
2431
|
+
if (typeof val === "string") {
|
|
2432
|
+
try {
|
|
2433
|
+
const parsed = JSON.parse(val);
|
|
2434
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
2435
|
+
} catch {
|
|
2436
|
+
return null;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
return null;
|
|
2440
|
+
},
|
|
2441
|
+
/**
|
|
2442
|
+
* MySQL: return Date object as-is, let mysql2 driver handle conversion
|
|
2443
|
+
* Note: MySQL DATETIME has no timezone - values stored/retrieved in server timezone
|
|
2444
|
+
*/
|
|
2445
|
+
serializeDatetime(val) {
|
|
2446
|
+
return val;
|
|
2447
|
+
},
|
|
2448
|
+
/**
|
|
2449
|
+
* MySQL: return Date object as-is, let mysql2 driver handle conversion
|
|
2450
|
+
*/
|
|
2451
|
+
serializeDate(val) {
|
|
2452
|
+
return val;
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2228
2455
|
var mysqlSqlBuilder = {
|
|
2229
2456
|
driverType: "mysql",
|
|
2230
2457
|
typeCast: mysqlTypeCast,
|
|
@@ -2360,6 +2587,103 @@ var mysqlSqlBuilder = {
|
|
|
2360
2587
|
}
|
|
2361
2588
|
};
|
|
2362
2589
|
|
|
2590
|
+
// src/drivers/SqliteHelper.ts
|
|
2591
|
+
function castToDatetime4(val) {
|
|
2592
|
+
if (val === null || val === void 0) {
|
|
2593
|
+
return null;
|
|
2594
|
+
}
|
|
2595
|
+
if (val instanceof Date) {
|
|
2596
|
+
return val;
|
|
2597
|
+
}
|
|
2598
|
+
if (typeof val === "string" || typeof val === "number") {
|
|
2599
|
+
const date = new Date(val);
|
|
2600
|
+
return isNaN(date.getTime()) ? null : date;
|
|
2601
|
+
}
|
|
2602
|
+
return null;
|
|
2603
|
+
}
|
|
2604
|
+
function castToBoolean4(val) {
|
|
2605
|
+
if (val === null || val === void 0) {
|
|
2606
|
+
return null;
|
|
2607
|
+
}
|
|
2608
|
+
if (typeof val === "boolean") {
|
|
2609
|
+
return val;
|
|
2610
|
+
}
|
|
2611
|
+
if (typeof val === "number") {
|
|
2612
|
+
return val !== 0;
|
|
2613
|
+
}
|
|
2614
|
+
if (typeof val === "string") {
|
|
2615
|
+
const lower = val.toLowerCase();
|
|
2616
|
+
if (lower === "true" || lower === "1") {
|
|
2617
|
+
return true;
|
|
2618
|
+
}
|
|
2619
|
+
if (lower === "false" || lower === "0") {
|
|
2620
|
+
return false;
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
return null;
|
|
2624
|
+
}
|
|
2625
|
+
function castToIntegerArray4(val) {
|
|
2626
|
+
if (val === null || val === void 0) {
|
|
2627
|
+
return [];
|
|
2628
|
+
}
|
|
2629
|
+
if (Array.isArray(val)) {
|
|
2630
|
+
return val.map((v) => {
|
|
2631
|
+
const n = parseInt(String(v), 10);
|
|
2632
|
+
return isNaN(n) ? 0 : n;
|
|
2633
|
+
});
|
|
2634
|
+
}
|
|
2635
|
+
if (typeof val === "string") {
|
|
2636
|
+
try {
|
|
2637
|
+
const parsed = JSON.parse(val);
|
|
2638
|
+
if (Array.isArray(parsed)) {
|
|
2639
|
+
return parsed.map((v) => {
|
|
2640
|
+
const n = parseInt(String(v), 10);
|
|
2641
|
+
return isNaN(n) ? 0 : n;
|
|
2642
|
+
});
|
|
2643
|
+
}
|
|
2644
|
+
} catch {
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
return [];
|
|
2648
|
+
}
|
|
2649
|
+
function castToStringArray4(val) {
|
|
2650
|
+
if (val === null || val === void 0) {
|
|
2651
|
+
return [];
|
|
2652
|
+
}
|
|
2653
|
+
if (Array.isArray(val)) {
|
|
2654
|
+
return val.map((v) => String(v));
|
|
2655
|
+
}
|
|
2656
|
+
if (typeof val === "string") {
|
|
2657
|
+
try {
|
|
2658
|
+
const parsed = JSON.parse(val);
|
|
2659
|
+
if (Array.isArray(parsed)) {
|
|
2660
|
+
return parsed.map((v) => String(v));
|
|
2661
|
+
}
|
|
2662
|
+
} catch {
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
return [];
|
|
2666
|
+
}
|
|
2667
|
+
function castToJson4(val) {
|
|
2668
|
+
if (val === null || val === void 0) {
|
|
2669
|
+
return null;
|
|
2670
|
+
}
|
|
2671
|
+
if (typeof val === "object" || typeof val === "number") {
|
|
2672
|
+
return val;
|
|
2673
|
+
}
|
|
2674
|
+
if (typeof val === "string") {
|
|
2675
|
+
try {
|
|
2676
|
+
return JSON.parse(val);
|
|
2677
|
+
} catch {
|
|
2678
|
+
return null;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
return null;
|
|
2682
|
+
}
|
|
2683
|
+
function formatSqlCast3(placeholder, _sqlCast) {
|
|
2684
|
+
return placeholder;
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2363
2687
|
// src/drivers/SqliteSqlBuilder.ts
|
|
2364
2688
|
var sqliteTypeCast = {
|
|
2365
2689
|
driverName: "sqlite",
|
|
@@ -2385,16 +2709,7 @@ var sqliteTypeCast = {
|
|
|
2385
2709
|
return JSON.stringify(val);
|
|
2386
2710
|
},
|
|
2387
2711
|
deserializeJson(val) {
|
|
2388
|
-
|
|
2389
|
-
if (typeof val === "object") return val;
|
|
2390
|
-
if (typeof val === "string") {
|
|
2391
|
-
try {
|
|
2392
|
-
return JSON.parse(val);
|
|
2393
|
-
} catch {
|
|
2394
|
-
return null;
|
|
2395
|
-
}
|
|
2396
|
-
}
|
|
2397
|
-
return null;
|
|
2712
|
+
return castToJson4(val);
|
|
2398
2713
|
},
|
|
2399
2714
|
serializeBooleanArray(val) {
|
|
2400
2715
|
if (val === null || val === void 0) return null;
|
|
@@ -3551,436 +3866,66 @@ var MysqlDriver = class {
|
|
|
3551
3866
|
const [selectResult] = await conn.query(selectSql, [insertId, insertId + affectedRows]);
|
|
3552
3867
|
const rows2 = selectResult;
|
|
3553
3868
|
this.logger.debug(`Retry succeeded in ${duration}ms, rows: ${rows2.length}`);
|
|
3554
|
-
return {
|
|
3555
|
-
rows: rows2,
|
|
3556
|
-
rowCount: rows2.length
|
|
3557
|
-
};
|
|
3558
|
-
}
|
|
3559
|
-
}
|
|
3560
|
-
}
|
|
3561
|
-
const resultObj = result;
|
|
3562
|
-
const rowCount = resultObj.affectedRows ?? 0;
|
|
3563
|
-
const rows = Array.isArray(result) ? result : [];
|
|
3564
|
-
this.logger.debug(`Retry succeeded in ${duration}ms, affected: ${rowCount}`);
|
|
3565
|
-
return {
|
|
3566
|
-
rows,
|
|
3567
|
-
rowCount
|
|
3568
|
-
};
|
|
3569
|
-
} catch (retryError) {
|
|
3570
|
-
this.logger.error(`Retry also failed: ${sqlWithoutReturning}`, retryError);
|
|
3571
|
-
throw retryError;
|
|
3572
|
-
}
|
|
3573
|
-
}
|
|
3574
|
-
this.logger.error(`Write failed: ${sqlWithoutReturning}`, error);
|
|
3575
|
-
throw error;
|
|
3576
|
-
}
|
|
3577
|
-
}
|
|
3578
|
-
/**
|
|
3579
|
-
* Get a connection for transaction (uses writer pool if available)
|
|
3580
|
-
*/
|
|
3581
|
-
async getConnection() {
|
|
3582
|
-
const pool = this.writerPool || this.pool;
|
|
3583
|
-
const connection = await pool.getConnection();
|
|
3584
|
-
return new MysqlConnection(connection, this.logger);
|
|
3585
|
-
}
|
|
3586
|
-
/**
|
|
3587
|
-
* Close all connections
|
|
3588
|
-
*/
|
|
3589
|
-
async close() {
|
|
3590
|
-
await closePool2(this.config);
|
|
3591
|
-
if (this.writerConfig) {
|
|
3592
|
-
await closePool2(this.writerConfig);
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
/**
|
|
3596
|
-
* Set logger
|
|
3597
|
-
*/
|
|
3598
|
-
setLogger(logger) {
|
|
3599
|
-
this.logger = logger;
|
|
3600
|
-
}
|
|
3601
|
-
/**
|
|
3602
|
-
* Get the underlying pool (for advanced use)
|
|
3603
|
-
*/
|
|
3604
|
-
getPool() {
|
|
3605
|
-
return this.pool;
|
|
3606
|
-
}
|
|
3607
|
-
/**
|
|
3608
|
-
* Get the underlying writer pool
|
|
3609
|
-
*/
|
|
3610
|
-
getWriterPool() {
|
|
3611
|
-
return this.writerPool;
|
|
3612
|
-
}
|
|
3613
|
-
};
|
|
3614
|
-
|
|
3615
|
-
// src/drivers/PostgresHelper.ts
|
|
3616
|
-
function castToDatetime2(val) {
|
|
3617
|
-
if (val === null || val === void 0) {
|
|
3618
|
-
return null;
|
|
3619
|
-
}
|
|
3620
|
-
if (val instanceof Date) {
|
|
3621
|
-
return val;
|
|
3622
|
-
}
|
|
3623
|
-
if (typeof val === "string" || typeof val === "number") {
|
|
3624
|
-
const date = new Date(val);
|
|
3625
|
-
return isNaN(date.getTime()) ? null : date;
|
|
3626
|
-
}
|
|
3627
|
-
return null;
|
|
3628
|
-
}
|
|
3629
|
-
function castToBoolean2(val) {
|
|
3630
|
-
if (val === null || val === void 0) {
|
|
3631
|
-
return null;
|
|
3632
|
-
}
|
|
3633
|
-
if (typeof val === "boolean") {
|
|
3634
|
-
return val;
|
|
3635
|
-
}
|
|
3636
|
-
if (typeof val === "string") {
|
|
3637
|
-
const lower = val.toLowerCase();
|
|
3638
|
-
if (lower === "true" || lower === "t" || lower === "1") {
|
|
3639
|
-
return true;
|
|
3640
|
-
}
|
|
3641
|
-
if (lower === "false" || lower === "f" || lower === "0") {
|
|
3642
|
-
return false;
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
if (typeof val === "number") {
|
|
3646
|
-
return val !== 0;
|
|
3647
|
-
}
|
|
3648
|
-
return null;
|
|
3649
|
-
}
|
|
3650
|
-
function castToIntegerArray2(val) {
|
|
3651
|
-
if (val === null || val === void 0) {
|
|
3652
|
-
return [];
|
|
3653
|
-
}
|
|
3654
|
-
if (Array.isArray(val)) {
|
|
3655
|
-
return val.map((v) => {
|
|
3656
|
-
if (typeof v === "number") return v;
|
|
3657
|
-
const n = parseInt(String(v), 10);
|
|
3658
|
-
return isNaN(n) ? 0 : n;
|
|
3659
|
-
});
|
|
3660
|
-
}
|
|
3661
|
-
if (typeof val === "string") {
|
|
3662
|
-
return pgArrayParse(val).map((v) => {
|
|
3663
|
-
const n = parseInt(v, 10);
|
|
3664
|
-
return isNaN(n) ? 0 : n;
|
|
3665
|
-
});
|
|
3666
|
-
}
|
|
3667
|
-
return [];
|
|
3668
|
-
}
|
|
3669
|
-
function castToNumericArray2(val) {
|
|
3670
|
-
if (val === null || val === void 0) {
|
|
3671
|
-
return [];
|
|
3672
|
-
}
|
|
3673
|
-
if (Array.isArray(val)) {
|
|
3674
|
-
return val.map((v) => {
|
|
3675
|
-
if (v === null || v === void 0) return null;
|
|
3676
|
-
if (typeof v === "number") return v;
|
|
3677
|
-
const n = parseFloat(String(v));
|
|
3678
|
-
return isNaN(n) ? null : n;
|
|
3679
|
-
});
|
|
3680
|
-
}
|
|
3681
|
-
if (typeof val === "string") {
|
|
3682
|
-
return pgArrayParse(val).map((v) => {
|
|
3683
|
-
if (v === "NULL" || v === "") return null;
|
|
3684
|
-
const n = parseFloat(v);
|
|
3685
|
-
return isNaN(n) ? null : n;
|
|
3686
|
-
});
|
|
3687
|
-
}
|
|
3688
|
-
return [];
|
|
3689
|
-
}
|
|
3690
|
-
function castToStringArray2(val) {
|
|
3691
|
-
if (val === null || val === void 0) {
|
|
3692
|
-
return [];
|
|
3693
|
-
}
|
|
3694
|
-
if (Array.isArray(val)) {
|
|
3695
|
-
return val.map((v) => String(v));
|
|
3696
|
-
}
|
|
3697
|
-
if (typeof val === "string") {
|
|
3698
|
-
return pgArrayParse(val);
|
|
3699
|
-
}
|
|
3700
|
-
return [];
|
|
3701
|
-
}
|
|
3702
|
-
function castToBooleanArray2(val) {
|
|
3703
|
-
if (val === null || val === void 0) {
|
|
3704
|
-
return [];
|
|
3705
|
-
}
|
|
3706
|
-
if (Array.isArray(val)) {
|
|
3707
|
-
return val.map((v) => castToBoolean2(v));
|
|
3708
|
-
}
|
|
3709
|
-
if (typeof val === "string") {
|
|
3710
|
-
return pgArrayParse(val).map((v) => castToBoolean2(v));
|
|
3711
|
-
}
|
|
3712
|
-
return [];
|
|
3713
|
-
}
|
|
3714
|
-
function castToDatetimeArray2(val) {
|
|
3715
|
-
if (val === null || val === void 0) {
|
|
3716
|
-
return [];
|
|
3717
|
-
}
|
|
3718
|
-
if (Array.isArray(val)) {
|
|
3719
|
-
return val.map((v) => castToDatetime2(v));
|
|
3720
|
-
}
|
|
3721
|
-
if (typeof val === "string") {
|
|
3722
|
-
return pgArrayParse(val).map((v) => castToDatetime2(v));
|
|
3723
|
-
}
|
|
3724
|
-
return [];
|
|
3725
|
-
}
|
|
3726
|
-
function castToJson2(val) {
|
|
3727
|
-
if (val === null || val === void 0) {
|
|
3728
|
-
return null;
|
|
3729
|
-
}
|
|
3730
|
-
if (typeof val === "object") {
|
|
3731
|
-
return val;
|
|
3732
|
-
}
|
|
3733
|
-
if (typeof val === "string") {
|
|
3734
|
-
try {
|
|
3735
|
-
return JSON.parse(val);
|
|
3736
|
-
} catch {
|
|
3737
|
-
return null;
|
|
3738
|
-
}
|
|
3739
|
-
}
|
|
3740
|
-
return null;
|
|
3741
|
-
}
|
|
3742
|
-
function pgArrayParse(literal) {
|
|
3743
|
-
if (!literal || literal === "{}") {
|
|
3744
|
-
return [];
|
|
3745
|
-
}
|
|
3746
|
-
let content = literal.trim();
|
|
3747
|
-
if (content.startsWith("{") && content.endsWith("}")) {
|
|
3748
|
-
content = content.slice(1, -1);
|
|
3749
|
-
}
|
|
3750
|
-
if (content === "") {
|
|
3751
|
-
return [];
|
|
3752
|
-
}
|
|
3753
|
-
const result = [];
|
|
3754
|
-
let current = "";
|
|
3755
|
-
let inQuotes = false;
|
|
3756
|
-
let escaped = false;
|
|
3757
|
-
for (let i = 0; i < content.length; i++) {
|
|
3758
|
-
const char = content[i];
|
|
3759
|
-
if (escaped) {
|
|
3760
|
-
current += char;
|
|
3761
|
-
escaped = false;
|
|
3762
|
-
continue;
|
|
3763
|
-
}
|
|
3764
|
-
if (char === "\\") {
|
|
3765
|
-
escaped = true;
|
|
3766
|
-
continue;
|
|
3767
|
-
}
|
|
3768
|
-
if (char === '"') {
|
|
3769
|
-
inQuotes = !inQuotes;
|
|
3770
|
-
continue;
|
|
3771
|
-
}
|
|
3772
|
-
if (char === "," && !inQuotes) {
|
|
3773
|
-
result.push(current);
|
|
3774
|
-
current = "";
|
|
3775
|
-
continue;
|
|
3776
|
-
}
|
|
3777
|
-
current += char;
|
|
3778
|
-
}
|
|
3779
|
-
if (current !== "" || result.length > 0) {
|
|
3780
|
-
result.push(current);
|
|
3781
|
-
}
|
|
3782
|
-
return result;
|
|
3783
|
-
}
|
|
3784
|
-
function formatSqlCast(placeholder, sqlCast) {
|
|
3785
|
-
return `${placeholder}::${sqlCast}`;
|
|
3786
|
-
}
|
|
3787
|
-
|
|
3788
|
-
// src/drivers/SqliteHelper.ts
|
|
3789
|
-
function castToDatetime3(val) {
|
|
3790
|
-
if (val === null || val === void 0) {
|
|
3791
|
-
return null;
|
|
3792
|
-
}
|
|
3793
|
-
if (val instanceof Date) {
|
|
3794
|
-
return val;
|
|
3795
|
-
}
|
|
3796
|
-
if (typeof val === "string" || typeof val === "number") {
|
|
3797
|
-
const date = new Date(val);
|
|
3798
|
-
return isNaN(date.getTime()) ? null : date;
|
|
3799
|
-
}
|
|
3800
|
-
return null;
|
|
3801
|
-
}
|
|
3802
|
-
function castToBoolean3(val) {
|
|
3803
|
-
if (val === null || val === void 0) {
|
|
3804
|
-
return null;
|
|
3805
|
-
}
|
|
3806
|
-
if (typeof val === "boolean") {
|
|
3807
|
-
return val;
|
|
3808
|
-
}
|
|
3809
|
-
if (typeof val === "number") {
|
|
3810
|
-
return val !== 0;
|
|
3811
|
-
}
|
|
3812
|
-
if (typeof val === "string") {
|
|
3813
|
-
const lower = val.toLowerCase();
|
|
3814
|
-
if (lower === "true" || lower === "1") {
|
|
3815
|
-
return true;
|
|
3816
|
-
}
|
|
3817
|
-
if (lower === "false" || lower === "0") {
|
|
3818
|
-
return false;
|
|
3819
|
-
}
|
|
3820
|
-
}
|
|
3821
|
-
return null;
|
|
3822
|
-
}
|
|
3823
|
-
function castToIntegerArray3(val) {
|
|
3824
|
-
if (val === null || val === void 0) {
|
|
3825
|
-
return [];
|
|
3826
|
-
}
|
|
3827
|
-
if (Array.isArray(val)) {
|
|
3828
|
-
return val.map((v) => {
|
|
3829
|
-
const n = parseInt(String(v), 10);
|
|
3830
|
-
return isNaN(n) ? 0 : n;
|
|
3831
|
-
});
|
|
3832
|
-
}
|
|
3833
|
-
if (typeof val === "string") {
|
|
3834
|
-
try {
|
|
3835
|
-
const parsed = JSON.parse(val);
|
|
3836
|
-
if (Array.isArray(parsed)) {
|
|
3837
|
-
return parsed.map((v) => {
|
|
3838
|
-
const n = parseInt(String(v), 10);
|
|
3839
|
-
return isNaN(n) ? 0 : n;
|
|
3840
|
-
});
|
|
3841
|
-
}
|
|
3842
|
-
} catch {
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
return [];
|
|
3846
|
-
}
|
|
3847
|
-
function castToStringArray3(val) {
|
|
3848
|
-
if (val === null || val === void 0) {
|
|
3849
|
-
return [];
|
|
3850
|
-
}
|
|
3851
|
-
if (Array.isArray(val)) {
|
|
3852
|
-
return val.map((v) => String(v));
|
|
3853
|
-
}
|
|
3854
|
-
if (typeof val === "string") {
|
|
3855
|
-
try {
|
|
3856
|
-
const parsed = JSON.parse(val);
|
|
3857
|
-
if (Array.isArray(parsed)) {
|
|
3858
|
-
return parsed.map((v) => String(v));
|
|
3859
|
-
}
|
|
3860
|
-
} catch {
|
|
3861
|
-
}
|
|
3862
|
-
}
|
|
3863
|
-
return [];
|
|
3864
|
-
}
|
|
3865
|
-
function castToJson3(val) {
|
|
3866
|
-
if (val === null || val === void 0) {
|
|
3867
|
-
return null;
|
|
3868
|
-
}
|
|
3869
|
-
if (typeof val === "object") {
|
|
3870
|
-
return val;
|
|
3871
|
-
}
|
|
3872
|
-
if (typeof val === "string") {
|
|
3873
|
-
try {
|
|
3874
|
-
return JSON.parse(val);
|
|
3875
|
-
} catch {
|
|
3876
|
-
return null;
|
|
3877
|
-
}
|
|
3878
|
-
}
|
|
3879
|
-
return null;
|
|
3880
|
-
}
|
|
3881
|
-
function formatSqlCast2(placeholder, _sqlCast) {
|
|
3882
|
-
return placeholder;
|
|
3883
|
-
}
|
|
3884
|
-
|
|
3885
|
-
// src/drivers/MysqlHelper.ts
|
|
3886
|
-
function castToDatetime4(val) {
|
|
3887
|
-
if (val === null || val === void 0) {
|
|
3888
|
-
return null;
|
|
3889
|
-
}
|
|
3890
|
-
if (val instanceof Date) {
|
|
3891
|
-
return val;
|
|
3892
|
-
}
|
|
3893
|
-
if (typeof val === "string" || typeof val === "number") {
|
|
3894
|
-
const date = new Date(val);
|
|
3895
|
-
return isNaN(date.getTime()) ? null : date;
|
|
3896
|
-
}
|
|
3897
|
-
return null;
|
|
3898
|
-
}
|
|
3899
|
-
function castToBoolean4(val) {
|
|
3900
|
-
if (val === null || val === void 0) {
|
|
3901
|
-
return null;
|
|
3902
|
-
}
|
|
3903
|
-
if (typeof val === "boolean") {
|
|
3904
|
-
return val;
|
|
3905
|
-
}
|
|
3906
|
-
if (typeof val === "number") {
|
|
3907
|
-
return val !== 0;
|
|
3908
|
-
}
|
|
3909
|
-
if (typeof val === "string") {
|
|
3910
|
-
const lower = val.toLowerCase();
|
|
3911
|
-
if (lower === "true" || lower === "1") {
|
|
3912
|
-
return true;
|
|
3913
|
-
}
|
|
3914
|
-
if (lower === "false" || lower === "0") {
|
|
3915
|
-
return false;
|
|
3916
|
-
}
|
|
3917
|
-
}
|
|
3918
|
-
if (Buffer.isBuffer(val)) {
|
|
3919
|
-
return val[0] !== 0;
|
|
3920
|
-
}
|
|
3921
|
-
return null;
|
|
3922
|
-
}
|
|
3923
|
-
function castToIntegerArray4(val) {
|
|
3924
|
-
if (val === null || val === void 0) {
|
|
3925
|
-
return [];
|
|
3926
|
-
}
|
|
3927
|
-
if (Array.isArray(val)) {
|
|
3928
|
-
return val.map((v) => {
|
|
3929
|
-
const n = parseInt(String(v), 10);
|
|
3930
|
-
return isNaN(n) ? 0 : n;
|
|
3931
|
-
});
|
|
3932
|
-
}
|
|
3933
|
-
if (typeof val === "string") {
|
|
3934
|
-
try {
|
|
3935
|
-
const parsed = JSON.parse(val);
|
|
3936
|
-
if (Array.isArray(parsed)) {
|
|
3937
|
-
return parsed.map((v) => {
|
|
3938
|
-
const n = parseInt(String(v), 10);
|
|
3939
|
-
return isNaN(n) ? 0 : n;
|
|
3940
|
-
});
|
|
3869
|
+
return {
|
|
3870
|
+
rows: rows2,
|
|
3871
|
+
rowCount: rows2.length
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
const resultObj = result;
|
|
3877
|
+
const rowCount = resultObj.affectedRows ?? 0;
|
|
3878
|
+
const rows = Array.isArray(result) ? result : [];
|
|
3879
|
+
this.logger.debug(`Retry succeeded in ${duration}ms, affected: ${rowCount}`);
|
|
3880
|
+
return {
|
|
3881
|
+
rows,
|
|
3882
|
+
rowCount
|
|
3883
|
+
};
|
|
3884
|
+
} catch (retryError) {
|
|
3885
|
+
this.logger.error(`Retry also failed: ${sqlWithoutReturning}`, retryError);
|
|
3886
|
+
throw retryError;
|
|
3887
|
+
}
|
|
3941
3888
|
}
|
|
3942
|
-
|
|
3889
|
+
this.logger.error(`Write failed: ${sqlWithoutReturning}`, error);
|
|
3890
|
+
throw error;
|
|
3943
3891
|
}
|
|
3944
3892
|
}
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
return val.map((v) => String(v));
|
|
3893
|
+
/**
|
|
3894
|
+
* Get a connection for transaction (uses writer pool if available)
|
|
3895
|
+
*/
|
|
3896
|
+
async getConnection() {
|
|
3897
|
+
const pool = this.writerPool || this.pool;
|
|
3898
|
+
const connection = await pool.getConnection();
|
|
3899
|
+
return new MysqlConnection(connection, this.logger);
|
|
3953
3900
|
}
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3901
|
+
/**
|
|
3902
|
+
* Close all connections
|
|
3903
|
+
*/
|
|
3904
|
+
async close() {
|
|
3905
|
+
await closePool2(this.config);
|
|
3906
|
+
if (this.writerConfig) {
|
|
3907
|
+
await closePool2(this.writerConfig);
|
|
3961
3908
|
}
|
|
3962
3909
|
}
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3910
|
+
/**
|
|
3911
|
+
* Set logger
|
|
3912
|
+
*/
|
|
3913
|
+
setLogger(logger) {
|
|
3914
|
+
this.logger = logger;
|
|
3968
3915
|
}
|
|
3969
|
-
|
|
3970
|
-
|
|
3916
|
+
/**
|
|
3917
|
+
* Get the underlying pool (for advanced use)
|
|
3918
|
+
*/
|
|
3919
|
+
getPool() {
|
|
3920
|
+
return this.pool;
|
|
3971
3921
|
}
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
}
|
|
3922
|
+
/**
|
|
3923
|
+
* Get the underlying writer pool
|
|
3924
|
+
*/
|
|
3925
|
+
getWriterPool() {
|
|
3926
|
+
return this.writerPool;
|
|
3978
3927
|
}
|
|
3979
|
-
|
|
3980
|
-
}
|
|
3981
|
-
function formatSqlCast3(placeholder, _sqlCast) {
|
|
3982
|
-
return placeholder;
|
|
3983
|
-
}
|
|
3928
|
+
};
|
|
3984
3929
|
|
|
3985
3930
|
// src/drivers/index.ts
|
|
3986
3931
|
function getSqlBuilder(driverType) {
|
|
@@ -4003,9 +3948,9 @@ function getSqlCastFormatter(driverType) {
|
|
|
4003
3948
|
case "postgres":
|
|
4004
3949
|
return (placeholder, sqlType) => formatSqlCast(placeholder, sqlType);
|
|
4005
3950
|
case "sqlite":
|
|
4006
|
-
return (placeholder, sqlType) => formatSqlCast2(placeholder, sqlType);
|
|
4007
|
-
case "mysql":
|
|
4008
3951
|
return (placeholder, sqlType) => formatSqlCast3(placeholder, sqlType);
|
|
3952
|
+
case "mysql":
|
|
3953
|
+
return (placeholder, sqlType) => formatSqlCast2(placeholder, sqlType);
|
|
4009
3954
|
default:
|
|
4010
3955
|
return (placeholder) => placeholder;
|
|
4011
3956
|
}
|
|
@@ -5344,7 +5289,7 @@ function orderToString(order) {
|
|
|
5344
5289
|
}
|
|
5345
5290
|
return order.toString();
|
|
5346
5291
|
}
|
|
5347
|
-
function createColumn(columnName, tableName, modelName, propertyName, sqlCast) {
|
|
5292
|
+
function createColumn(columnName, tableName, modelName, propertyName, sqlCast, serialize) {
|
|
5348
5293
|
const fn = function() {
|
|
5349
5294
|
return columnName;
|
|
5350
5295
|
};
|
|
@@ -5379,6 +5324,11 @@ function createColumn(columnName, tableName, modelName, propertyName, sqlCast) {
|
|
|
5379
5324
|
writable: false,
|
|
5380
5325
|
enumerable: true
|
|
5381
5326
|
});
|
|
5327
|
+
Object.defineProperty(fn, "serialize", {
|
|
5328
|
+
value: serialize,
|
|
5329
|
+
writable: false,
|
|
5330
|
+
enumerable: false
|
|
5331
|
+
});
|
|
5382
5332
|
if (sqlCast) {
|
|
5383
5333
|
fn.eq = (value) => ({ [columnName]: new DBCast(value, sqlCast, "=") });
|
|
5384
5334
|
fn.ne = (value) => ({ [columnName]: new DBCast(value, sqlCast, "!=") });
|
|
@@ -5525,7 +5475,12 @@ function createOrCond(condGroups) {
|
|
|
5525
5475
|
function isOrCond(cond) {
|
|
5526
5476
|
return typeof cond === "object" && cond !== null && "_type" in cond && cond._type === "or";
|
|
5527
5477
|
}
|
|
5528
|
-
function
|
|
5478
|
+
function serializeCondValue(col, value, typeCast) {
|
|
5479
|
+
const serialize = col.serialize;
|
|
5480
|
+
if (serialize === void 0) return value;
|
|
5481
|
+
return Array.isArray(value) ? value.map((v) => serialize(v, typeCast)) : serialize(value, typeCast);
|
|
5482
|
+
}
|
|
5483
|
+
function condToKeyValue(cond, typeCast) {
|
|
5529
5484
|
if (cond.length === 1) {
|
|
5530
5485
|
return [cond[0], true];
|
|
5531
5486
|
}
|
|
@@ -5535,7 +5490,7 @@ function condToKeyValue(cond) {
|
|
|
5535
5490
|
}
|
|
5536
5491
|
if (Array.isArray(keyOrCol)) {
|
|
5537
5492
|
const columns = keyOrCol;
|
|
5538
|
-
const tuples = value;
|
|
5493
|
+
const tuples = value.map((t) => t.map((v, i) => serializeCondValue(columns[i], v, typeCast)));
|
|
5539
5494
|
const columnNames = columns.map((col2) => col2.columnName);
|
|
5540
5495
|
return ["__tuple__", dbTupleIn(columnNames, tuples)];
|
|
5541
5496
|
}
|
|
@@ -5550,13 +5505,14 @@ function condToKeyValue(cond) {
|
|
|
5550
5505
|
if (value instanceof DBToken) {
|
|
5551
5506
|
return [col.columnName, value];
|
|
5552
5507
|
}
|
|
5508
|
+
const bound = serializeCondValue(col, value, typeCast);
|
|
5553
5509
|
if (sqlCast) {
|
|
5554
|
-
if (Array.isArray(
|
|
5555
|
-
return [col.columnName, new DBCastArray(
|
|
5510
|
+
if (Array.isArray(bound)) {
|
|
5511
|
+
return [col.columnName, new DBCastArray(bound, sqlCast)];
|
|
5556
5512
|
}
|
|
5557
|
-
return [col.columnName, new DBCast(
|
|
5513
|
+
return [col.columnName, new DBCast(bound, sqlCast, "=")];
|
|
5558
5514
|
}
|
|
5559
|
-
return [col.columnName,
|
|
5515
|
+
return [col.columnName, bound];
|
|
5560
5516
|
}
|
|
5561
5517
|
function sqlFragmentToKeyValue(frag) {
|
|
5562
5518
|
if (frag.params.length === 0) {
|
|
@@ -5567,14 +5523,14 @@ function sqlFragmentToKeyValue(frag) {
|
|
|
5567
5523
|
}
|
|
5568
5524
|
return [frag.sql, [...frag.params]];
|
|
5569
5525
|
}
|
|
5570
|
-
function condsToRecord(conditions) {
|
|
5526
|
+
function condsToRecord(conditions, typeCast) {
|
|
5571
5527
|
const result = {};
|
|
5572
5528
|
for (const cond of conditions) {
|
|
5573
5529
|
if (cond === SKIP) {
|
|
5574
5530
|
continue;
|
|
5575
5531
|
}
|
|
5576
5532
|
if (isOrCond(cond)) {
|
|
5577
|
-
const orGroups = cond.conditions.map((group) => condsToRecord(group));
|
|
5533
|
+
const orGroups = cond.conditions.map((group) => condsToRecord(group, typeCast));
|
|
5578
5534
|
result["__or__"] = orGroups;
|
|
5579
5535
|
} else if (isAnySqlFragment(cond)) {
|
|
5580
5536
|
const kv = sqlFragmentToKeyValue(cond);
|
|
@@ -5583,7 +5539,7 @@ function condsToRecord(conditions) {
|
|
|
5583
5539
|
result[key] = value;
|
|
5584
5540
|
}
|
|
5585
5541
|
} else {
|
|
5586
|
-
const kv = condToKeyValue(cond);
|
|
5542
|
+
const kv = condToKeyValue(cond, typeCast);
|
|
5587
5543
|
if (kv === null) continue;
|
|
5588
5544
|
const [key, value] = kv;
|
|
5589
5545
|
result[key] = value;
|
|
@@ -5632,12 +5588,14 @@ function resolvePgArrayCast(sql2, values) {
|
|
|
5632
5588
|
function encodeJsonArrayParam(dialect, values) {
|
|
5633
5589
|
return encodeJsonParam(dialect, values);
|
|
5634
5590
|
}
|
|
5591
|
+
var BIGINT_SENTINEL = "\0int:";
|
|
5635
5592
|
function encodeJsonParam(dialect, payload) {
|
|
5636
|
-
|
|
5637
|
-
if (typeof v === "bigint") return
|
|
5593
|
+
const tagged = JSON.stringify(payload, (_key, v) => {
|
|
5594
|
+
if (typeof v === "bigint") return `${BIGINT_SENTINEL}${v.toString()}`;
|
|
5638
5595
|
if (dialect === "mysql" && typeof v === "boolean") return v ? 1 : 0;
|
|
5639
5596
|
return v;
|
|
5640
5597
|
});
|
|
5598
|
+
return tagged.replace(/"\\u0000int:(-?\d+)"/g, "$1");
|
|
5641
5599
|
}
|
|
5642
5600
|
|
|
5643
5601
|
// src/scp/makesql/json-batch.ts
|
|
@@ -5799,8 +5757,8 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
5799
5757
|
return "passthrough";
|
|
5800
5758
|
}
|
|
5801
5759
|
switch (t) {
|
|
5802
|
-
//
|
|
5803
|
-
//
|
|
5760
|
+
// Integer family. The PostgreSQL SERIAL types are the same integers under an auto-increment
|
|
5761
|
+
// default (SERIAL/SERIAL4=int4, SMALLSERIAL/SERIAL2=int2, BIGSERIAL/SERIAL8=int8).
|
|
5804
5762
|
case "INTEGER":
|
|
5805
5763
|
case "INT":
|
|
5806
5764
|
case "SMALLINT":
|
|
@@ -5812,13 +5770,11 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
5812
5770
|
case "SERIAL4":
|
|
5813
5771
|
case "SMALLSERIAL":
|
|
5814
5772
|
case "SERIAL2":
|
|
5815
|
-
return "int32";
|
|
5816
|
-
// 64-bit int: needs JS bigint for exactness.
|
|
5817
5773
|
case "BIGINT":
|
|
5818
5774
|
case "INT8":
|
|
5819
5775
|
case "BIGSERIAL":
|
|
5820
5776
|
case "SERIAL8":
|
|
5821
|
-
return "
|
|
5777
|
+
return "int";
|
|
5822
5778
|
case "BOOLEAN":
|
|
5823
5779
|
case "BOOL":
|
|
5824
5780
|
return "bool";
|
|
@@ -5853,31 +5809,33 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
5853
5809
|
);
|
|
5854
5810
|
}
|
|
5855
5811
|
}
|
|
5812
|
+
var I64_MIN2 = -(2n ** 63n);
|
|
5813
|
+
var I64_MAX2 = 2n ** 63n - 1n;
|
|
5814
|
+
function checkI642(v) {
|
|
5815
|
+
if (v < I64_MIN2 || v > I64_MAX2) {
|
|
5816
|
+
throw new Error(`materialize int: ${v} is outside the i64 range behavior-contracts' \`int\` admits`);
|
|
5817
|
+
}
|
|
5818
|
+
return v;
|
|
5819
|
+
}
|
|
5856
5820
|
function materializeCell(value, klass) {
|
|
5857
5821
|
if (value === null || value === void 0) return value;
|
|
5858
5822
|
switch (klass) {
|
|
5859
|
-
case "
|
|
5860
|
-
if (typeof value === "bigint") return value
|
|
5823
|
+
case "int": {
|
|
5824
|
+
if (typeof value === "bigint") return checkI642(value);
|
|
5861
5825
|
if (typeof value === "string") {
|
|
5862
|
-
if (!/^-?\d+$/.test(value)) throw new Error(`materialize
|
|
5863
|
-
return value;
|
|
5826
|
+
if (!/^-?\d+$/.test(value)) throw new Error(`materialize int: driver returned a non-integer string '${value}'`);
|
|
5827
|
+
return checkI642(BigInt(value));
|
|
5864
5828
|
}
|
|
5865
5829
|
if (typeof value === "number") {
|
|
5866
|
-
if (!Number.isInteger(value)) throw new Error(`materialize
|
|
5830
|
+
if (!Number.isInteger(value)) throw new Error(`materialize int: driver returned a non-integer number ${value} for an integer column`);
|
|
5867
5831
|
if (!Number.isSafeInteger(value)) {
|
|
5868
5832
|
throw new Error(
|
|
5869
|
-
`materialize
|
|
5833
|
+
`materialize int: driver returned an UNSAFE JS number ${value} for an integer column \u2014 precision was already lost before materialization (the driver must return integers as bigint/string, not a rounded double). Configure the driver (better-sqlite3 safeIntegers / mysql2 supportBigNumbers+bigNumberStrings / pg int-as-bigint).`
|
|
5870
5834
|
);
|
|
5871
5835
|
}
|
|
5872
|
-
return value
|
|
5836
|
+
return BigInt(value);
|
|
5873
5837
|
}
|
|
5874
|
-
throw new Error(`materialize
|
|
5875
|
-
}
|
|
5876
|
-
case "int32": {
|
|
5877
|
-
if (typeof value === "number") return value;
|
|
5878
|
-
if (typeof value === "bigint") return Number(value);
|
|
5879
|
-
if (typeof value === "string" && /^-?\d+$/.test(value)) return Number(value);
|
|
5880
|
-
throw new Error(`materialize int32: unexpected driver JS type ${typeof value} (${String(value)})`);
|
|
5838
|
+
throw new Error(`materialize int: unexpected driver JS type ${typeof value}`);
|
|
5881
5839
|
}
|
|
5882
5840
|
case "date": {
|
|
5883
5841
|
if (typeof value === "string") return value;
|
|
@@ -6376,133 +6334,131 @@ function compileCreateManyBundle(name, options, dialectName = "sqlite", resolveC
|
|
|
6376
6334
|
var import_reflect_metadata = __toESM(require_Reflect());
|
|
6377
6335
|
var COLUMNS_KEY = /* @__PURE__ */ Symbol("litedbmodel:columns");
|
|
6378
6336
|
var RELATIONS_KEY = /* @__PURE__ */ Symbol("litedbmodel:relations");
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
return materializeCell(v, "date");
|
|
6397
|
-
},
|
|
6398
|
-
// Delegate to driver-specific serializeDatetime
|
|
6399
|
-
serialize: (val, typeCast) => {
|
|
6400
|
-
if (val === null || val === void 0) return null;
|
|
6401
|
-
if (val instanceof Date) {
|
|
6402
|
-
return typeCast?.serializeDatetime(val) ?? val;
|
|
6403
|
-
}
|
|
6404
|
-
return val;
|
|
6405
|
-
},
|
|
6406
|
-
sqlCast: "timestamp"
|
|
6407
|
-
};
|
|
6408
|
-
case Number:
|
|
6409
|
-
return {
|
|
6410
|
-
typeCast: (v) => {
|
|
6411
|
-
if (v === void 0) return void 0;
|
|
6412
|
-
if (v === null) return null;
|
|
6413
|
-
const n = Number(v);
|
|
6414
|
-
return isNaN(n) ? null : n;
|
|
6415
|
-
}
|
|
6416
|
-
};
|
|
6417
|
-
case BigInt:
|
|
6418
|
-
return {
|
|
6419
|
-
// v2 read contract: BIGINT/INT8 → EXACT decimal STRING (no i64 rounding, JSON-safe), via the
|
|
6420
|
-
// shared materializer. NOTE: the TS field type stays `bigint` in existing models for source
|
|
6421
|
-
// compat, but the VALUE is now the exact string — the whole point of the #9 realignment.
|
|
6422
|
-
typeCast: (v) => {
|
|
6423
|
-
if (v === void 0) return void 0;
|
|
6424
|
-
return materializeCell(v, "int64");
|
|
6425
|
-
},
|
|
6426
|
-
sqlCast: "bigint"
|
|
6427
|
-
};
|
|
6428
|
-
// Array, Object, String, and other types require explicit specification
|
|
6429
|
-
default:
|
|
6430
|
-
return void 0;
|
|
6337
|
+
if (typeof Symbol === "function" && !Symbol.metadata) {
|
|
6338
|
+
Object.defineProperty(Symbol, "metadata", {
|
|
6339
|
+
value: /* @__PURE__ */ Symbol.for("Symbol.metadata"),
|
|
6340
|
+
writable: false,
|
|
6341
|
+
enumerable: false,
|
|
6342
|
+
configurable: true
|
|
6343
|
+
});
|
|
6344
|
+
}
|
|
6345
|
+
function isStandardContext(second) {
|
|
6346
|
+
return typeof second === "object" && second !== null && typeof second.kind === "string";
|
|
6347
|
+
}
|
|
6348
|
+
function classMetadataBag(context, propertyKey) {
|
|
6349
|
+
const bag = context.metadata;
|
|
6350
|
+
if (bag === void 0) {
|
|
6351
|
+
throw new Error(
|
|
6352
|
+
`litedbmodel: the standard-decorator context for '${propertyKey}' carries no \`context.metadata\`. litedbmodel defines \`Symbol.metadata\` on import, which every current emit needs to create the bag \u2014 import litedbmodel (or 'litedbmodel/decorators') BEFORE the module that defines the model.`
|
|
6353
|
+
);
|
|
6431
6354
|
}
|
|
6355
|
+
return bag;
|
|
6432
6356
|
}
|
|
6433
|
-
function
|
|
6434
|
-
const
|
|
6435
|
-
if (
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
return "TIMESTAMP";
|
|
6445
|
-
case BigInt:
|
|
6446
|
-
return "BIGINT";
|
|
6447
|
-
default:
|
|
6448
|
-
return void 0;
|
|
6357
|
+
function legacyColumnMap(constructor) {
|
|
6358
|
+
const own = Reflect.getOwnMetadata(COLUMNS_KEY, constructor);
|
|
6359
|
+
if (own !== void 0) return own;
|
|
6360
|
+
const inherited = Reflect.getMetadata(COLUMNS_KEY, constructor);
|
|
6361
|
+
const map = new Map(inherited);
|
|
6362
|
+
Reflect.defineMetadata(COLUMNS_KEY, map, constructor);
|
|
6363
|
+
return map;
|
|
6364
|
+
}
|
|
6365
|
+
function standardColumnMap(bag) {
|
|
6366
|
+
if (!Object.prototype.hasOwnProperty.call(bag, COLUMNS_KEY)) {
|
|
6367
|
+
bag[COLUMNS_KEY] = new Map(bag[COLUMNS_KEY]);
|
|
6449
6368
|
}
|
|
6369
|
+
return bag[COLUMNS_KEY];
|
|
6450
6370
|
}
|
|
6451
|
-
function
|
|
6452
|
-
const
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
}
|
|
6371
|
+
function legacyRelationList(constructor) {
|
|
6372
|
+
const own = Reflect.getOwnMetadata(RELATIONS_KEY, constructor);
|
|
6373
|
+
if (own !== void 0) return own;
|
|
6374
|
+
const inherited = Reflect.getMetadata(RELATIONS_KEY, constructor);
|
|
6375
|
+
const list = inherited !== void 0 ? [...inherited] : [];
|
|
6376
|
+
Reflect.defineMetadata(RELATIONS_KEY, list, constructor);
|
|
6377
|
+
return list;
|
|
6378
|
+
}
|
|
6379
|
+
function standardRelationList(bag) {
|
|
6380
|
+
if (!Object.prototype.hasOwnProperty.call(bag, RELATIONS_KEY)) {
|
|
6381
|
+
const inherited = bag[RELATIONS_KEY];
|
|
6382
|
+
bag[RELATIONS_KEY] = inherited !== void 0 ? [...inherited] : [];
|
|
6464
6383
|
}
|
|
6465
|
-
|
|
6384
|
+
return bag[RELATIONS_KEY];
|
|
6385
|
+
}
|
|
6386
|
+
function registerColumn(columns, propertyKey, options) {
|
|
6466
6387
|
columns.set(propertyKey, {
|
|
6467
6388
|
columnName: options.columnName,
|
|
6468
|
-
typeCast:
|
|
6469
|
-
serialize:
|
|
6389
|
+
typeCast: options.typeCast,
|
|
6390
|
+
serialize: options.serialize,
|
|
6470
6391
|
primaryKey: options.primaryKey,
|
|
6471
6392
|
autoIncrement: options.autoIncrement,
|
|
6472
|
-
sqlCast:
|
|
6473
|
-
...baseSqlType !== void 0 ? { baseSqlType } : {}
|
|
6393
|
+
sqlCast: options.sqlCast,
|
|
6394
|
+
...options.baseSqlType !== void 0 ? { baseSqlType: options.baseSqlType } : {}
|
|
6474
6395
|
});
|
|
6475
|
-
Reflect.defineMetadata(COLUMNS_KEY, columns, constructor);
|
|
6476
6396
|
}
|
|
6477
|
-
function
|
|
6397
|
+
function parseColumnOptions(columnNameOrOptions, propKey) {
|
|
6398
|
+
if (typeof columnNameOrOptions === "string") return { columnName: columnNameOrOptions };
|
|
6399
|
+
if (columnNameOrOptions) {
|
|
6400
|
+
return {
|
|
6401
|
+
columnName: columnNameOrOptions.columnName || propKey,
|
|
6402
|
+
primaryKey: columnNameOrOptions.primaryKey,
|
|
6403
|
+
autoIncrement: columnNameOrOptions.autoIncrement
|
|
6404
|
+
};
|
|
6405
|
+
}
|
|
6406
|
+
return { columnName: propKey };
|
|
6407
|
+
}
|
|
6408
|
+
function rejectNonText(family, val) {
|
|
6409
|
+
if (val === null || val === void 0) return null;
|
|
6410
|
+
if (val instanceof Date) {
|
|
6411
|
+
throw new Error(
|
|
6412
|
+
`litedbmodel: @column.${family}() received a Date. A text column cannot serialize one \u2014 the driver would store an object literal. Use @column.datetime() / @column.date() for a date column, or format the value yourself.`
|
|
6413
|
+
);
|
|
6414
|
+
}
|
|
6415
|
+
if (typeof val === "object") {
|
|
6416
|
+
throw new Error(
|
|
6417
|
+
`litedbmodel: @column.${family}() received an object. Use @column.json<T>() for a JSON column, or @column.custom() with a serializer.`
|
|
6418
|
+
);
|
|
6419
|
+
}
|
|
6420
|
+
return val;
|
|
6421
|
+
}
|
|
6422
|
+
function materializeString(family, v) {
|
|
6423
|
+
if (v === void 0 || v === null) return v;
|
|
6424
|
+
if (typeof v === "string") return v;
|
|
6425
|
+
if (typeof v === "number" || typeof v === "bigint" || typeof v === "boolean") return String(v);
|
|
6426
|
+
throw new Error(
|
|
6427
|
+
`materialize ${family}: driver returned ${typeof v} for a ${family} column. Use @column.passthrough() for a BYTEA/BLOB column, or @column.json<T>() for JSON.`
|
|
6428
|
+
);
|
|
6429
|
+
}
|
|
6430
|
+
function createColumnDecorator(typeCast, serialize, sqlCast, baseSqlType) {
|
|
6478
6431
|
return function(columnNameOrOptions) {
|
|
6479
|
-
return function(
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
} else {
|
|
6492
|
-
columnName = propKey;
|
|
6432
|
+
return function(targetOrValue, keyOrContext) {
|
|
6433
|
+
if (isStandardContext(keyOrContext)) {
|
|
6434
|
+
const propKey2 = String(keyOrContext.name);
|
|
6435
|
+
const parsed2 = parseColumnOptions(columnNameOrOptions, propKey2);
|
|
6436
|
+
registerColumn(standardColumnMap(classMetadataBag(keyOrContext, propKey2)), propKey2, {
|
|
6437
|
+
...parsed2,
|
|
6438
|
+
typeCast,
|
|
6439
|
+
serialize,
|
|
6440
|
+
sqlCast,
|
|
6441
|
+
baseSqlType
|
|
6442
|
+
});
|
|
6443
|
+
return;
|
|
6493
6444
|
}
|
|
6494
|
-
|
|
6495
|
-
|
|
6445
|
+
const propKey = String(keyOrContext);
|
|
6446
|
+
const parsed = parseColumnOptions(columnNameOrOptions, propKey);
|
|
6447
|
+
registerColumn(legacyColumnMap(targetOrValue.constructor), propKey, {
|
|
6448
|
+
...parsed,
|
|
6496
6449
|
typeCast,
|
|
6497
6450
|
serialize,
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
autoIncrement,
|
|
6501
|
-
sqlCast
|
|
6451
|
+
sqlCast,
|
|
6452
|
+
baseSqlType
|
|
6502
6453
|
});
|
|
6503
6454
|
};
|
|
6504
6455
|
};
|
|
6505
6456
|
}
|
|
6457
|
+
function requireColumnFamily() {
|
|
6458
|
+
throw new Error(
|
|
6459
|
+
"litedbmodel: `@column()` no longer declares a column \u2014 a column must state its type with a family: @column.text() / .decimal() / .number() / .boolean() / .bigint() / .datetime() / .date() / .uuid() / .json() / .stringArray() / .intArray() / .numericArray() / .booleanArray() / .datetimeArray() / .passthrough() / .custom(). Every family takes the same argument as `@column()` did (`@column.text('db_name')`, `@column.number({ primaryKey: true })`). The bare form inferred the type from `emitDecoratorMetadata`, which esbuild (tsx/vite/vitest) never emits and standard decorators do not have, so it silently produced untyped reads."
|
|
6460
|
+
);
|
|
6461
|
+
}
|
|
6506
6462
|
function serializeArray(val, typeCast) {
|
|
6507
6463
|
if (val === null || val === void 0) return null;
|
|
6508
6464
|
if (!Array.isArray(val)) return val;
|
|
@@ -6540,19 +6496,47 @@ function serializeJson(val, typeCast) {
|
|
|
6540
6496
|
return JSON.stringify(val);
|
|
6541
6497
|
}
|
|
6542
6498
|
var column = Object.assign(
|
|
6543
|
-
//
|
|
6544
|
-
|
|
6499
|
+
// The bare `@column()` declared no type — it is rejected, with the migration in the message.
|
|
6500
|
+
(_columnNameOrOptions) => requireColumnFamily(),
|
|
6545
6501
|
{
|
|
6546
6502
|
// ============================================
|
|
6547
6503
|
// Primitive Types
|
|
6548
6504
|
// ============================================
|
|
6505
|
+
/**
|
|
6506
|
+
* Text type (TEXT / VARCHAR / CHAR / ENUM / citext) — the driver value is already a string, so no
|
|
6507
|
+
* cast is applied. The family still DECLARES the column so the typed read types it as `TEXT`.
|
|
6508
|
+
* @example @column.text() name?: string;
|
|
6509
|
+
* @example @column.text('user_name') name?: string;
|
|
6510
|
+
*/
|
|
6511
|
+
text: (columnNameOrOptions) => createColumnDecorator(
|
|
6512
|
+
(v) => materializeString("text", v),
|
|
6513
|
+
// the family DECLARES `string`, so it hands back one
|
|
6514
|
+
(val) => rejectNonText("text", val),
|
|
6515
|
+
// …and it cannot SERIALIZE a Date or an object
|
|
6516
|
+
void 0,
|
|
6517
|
+
// no sqlCast family (a text literal needs no SQL cast)
|
|
6518
|
+
"TEXT"
|
|
6519
|
+
// §4.1 token: types the SCP typed read
|
|
6520
|
+
)(columnNameOrOptions),
|
|
6521
|
+
/**
|
|
6522
|
+
* Exact decimal type (NUMERIC / DECIMAL) — read back as its exact decimal STRING (a JS number
|
|
6523
|
+
* rounds past 2^53). The family states the column is `numeric`, so a write binds the string as a
|
|
6524
|
+
* numeric — a batch write (`createMany` / `updateMany`) included.
|
|
6525
|
+
* @example @column.decimal() price?: string;
|
|
6526
|
+
*/
|
|
6527
|
+
decimal: (columnNameOrOptions) => createColumnDecorator(
|
|
6528
|
+
(v) => materializeString("decimal", v),
|
|
6529
|
+
(val) => rejectNonText("decimal", val),
|
|
6530
|
+
"numeric"
|
|
6531
|
+
// sqlCast for WHERE / INSERT / batch-write type casting
|
|
6532
|
+
)(columnNameOrOptions),
|
|
6549
6533
|
/**
|
|
6550
6534
|
* Boolean type conversion
|
|
6551
6535
|
* Converts 't'/'f', 'true'/'false', 1/0 to boolean
|
|
6552
6536
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6553
6537
|
* @example @column.boolean() is_active?: boolean;
|
|
6554
6538
|
*/
|
|
6555
|
-
boolean: (
|
|
6539
|
+
boolean: (columnNameOrOptions) => createColumnDecorator(
|
|
6556
6540
|
// v2 read contract: BOOLEAN → boolean, via the shared materializer (issue #9).
|
|
6557
6541
|
(v) => {
|
|
6558
6542
|
if (v === void 0) return void 0;
|
|
@@ -6560,42 +6544,38 @@ var column = Object.assign(
|
|
|
6560
6544
|
},
|
|
6561
6545
|
void 0,
|
|
6562
6546
|
// no custom serialize
|
|
6563
|
-
false,
|
|
6564
|
-
// allow auto-inference
|
|
6565
6547
|
"boolean"
|
|
6566
6548
|
// sqlCast for updateMany type inference
|
|
6567
|
-
)(
|
|
6549
|
+
)(columnNameOrOptions),
|
|
6568
6550
|
/**
|
|
6569
6551
|
* Number type conversion (from string)
|
|
6570
6552
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6571
6553
|
* @example @column.number() amount?: number;
|
|
6572
6554
|
*/
|
|
6573
|
-
number: (
|
|
6555
|
+
number: (columnNameOrOptions) => createColumnDecorator((v) => {
|
|
6574
6556
|
if (v === void 0) return void 0;
|
|
6575
6557
|
if (v === null) return null;
|
|
6576
6558
|
const n = Number(v);
|
|
6577
6559
|
return isNaN(n) ? null : n;
|
|
6578
|
-
})(
|
|
6560
|
+
})(columnNameOrOptions),
|
|
6579
6561
|
/**
|
|
6580
6562
|
* BigInt type conversion
|
|
6581
6563
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6582
|
-
* @example @column.bigint() large_id?: bigint;
|
|
6564
|
+
* @example @column.bigint() large_id?: bigint; // bc `int` — a JS bigint, checked i64
|
|
6583
6565
|
*/
|
|
6584
|
-
bigint: (
|
|
6585
|
-
//
|
|
6586
|
-
//
|
|
6587
|
-
//
|
|
6566
|
+
bigint: (columnNameOrOptions) => createColumnDecorator(
|
|
6567
|
+
// An integer column reads back as a JS `bigint` — behavior-contracts' `int` value model
|
|
6568
|
+
// (`int` = bigint, checked i64), which is what the drivers already hand over. `JSON.stringify`
|
|
6569
|
+
// does not serialize a bigint: give the field a `toJSON`, or convert at the boundary.
|
|
6588
6570
|
(v) => {
|
|
6589
6571
|
if (v === void 0) return void 0;
|
|
6590
|
-
return materializeCell(v, "
|
|
6572
|
+
return materializeCell(v, "int");
|
|
6591
6573
|
},
|
|
6592
6574
|
void 0,
|
|
6593
6575
|
// no custom serialize
|
|
6594
|
-
false,
|
|
6595
|
-
// allow auto-inference
|
|
6596
6576
|
"bigint"
|
|
6597
6577
|
// sqlCast for WHERE/INSERT type casting
|
|
6598
|
-
)(
|
|
6578
|
+
)(columnNameOrOptions),
|
|
6599
6579
|
// ============================================
|
|
6600
6580
|
// Date/Time Types
|
|
6601
6581
|
// ============================================
|
|
@@ -6607,9 +6587,9 @@ var column = Object.assign(
|
|
|
6607
6587
|
* - PostgreSQL: Serializes to ISO 8601 UTC string with 'Z' suffix for explicit timezone
|
|
6608
6588
|
* - MySQL/SQLite: Passes Date object to driver (driver-dependent timezone handling)
|
|
6609
6589
|
*
|
|
6610
|
-
* @example @column.datetime() created_at?: Date
|
|
6590
|
+
* @example @column.datetime() created_at?: string; // TZ-attached string, NOT a JS Date
|
|
6611
6591
|
*/
|
|
6612
|
-
datetime: (
|
|
6592
|
+
datetime: (columnNameOrOptions) => createColumnDecorator(
|
|
6613
6593
|
// v2 read contract: DATE/TIMESTAMP/TIMESTAMPTZ/DATETIME/TIME → TZ-attached STRING (NOT a
|
|
6614
6594
|
// TZ-shifted JS Date), via the shared materializer (issue #9). A driver already returning the
|
|
6615
6595
|
// native textual form passes through; a JS Date is rendered to its lossless ISO instant.
|
|
@@ -6625,11 +6605,9 @@ var column = Object.assign(
|
|
|
6625
6605
|
}
|
|
6626
6606
|
return val;
|
|
6627
6607
|
},
|
|
6628
|
-
false,
|
|
6629
|
-
// allow auto-inference
|
|
6630
6608
|
"timestamp"
|
|
6631
6609
|
// sqlCast for updateMany type inference
|
|
6632
|
-
)(
|
|
6610
|
+
)(columnNameOrOptions),
|
|
6633
6611
|
/**
|
|
6634
6612
|
* Date type conversion — returns YYYY-MM-DD string.
|
|
6635
6613
|
* Preserves null for nullable columns, undefined stays undefined.
|
|
@@ -6637,9 +6615,9 @@ var column = Object.assign(
|
|
|
6637
6615
|
* DB values (Date object or string) are normalized to 'YYYY-MM-DD' string.
|
|
6638
6616
|
* On write, string values are passed through; Date objects are formatted as 'YYYY-MM-DD'.
|
|
6639
6617
|
*
|
|
6640
|
-
* @example @column.date() birth_date?: string;
|
|
6618
|
+
* @example @column.date() birth_date?: string; // 'YYYY-MM-DD'
|
|
6641
6619
|
*/
|
|
6642
|
-
date: (
|
|
6620
|
+
date: (columnNameOrOptions) => createColumnDecorator(
|
|
6643
6621
|
(v) => {
|
|
6644
6622
|
if (v === void 0) return void 0;
|
|
6645
6623
|
if (v === null) return null;
|
|
@@ -6664,11 +6642,9 @@ var column = Object.assign(
|
|
|
6664
6642
|
}
|
|
6665
6643
|
return val;
|
|
6666
6644
|
},
|
|
6667
|
-
false,
|
|
6668
|
-
// allow auto-inference
|
|
6669
6645
|
"date"
|
|
6670
6646
|
// sqlCast for updateMany type inference
|
|
6671
|
-
)(
|
|
6647
|
+
)(columnNameOrOptions),
|
|
6672
6648
|
// ============================================
|
|
6673
6649
|
// Array Types
|
|
6674
6650
|
// ============================================
|
|
@@ -6677,71 +6653,71 @@ var column = Object.assign(
|
|
|
6677
6653
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6678
6654
|
* @example @column.stringArray() tags?: string[];
|
|
6679
6655
|
*/
|
|
6680
|
-
stringArray: (
|
|
6656
|
+
stringArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6681
6657
|
(v) => {
|
|
6682
6658
|
if (v === void 0) return void 0;
|
|
6683
6659
|
if (v === null) return null;
|
|
6684
|
-
return
|
|
6660
|
+
return castToStringArray2(v);
|
|
6685
6661
|
},
|
|
6686
6662
|
serializeArray,
|
|
6687
|
-
false,
|
|
6688
6663
|
"text[]"
|
|
6689
|
-
)(
|
|
6664
|
+
)(columnNameOrOptions),
|
|
6690
6665
|
/**
|
|
6691
6666
|
* Integer array type conversion (integer[])
|
|
6692
6667
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6693
6668
|
* @example @column.intArray() scores?: number[];
|
|
6694
6669
|
*/
|
|
6695
|
-
intArray: (
|
|
6670
|
+
intArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6696
6671
|
(v) => {
|
|
6697
6672
|
if (v === void 0) return void 0;
|
|
6698
6673
|
if (v === null) return null;
|
|
6699
|
-
return
|
|
6674
|
+
return castToIntegerArray2(v);
|
|
6700
6675
|
},
|
|
6701
6676
|
serializeArray,
|
|
6702
|
-
false,
|
|
6703
6677
|
"int[]"
|
|
6704
|
-
)(
|
|
6678
|
+
)(columnNameOrOptions),
|
|
6705
6679
|
/**
|
|
6706
6680
|
* Numeric array type conversion (numeric[], allows null elements)
|
|
6707
6681
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6708
6682
|
* @example @column.numericArray() values?: (number | null)[];
|
|
6709
6683
|
*/
|
|
6710
|
-
numericArray: (
|
|
6684
|
+
numericArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6711
6685
|
(v) => {
|
|
6712
6686
|
if (v === void 0) return void 0;
|
|
6713
6687
|
if (v === null) return null;
|
|
6714
|
-
return
|
|
6688
|
+
return castToNumericArray2(v);
|
|
6715
6689
|
},
|
|
6716
6690
|
serializeArray,
|
|
6717
|
-
false,
|
|
6718
6691
|
"numeric[]"
|
|
6719
|
-
)(
|
|
6692
|
+
)(columnNameOrOptions),
|
|
6720
6693
|
/**
|
|
6721
6694
|
* Boolean array type conversion (boolean[])
|
|
6722
6695
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6723
6696
|
* @example @column.booleanArray() flags?: (boolean | null)[];
|
|
6724
6697
|
*/
|
|
6725
|
-
booleanArray: (
|
|
6698
|
+
booleanArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6726
6699
|
(v) => {
|
|
6727
6700
|
if (v === void 0) return void 0;
|
|
6728
6701
|
if (v === null) return null;
|
|
6729
|
-
return
|
|
6702
|
+
return castToBooleanArray2(v);
|
|
6730
6703
|
},
|
|
6731
6704
|
serializeBooleanArray,
|
|
6732
|
-
false,
|
|
6733
6705
|
"boolean[]"
|
|
6734
|
-
)(
|
|
6706
|
+
)(columnNameOrOptions),
|
|
6735
6707
|
/**
|
|
6736
6708
|
* DateTime array type conversion (timestamp[])
|
|
6737
6709
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6738
|
-
* @example @column.datetimeArray() event_dates?: (
|
|
6710
|
+
* @example @column.datetimeArray() event_dates?: (string | null)[];
|
|
6739
6711
|
*/
|
|
6740
|
-
datetimeArray: (
|
|
6712
|
+
datetimeArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6713
|
+
// Element-wise the SAME contract as `@column.datetime()`: a TZ-attached STRING, never a
|
|
6714
|
+
// TZ-shifted JS Date. The array family used to be the one place a `Date` still came back, so
|
|
6715
|
+
// `JSON.stringify` of a row silently re-rendered those elements in UTC — the exact hazard #9
|
|
6716
|
+
// closed for the scalar.
|
|
6741
6717
|
(v) => {
|
|
6742
6718
|
if (v === void 0) return void 0;
|
|
6743
6719
|
if (v === null) return null;
|
|
6744
|
-
return
|
|
6720
|
+
return castToDatetimeArray2(v).map((d) => d === null ? null : materializeCell(d, "date"));
|
|
6745
6721
|
},
|
|
6746
6722
|
// DateTime arrays serialize each Date to ISO string
|
|
6747
6723
|
(val) => {
|
|
@@ -6750,7 +6726,7 @@ var column = Object.assign(
|
|
|
6750
6726
|
const mapped = val.map((v) => v === null ? "NULL" : v instanceof Date ? v.toISOString() : String(v));
|
|
6751
6727
|
return `{${mapped.join(",")}}`;
|
|
6752
6728
|
}
|
|
6753
|
-
)(
|
|
6729
|
+
)(columnNameOrOptions),
|
|
6754
6730
|
// ============================================
|
|
6755
6731
|
// JSON Types
|
|
6756
6732
|
// ============================================
|
|
@@ -6760,16 +6736,15 @@ var column = Object.assign(
|
|
|
6760
6736
|
* @example @column.json() metadata?: Record<string, unknown>;
|
|
6761
6737
|
* @example @column.json<UserSettings>() settings?: UserSettings;
|
|
6762
6738
|
*/
|
|
6763
|
-
json: (
|
|
6739
|
+
json: (columnNameOrOptions) => createColumnDecorator(
|
|
6764
6740
|
(v) => {
|
|
6765
6741
|
if (v === void 0) return void 0;
|
|
6766
6742
|
if (v === null) return null;
|
|
6767
|
-
return
|
|
6743
|
+
return castToJson2(v);
|
|
6768
6744
|
},
|
|
6769
6745
|
serializeJson,
|
|
6770
|
-
false,
|
|
6771
6746
|
"jsonb"
|
|
6772
|
-
)(
|
|
6747
|
+
)(columnNameOrOptions),
|
|
6773
6748
|
// ============================================
|
|
6774
6749
|
// UUID Type (PostgreSQL)
|
|
6775
6750
|
// ============================================
|
|
@@ -6798,61 +6773,101 @@ var column = Object.assign(
|
|
|
6798
6773
|
if (v === null) return null;
|
|
6799
6774
|
return String(v);
|
|
6800
6775
|
},
|
|
6801
|
-
|
|
6802
|
-
//
|
|
6803
|
-
true,
|
|
6804
|
-
// Skip auto-inference
|
|
6776
|
+
(val) => rejectNonText("uuid", val),
|
|
6777
|
+
// the ::uuid cast handles the rest
|
|
6805
6778
|
"uuid"
|
|
6806
6779
|
// SQL type for casting
|
|
6807
6780
|
)(columnNameOrOptions),
|
|
6808
6781
|
// ============================================
|
|
6809
6782
|
// Custom Type Conversion
|
|
6810
6783
|
// ============================================
|
|
6784
|
+
/**
|
|
6785
|
+
* The driver's value, UNCAST — for a column whose type the library has no cast for (`BYTEA` /
|
|
6786
|
+
* `BLOB` arrives as a driver Buffer, a vendor type as whatever the driver decodes). It states
|
|
6787
|
+
* "this column is passed through", which is a DECLARATION; the removed bare `@column()` was the
|
|
6788
|
+
* absence of one, and produced this same passthrough by accident for every unresolvable type.
|
|
6789
|
+
* @example @column.passthrough() payload?: unknown;
|
|
6790
|
+
*/
|
|
6791
|
+
passthrough: (columnNameOrOptions) => createColumnDecorator()(columnNameOrOptions),
|
|
6811
6792
|
/**
|
|
6812
6793
|
* Custom type conversion with user-provided function
|
|
6813
6794
|
* @example @column.custom((v) => String(v).toUpperCase()) status?: string;
|
|
6814
6795
|
* @example @column.custom((v) => v, (v) => JSON.stringify(v)) data?: MyType; // with serializer
|
|
6815
6796
|
*/
|
|
6816
|
-
custom: (castFn, serializeFn,
|
|
6797
|
+
custom: (castFn, serializeFn, columnNameOrOptions) => createColumnDecorator(castFn, serializeFn)(columnNameOrOptions)
|
|
6817
6798
|
}
|
|
6818
6799
|
);
|
|
6819
|
-
function registerRelation(
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6800
|
+
function registerRelation(relations, propertyKey, type, keysFactory, options) {
|
|
6801
|
+
relations.push({ propertyKey, type, keysFactory, options });
|
|
6802
|
+
}
|
|
6803
|
+
function createRelationDecorator(type, keys, options) {
|
|
6804
|
+
return function(targetOrValue, keyOrContext) {
|
|
6805
|
+
if (isStandardContext(keyOrContext)) {
|
|
6806
|
+
const propKey2 = String(keyOrContext.name);
|
|
6807
|
+
registerRelation(standardRelationList(classMetadataBag(keyOrContext, propKey2)), propKey2, type, keys, options);
|
|
6808
|
+
if (typeof keyOrContext.addInitializer !== "function") {
|
|
6809
|
+
throw new Error(
|
|
6810
|
+
`litedbmodel: the standard-decorator context for relation '${propKey2}' has no \`addInitializer\`, so the class field cannot be removed and would shadow the relation getter.`
|
|
6811
|
+
);
|
|
6812
|
+
}
|
|
6813
|
+
keyOrContext.addInitializer(function() {
|
|
6814
|
+
if (Object.prototype.hasOwnProperty.call(this, propKey2)) {
|
|
6815
|
+
delete this[propKey2];
|
|
6816
|
+
}
|
|
6817
|
+
});
|
|
6818
|
+
return;
|
|
6819
|
+
}
|
|
6820
|
+
const propKey = String(keyOrContext);
|
|
6821
|
+
registerRelation(legacyRelationList(targetOrValue.constructor), propKey, type, keys, options);
|
|
6822
|
+
};
|
|
6829
6823
|
}
|
|
6830
6824
|
function hasMany(keys, options) {
|
|
6831
|
-
return
|
|
6832
|
-
registerRelation(target, String(propertyKey), "hasMany", keys, options);
|
|
6833
|
-
};
|
|
6825
|
+
return createRelationDecorator("hasMany", keys, options);
|
|
6834
6826
|
}
|
|
6835
6827
|
function belongsTo(keys, options) {
|
|
6836
|
-
return
|
|
6837
|
-
registerRelation(target, String(propertyKey), "belongsTo", keys, options);
|
|
6838
|
-
};
|
|
6828
|
+
return createRelationDecorator("belongsTo", keys, options);
|
|
6839
6829
|
}
|
|
6840
6830
|
function hasOne(keys, options) {
|
|
6841
|
-
return
|
|
6842
|
-
registerRelation(target, String(propertyKey), "hasOne", keys, options);
|
|
6843
|
-
};
|
|
6831
|
+
return createRelationDecorator("hasOne", keys, options);
|
|
6844
6832
|
}
|
|
6845
6833
|
function getRelationMeta(modelClass) {
|
|
6846
6834
|
return modelClass._relationMeta || Reflect.getMetadata(RELATIONS_KEY, modelClass) || [];
|
|
6847
6835
|
}
|
|
6848
|
-
function model(tableNameOrConstructor,
|
|
6836
|
+
function model(tableNameOrConstructor, optionsOrContext) {
|
|
6849
6837
|
if (typeof tableNameOrConstructor === "string") {
|
|
6850
6838
|
const tableName = tableNameOrConstructor;
|
|
6851
|
-
|
|
6852
|
-
|
|
6839
|
+
const options = optionsOrContext;
|
|
6840
|
+
return function(constructor, context) {
|
|
6841
|
+
return applyToClass(constructor, context, tableName, options);
|
|
6842
|
+
};
|
|
6843
|
+
}
|
|
6844
|
+
return applyToClass(tableNameOrConstructor, optionsOrContext);
|
|
6845
|
+
}
|
|
6846
|
+
function applyToClass(constructor, context, tableName, options) {
|
|
6847
|
+
const members = modelMembers(constructor, context);
|
|
6848
|
+
if (!isStandardContext(context)) return applyModelDecorator(constructor, members, tableName, options);
|
|
6849
|
+
if (typeof context.addInitializer !== "function") {
|
|
6850
|
+
throw new Error(
|
|
6851
|
+
`litedbmodel: the standard-decorator context for '${constructor.name}' has no \`addInitializer\`, so \`@model\` cannot assemble the model after the class is defined.`
|
|
6852
|
+
);
|
|
6853
|
+
}
|
|
6854
|
+
context.addInitializer(function() {
|
|
6855
|
+
applyModelDecorator(this, members, tableName, options);
|
|
6856
|
+
});
|
|
6857
|
+
return constructor;
|
|
6858
|
+
}
|
|
6859
|
+
function modelMembers(constructor, context) {
|
|
6860
|
+
if (isStandardContext(context)) {
|
|
6861
|
+
const bag = classMetadataBag(context, String(constructor.name ?? "model"));
|
|
6862
|
+
return {
|
|
6863
|
+
columns: bag[COLUMNS_KEY] ?? /* @__PURE__ */ new Map(),
|
|
6864
|
+
relations: bag[RELATIONS_KEY] ?? []
|
|
6853
6865
|
};
|
|
6854
6866
|
}
|
|
6855
|
-
return
|
|
6867
|
+
return {
|
|
6868
|
+
columns: Reflect.getMetadata(COLUMNS_KEY, constructor) ?? /* @__PURE__ */ new Map(),
|
|
6869
|
+
relations: Reflect.getMetadata(RELATIONS_KEY, constructor) ?? []
|
|
6870
|
+
};
|
|
6856
6871
|
}
|
|
6857
6872
|
function isCompositeKeys(keys) {
|
|
6858
6873
|
return Array.isArray(keys[0]);
|
|
@@ -6872,9 +6887,8 @@ function parseKeys(keys) {
|
|
|
6872
6887
|
};
|
|
6873
6888
|
}
|
|
6874
6889
|
}
|
|
6875
|
-
function applyModelDecorator(constructor, tableName, options) {
|
|
6876
|
-
const columns
|
|
6877
|
-
const relations = Reflect.getMetadata(RELATIONS_KEY, constructor) || [];
|
|
6890
|
+
function applyModelDecorator(constructor, members, tableName, options) {
|
|
6891
|
+
const { columns, relations } = members;
|
|
6878
6892
|
const modelName = constructor.name;
|
|
6879
6893
|
if (tableName) {
|
|
6880
6894
|
Object.defineProperty(constructor, "TABLE_NAME", {
|
|
@@ -6937,7 +6951,7 @@ function applyModelDecorator(constructor, tableName, options) {
|
|
|
6937
6951
|
const effectiveTableName = tableName ?? modelName.toLowerCase();
|
|
6938
6952
|
for (const [propKey, meta] of columns) {
|
|
6939
6953
|
Object.defineProperty(constructor, propKey, {
|
|
6940
|
-
value: createColumn(meta.columnName, effectiveTableName, modelName, propKey, meta.sqlCast),
|
|
6954
|
+
value: createColumn(meta.columnName, effectiveTableName, modelName, propKey, meta.sqlCast, meta.serialize),
|
|
6941
6955
|
writable: false,
|
|
6942
6956
|
enumerable: true,
|
|
6943
6957
|
configurable: false
|
|
@@ -6981,17 +6995,36 @@ function applyModelDecorator(constructor, tableName, options) {
|
|
|
6981
6995
|
const keys = keysFactory();
|
|
6982
6996
|
const { sourceKeys, targetKeys, targetModelName } = parseKeys(keys);
|
|
6983
6997
|
const order = options2?.order ? orderToString(options2.order()) : null;
|
|
6984
|
-
const conditions = options2?.where ? condsToRecord(options2.where()) : void 0;
|
|
6985
6998
|
return this._loadRelation(type, targetModelName, {
|
|
6986
6999
|
sourceKeys,
|
|
6987
7000
|
targetKeys,
|
|
6988
7001
|
order,
|
|
6989
|
-
|
|
7002
|
+
where: options2?.where?.(),
|
|
6990
7003
|
limit: options2?.limit,
|
|
6991
7004
|
hardLimit: options2?.hardLimit,
|
|
6992
7005
|
relationName: propertyKey
|
|
6993
7006
|
});
|
|
6994
7007
|
},
|
|
7008
|
+
/**
|
|
7009
|
+
* A relation is a getter, but a class FIELD declaring it still writes to the property. Which
|
|
7010
|
+
* write it is depends on `useDefineForClassFields`: with define semantics (the default from
|
|
7011
|
+
* target ES2022) the field is `defineProperty`-d onto the instance, bypassing this setter — the
|
|
7012
|
+
* standard protocol's initializer removes that shadowing property. With SET semantics (the
|
|
7013
|
+
* default below ES2022) the field ASSIGNS, and an accessor with no setter throws
|
|
7014
|
+
* `Cannot set property … which has only a getter` on EVERY instantiation.
|
|
7015
|
+
*
|
|
7016
|
+
* So: the field's own `undefined` is ignored, and any other value is honoured as an own
|
|
7017
|
+
* property — priming a relation (a loaded graph, a test double) reads back what was set.
|
|
7018
|
+
*/
|
|
7019
|
+
set: function(value) {
|
|
7020
|
+
if (value === void 0) return;
|
|
7021
|
+
Object.defineProperty(this, propertyKey, {
|
|
7022
|
+
value,
|
|
7023
|
+
writable: true,
|
|
7024
|
+
enumerable: true,
|
|
7025
|
+
configurable: true
|
|
7026
|
+
});
|
|
7027
|
+
},
|
|
6995
7028
|
enumerable: true,
|
|
6996
7029
|
configurable: false
|
|
6997
7030
|
});
|
|
@@ -7109,6 +7142,7 @@ function serializeRecord(modelClass, record, typeCast) {
|
|
|
7109
7142
|
// src/scp/decorator-adapter.ts
|
|
7110
7143
|
var COLUMN_FAMILY_SQL_TYPE = {
|
|
7111
7144
|
boolean: "BOOLEAN",
|
|
7145
|
+
numeric: "NUMERIC",
|
|
7112
7146
|
bigint: "BIGINT",
|
|
7113
7147
|
timestamp: "TIMESTAMP",
|
|
7114
7148
|
date: "DATE",
|
|
@@ -7261,23 +7295,6 @@ function createDriver(config, options) {
|
|
|
7261
7295
|
}
|
|
7262
7296
|
function getTypeCastForDriver(driverType) {
|
|
7263
7297
|
if (driverType === "sqlite") {
|
|
7264
|
-
return {
|
|
7265
|
-
castToDatetime: castToDatetime3,
|
|
7266
|
-
castToBoolean: castToBoolean3,
|
|
7267
|
-
castToIntegerArray: castToIntegerArray3,
|
|
7268
|
-
castToNumericArray: (val) => castToIntegerArray3(val).map((v) => v),
|
|
7269
|
-
castToStringArray: castToStringArray3,
|
|
7270
|
-
castToBooleanArray: (val) => {
|
|
7271
|
-
const arr = castToStringArray3(val);
|
|
7272
|
-
return arr.map((v) => castToBoolean3(v));
|
|
7273
|
-
},
|
|
7274
|
-
castToDatetimeArray: (val) => {
|
|
7275
|
-
const arr = castToStringArray3(val);
|
|
7276
|
-
return arr.map((v) => castToDatetime3(v));
|
|
7277
|
-
},
|
|
7278
|
-
castToJson: castToJson3
|
|
7279
|
-
};
|
|
7280
|
-
} else if (driverType === "mysql") {
|
|
7281
7298
|
return {
|
|
7282
7299
|
castToDatetime: castToDatetime4,
|
|
7283
7300
|
castToBoolean: castToBoolean4,
|
|
@@ -7294,16 +7311,33 @@ function getTypeCastForDriver(driverType) {
|
|
|
7294
7311
|
},
|
|
7295
7312
|
castToJson: castToJson4
|
|
7296
7313
|
};
|
|
7314
|
+
} else if (driverType === "mysql") {
|
|
7315
|
+
return {
|
|
7316
|
+
castToDatetime: castToDatetime3,
|
|
7317
|
+
castToBoolean: castToBoolean3,
|
|
7318
|
+
castToIntegerArray: castToIntegerArray3,
|
|
7319
|
+
castToNumericArray: (val) => castToIntegerArray3(val).map((v) => v),
|
|
7320
|
+
castToStringArray: castToStringArray3,
|
|
7321
|
+
castToBooleanArray: (val) => {
|
|
7322
|
+
const arr = castToStringArray3(val);
|
|
7323
|
+
return arr.map((v) => castToBoolean3(v));
|
|
7324
|
+
},
|
|
7325
|
+
castToDatetimeArray: (val) => {
|
|
7326
|
+
const arr = castToStringArray3(val);
|
|
7327
|
+
return arr.map((v) => castToDatetime3(v));
|
|
7328
|
+
},
|
|
7329
|
+
castToJson: castToJson3
|
|
7330
|
+
};
|
|
7297
7331
|
} else {
|
|
7298
7332
|
return {
|
|
7299
|
-
castToDatetime
|
|
7300
|
-
castToBoolean
|
|
7301
|
-
castToIntegerArray
|
|
7302
|
-
castToNumericArray
|
|
7303
|
-
castToStringArray
|
|
7304
|
-
castToBooleanArray
|
|
7305
|
-
castToDatetimeArray
|
|
7306
|
-
castToJson
|
|
7333
|
+
castToDatetime,
|
|
7334
|
+
castToBoolean,
|
|
7335
|
+
castToIntegerArray,
|
|
7336
|
+
castToNumericArray,
|
|
7337
|
+
castToStringArray,
|
|
7338
|
+
castToBooleanArray,
|
|
7339
|
+
castToDatetimeArray,
|
|
7340
|
+
castToJson
|
|
7307
7341
|
};
|
|
7308
7342
|
}
|
|
7309
7343
|
}
|
|
@@ -8054,8 +8088,8 @@ var DBModel = class _DBModel {
|
|
|
8054
8088
|
* ```typescript
|
|
8055
8089
|
* @model('users')
|
|
8056
8090
|
* class UserModel extends DBModel {
|
|
8057
|
-
* @column() id?: number;
|
|
8058
|
-
* @column() name?: string;
|
|
8091
|
+
* @column.number() id?: number;
|
|
8092
|
+
* @column.text() name?: string;
|
|
8059
8093
|
* }
|
|
8060
8094
|
* export const User = UserModel.asModel();
|
|
8061
8095
|
* export type User = UserModel;
|
|
@@ -8187,15 +8221,14 @@ var DBModel = class _DBModel {
|
|
|
8187
8221
|
static _scpColumnTypesCache = /* @__PURE__ */ new WeakMap();
|
|
8188
8222
|
/**
|
|
8189
8223
|
* The §4.1 column-type OVERRIDES for the SCP read/write bundle (the F1 `columnTypes` escape hatch).
|
|
8190
|
-
*
|
|
8191
|
-
*
|
|
8192
|
-
*
|
|
8193
|
-
* otherwise take the blanket-INTEGER default and THROW `materialize int32` on a live string. Because
|
|
8224
|
+
* A column whose SQL type cannot be derived from its family — `@column.number()`, whose JS `number`
|
|
8225
|
+
* backs an INTEGER just as well as a REAL/DECIMAL (pg returns DECIMAL as a string that an `int32`
|
|
8226
|
+
* materialize REJECTS) — would otherwise take the blanket-INTEGER default and THROW. Because
|
|
8194
8227
|
* the DBModel read path does its OWN v1 de-box (`_createInstance` → `typeCastFromDB`), the SCP typed
|
|
8195
8228
|
* read only needs a NON-THROWING, passthrough-safe SQL type for such columns: we pin them to `TEXT`
|
|
8196
8229
|
* (passthrough — the driver value flows through unchanged, then v1 casts it). Columns WITH a derivable
|
|
8197
|
-
* type (
|
|
8198
|
-
*
|
|
8230
|
+
* type (every family but `@column.number()`) keep it. This preserves the v1 read contract exactly
|
|
8231
|
+
* (int→number, string→string) while never throwing on a column whose width the model did not state.
|
|
8199
8232
|
* @internal
|
|
8200
8233
|
*/
|
|
8201
8234
|
static _scpColumnTypes() {
|
|
@@ -8207,7 +8240,7 @@ var DBModel = class _DBModel {
|
|
|
8207
8240
|
for (const [propKey, m] of meta) {
|
|
8208
8241
|
const baseSqlType = m.baseSqlType;
|
|
8209
8242
|
if (m.sqlCast !== void 0) continue;
|
|
8210
|
-
if (baseSqlType !== void 0
|
|
8243
|
+
if (baseSqlType !== void 0) continue;
|
|
8211
8244
|
columnTypes[propKey] = "TEXT";
|
|
8212
8245
|
}
|
|
8213
8246
|
}
|
|
@@ -8316,6 +8349,30 @@ var DBModel = class _DBModel {
|
|
|
8316
8349
|
return void 0;
|
|
8317
8350
|
}
|
|
8318
8351
|
}
|
|
8352
|
+
/**
|
|
8353
|
+
* A subquery's `[column, value]` conditions, each literal value bound the way the column's family
|
|
8354
|
+
* writes it (see {@link _getConditionTypeCast}); a correlation reference passes through.
|
|
8355
|
+
* @internal
|
|
8356
|
+
*/
|
|
8357
|
+
static _subqueryConditions(conditions) {
|
|
8358
|
+
const typeCast = this._getConditionTypeCast();
|
|
8359
|
+
return conditions.map(([col, value]) => ({
|
|
8360
|
+
column: col,
|
|
8361
|
+
value: value instanceof DBToken ? value : serializeCondValue(col, value, typeCast)
|
|
8362
|
+
}));
|
|
8363
|
+
}
|
|
8364
|
+
/**
|
|
8365
|
+
* The driver's type cast a condition value binds with — the one a create / update serializes with.
|
|
8366
|
+
* Returns undefined if DBHandler is not initialized, like {@link _getSqlCastFormatter}.
|
|
8367
|
+
* @internal
|
|
8368
|
+
*/
|
|
8369
|
+
static _getConditionTypeCast() {
|
|
8370
|
+
try {
|
|
8371
|
+
return getTypeCast2(this.getDriverType());
|
|
8372
|
+
} catch {
|
|
8373
|
+
return void 0;
|
|
8374
|
+
}
|
|
8375
|
+
}
|
|
8319
8376
|
/**
|
|
8320
8377
|
* Get a DBHandler instance for this model.
|
|
8321
8378
|
* Connection priority:
|
|
@@ -8550,7 +8607,7 @@ var DBModel = class _DBModel {
|
|
|
8550
8607
|
}
|
|
8551
8608
|
const normalizedCond = normalizeConditions(conditions);
|
|
8552
8609
|
if (this.FIND_FILTER) {
|
|
8553
|
-
const filterCondition = condsToRecord(this.FIND_FILTER);
|
|
8610
|
+
const filterCondition = condsToRecord(this.FIND_FILTER, this._getConditionTypeCast());
|
|
8554
8611
|
normalizedCond.add(filterCondition);
|
|
8555
8612
|
}
|
|
8556
8613
|
const formatter = this._getSqlCastFormatter();
|
|
@@ -8669,7 +8726,7 @@ var DBModel = class _DBModel {
|
|
|
8669
8726
|
/** Merge FIND_FILTER (the model's default filter) into a condition object (v1 `_buildSelectSQL` parity). */
|
|
8670
8727
|
static _mergeFindFilter(conditions) {
|
|
8671
8728
|
if (!this.FIND_FILTER) return conditions;
|
|
8672
|
-
const filter = condsToRecord(this.FIND_FILTER);
|
|
8729
|
+
const filter = condsToRecord(this.FIND_FILTER, this._getConditionTypeCast());
|
|
8673
8730
|
return { ...conditions, ...filter };
|
|
8674
8731
|
}
|
|
8675
8732
|
/** Build model instances from raw rows, wiring the deferred relation context (v1 `query` parity). @internal */
|
|
@@ -8738,7 +8795,7 @@ var DBModel = class _DBModel {
|
|
|
8738
8795
|
}
|
|
8739
8796
|
const normalizedCond = normalizeConditions(conditions);
|
|
8740
8797
|
if (this.FIND_FILTER) {
|
|
8741
|
-
const filterCondition = condsToRecord(this.FIND_FILTER);
|
|
8798
|
+
const filterCondition = condsToRecord(this.FIND_FILTER, this._getConditionTypeCast());
|
|
8742
8799
|
normalizedCond.add(filterCondition);
|
|
8743
8800
|
}
|
|
8744
8801
|
const formatter = this._getSqlCastFormatter();
|
|
@@ -9071,10 +9128,7 @@ var DBModel = class _DBModel {
|
|
|
9071
9128
|
const parentColumns = pairs.map((pair) => pair[0]);
|
|
9072
9129
|
const selectColumns = pairs.map((pair) => pair[1]);
|
|
9073
9130
|
const targetTableName = selectColumns[0]?.tableName ?? "";
|
|
9074
|
-
const subqueryConditions =
|
|
9075
|
-
column: col,
|
|
9076
|
-
value
|
|
9077
|
-
}));
|
|
9131
|
+
const subqueryConditions = this._subqueryConditions(conditions);
|
|
9078
9132
|
return ["__subquery__", new DBSubquery(parentColumns, targetTableName, selectColumns, subqueryConditions, "IN")];
|
|
9079
9133
|
}
|
|
9080
9134
|
/**
|
|
@@ -9110,10 +9164,7 @@ var DBModel = class _DBModel {
|
|
|
9110
9164
|
const parentColumns = pairs.map((pair) => pair[0]);
|
|
9111
9165
|
const selectColumns = pairs.map((pair) => pair[1]);
|
|
9112
9166
|
const targetTableName = selectColumns[0]?.tableName ?? "";
|
|
9113
|
-
const subqueryConditions =
|
|
9114
|
-
column: col,
|
|
9115
|
-
value
|
|
9116
|
-
}));
|
|
9167
|
+
const subqueryConditions = this._subqueryConditions(conditions);
|
|
9117
9168
|
return ["__subquery__", new DBSubquery(parentColumns, targetTableName, selectColumns, subqueryConditions, "NOT IN")];
|
|
9118
9169
|
}
|
|
9119
9170
|
/**
|
|
@@ -9141,10 +9192,7 @@ var DBModel = class _DBModel {
|
|
|
9141
9192
|
*/
|
|
9142
9193
|
static exists(conditions) {
|
|
9143
9194
|
const targetTableName = conditions[0]?.[0]?.tableName ?? "";
|
|
9144
|
-
const subqueryConditions =
|
|
9145
|
-
column: col,
|
|
9146
|
-
value
|
|
9147
|
-
}));
|
|
9195
|
+
const subqueryConditions = this._subqueryConditions(conditions);
|
|
9148
9196
|
return ["__exists__", new DBExists(targetTableName, subqueryConditions, false)];
|
|
9149
9197
|
}
|
|
9150
9198
|
/**
|
|
@@ -9171,10 +9219,7 @@ var DBModel = class _DBModel {
|
|
|
9171
9219
|
*/
|
|
9172
9220
|
static notExists(conditions) {
|
|
9173
9221
|
const targetTableName = conditions[0]?.[0]?.tableName ?? "";
|
|
9174
|
-
const subqueryConditions =
|
|
9175
|
-
column: col,
|
|
9176
|
-
value
|
|
9177
|
-
}));
|
|
9222
|
+
const subqueryConditions = this._subqueryConditions(conditions);
|
|
9178
9223
|
return ["__exists__", new DBExists(targetTableName, subqueryConditions, true)];
|
|
9179
9224
|
}
|
|
9180
9225
|
// ============================================
|
|
@@ -9425,7 +9470,7 @@ var DBModel = class _DBModel {
|
|
|
9425
9470
|
}
|
|
9426
9471
|
const relationConfig = {
|
|
9427
9472
|
targetClass: TargetClass,
|
|
9428
|
-
conditions: config.
|
|
9473
|
+
conditions: config.where ? condsToRecord(config.where, TargetClass._getConditionTypeCast()) : void 0,
|
|
9429
9474
|
order: config.order,
|
|
9430
9475
|
limit: config.limit,
|
|
9431
9476
|
hardLimit: config.hardLimit,
|
|
@@ -9722,7 +9767,7 @@ var DBModel = class _DBModel {
|
|
|
9722
9767
|
*/
|
|
9723
9768
|
static find(conditions, options) {
|
|
9724
9769
|
const core = async (conds, opts) => {
|
|
9725
|
-
const conditionRecord = condsToRecord(conds);
|
|
9770
|
+
const conditionRecord = condsToRecord(conds, this._getConditionTypeCast());
|
|
9726
9771
|
const hardLimit = _DBModel._limitConfig.findHardLimit;
|
|
9727
9772
|
const shouldCheckLimit = hardLimit != null && !opts?.limit;
|
|
9728
9773
|
const effectiveOpts = shouldCheckLimit ? { ...opts, limit: hardLimit + 1 } : opts;
|
|
@@ -9756,7 +9801,7 @@ var DBModel = class _DBModel {
|
|
|
9756
9801
|
*/
|
|
9757
9802
|
static findOne(conditions, options) {
|
|
9758
9803
|
const core = async (conds, opts) => {
|
|
9759
|
-
const conditionRecord = condsToRecord(conds);
|
|
9804
|
+
const conditionRecord = condsToRecord(conds, this._getConditionTypeCast());
|
|
9760
9805
|
const results = await this._select(conditionRecord, { ...opts, limit: 1 });
|
|
9761
9806
|
return results.length > 0 ? results[0] : null;
|
|
9762
9807
|
};
|
|
@@ -9834,7 +9879,7 @@ var DBModel = class _DBModel {
|
|
|
9834
9879
|
*/
|
|
9835
9880
|
static count(conditions) {
|
|
9836
9881
|
const core = async (conds) => {
|
|
9837
|
-
const conditionRecord = condsToRecord(conds);
|
|
9882
|
+
const conditionRecord = condsToRecord(conds, this._getConditionTypeCast());
|
|
9838
9883
|
return this._count(conditionRecord);
|
|
9839
9884
|
};
|
|
9840
9885
|
return this._applyMiddleware("count", core, [conditions]);
|
|
@@ -9968,7 +10013,7 @@ var DBModel = class _DBModel {
|
|
|
9968
10013
|
*/
|
|
9969
10014
|
static update(conditions, values, options) {
|
|
9970
10015
|
const core = async (conds, vals, opts) => {
|
|
9971
|
-
const conditionRecord = condsToRecord(conds);
|
|
10016
|
+
const conditionRecord = condsToRecord(conds, this._getConditionTypeCast());
|
|
9972
10017
|
const valueRecord = pairsToRecord(vals);
|
|
9973
10018
|
if (!opts?.returning) {
|
|
9974
10019
|
await this._update(conditionRecord, valueRecord, {});
|
|
@@ -10020,7 +10065,7 @@ var DBModel = class _DBModel {
|
|
|
10020
10065
|
*/
|
|
10021
10066
|
static delete(conditions, options) {
|
|
10022
10067
|
const core = async (conds, opts) => {
|
|
10023
|
-
const conditionRecord = condsToRecord(conds);
|
|
10068
|
+
const conditionRecord = condsToRecord(conds, this._getConditionTypeCast());
|
|
10024
10069
|
if (!opts?.returning) {
|
|
10025
10070
|
await this._delete(conditionRecord, {});
|
|
10026
10071
|
return null;
|
|
@@ -10426,12 +10471,12 @@ var DBModel = class _DBModel {
|
|
|
10426
10471
|
* // Define models using appropriate base class
|
|
10427
10472
|
* @model('users')
|
|
10428
10473
|
* class UserModel extends BaseDB {
|
|
10429
|
-
* @column() id?: number;
|
|
10474
|
+
* @column.number() id?: number;
|
|
10430
10475
|
* }
|
|
10431
10476
|
*
|
|
10432
10477
|
* @model('articles')
|
|
10433
10478
|
* class ArticleModel extends CmsDB {
|
|
10434
|
-
* @column() id?: number;
|
|
10479
|
+
* @column.number() id?: number;
|
|
10435
10480
|
* }
|
|
10436
10481
|
*
|
|
10437
10482
|
* // Each base class has independent transactions
|