forge-sql-orm 2.1.0 → 2.1.1
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 +396 -20
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +397 -21
- 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 +165 -18
- 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.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 +306 -6
- package/src/core/ForgeSQLQueryBuilder.ts +181 -16
- package/src/lib/drizzle/extensions/additionalActions.ts +350 -46
- package/src/lib/drizzle/extensions/types.d.ts +38 -7
- package/src/utils/cacheContextUtils.ts +2 -0
- package/src/utils/sqlUtils.ts +38 -12
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);
|
|
@@ -1043,11 +1065,34 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
|
|
|
1043
1065
|
return forgeDriver(modifiedQuery, params, method);
|
|
1044
1066
|
};
|
|
1045
1067
|
}
|
|
1068
|
+
const NON_CACHE_CLEARING_ERROR_CODES = [
|
|
1069
|
+
"VALIDATION_ERROR",
|
|
1070
|
+
"CONSTRAINT_ERROR"
|
|
1071
|
+
];
|
|
1072
|
+
const CACHE_CLEARING_ERROR_CODES = [
|
|
1073
|
+
"DEADLOCK",
|
|
1074
|
+
"LOCK_WAIT_TIMEOUT",
|
|
1075
|
+
"CONNECTION_ERROR"
|
|
1076
|
+
];
|
|
1077
|
+
const NON_CACHE_CLEARING_PATTERNS = [
|
|
1078
|
+
/validation/i,
|
|
1079
|
+
/constraint/i
|
|
1080
|
+
];
|
|
1081
|
+
const CACHE_CLEARING_PATTERNS = [
|
|
1082
|
+
/timeout/i,
|
|
1083
|
+
/connection/i
|
|
1084
|
+
];
|
|
1046
1085
|
function shouldClearCacheOnError(error) {
|
|
1047
|
-
if (error?.code
|
|
1086
|
+
if (error?.code && NON_CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
if (error?.message && NON_CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1048
1090
|
return false;
|
|
1049
1091
|
}
|
|
1050
|
-
if (error?.code
|
|
1092
|
+
if (error?.code && CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1093
|
+
return true;
|
|
1094
|
+
}
|
|
1095
|
+
if (error?.message && CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1051
1096
|
return true;
|
|
1052
1097
|
}
|
|
1053
1098
|
return true;
|
|
@@ -1216,6 +1261,41 @@ const DEFAULT_OPTIONS = {
|
|
|
1216
1261
|
cacheEntityExpirationName: "expiration",
|
|
1217
1262
|
cacheEntityDataName: "data"
|
|
1218
1263
|
};
|
|
1264
|
+
function createRawQueryExecutor(db, options, useGlobalCache = false) {
|
|
1265
|
+
return async function(query, cacheTtl) {
|
|
1266
|
+
let sql$12;
|
|
1267
|
+
if (sql.isSQLWrapper(query)) {
|
|
1268
|
+
const sqlWrapper = query;
|
|
1269
|
+
sql$12 = sqlWrapper.getSQL().toQuery(db.dialect);
|
|
1270
|
+
} else {
|
|
1271
|
+
sql$12 = {
|
|
1272
|
+
sql: query,
|
|
1273
|
+
params: []
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
const localCacheResult = await getQueryLocalCacheQuery(sql$12);
|
|
1277
|
+
if (localCacheResult) {
|
|
1278
|
+
return localCacheResult;
|
|
1279
|
+
}
|
|
1280
|
+
if (useGlobalCache) {
|
|
1281
|
+
const cacheResult = await getFromCache({ toSQL: () => sql$12 }, options);
|
|
1282
|
+
if (cacheResult) {
|
|
1283
|
+
return cacheResult;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
const results = await db.execute(query);
|
|
1287
|
+
await saveQueryLocalCacheQuery(sql$12, results);
|
|
1288
|
+
if (useGlobalCache) {
|
|
1289
|
+
await setCacheResult(
|
|
1290
|
+
{ toSQL: () => sql$12 },
|
|
1291
|
+
options,
|
|
1292
|
+
results,
|
|
1293
|
+
cacheTtl ?? options.cacheTTL ?? 120
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
return results;
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1219
1299
|
function patchDbWithSelectAliased(db, options) {
|
|
1220
1300
|
const newOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
1221
1301
|
db.selectAliased = function(fields) {
|
|
@@ -1227,15 +1307,6 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1227
1307
|
newOptions
|
|
1228
1308
|
);
|
|
1229
1309
|
};
|
|
1230
|
-
db.selectAliasedDistinct = function(fields) {
|
|
1231
|
-
return createAliasedSelectBuilder(
|
|
1232
|
-
db,
|
|
1233
|
-
fields,
|
|
1234
|
-
(selections) => db.selectDistinct(selections),
|
|
1235
|
-
false,
|
|
1236
|
-
newOptions
|
|
1237
|
-
);
|
|
1238
|
-
};
|
|
1239
1310
|
db.selectAliasedCacheable = function(fields, cacheTtl) {
|
|
1240
1311
|
return createAliasedSelectBuilder(
|
|
1241
1312
|
db,
|
|
@@ -1246,6 +1317,15 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1246
1317
|
cacheTtl
|
|
1247
1318
|
);
|
|
1248
1319
|
};
|
|
1320
|
+
db.selectAliasedDistinct = function(fields) {
|
|
1321
|
+
return createAliasedSelectBuilder(
|
|
1322
|
+
db,
|
|
1323
|
+
fields,
|
|
1324
|
+
(selections) => db.selectDistinct(selections),
|
|
1325
|
+
false,
|
|
1326
|
+
newOptions
|
|
1327
|
+
);
|
|
1328
|
+
};
|
|
1249
1329
|
db.selectAliasedDistinctCacheable = function(fields, cacheTtl) {
|
|
1250
1330
|
return createAliasedSelectBuilder(
|
|
1251
1331
|
db,
|
|
@@ -1256,6 +1336,18 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1256
1336
|
cacheTtl
|
|
1257
1337
|
);
|
|
1258
1338
|
};
|
|
1339
|
+
db.selectFrom = function(table2) {
|
|
1340
|
+
return db.selectAliased(drizzleOrm.getTableColumns(table2)).from(table2);
|
|
1341
|
+
};
|
|
1342
|
+
db.selectFromCacheable = function(table2, cacheTtl) {
|
|
1343
|
+
return db.selectAliasedCacheable(drizzleOrm.getTableColumns(table2), cacheTtl).from(table2);
|
|
1344
|
+
};
|
|
1345
|
+
db.selectDistinctFrom = function(table2) {
|
|
1346
|
+
return db.selectAliasedDistinct(drizzleOrm.getTableColumns(table2)).from(table2);
|
|
1347
|
+
};
|
|
1348
|
+
db.selectDistinctFromCacheable = function(table2, cacheTtl) {
|
|
1349
|
+
return db.selectAliasedDistinctCacheable(drizzleOrm.getTableColumns(table2), cacheTtl).from(table2);
|
|
1350
|
+
};
|
|
1259
1351
|
db.insertWithCacheContext = function(table2) {
|
|
1260
1352
|
return insertAndEvictCacheBuilder(db, table2, newOptions, false);
|
|
1261
1353
|
};
|
|
@@ -1274,6 +1366,8 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1274
1366
|
db.deleteAndEvictCache = function(table2) {
|
|
1275
1367
|
return deleteAndEvictCacheBuilder(db, table2, newOptions, true);
|
|
1276
1368
|
};
|
|
1369
|
+
db.executeQuery = createRawQueryExecutor(db, newOptions, false);
|
|
1370
|
+
db.executeQueryCacheable = createRawQueryExecutor(db, newOptions, true);
|
|
1277
1371
|
return db;
|
|
1278
1372
|
}
|
|
1279
1373
|
class ForgeSQLAnalyseOperation {
|
|
@@ -1741,7 +1835,7 @@ class ForgeSQLORMImpl {
|
|
|
1741
1835
|
*/
|
|
1742
1836
|
async executeWithCacheContextAndReturnValue(cacheContext) {
|
|
1743
1837
|
return await this.executeWithLocalCacheContextAndReturnValue(
|
|
1744
|
-
async () => await cacheApplicationContext.run({ tables: /* @__PURE__ */ new Set() }, async () => {
|
|
1838
|
+
async () => await cacheApplicationContext.run(cacheApplicationContext.getStore() ?? { tables: /* @__PURE__ */ new Set() }, async () => {
|
|
1745
1839
|
try {
|
|
1746
1840
|
return await cacheContext();
|
|
1747
1841
|
} finally {
|
|
@@ -1756,19 +1850,19 @@ class ForgeSQLORMImpl {
|
|
|
1756
1850
|
/**
|
|
1757
1851
|
* Executes operations within a local cache context and returns a value.
|
|
1758
1852
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1759
|
-
*
|
|
1853
|
+
*
|
|
1760
1854
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1761
1855
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
1762
1856
|
*/
|
|
1763
1857
|
async executeWithLocalCacheContextAndReturnValue(cacheContext) {
|
|
1764
|
-
return await localCacheApplicationContext.run({ cache: {} }, async () => {
|
|
1858
|
+
return await localCacheApplicationContext.run(localCacheApplicationContext.getStore() ?? { cache: {} }, async () => {
|
|
1765
1859
|
return await cacheContext();
|
|
1766
1860
|
});
|
|
1767
1861
|
}
|
|
1768
1862
|
/**
|
|
1769
1863
|
* Executes operations within a local cache context.
|
|
1770
1864
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1771
|
-
*
|
|
1865
|
+
*
|
|
1772
1866
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1773
1867
|
* @returns Promise that resolves when all operations are complete
|
|
1774
1868
|
*/
|
|
@@ -1992,6 +2086,147 @@ class ForgeSQLORMImpl {
|
|
|
1992
2086
|
}
|
|
1993
2087
|
return this.drizzle.selectAliasedDistinctCacheable(fields, cacheTTL);
|
|
1994
2088
|
}
|
|
2089
|
+
/**
|
|
2090
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2091
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2092
|
+
*
|
|
2093
|
+
* @template T - The type of the table
|
|
2094
|
+
* @param table - The table to select from
|
|
2095
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2096
|
+
* @example
|
|
2097
|
+
* ```typescript
|
|
2098
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2099
|
+
* ```
|
|
2100
|
+
*/
|
|
2101
|
+
selectFrom(table2) {
|
|
2102
|
+
return this.drizzle.selectFrom(table2);
|
|
2103
|
+
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2106
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2107
|
+
*
|
|
2108
|
+
* @template T - The type of the table
|
|
2109
|
+
* @param table - The table to select from
|
|
2110
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2111
|
+
* @example
|
|
2112
|
+
* ```typescript
|
|
2113
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2114
|
+
* ```
|
|
2115
|
+
*/
|
|
2116
|
+
selectDistinctFrom(table2) {
|
|
2117
|
+
return this.drizzle.selectDistinctFrom(table2);
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2121
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2122
|
+
*
|
|
2123
|
+
* @template T - The type of the table
|
|
2124
|
+
* @param table - The table to select from
|
|
2125
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2126
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2127
|
+
* @example
|
|
2128
|
+
* ```typescript
|
|
2129
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2130
|
+
* ```
|
|
2131
|
+
*/
|
|
2132
|
+
selectCacheableFrom(table2, cacheTTL) {
|
|
2133
|
+
return this.drizzle.selectFromCacheable(table2, cacheTTL);
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2137
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2138
|
+
*
|
|
2139
|
+
* @template T - The type of the table
|
|
2140
|
+
* @param table - The table to select from
|
|
2141
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2142
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2143
|
+
* @example
|
|
2144
|
+
* ```typescript
|
|
2145
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2146
|
+
* ```
|
|
2147
|
+
*/
|
|
2148
|
+
selectDistinctCacheableFrom(table2, cacheTTL) {
|
|
2149
|
+
return this.drizzle.selectDistinctFromCacheable(table2, cacheTTL);
|
|
2150
|
+
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Executes a raw SQL query with local cache support.
|
|
2153
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2154
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2155
|
+
*
|
|
2156
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2157
|
+
* @returns Promise with query results
|
|
2158
|
+
* @example
|
|
2159
|
+
* ```typescript
|
|
2160
|
+
* // Using SQLWrapper
|
|
2161
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2162
|
+
*
|
|
2163
|
+
* // Using string
|
|
2164
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2165
|
+
* ```
|
|
2166
|
+
*/
|
|
2167
|
+
execute(query) {
|
|
2168
|
+
return this.drizzle.executeQuery(query);
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2172
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2173
|
+
* - Local cache: Within the current invocation context
|
|
2174
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2175
|
+
*
|
|
2176
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2177
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2178
|
+
* @returns Promise with query results
|
|
2179
|
+
* @example
|
|
2180
|
+
* ```typescript
|
|
2181
|
+
* // Using SQLWrapper with custom TTL
|
|
2182
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2183
|
+
*
|
|
2184
|
+
* // Using string with default TTL
|
|
2185
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2186
|
+
* ```
|
|
2187
|
+
*/
|
|
2188
|
+
executeCacheable(query, cacheTtl) {
|
|
2189
|
+
return this.drizzle.executeQueryCacheable(query, cacheTtl);
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2193
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2194
|
+
*
|
|
2195
|
+
* @returns WithBuilder for creating CTEs
|
|
2196
|
+
* @example
|
|
2197
|
+
* ```typescript
|
|
2198
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2199
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2200
|
+
* .from(users)
|
|
2201
|
+
* .groupBy(users.id)
|
|
2202
|
+
* );
|
|
2203
|
+
* ```
|
|
2204
|
+
*/
|
|
2205
|
+
get $with() {
|
|
2206
|
+
return this.drizzle.$with;
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2210
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2211
|
+
*
|
|
2212
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2213
|
+
* @returns Query builder with CTE support
|
|
2214
|
+
* @example
|
|
2215
|
+
* ```typescript
|
|
2216
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2217
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2218
|
+
* .from(users)
|
|
2219
|
+
* .groupBy(users.id)
|
|
2220
|
+
* );
|
|
2221
|
+
*
|
|
2222
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2223
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2224
|
+
* .from(withQuery);
|
|
2225
|
+
* ```
|
|
2226
|
+
*/
|
|
2227
|
+
with(...queries) {
|
|
2228
|
+
return this.drizzle.with(...queries);
|
|
2229
|
+
}
|
|
1995
2230
|
}
|
|
1996
2231
|
class ForgeSQLORM {
|
|
1997
2232
|
ormInstance;
|
|
@@ -2004,6 +2239,68 @@ class ForgeSQLORM {
|
|
|
2004
2239
|
selectDistinctCacheable(fields, cacheTTL) {
|
|
2005
2240
|
return this.ormInstance.selectDistinctCacheable(fields, cacheTTL);
|
|
2006
2241
|
}
|
|
2242
|
+
/**
|
|
2243
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2244
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2245
|
+
*
|
|
2246
|
+
* @template T - The type of the table
|
|
2247
|
+
* @param table - The table to select from
|
|
2248
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2249
|
+
* @example
|
|
2250
|
+
* ```typescript
|
|
2251
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2252
|
+
* ```
|
|
2253
|
+
*/
|
|
2254
|
+
selectFrom(table2) {
|
|
2255
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFrom(table2);
|
|
2256
|
+
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2259
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2260
|
+
*
|
|
2261
|
+
* @template T - The type of the table
|
|
2262
|
+
* @param table - The table to select from
|
|
2263
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2264
|
+
* @example
|
|
2265
|
+
* ```typescript
|
|
2266
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2267
|
+
* ```
|
|
2268
|
+
*/
|
|
2269
|
+
selectDistinctFrom(table2) {
|
|
2270
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFrom(table2);
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2274
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2275
|
+
*
|
|
2276
|
+
* @template T - The type of the table
|
|
2277
|
+
* @param table - The table to select from
|
|
2278
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2279
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2280
|
+
* @example
|
|
2281
|
+
* ```typescript
|
|
2282
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2283
|
+
* ```
|
|
2284
|
+
*/
|
|
2285
|
+
selectCacheableFrom(table2, cacheTTL) {
|
|
2286
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFromCacheable(table2, cacheTTL);
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2290
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2291
|
+
*
|
|
2292
|
+
* @template T - The type of the table
|
|
2293
|
+
* @param table - The table to select from
|
|
2294
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2295
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2296
|
+
* @example
|
|
2297
|
+
* ```typescript
|
|
2298
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2299
|
+
* ```
|
|
2300
|
+
*/
|
|
2301
|
+
selectDistinctCacheableFrom(table2, cacheTTL) {
|
|
2302
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFromCacheable(table2, cacheTTL);
|
|
2303
|
+
}
|
|
2007
2304
|
executeWithCacheContext(cacheContext) {
|
|
2008
2305
|
return this.ormInstance.executeWithCacheContext(cacheContext);
|
|
2009
2306
|
}
|
|
@@ -2013,7 +2310,7 @@ class ForgeSQLORM {
|
|
|
2013
2310
|
/**
|
|
2014
2311
|
* Executes operations within a local cache context.
|
|
2015
2312
|
* This provides in-memory caching for select queries within a single request scope.
|
|
2016
|
-
*
|
|
2313
|
+
*
|
|
2017
2314
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
2018
2315
|
* @returns Promise that resolves when all operations are complete
|
|
2019
2316
|
*/
|
|
@@ -2023,7 +2320,7 @@ class ForgeSQLORM {
|
|
|
2023
2320
|
/**
|
|
2024
2321
|
* Executes operations within a local cache context and returns a value.
|
|
2025
2322
|
* This provides in-memory caching for select queries within a single request scope.
|
|
2026
|
-
*
|
|
2323
|
+
*
|
|
2027
2324
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
2028
2325
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
2029
2326
|
*/
|
|
@@ -2176,6 +2473,85 @@ class ForgeSQLORM {
|
|
|
2176
2473
|
getDrizzleQueryBuilder() {
|
|
2177
2474
|
return this.ormInstance.getDrizzleQueryBuilder();
|
|
2178
2475
|
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Executes a raw SQL query with local cache support.
|
|
2478
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2479
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2480
|
+
*
|
|
2481
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2482
|
+
* @returns Promise with query results
|
|
2483
|
+
* @example
|
|
2484
|
+
* ```typescript
|
|
2485
|
+
* // Using SQLWrapper
|
|
2486
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2487
|
+
*
|
|
2488
|
+
* // Using string
|
|
2489
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2490
|
+
* ```
|
|
2491
|
+
*/
|
|
2492
|
+
execute(query) {
|
|
2493
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQuery(query);
|
|
2494
|
+
}
|
|
2495
|
+
/**
|
|
2496
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2497
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2498
|
+
* - Local cache: Within the current invocation context
|
|
2499
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2500
|
+
*
|
|
2501
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2502
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2503
|
+
* @returns Promise with query results
|
|
2504
|
+
* @example
|
|
2505
|
+
* ```typescript
|
|
2506
|
+
* // Using SQLWrapper with custom TTL
|
|
2507
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2508
|
+
*
|
|
2509
|
+
* // Using string with default TTL
|
|
2510
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2511
|
+
* ```
|
|
2512
|
+
*/
|
|
2513
|
+
executeCacheable(query, cacheTtl) {
|
|
2514
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQueryCacheable(query, cacheTtl);
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2518
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2519
|
+
*
|
|
2520
|
+
* @returns WithBuilder for creating CTEs
|
|
2521
|
+
* @example
|
|
2522
|
+
* ```typescript
|
|
2523
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2524
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2525
|
+
* .from(users)
|
|
2526
|
+
* .groupBy(users.id)
|
|
2527
|
+
* );
|
|
2528
|
+
* ```
|
|
2529
|
+
*/
|
|
2530
|
+
get $with() {
|
|
2531
|
+
return this.ormInstance.getDrizzleQueryBuilder().$with;
|
|
2532
|
+
}
|
|
2533
|
+
/**
|
|
2534
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2535
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2536
|
+
*
|
|
2537
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2538
|
+
* @returns Query builder with CTE support
|
|
2539
|
+
* @example
|
|
2540
|
+
* ```typescript
|
|
2541
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2542
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2543
|
+
* .from(users)
|
|
2544
|
+
* .groupBy(users.id)
|
|
2545
|
+
* );
|
|
2546
|
+
*
|
|
2547
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2548
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2549
|
+
* .from(withQuery);
|
|
2550
|
+
* ```
|
|
2551
|
+
*/
|
|
2552
|
+
with(...queries) {
|
|
2553
|
+
return this.ormInstance.getDrizzleQueryBuilder().with(...queries);
|
|
2554
|
+
}
|
|
2179
2555
|
}
|
|
2180
2556
|
const forgeDateTimeString = mysqlCore.customType({
|
|
2181
2557
|
dataType() {
|