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.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isTable, sql, eq, and } from "drizzle-orm";
|
|
1
|
+
import { isTable, sql, eq, and, getTableColumns } from "drizzle-orm";
|
|
2
2
|
import { DateTime } from "luxon";
|
|
3
3
|
import { isSQLWrapper } from "drizzle-orm/sql/sql";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -31,12 +31,34 @@ const parseDateTime = (value, format) => {
|
|
|
31
31
|
return result;
|
|
32
32
|
};
|
|
33
33
|
function formatDateTime(value, format) {
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
34
|
+
let dt = null;
|
|
35
|
+
if (value instanceof Date) {
|
|
36
|
+
dt = DateTime.fromJSDate(value);
|
|
37
|
+
} else if (typeof value === "string") {
|
|
38
|
+
for (const parser of [
|
|
39
|
+
DateTime.fromISO,
|
|
40
|
+
DateTime.fromRFC2822,
|
|
41
|
+
DateTime.fromSQL,
|
|
42
|
+
DateTime.fromHTTP
|
|
43
|
+
]) {
|
|
44
|
+
dt = parser(value);
|
|
45
|
+
if (dt.isValid) break;
|
|
46
|
+
}
|
|
47
|
+
if (!dt?.isValid) {
|
|
48
|
+
const parsed = Number(value);
|
|
49
|
+
if (!isNaN(parsed)) {
|
|
50
|
+
dt = DateTime.fromMillis(parsed);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} else if (typeof value === "number") {
|
|
54
|
+
dt = DateTime.fromMillis(value);
|
|
37
55
|
} else {
|
|
56
|
+
throw new Error("Unsupported type");
|
|
57
|
+
}
|
|
58
|
+
if (!dt?.isValid) {
|
|
38
59
|
throw new Error("Invalid Date");
|
|
39
60
|
}
|
|
61
|
+
return dt.toFormat(format);
|
|
40
62
|
}
|
|
41
63
|
function getPrimaryKeys(table) {
|
|
42
64
|
const { columns, primaryKeys } = getTableMetadata(table);
|
|
@@ -1024,11 +1046,34 @@ function createForgeDriverProxy(options, logRawSqlQuery) {
|
|
|
1024
1046
|
return forgeDriver(modifiedQuery, params, method);
|
|
1025
1047
|
};
|
|
1026
1048
|
}
|
|
1049
|
+
const NON_CACHE_CLEARING_ERROR_CODES = [
|
|
1050
|
+
"VALIDATION_ERROR",
|
|
1051
|
+
"CONSTRAINT_ERROR"
|
|
1052
|
+
];
|
|
1053
|
+
const CACHE_CLEARING_ERROR_CODES = [
|
|
1054
|
+
"DEADLOCK",
|
|
1055
|
+
"LOCK_WAIT_TIMEOUT",
|
|
1056
|
+
"CONNECTION_ERROR"
|
|
1057
|
+
];
|
|
1058
|
+
const NON_CACHE_CLEARING_PATTERNS = [
|
|
1059
|
+
/validation/i,
|
|
1060
|
+
/constraint/i
|
|
1061
|
+
];
|
|
1062
|
+
const CACHE_CLEARING_PATTERNS = [
|
|
1063
|
+
/timeout/i,
|
|
1064
|
+
/connection/i
|
|
1065
|
+
];
|
|
1027
1066
|
function shouldClearCacheOnError(error) {
|
|
1028
|
-
if (error?.code
|
|
1067
|
+
if (error?.code && NON_CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
if (error?.message && NON_CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1029
1071
|
return false;
|
|
1030
1072
|
}
|
|
1031
|
-
if (error?.code
|
|
1073
|
+
if (error?.code && CACHE_CLEARING_ERROR_CODES.includes(error.code)) {
|
|
1074
|
+
return true;
|
|
1075
|
+
}
|
|
1076
|
+
if (error?.message && CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
|
|
1032
1077
|
return true;
|
|
1033
1078
|
}
|
|
1034
1079
|
return true;
|
|
@@ -1197,6 +1242,41 @@ const DEFAULT_OPTIONS = {
|
|
|
1197
1242
|
cacheEntityExpirationName: "expiration",
|
|
1198
1243
|
cacheEntityDataName: "data"
|
|
1199
1244
|
};
|
|
1245
|
+
function createRawQueryExecutor(db, options, useGlobalCache = false) {
|
|
1246
|
+
return async function(query, cacheTtl) {
|
|
1247
|
+
let sql2;
|
|
1248
|
+
if (isSQLWrapper(query)) {
|
|
1249
|
+
const sqlWrapper = query;
|
|
1250
|
+
sql2 = sqlWrapper.getSQL().toQuery(db.dialect);
|
|
1251
|
+
} else {
|
|
1252
|
+
sql2 = {
|
|
1253
|
+
sql: query,
|
|
1254
|
+
params: []
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
const localCacheResult = await getQueryLocalCacheQuery(sql2);
|
|
1258
|
+
if (localCacheResult) {
|
|
1259
|
+
return localCacheResult;
|
|
1260
|
+
}
|
|
1261
|
+
if (useGlobalCache) {
|
|
1262
|
+
const cacheResult = await getFromCache({ toSQL: () => sql2 }, options);
|
|
1263
|
+
if (cacheResult) {
|
|
1264
|
+
return cacheResult;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
const results = await db.execute(query);
|
|
1268
|
+
await saveQueryLocalCacheQuery(sql2, results);
|
|
1269
|
+
if (useGlobalCache) {
|
|
1270
|
+
await setCacheResult(
|
|
1271
|
+
{ toSQL: () => sql2 },
|
|
1272
|
+
options,
|
|
1273
|
+
results,
|
|
1274
|
+
cacheTtl ?? options.cacheTTL ?? 120
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
return results;
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1200
1280
|
function patchDbWithSelectAliased(db, options) {
|
|
1201
1281
|
const newOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
1202
1282
|
db.selectAliased = function(fields) {
|
|
@@ -1208,15 +1288,6 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1208
1288
|
newOptions
|
|
1209
1289
|
);
|
|
1210
1290
|
};
|
|
1211
|
-
db.selectAliasedDistinct = function(fields) {
|
|
1212
|
-
return createAliasedSelectBuilder(
|
|
1213
|
-
db,
|
|
1214
|
-
fields,
|
|
1215
|
-
(selections) => db.selectDistinct(selections),
|
|
1216
|
-
false,
|
|
1217
|
-
newOptions
|
|
1218
|
-
);
|
|
1219
|
-
};
|
|
1220
1291
|
db.selectAliasedCacheable = function(fields, cacheTtl) {
|
|
1221
1292
|
return createAliasedSelectBuilder(
|
|
1222
1293
|
db,
|
|
@@ -1227,6 +1298,15 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1227
1298
|
cacheTtl
|
|
1228
1299
|
);
|
|
1229
1300
|
};
|
|
1301
|
+
db.selectAliasedDistinct = function(fields) {
|
|
1302
|
+
return createAliasedSelectBuilder(
|
|
1303
|
+
db,
|
|
1304
|
+
fields,
|
|
1305
|
+
(selections) => db.selectDistinct(selections),
|
|
1306
|
+
false,
|
|
1307
|
+
newOptions
|
|
1308
|
+
);
|
|
1309
|
+
};
|
|
1230
1310
|
db.selectAliasedDistinctCacheable = function(fields, cacheTtl) {
|
|
1231
1311
|
return createAliasedSelectBuilder(
|
|
1232
1312
|
db,
|
|
@@ -1237,6 +1317,18 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1237
1317
|
cacheTtl
|
|
1238
1318
|
);
|
|
1239
1319
|
};
|
|
1320
|
+
db.selectFrom = function(table) {
|
|
1321
|
+
return db.selectAliased(getTableColumns(table)).from(table);
|
|
1322
|
+
};
|
|
1323
|
+
db.selectFromCacheable = function(table, cacheTtl) {
|
|
1324
|
+
return db.selectAliasedCacheable(getTableColumns(table), cacheTtl).from(table);
|
|
1325
|
+
};
|
|
1326
|
+
db.selectDistinctFrom = function(table) {
|
|
1327
|
+
return db.selectAliasedDistinct(getTableColumns(table)).from(table);
|
|
1328
|
+
};
|
|
1329
|
+
db.selectDistinctFromCacheable = function(table, cacheTtl) {
|
|
1330
|
+
return db.selectAliasedDistinctCacheable(getTableColumns(table), cacheTtl).from(table);
|
|
1331
|
+
};
|
|
1240
1332
|
db.insertWithCacheContext = function(table) {
|
|
1241
1333
|
return insertAndEvictCacheBuilder(db, table, newOptions, false);
|
|
1242
1334
|
};
|
|
@@ -1255,6 +1347,8 @@ function patchDbWithSelectAliased(db, options) {
|
|
|
1255
1347
|
db.deleteAndEvictCache = function(table) {
|
|
1256
1348
|
return deleteAndEvictCacheBuilder(db, table, newOptions, true);
|
|
1257
1349
|
};
|
|
1350
|
+
db.executeQuery = createRawQueryExecutor(db, newOptions, false);
|
|
1351
|
+
db.executeQueryCacheable = createRawQueryExecutor(db, newOptions, true);
|
|
1258
1352
|
return db;
|
|
1259
1353
|
}
|
|
1260
1354
|
class ForgeSQLAnalyseOperation {
|
|
@@ -1722,7 +1816,7 @@ class ForgeSQLORMImpl {
|
|
|
1722
1816
|
*/
|
|
1723
1817
|
async executeWithCacheContextAndReturnValue(cacheContext) {
|
|
1724
1818
|
return await this.executeWithLocalCacheContextAndReturnValue(
|
|
1725
|
-
async () => await cacheApplicationContext.run({ tables: /* @__PURE__ */ new Set() }, async () => {
|
|
1819
|
+
async () => await cacheApplicationContext.run(cacheApplicationContext.getStore() ?? { tables: /* @__PURE__ */ new Set() }, async () => {
|
|
1726
1820
|
try {
|
|
1727
1821
|
return await cacheContext();
|
|
1728
1822
|
} finally {
|
|
@@ -1737,19 +1831,19 @@ class ForgeSQLORMImpl {
|
|
|
1737
1831
|
/**
|
|
1738
1832
|
* Executes operations within a local cache context and returns a value.
|
|
1739
1833
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1740
|
-
*
|
|
1834
|
+
*
|
|
1741
1835
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1742
1836
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
1743
1837
|
*/
|
|
1744
1838
|
async executeWithLocalCacheContextAndReturnValue(cacheContext) {
|
|
1745
|
-
return await localCacheApplicationContext.run({ cache: {} }, async () => {
|
|
1839
|
+
return await localCacheApplicationContext.run(localCacheApplicationContext.getStore() ?? { cache: {} }, async () => {
|
|
1746
1840
|
return await cacheContext();
|
|
1747
1841
|
});
|
|
1748
1842
|
}
|
|
1749
1843
|
/**
|
|
1750
1844
|
* Executes operations within a local cache context.
|
|
1751
1845
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1752
|
-
*
|
|
1846
|
+
*
|
|
1753
1847
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1754
1848
|
* @returns Promise that resolves when all operations are complete
|
|
1755
1849
|
*/
|
|
@@ -1973,6 +2067,147 @@ class ForgeSQLORMImpl {
|
|
|
1973
2067
|
}
|
|
1974
2068
|
return this.drizzle.selectAliasedDistinctCacheable(fields, cacheTTL);
|
|
1975
2069
|
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2072
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2073
|
+
*
|
|
2074
|
+
* @template T - The type of the table
|
|
2075
|
+
* @param table - The table to select from
|
|
2076
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2077
|
+
* @example
|
|
2078
|
+
* ```typescript
|
|
2079
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2080
|
+
* ```
|
|
2081
|
+
*/
|
|
2082
|
+
selectFrom(table) {
|
|
2083
|
+
return this.drizzle.selectFrom(table);
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2087
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2088
|
+
*
|
|
2089
|
+
* @template T - The type of the table
|
|
2090
|
+
* @param table - The table to select from
|
|
2091
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2092
|
+
* @example
|
|
2093
|
+
* ```typescript
|
|
2094
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2095
|
+
* ```
|
|
2096
|
+
*/
|
|
2097
|
+
selectDistinctFrom(table) {
|
|
2098
|
+
return this.drizzle.selectDistinctFrom(table);
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2102
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2103
|
+
*
|
|
2104
|
+
* @template T - The type of the table
|
|
2105
|
+
* @param table - The table to select from
|
|
2106
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2107
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2108
|
+
* @example
|
|
2109
|
+
* ```typescript
|
|
2110
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2111
|
+
* ```
|
|
2112
|
+
*/
|
|
2113
|
+
selectCacheableFrom(table, cacheTTL) {
|
|
2114
|
+
return this.drizzle.selectFromCacheable(table, cacheTTL);
|
|
2115
|
+
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2118
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2119
|
+
*
|
|
2120
|
+
* @template T - The type of the table
|
|
2121
|
+
* @param table - The table to select from
|
|
2122
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2123
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2124
|
+
* @example
|
|
2125
|
+
* ```typescript
|
|
2126
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2127
|
+
* ```
|
|
2128
|
+
*/
|
|
2129
|
+
selectDistinctCacheableFrom(table, cacheTTL) {
|
|
2130
|
+
return this.drizzle.selectDistinctFromCacheable(table, cacheTTL);
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Executes a raw SQL query with local cache support.
|
|
2134
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2135
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2136
|
+
*
|
|
2137
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2138
|
+
* @returns Promise with query results
|
|
2139
|
+
* @example
|
|
2140
|
+
* ```typescript
|
|
2141
|
+
* // Using SQLWrapper
|
|
2142
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2143
|
+
*
|
|
2144
|
+
* // Using string
|
|
2145
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2146
|
+
* ```
|
|
2147
|
+
*/
|
|
2148
|
+
execute(query) {
|
|
2149
|
+
return this.drizzle.executeQuery(query);
|
|
2150
|
+
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2153
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2154
|
+
* - Local cache: Within the current invocation context
|
|
2155
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2156
|
+
*
|
|
2157
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2158
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2159
|
+
* @returns Promise with query results
|
|
2160
|
+
* @example
|
|
2161
|
+
* ```typescript
|
|
2162
|
+
* // Using SQLWrapper with custom TTL
|
|
2163
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2164
|
+
*
|
|
2165
|
+
* // Using string with default TTL
|
|
2166
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2167
|
+
* ```
|
|
2168
|
+
*/
|
|
2169
|
+
executeCacheable(query, cacheTtl) {
|
|
2170
|
+
return this.drizzle.executeQueryCacheable(query, cacheTtl);
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2174
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2175
|
+
*
|
|
2176
|
+
* @returns WithBuilder for creating CTEs
|
|
2177
|
+
* @example
|
|
2178
|
+
* ```typescript
|
|
2179
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2180
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2181
|
+
* .from(users)
|
|
2182
|
+
* .groupBy(users.id)
|
|
2183
|
+
* );
|
|
2184
|
+
* ```
|
|
2185
|
+
*/
|
|
2186
|
+
get $with() {
|
|
2187
|
+
return this.drizzle.$with;
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2191
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2192
|
+
*
|
|
2193
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2194
|
+
* @returns Query builder with CTE support
|
|
2195
|
+
* @example
|
|
2196
|
+
* ```typescript
|
|
2197
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2198
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2199
|
+
* .from(users)
|
|
2200
|
+
* .groupBy(users.id)
|
|
2201
|
+
* );
|
|
2202
|
+
*
|
|
2203
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2204
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2205
|
+
* .from(withQuery);
|
|
2206
|
+
* ```
|
|
2207
|
+
*/
|
|
2208
|
+
with(...queries) {
|
|
2209
|
+
return this.drizzle.with(...queries);
|
|
2210
|
+
}
|
|
1976
2211
|
}
|
|
1977
2212
|
class ForgeSQLORM {
|
|
1978
2213
|
ormInstance;
|
|
@@ -1985,6 +2220,68 @@ class ForgeSQLORM {
|
|
|
1985
2220
|
selectDistinctCacheable(fields, cacheTTL) {
|
|
1986
2221
|
return this.ormInstance.selectDistinctCacheable(fields, cacheTTL);
|
|
1987
2222
|
}
|
|
2223
|
+
/**
|
|
2224
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
2225
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
2226
|
+
*
|
|
2227
|
+
* @template T - The type of the table
|
|
2228
|
+
* @param table - The table to select from
|
|
2229
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
2230
|
+
* @example
|
|
2231
|
+
* ```typescript
|
|
2232
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
selectFrom(table) {
|
|
2236
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFrom(table);
|
|
2237
|
+
}
|
|
2238
|
+
/**
|
|
2239
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
2240
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
2241
|
+
*
|
|
2242
|
+
* @template T - The type of the table
|
|
2243
|
+
* @param table - The table to select from
|
|
2244
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
2245
|
+
* @example
|
|
2246
|
+
* ```typescript
|
|
2247
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
2248
|
+
* ```
|
|
2249
|
+
*/
|
|
2250
|
+
selectDistinctFrom(table) {
|
|
2251
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFrom(table);
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
2255
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
2256
|
+
*
|
|
2257
|
+
* @template T - The type of the table
|
|
2258
|
+
* @param table - The table to select from
|
|
2259
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2260
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
2261
|
+
* @example
|
|
2262
|
+
* ```typescript
|
|
2263
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
2264
|
+
* ```
|
|
2265
|
+
*/
|
|
2266
|
+
selectCacheableFrom(table, cacheTTL) {
|
|
2267
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFromCacheable(table, cacheTTL);
|
|
2268
|
+
}
|
|
2269
|
+
/**
|
|
2270
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
2271
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
2272
|
+
*
|
|
2273
|
+
* @template T - The type of the table
|
|
2274
|
+
* @param table - The table to select from
|
|
2275
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
2276
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
2277
|
+
* @example
|
|
2278
|
+
* ```typescript
|
|
2279
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
2280
|
+
* ```
|
|
2281
|
+
*/
|
|
2282
|
+
selectDistinctCacheableFrom(table, cacheTTL) {
|
|
2283
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFromCacheable(table, cacheTTL);
|
|
2284
|
+
}
|
|
1988
2285
|
executeWithCacheContext(cacheContext) {
|
|
1989
2286
|
return this.ormInstance.executeWithCacheContext(cacheContext);
|
|
1990
2287
|
}
|
|
@@ -1994,7 +2291,7 @@ class ForgeSQLORM {
|
|
|
1994
2291
|
/**
|
|
1995
2292
|
* Executes operations within a local cache context.
|
|
1996
2293
|
* This provides in-memory caching for select queries within a single request scope.
|
|
1997
|
-
*
|
|
2294
|
+
*
|
|
1998
2295
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
1999
2296
|
* @returns Promise that resolves when all operations are complete
|
|
2000
2297
|
*/
|
|
@@ -2004,7 +2301,7 @@ class ForgeSQLORM {
|
|
|
2004
2301
|
/**
|
|
2005
2302
|
* Executes operations within a local cache context and returns a value.
|
|
2006
2303
|
* This provides in-memory caching for select queries within a single request scope.
|
|
2007
|
-
*
|
|
2304
|
+
*
|
|
2008
2305
|
* @param cacheContext - Function containing operations that will benefit from local caching
|
|
2009
2306
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
2010
2307
|
*/
|
|
@@ -2157,6 +2454,85 @@ class ForgeSQLORM {
|
|
|
2157
2454
|
getDrizzleQueryBuilder() {
|
|
2158
2455
|
return this.ormInstance.getDrizzleQueryBuilder();
|
|
2159
2456
|
}
|
|
2457
|
+
/**
|
|
2458
|
+
* Executes a raw SQL query with local cache support.
|
|
2459
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
2460
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
2461
|
+
*
|
|
2462
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2463
|
+
* @returns Promise with query results
|
|
2464
|
+
* @example
|
|
2465
|
+
* ```typescript
|
|
2466
|
+
* // Using SQLWrapper
|
|
2467
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
2468
|
+
*
|
|
2469
|
+
* // Using string
|
|
2470
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
2471
|
+
* ```
|
|
2472
|
+
*/
|
|
2473
|
+
execute(query) {
|
|
2474
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQuery(query);
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
2478
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
2479
|
+
* - Local cache: Within the current invocation context
|
|
2480
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
2481
|
+
*
|
|
2482
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
2483
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
2484
|
+
* @returns Promise with query results
|
|
2485
|
+
* @example
|
|
2486
|
+
* ```typescript
|
|
2487
|
+
* // Using SQLWrapper with custom TTL
|
|
2488
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
2489
|
+
*
|
|
2490
|
+
* // Using string with default TTL
|
|
2491
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
2492
|
+
* ```
|
|
2493
|
+
*/
|
|
2494
|
+
executeCacheable(query, cacheTtl) {
|
|
2495
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQueryCacheable(query, cacheTtl);
|
|
2496
|
+
}
|
|
2497
|
+
/**
|
|
2498
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
2499
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2500
|
+
*
|
|
2501
|
+
* @returns WithBuilder for creating CTEs
|
|
2502
|
+
* @example
|
|
2503
|
+
* ```typescript
|
|
2504
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2505
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2506
|
+
* .from(users)
|
|
2507
|
+
* .groupBy(users.id)
|
|
2508
|
+
* );
|
|
2509
|
+
* ```
|
|
2510
|
+
*/
|
|
2511
|
+
get $with() {
|
|
2512
|
+
return this.ormInstance.getDrizzleQueryBuilder().$with;
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
2516
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
2517
|
+
*
|
|
2518
|
+
* @param queries - Array of CTE queries created with $with()
|
|
2519
|
+
* @returns Query builder with CTE support
|
|
2520
|
+
* @example
|
|
2521
|
+
* ```typescript
|
|
2522
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
2523
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
2524
|
+
* .from(users)
|
|
2525
|
+
* .groupBy(users.id)
|
|
2526
|
+
* );
|
|
2527
|
+
*
|
|
2528
|
+
* const result = await forgeSQL.with(withQuery)
|
|
2529
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
2530
|
+
* .from(withQuery);
|
|
2531
|
+
* ```
|
|
2532
|
+
*/
|
|
2533
|
+
with(...queries) {
|
|
2534
|
+
return this.ormInstance.getDrizzleQueryBuilder().with(...queries);
|
|
2535
|
+
}
|
|
2160
2536
|
}
|
|
2161
2537
|
const forgeDateTimeString = customType({
|
|
2162
2538
|
dataType() {
|