forge-sql-orm 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +337 -17
- package/dist/ForgeSQLORM.js +424 -34
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +425 -35
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts +144 -0
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +149 -2
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts +50 -2
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/utils/cacheContextUtils.d.ts +4 -2
- package/dist/utils/cacheContextUtils.d.ts.map +1 -1
- package/dist/utils/sqlUtils.d.ts +6 -6
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/core/ForgeSQLORM.ts +319 -13
- package/src/core/ForgeSQLQueryBuilder.ts +218 -0
- package/src/lib/drizzle/extensions/additionalActions.ts +387 -34
- package/src/lib/drizzle/extensions/types.d.ts +36 -0
- package/src/utils/cacheContextUtils.ts +16 -2
- package/src/utils/sqlUtils.ts +34 -9
package/dist/ForgeSQLORM.js
CHANGED
|
@@ -50,12 +50,34 @@ const parseDateTime = (value, format) => {
|
|
|
50
50
|
return result;
|
|
51
51
|
};
|
|
52
52
|
function formatDateTime(value, format) {
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
53
|
+
let dt = null;
|
|
54
|
+
if (value instanceof Date) {
|
|
55
|
+
dt = luxon.DateTime.fromJSDate(value);
|
|
56
|
+
} else if (typeof value === "string") {
|
|
57
|
+
for (const parser of [
|
|
58
|
+
luxon.DateTime.fromISO,
|
|
59
|
+
luxon.DateTime.fromRFC2822,
|
|
60
|
+
luxon.DateTime.fromSQL,
|
|
61
|
+
luxon.DateTime.fromHTTP
|
|
62
|
+
]) {
|
|
63
|
+
dt = parser(value);
|
|
64
|
+
if (dt.isValid) break;
|
|
65
|
+
}
|
|
66
|
+
if (!dt?.isValid) {
|
|
67
|
+
const parsed = Number(value);
|
|
68
|
+
if (!isNaN(parsed)) {
|
|
69
|
+
dt = luxon.DateTime.fromMillis(parsed);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else if (typeof value === "number") {
|
|
73
|
+
dt = luxon.DateTime.fromMillis(value);
|
|
56
74
|
} else {
|
|
75
|
+
throw new Error("Unsupported type");
|
|
76
|
+
}
|
|
77
|
+
if (!dt?.isValid) {
|
|
57
78
|
throw new Error("Invalid Date");
|
|
58
79
|
}
|
|
80
|
+
return dt.toFormat(format);
|
|
59
81
|
}
|
|
60
82
|
function getPrimaryKeys(table2) {
|
|
61
83
|
const { columns, primaryKeys } = getTableMetadata(table2);
|
|
@@ -531,7 +553,7 @@ async function saveTableIfInsideCacheContext(table$1) {
|
|
|
531
553
|
context.tables.add(tableName);
|
|
532
554
|
}
|
|
533
555
|
}
|
|
534
|
-
async function saveQueryLocalCacheQuery(query, rows) {
|
|
556
|
+
async function saveQueryLocalCacheQuery(query, rows, options) {
|
|
535
557
|
const context = localCacheApplicationContext.getStore();
|
|
536
558
|
if (context) {
|
|
537
559
|
if (!context.cache) {
|
|
@@ -543,9 +565,15 @@ async function saveQueryLocalCacheQuery(query, rows) {
|
|
|
543
565
|
sql: sql2.toSQL().sql.toLowerCase(),
|
|
544
566
|
data: rows
|
|
545
567
|
};
|
|
568
|
+
if (options.logRawSqlQuery) {
|
|
569
|
+
const q = sql2.toSQL();
|
|
570
|
+
console.log(
|
|
571
|
+
`[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`
|
|
572
|
+
);
|
|
573
|
+
}
|
|
546
574
|
}
|
|
547
575
|
}
|
|
548
|
-
async function getQueryLocalCacheQuery(query) {
|
|
576
|
+
async function getQueryLocalCacheQuery(query, options) {
|
|
549
577
|
const context = localCacheApplicationContext.getStore();
|
|
550
578
|
if (context) {
|
|
551
579
|
if (!context.cache) {
|
|
@@ -554,6 +582,12 @@ async function getQueryLocalCacheQuery(query) {
|
|
|
554
582
|
const sql2 = query;
|
|
555
583
|
const key = hashKey(sql2.toSQL());
|
|
556
584
|
if (context.cache[key] && context.cache[key].sql === sql2.toSQL().sql.toLowerCase()) {
|
|
585
|
+
if (options.logRawSqlQuery) {
|
|
586
|
+
const q = sql2.toSQL();
|
|
587
|
+
console.log(
|
|
588
|
+
`[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`
|
|
589
|
+
);
|
|
590
|
+
}
|
|
557
591
|
return context.cache[key].data;
|
|
558
592
|
}
|
|
559
593
|
}
|
|
@@ -1043,11 +1077,21 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
|
|
|
1043
1077
|
return forgeDriver(modifiedQuery, params, method);
|
|
1044
1078
|
};
|
|
1045
1079
|
}
|
|
1080
|
+
const NON_CACHE_CLEARING_ERROR_CODES = ["VALIDATION_ERROR", "CONSTRAINT_ERROR"];
|
|
1081
|
+
const CACHE_CLEARING_ERROR_CODES = ["DEADLOCK", "LOCK_WAIT_TIMEOUT", "CONNECTION_ERROR"];
|
|
1082
|
+
const NON_CACHE_CLEARING_PATTERNS = [/validation/i, /constraint/i];
|
|
1083
|
+
const CACHE_CLEARING_PATTERNS = [/timeout/i, /connection/i];
|
|
1046
1084
|
function shouldClearCacheOnError(error) {
|
|
1047
|
-
if (error?.code
|
|
1085
|
+
if (error?.code && NON_CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1086
|
+
return false;
|
|
1087
|
+
}
|
|
1088
|
+
if (error?.message && NON_CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1048
1089
|
return false;
|
|
1049
1090
|
}
|
|
1050
|
-
if (error?.code
|
|
1091
|
+
if (error?.code && CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1092
|
+
return true;
|
|
1093
|
+
}
|
|
1094
|
+
if (error?.message && CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1051
1095
|
return true;
|
|
1052
1096
|
}
|
|
1053
1097
|
return true;
|
|
@@ -1128,7 +1172,7 @@ function deleteAndEvictCacheBuilder(db, table2, options, isCached) {
|
|
|
1128
1172
|
}
|
|
1129
1173
|
async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap, onfulfilled, onrejected) {
|
|
1130
1174
|
try {
|
|
1131
|
-
const localCached = await getQueryLocalCacheQuery(target);
|
|
1175
|
+
const localCached = await getQueryLocalCacheQuery(target, options);
|
|
1132
1176
|
if (localCached) {
|
|
1133
1177
|
return onfulfilled?.(localCached);
|
|
1134
1178
|
}
|
|
@@ -1138,7 +1182,7 @@ async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap
|
|
|
1138
1182
|
}
|
|
1139
1183
|
const rows = await target.execute();
|
|
1140
1184
|
const transformed = applyFromDriverTransform(rows, selections, aliasMap);
|
|
1141
|
-
await saveQueryLocalCacheQuery(target, transformed);
|
|
1185
|
+
await saveQueryLocalCacheQuery(target, transformed, options);
|
|
1142
1186
|
await setCacheResult(target, options, transformed, cacheTtl).catch((cacheError) => {
|
|
1143
1187
|
console.warn("Cache set error:", cacheError);
|
|
1144
1188
|
});
|
|
@@ -1147,15 +1191,15 @@ async function handleCachedQuery(target, options, cacheTtl, selections, aliasMap
|
|
|
1147
1191
|
return onrejected?.(error);
|
|
1148
1192
|
}
|
|
1149
1193
|
}
|
|
1150
|
-
async function handleNonCachedQuery(target, selections, aliasMap, onfulfilled, onrejected) {
|
|
1194
|
+
async function handleNonCachedQuery(target, options, selections, aliasMap, onfulfilled, onrejected) {
|
|
1151
1195
|
try {
|
|
1152
|
-
const localCached = await getQueryLocalCacheQuery(target);
|
|
1196
|
+
const localCached = await getQueryLocalCacheQuery(target, options);
|
|
1153
1197
|
if (localCached) {
|
|
1154
1198
|
return onfulfilled?.(localCached);
|
|
1155
1199
|
}
|
|
1156
1200
|
const rows = await target.execute();
|
|
1157
1201
|
const transformed = applyFromDriverTransform(rows, selections, aliasMap);
|
|
1158
|
-
await saveQueryLocalCacheQuery(target, transformed);
|
|
1202
|
+
await saveQueryLocalCacheQuery(target, transformed, options);
|
|
1159
1203
|
return onfulfilled?.(transformed);
|
|
1160
1204
|
} catch (error) {
|
|
1161
1205
|
return onrejected?.(error);
|
|
@@ -1187,7 +1231,14 @@ function createAliasedSelectBuilder(db, fields, selectFn, useCache, options, cac
|
|
|
1187
1231
|
onrejected
|
|
1188
1232
|
);
|
|
1189
1233
|
} else {
|
|
1190
|
-
return handleNonCachedQuery(
|
|
1234
|
+
return handleNonCachedQuery(
|
|
1235
|
+
target,
|
|
1236
|
+
options,
|
|
1237
|
+
selections,
|
|
1238
|
+
aliasMap,
|
|
1239
|
+
onfulfilled,
|
|
1240
|
+
onrejected
|
|
1241
|
+
);
|
|
1191
1242
|
}
|
|
1192
1243
|
};
|
|
1193
1244
|
}
|
|
@@ -1216,6 +1267,43 @@ const DEFAULT_OPTIONS = {
|
|
|
1216
1267
|
cacheEntityExpirationName: "expiration",
|
|
1217
1268
|
cacheEntityDataName: "data"
|
|
1218
1269
|
};
|
|
1270
|
+
function createRawQueryExecutor(db, options, useGlobalCache = false) {
|
|
1271
|
+
return async function(query, cacheTtl) {
|
|
1272
|
+
let sql$12;
|
|
1273
|
+
if (sql.isSQLWrapper(query)) {
|
|
1274
|
+
const sqlWrapper = query;
|
|
1275
|
+
sql$12 = sqlWrapper.getSQL().toQuery(
|
|
1276
|
+
db.dialect
|
|
1277
|
+
);
|
|
1278
|
+
} else {
|
|
1279
|
+
sql$12 = {
|
|
1280
|
+
sql: query,
|
|
1281
|
+
params: []
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
const localCacheResult = await getQueryLocalCacheQuery(sql$12, options);
|
|
1285
|
+
if (localCacheResult) {
|
|
1286
|
+
return localCacheResult;
|
|
1287
|
+
}
|
|
1288
|
+
if (useGlobalCache) {
|
|
1289
|
+
const cacheResult = await getFromCache({ toSQL: () => sql$12 }, options);
|
|
1290
|
+
if (cacheResult) {
|
|
1291
|
+
return cacheResult;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
const results = await db.execute(query);
|
|
1295
|
+
await saveQueryLocalCacheQuery(sql$12, results, options);
|
|
1296
|
+
if (useGlobalCache) {
|
|
1297
|
+
await setCacheResult(
|
|
1298
|
+
{ toSQL: () => sql$12 },
|
|
1299
|
+
options,
|
|
1300
|
+
results,
|
|
1301
|
+
cacheTtl ?? options.cacheTTL ?? 120
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
return results;
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1219
1307
|
function patchDbWithSelectAliased(db, options) {
|
|
1220
1308
|
const newOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
1221
1309
|
db.selectAliased = function(fields) {
|
|
@@ -1227,15 +1315,6 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1227
1315
|
newOptions
|
|
1228
1316
|
);
|
|
1229
1317
|
};
|
|
1230
|
-
db.selectAliasedDistinct = function(fields) {
|
|
1231
|
-
return createAliasedSelectBuilder(
|
|
1232
|
-
db,
|
|
1233
|
-
fields,
|
|
1234
|
-
(selections) => db.selectDistinct(selections),
|
|
1235
|
-
false,
|
|
1236
|
-
newOptions
|
|
1237
|
-
);
|
|
1238
|
-
};
|
|
1239
1318
|
db.selectAliasedCacheable = function(fields, cacheTtl) {
|
|
1240
1319
|
return createAliasedSelectBuilder(
|
|
1241
1320
|
db,
|
|
@@ -1246,6 +1325,15 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1246
1325
|
cacheTtl
|
|
1247
1326
|
);
|
|
1248
1327
|
};
|
|
1328
|
+
db.selectAliasedDistinct = function(fields) {
|
|
1329
|
+
return createAliasedSelectBuilder(
|
|
1330
|
+
db,
|
|
1331
|
+
fields,
|
|
1332
|
+
(selections) => db.selectDistinct(selections),
|
|
1333
|
+
false,
|
|
1334
|
+
newOptions
|
|
1335
|
+
);
|
|
1336
|
+
};
|
|
1249
1337
|
db.selectAliasedDistinctCacheable = function(fields, cacheTtl) {
|
|
1250
1338
|
return createAliasedSelectBuilder(
|
|
1251
1339
|
db,
|
|
@@ -1256,6 +1344,18 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1256
1344
|
cacheTtl
|
|
1257
1345
|
);
|
|
1258
1346
|
};
|
|
1347
|
+
db.selectFrom = function(table2) {
|
|
1348
|
+
return db.selectAliased(drizzleOrm.getTableColumns(table2)).from(table2);
|
|
1349
|
+
};
|
|
1350
|
+
db.selectFromCacheable = function(table2, cacheTtl) {
|
|
1351
|
+
return db.selectAliasedCacheable(drizzleOrm.getTableColumns(table2), cacheTtl).from(table2);
|
|
1352
|
+
};
|
|
1353
|
+
db.selectDistinctFrom = function(table2) {
|
|
1354
|
+
return db.selectAliasedDistinct(drizzleOrm.getTableColumns(table2)).from(table2);
|
|
1355
|
+
};
|
|
1356
|
+
db.selectDistinctFromCacheable = function(table2, cacheTtl) {
|
|
1357
|
+
return db.selectAliasedDistinctCacheable(drizzleOrm.getTableColumns(table2), cacheTtl).from(table2);
|
|
1358
|
+
};
|
|
1259
1359
|
db.insertWithCacheContext = function(table2) {
|
|
1260
1360
|
return insertAndEvictCacheBuilder(db, table2, newOptions, false);
|
|
1261
1361
|
};
|
|
@@ -1274,6 +1374,8 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1274
1374
|
db.deleteAndEvictCache = function(table2) {
|
|
1275
1375
|
return deleteAndEvictCacheBuilder(db, table2, newOptions, true);
|
|
1276
1376
|
};
|
|
1377
|
+
db.executeQuery = createRawQueryExecutor(db, newOptions, false);
|
|
1378
|
+
db.executeQueryCacheable = createRawQueryExecutor(db, newOptions, true);
|
|
1277
1379
|
return db;
|
|
1278
1380
|
}
|
|
1279
1381
|
class ForgeSQLAnalyseOperation {
|
|
@@ -1741,16 +1843,19 @@ class ForgeSQLORMImpl {
|
|
|
1741
1843
|
*/
|
|
1742
1844
|
async executeWithCacheContextAndReturnValue(cacheContext) {
|
|
1743
1845
|
return await this.executeWithLocalCacheContextAndReturnValue(
|
|
1744
|
-
async () => await cacheApplicationContext.run(
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1846
|
+
async () => await cacheApplicationContext.run(
|
|
1847
|
+
cacheApplicationContext.getStore() ?? { tables: /* @__PURE__ */ new Set() },
|
|
1848
|
+
async () => {
|
|
1849
|
+
try {
|
|
1850
|
+
return await cacheContext();
|
|
1851
|
+
} finally {
|
|
1852
|
+
await clearTablesCache(
|
|
1853
|
+
Array.from(cacheApplicationContext.getStore()?.tables ?? []),
|
|
1854
|
+
this.options
|
|
1855
|
+
);
|
|
1856
|
+
}
|
|
1752
1857
|
}
|
|
1753
|
-
|
|
1858
|
+
)
|
|
1754
1859
|
);
|
|
1755
1860
|
}
|
|
1756
1861
|
/**
|
|
@@ -1761,9 +1866,12 @@ class ForgeSQLORMImpl {
|
|
|
1761
1866
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
1762
1867
|
*/
|
|
1763
1868
|
async executeWithLocalCacheContextAndReturnValue(cacheContext) {
|
|
1764
|
-
return await localCacheApplicationContext.run(
|
|
1765
|
-
|
|
1766
|
-
|
|
1869
|
+
return await localCacheApplicationContext.run(
|
|
1870
|
+
localCacheApplicationContext.getStore() ?? { cache: {} },
|
|
1871
|
+
async () => {
|
|
1872
|
+
return await cacheContext();
|
|
1873
|
+
}
|
|
1874
|
+
);
|
|
1767
1875
|
}
|
|
1768
1876
|
/**
|
|
1769
1877
|
* Executes operations within a local cache context.
|
|
@@ -1992,6 +2100,147 @@ class ForgeSQLORMImpl {
|
|
|
1992
2100
|
}
|
|
1993
2101
|
return this.drizzle.selectAliasedDistinctCacheable(fields, cacheTTL);
|
|
1994
2102
|
}
|
|
2103
|
+
/**
|
|
2104
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2105
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2106
|
+
*
|
|
2107
|
+
* @template T - The type of the table
|
|
2108
|
+
* @param table - The table to select from
|
|
2109
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2110
|
+
* @example
|
|
2111
|
+
* ```typescript
|
|
2112
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2113
|
+
* ```
|
|
2114
|
+
*/
|
|
2115
|
+
selectFrom(table2) {
|
|
2116
|
+
return this.drizzle.selectFrom(table2);
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2120
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2121
|
+
*
|
|
2122
|
+
* @template T - The type of the table
|
|
2123
|
+
* @param table - The table to select from
|
|
2124
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2125
|
+
* @example
|
|
2126
|
+
* ```typescript
|
|
2127
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2128
|
+
* ```
|
|
2129
|
+
*/
|
|
2130
|
+
selectDistinctFrom(table2) {
|
|
2131
|
+
return this.drizzle.selectDistinctFrom(table2);
|
|
2132
|
+
}
|
|
2133
|
+
/**
|
|
2134
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2135
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2136
|
+
*
|
|
2137
|
+
* @template T - The type of the table
|
|
2138
|
+
* @param table - The table to select from
|
|
2139
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2140
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2141
|
+
* @example
|
|
2142
|
+
* ```typescript
|
|
2143
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2144
|
+
* ```
|
|
2145
|
+
*/
|
|
2146
|
+
selectCacheableFrom(table2, cacheTTL) {
|
|
2147
|
+
return this.drizzle.selectFromCacheable(table2, cacheTTL);
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2151
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2152
|
+
*
|
|
2153
|
+
* @template T - The type of the table
|
|
2154
|
+
* @param table - The table to select from
|
|
2155
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2156
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2157
|
+
* @example
|
|
2158
|
+
* ```typescript
|
|
2159
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2160
|
+
* ```
|
|
2161
|
+
*/
|
|
2162
|
+
selectDistinctCacheableFrom(table2, cacheTTL) {
|
|
2163
|
+
return this.drizzle.selectDistinctFromCacheable(table2, cacheTTL);
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Executes a raw SQL query with local cache support.
|
|
2167
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2168
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2169
|
+
*
|
|
2170
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2171
|
+
* @returns Promise with query results
|
|
2172
|
+
* @example
|
|
2173
|
+
* ```typescript
|
|
2174
|
+
* // Using SQLWrapper
|
|
2175
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2176
|
+
*
|
|
2177
|
+
* // Using string
|
|
2178
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2179
|
+
* ```
|
|
2180
|
+
*/
|
|
2181
|
+
execute(query) {
|
|
2182
|
+
return this.drizzle.executeQuery(query);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2186
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2187
|
+
* - Local cache: Within the current invocation context
|
|
2188
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2189
|
+
*
|
|
2190
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2191
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2192
|
+
* @returns Promise with query results
|
|
2193
|
+
* @example
|
|
2194
|
+
* ```typescript
|
|
2195
|
+
* // Using SQLWrapper with custom TTL
|
|
2196
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2197
|
+
*
|
|
2198
|
+
* // Using string with default TTL
|
|
2199
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2200
|
+
* ```
|
|
2201
|
+
*/
|
|
2202
|
+
executeCacheable(query, cacheTtl) {
|
|
2203
|
+
return this.drizzle.executeQueryCacheable(query, cacheTtl);
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2207
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2208
|
+
*
|
|
2209
|
+
* @returns WithBuilder for creating CTEs
|
|
2210
|
+
* @example
|
|
2211
|
+
* ```typescript
|
|
2212
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2213
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2214
|
+
* .from(users)
|
|
2215
|
+
* .groupBy(users.id)
|
|
2216
|
+
* );
|
|
2217
|
+
* ```
|
|
2218
|
+
*/
|
|
2219
|
+
get $with() {
|
|
2220
|
+
return this.drizzle.$with;
|
|
2221
|
+
}
|
|
2222
|
+
/**
|
|
2223
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2224
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2225
|
+
*
|
|
2226
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2227
|
+
* @returns Query builder with CTE support
|
|
2228
|
+
* @example
|
|
2229
|
+
* ```typescript
|
|
2230
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2231
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2232
|
+
* .from(users)
|
|
2233
|
+
* .groupBy(users.id)
|
|
2234
|
+
* );
|
|
2235
|
+
*
|
|
2236
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2237
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2238
|
+
* .from(withQuery);
|
|
2239
|
+
* ```
|
|
2240
|
+
*/
|
|
2241
|
+
with(...queries) {
|
|
2242
|
+
return this.drizzle.with(...queries);
|
|
2243
|
+
}
|
|
1995
2244
|
}
|
|
1996
2245
|
class ForgeSQLORM {
|
|
1997
2246
|
ormInstance;
|
|
@@ -2004,6 +2253,68 @@ class ForgeSQLORM {
|
|
|
2004
2253
|
selectDistinctCacheable(fields, cacheTTL) {
|
|
2005
2254
|
return this.ormInstance.selectDistinctCacheable(fields, cacheTTL);
|
|
2006
2255
|
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2258
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2259
|
+
*
|
|
2260
|
+
* @template T - The type of the table
|
|
2261
|
+
* @param table - The table to select from
|
|
2262
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2263
|
+
* @example
|
|
2264
|
+
* ```typescript
|
|
2265
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2266
|
+
* ```
|
|
2267
|
+
*/
|
|
2268
|
+
selectFrom(table2) {
|
|
2269
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFrom(table2);
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2273
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2274
|
+
*
|
|
2275
|
+
* @template T - The type of the table
|
|
2276
|
+
* @param table - The table to select from
|
|
2277
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2278
|
+
* @example
|
|
2279
|
+
* ```typescript
|
|
2280
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2281
|
+
* ```
|
|
2282
|
+
*/
|
|
2283
|
+
selectDistinctFrom(table2) {
|
|
2284
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFrom(table2);
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2288
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2289
|
+
*
|
|
2290
|
+
* @template T - The type of the table
|
|
2291
|
+
* @param table - The table to select from
|
|
2292
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2293
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2294
|
+
* @example
|
|
2295
|
+
* ```typescript
|
|
2296
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2297
|
+
* ```
|
|
2298
|
+
*/
|
|
2299
|
+
selectCacheableFrom(table2, cacheTTL) {
|
|
2300
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFromCacheable(table2, cacheTTL);
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2304
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2305
|
+
*
|
|
2306
|
+
* @template T - The type of the table
|
|
2307
|
+
* @param table - The table to select from
|
|
2308
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2309
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2310
|
+
* @example
|
|
2311
|
+
* ```typescript
|
|
2312
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2313
|
+
* ```
|
|
2314
|
+
*/
|
|
2315
|
+
selectDistinctCacheableFrom(table2, cacheTTL) {
|
|
2316
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFromCacheable(table2, cacheTTL);
|
|
2317
|
+
}
|
|
2007
2318
|
executeWithCacheContext(cacheContext) {
|
|
2008
2319
|
return this.ormInstance.executeWithCacheContext(cacheContext);
|
|
2009
2320
|
}
|
|
@@ -2176,6 +2487,85 @@ class ForgeSQLORM {
|
|
|
2176
2487
|
getDrizzleQueryBuilder() {
|
|
2177
2488
|
return this.ormInstance.getDrizzleQueryBuilder();
|
|
2178
2489
|
}
|
|
2490
|
+
/**
|
|
2491
|
+
* Executes a raw SQL query with local cache support.
|
|
2492
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2493
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2494
|
+
*
|
|
2495
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2496
|
+
* @returns Promise with query results
|
|
2497
|
+
* @example
|
|
2498
|
+
* ```typescript
|
|
2499
|
+
* // Using SQLWrapper
|
|
2500
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2501
|
+
*
|
|
2502
|
+
* // Using string
|
|
2503
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2504
|
+
* ```
|
|
2505
|
+
*/
|
|
2506
|
+
execute(query) {
|
|
2507
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQuery(query);
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2511
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2512
|
+
* - Local cache: Within the current invocation context
|
|
2513
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2514
|
+
*
|
|
2515
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2516
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2517
|
+
* @returns Promise with query results
|
|
2518
|
+
* @example
|
|
2519
|
+
* ```typescript
|
|
2520
|
+
* // Using SQLWrapper with custom TTL
|
|
2521
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2522
|
+
*
|
|
2523
|
+
* // Using string with default TTL
|
|
2524
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2525
|
+
* ```
|
|
2526
|
+
*/
|
|
2527
|
+
executeCacheable(query, cacheTtl) {
|
|
2528
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQueryCacheable(query, cacheTtl);
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2532
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2533
|
+
*
|
|
2534
|
+
* @returns WithBuilder for creating CTEs
|
|
2535
|
+
* @example
|
|
2536
|
+
* ```typescript
|
|
2537
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2538
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2539
|
+
* .from(users)
|
|
2540
|
+
* .groupBy(users.id)
|
|
2541
|
+
* );
|
|
2542
|
+
* ```
|
|
2543
|
+
*/
|
|
2544
|
+
get $with() {
|
|
2545
|
+
return this.ormInstance.getDrizzleQueryBuilder().$with;
|
|
2546
|
+
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2549
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2550
|
+
*
|
|
2551
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2552
|
+
* @returns Query builder with CTE support
|
|
2553
|
+
* @example
|
|
2554
|
+
* ```typescript
|
|
2555
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2556
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2557
|
+
* .from(users)
|
|
2558
|
+
* .groupBy(users.id)
|
|
2559
|
+
* );
|
|
2560
|
+
*
|
|
2561
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2562
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2563
|
+
* .from(withQuery);
|
|
2564
|
+
* ```
|
|
2565
|
+
*/
|
|
2566
|
+
with(...queries) {
|
|
2567
|
+
return this.ormInstance.getDrizzleQueryBuilder().with(...queries);
|
|
2568
|
+
}
|
|
2179
2569
|
}
|
|
2180
2570
|
const forgeDateTimeString = mysqlCore.customType({
|
|
2181
2571
|
dataType() {
|