forge-sql-orm 2.1.1 → 2.1.3

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.
Files changed (33) hide show
  1. package/dist/ForgeSQLORM.js +142 -103
  2. package/dist/ForgeSQLORM.js.map +1 -1
  3. package/dist/ForgeSQLORM.mjs +142 -103
  4. package/dist/ForgeSQLORM.mjs.map +1 -1
  5. package/dist/core/ForgeSQLORM.d.ts.map +1 -1
  6. package/dist/core/ForgeSQLQueryBuilder.d.ts +24 -25
  7. package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
  8. package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
  9. package/dist/utils/cacheContextUtils.d.ts +4 -2
  10. package/dist/utils/cacheContextUtils.d.ts.map +1 -1
  11. package/dist/utils/cacheUtils.d.ts.map +1 -1
  12. package/dist/utils/forgeDriver.d.ts.map +1 -1
  13. package/dist/utils/forgeDriverProxy.d.ts.map +1 -1
  14. package/dist/utils/sqlUtils.d.ts +1 -1
  15. package/dist/utils/sqlUtils.d.ts.map +1 -1
  16. package/dist/webtriggers/applyMigrationsWebTrigger.d.ts.map +1 -1
  17. package/dist/webtriggers/dropMigrationWebTrigger.d.ts.map +1 -1
  18. package/dist/webtriggers/dropTablesMigrationWebTrigger.d.ts.map +1 -1
  19. package/dist/webtriggers/fetchSchemaWebTrigger.d.ts.map +1 -1
  20. package/package.json +5 -5
  21. package/src/core/ForgeSQLORM.ts +29 -23
  22. package/src/core/ForgeSQLQueryBuilder.ts +185 -128
  23. package/src/lib/drizzle/extensions/additionalActions.ts +125 -76
  24. package/src/lib/drizzle/extensions/types.d.ts +16 -11
  25. package/src/utils/cacheContextUtils.ts +16 -4
  26. package/src/utils/cacheUtils.ts +3 -1
  27. package/src/utils/forgeDriver.ts +16 -21
  28. package/src/utils/forgeDriverProxy.ts +10 -3
  29. package/src/utils/sqlUtils.ts +59 -35
  30. package/src/webtriggers/applyMigrationsWebTrigger.ts +18 -14
  31. package/src/webtriggers/dropMigrationWebTrigger.ts +8 -4
  32. package/src/webtriggers/dropTablesMigrationWebTrigger.ts +8 -4
  33. package/src/webtriggers/fetchSchemaWebTrigger.ts +7 -3
@@ -1,28 +1,35 @@
1
1
  import {
2
- MySqlRawQueryResult,
3
- MySqlRemoteDatabase,
4
- MySqlRemotePreparedQueryHKT,
5
- MySqlRemoteQueryResultHKT,
2
+ MySqlRawQueryResult,
3
+ MySqlRemoteDatabase,
4
+ MySqlRemotePreparedQueryHKT,
5
+ MySqlRemoteQueryResultHKT,
6
6
  } from "drizzle-orm/mysql-proxy";
7
7
 
8
- import {SelectedFields} from "drizzle-orm/mysql-core/query-builders/select.types";
9
- import {applyFromDriverTransform, ForgeSqlOrmOptions, mapSelectFieldsWithAlias} from "../../..";
10
- import {MySqlSelectBase, MySqlSelectBuilder} from "drizzle-orm/mysql-core";
11
- import type {MySqlTable} from "drizzle-orm/mysql-core/table";
12
- import {MySqlDeleteBase, MySqlInsertBuilder, MySqlUpdateBuilder,} from "drizzle-orm/mysql-core/query-builders";
13
- import {clearCache, getFromCache, setCacheResult} from "../../../utils/cacheUtils";
8
+ import { SelectedFields } from "drizzle-orm/mysql-core/query-builders/select.types";
9
+ import { applyFromDriverTransform, ForgeSqlOrmOptions, mapSelectFieldsWithAlias } from "../../..";
10
+ import { MySqlSelectBase, MySqlSelectBuilder } from "drizzle-orm/mysql-core";
11
+ import type { MySqlTable } from "drizzle-orm/mysql-core/table";
12
+ import {
13
+ MySqlDeleteBase,
14
+ MySqlInsertBuilder,
15
+ MySqlUpdateBuilder,
16
+ } from "drizzle-orm/mysql-core/query-builders";
17
+ import { clearCache, getFromCache, setCacheResult } from "../../../utils/cacheUtils";
14
18
  import {
15
- cacheApplicationContext,
16
- evictLocalCacheQuery,
17
- getQueryLocalCacheQuery,
18
- saveQueryLocalCacheQuery,
19
- saveTableIfInsideCacheContext,
19
+ cacheApplicationContext,
20
+ evictLocalCacheQuery,
21
+ getQueryLocalCacheQuery,
22
+ saveQueryLocalCacheQuery,
23
+ saveTableIfInsideCacheContext,
20
24
  } from "../../../utils/cacheContextUtils";
21
- import {BuildQueryConfig, isSQLWrapper, SQLWrapper} from "drizzle-orm/sql/sql";
22
- import type {MySqlQueryResultKind} from "drizzle-orm/mysql-core/session";
23
- import {getTableColumns, Query} from "drizzle-orm";
24
- import {MySqlDialect} from "drizzle-orm/mysql-core/dialect";
25
- import type {GetSelectTableName, GetSelectTableSelection} from "drizzle-orm/query-builders/select.types";
25
+ import { BuildQueryConfig, isSQLWrapper, SQLWrapper } from "drizzle-orm/sql/sql";
26
+ import type { MySqlQueryResultKind } from "drizzle-orm/mysql-core/session";
27
+ import { getTableColumns, Query } from "drizzle-orm";
28
+ import { MySqlDialect } from "drizzle-orm/mysql-core/dialect";
29
+ import type {
30
+ GetSelectTableName,
31
+ GetSelectTableSelection,
32
+ } from "drizzle-orm/query-builders/select.types";
26
33
 
27
34
  // ============================================================================
28
35
  // TYPES AND INTERFACES
@@ -40,35 +47,22 @@ interface QueryBuilder {
40
47
  /**
41
48
  * Error codes that should not trigger cache clearing
42
49
  */
43
- const NON_CACHE_CLEARING_ERROR_CODES = [
44
- "VALIDATION_ERROR",
45
- "CONSTRAINT_ERROR"
46
- ] as const;
50
+ const NON_CACHE_CLEARING_ERROR_CODES = ["VALIDATION_ERROR", "CONSTRAINT_ERROR"] as const;
47
51
 
48
52
  /**
49
53
  * Error codes that should trigger cache clearing
50
54
  */
51
- const CACHE_CLEARING_ERROR_CODES = [
52
- "DEADLOCK",
53
- "LOCK_WAIT_TIMEOUT",
54
- "CONNECTION_ERROR"
55
- ] as const;
55
+ const CACHE_CLEARING_ERROR_CODES = ["DEADLOCK", "LOCK_WAIT_TIMEOUT", "CONNECTION_ERROR"] as const;
56
56
 
57
57
  /**
58
58
  * Error message patterns that should not trigger cache clearing
59
59
  */
60
- const NON_CACHE_CLEARING_PATTERNS = [
61
- /validation/i,
62
- /constraint/i
63
- ] as const;
60
+ const NON_CACHE_CLEARING_PATTERNS = [/validation/i, /constraint/i] as const;
64
61
 
65
62
  /**
66
63
  * Error message patterns that should trigger cache clearing
67
64
  */
68
- const CACHE_CLEARING_PATTERNS = [
69
- /timeout/i,
70
- /connection/i
71
- ] as const;
65
+ const CACHE_CLEARING_PATTERNS = [/timeout/i, /connection/i] as const;
72
66
 
73
67
  // ============================================================================
74
68
  // CACHE MANAGEMENT UTILITIES
@@ -87,7 +81,10 @@ function shouldClearCacheOnError(error: any): boolean {
87
81
  return false;
88
82
  }
89
83
 
90
- if (error?.message && NON_CACHE_CLEARING_PATTERNS.some(pattern => pattern.test(error.message))) {
84
+ if (
85
+ error?.message &&
86
+ NON_CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))
87
+ ) {
91
88
  return false;
92
89
  }
93
90
 
@@ -96,7 +93,7 @@ function shouldClearCacheOnError(error: any): boolean {
96
93
  return true;
97
94
  }
98
95
 
99
- if (error?.message && CACHE_CLEARING_PATTERNS.some(pattern => pattern.test(error.message))) {
96
+ if (error?.message && CACHE_CLEARING_PATTERNS.some((pattern) => pattern.test(error.message))) {
100
97
  return true;
101
98
  }
102
99
 
@@ -142,41 +139,82 @@ export type SelectAliasedDistinctCacheableType = <TSelection extends SelectedFie
142
139
  * Type for select queries from table with field aliasing
143
140
  */
144
141
  export type SelectAllFromAliasedType = <T extends MySqlTable>(
145
- table: T,
146
- ) => MySqlSelectBase<GetSelectTableName<T>, T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"], T["_"]["columns"] extends undefined ? "single" : "partial", MySqlRemotePreparedQueryHKT, GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {}, false, never, any>;
142
+ table: T,
143
+ ) => MySqlSelectBase<
144
+ GetSelectTableName<T>,
145
+ T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
146
+ T["_"]["columns"] extends undefined ? "single" : "partial",
147
+ MySqlRemotePreparedQueryHKT,
148
+ GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
149
+ false,
150
+ never,
151
+ any
152
+ >;
147
153
 
148
154
  /**
149
155
  * Type for select distinct queries from table with field aliasing
150
156
  */
151
157
  export type SelectAllDistinctFromAliasedType = <T extends MySqlTable>(
152
- table: T,
153
- ) => MySqlSelectBase<GetSelectTableName<T>, T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"], T["_"]["columns"] extends undefined ? "single" : "partial", MySqlRemotePreparedQueryHKT, GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {}, false, never, any>;
158
+ table: T,
159
+ ) => MySqlSelectBase<
160
+ GetSelectTableName<T>,
161
+ T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
162
+ T["_"]["columns"] extends undefined ? "single" : "partial",
163
+ MySqlRemotePreparedQueryHKT,
164
+ GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
165
+ false,
166
+ never,
167
+ any
168
+ >;
154
169
 
155
170
  /**
156
171
  * Type for select queries from table with field aliasing and caching
157
172
  */
158
173
  export type SelectAllFromCacheableAliasedType = <T extends MySqlTable>(
159
- table: T,
160
- cacheTtl?: number,
161
- ) => MySqlSelectBase<GetSelectTableName<T>, T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"], T["_"]["columns"] extends undefined ? "single" : "partial", MySqlRemotePreparedQueryHKT, GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {}, false, never, any>;
174
+ table: T,
175
+ cacheTtl?: number,
176
+ ) => MySqlSelectBase<
177
+ GetSelectTableName<T>,
178
+ T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
179
+ T["_"]["columns"] extends undefined ? "single" : "partial",
180
+ MySqlRemotePreparedQueryHKT,
181
+ GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
182
+ false,
183
+ never,
184
+ any
185
+ >;
162
186
 
163
187
  /**
164
188
  * Type for select distinct queries from table with field aliasing and caching
165
189
  */
166
190
  export type SelectAllDistinctFromCacheableAliasedType = <T extends MySqlTable>(
167
- table: T,
168
- cacheTtl?: number,
169
- ) => MySqlSelectBase<GetSelectTableName<T>, T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"], T["_"]["columns"] extends undefined ? "single" : "partial", MySqlRemotePreparedQueryHKT, GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {}, false, never, any>;
191
+ table: T,
192
+ cacheTtl?: number,
193
+ ) => MySqlSelectBase<
194
+ GetSelectTableName<T>,
195
+ T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
196
+ T["_"]["columns"] extends undefined ? "single" : "partial",
197
+ MySqlRemotePreparedQueryHKT,
198
+ GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
199
+ false,
200
+ never,
201
+ any
202
+ >;
170
203
 
171
204
  /**
172
205
  * Type for executing raw SQL queries with local cache
173
206
  */
174
- export type ExecuteQuery = (query: SQLWrapper | string) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
207
+ export type ExecuteQuery = (
208
+ query: SQLWrapper | string,
209
+ ) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
175
210
 
176
211
  /**
177
212
  * Type for executing raw SQL queries with local and global cache
178
213
  */
179
- export type ExecuteQueryCacheable = (query: SQLWrapper | string, cacheTtl?: number) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
214
+ export type ExecuteQueryCacheable = (
215
+ query: SQLWrapper | string,
216
+ cacheTtl?: number,
217
+ ) => Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
180
218
 
181
219
  /**
182
220
  * Type for insert operations with cache eviction
@@ -229,8 +267,8 @@ async function handleSuccessfulExecution(
229
267
  if (shouldClearCacheOnError(error)) {
230
268
  await evictLocalCacheQuery(table, options);
231
269
  if (isCached) {
232
- await clearCache(table, options).catch(() => {
233
- console.warn("Ignore cache clear errors");
270
+ await clearCache(table, options).catch((e) => {
271
+ console.warn("Ignore cache clear errors", e);
234
272
  });
235
273
  } else {
236
274
  await saveTableIfInsideCacheContext(table);
@@ -406,7 +444,7 @@ async function handleCachedQuery(
406
444
  onrejected?: any,
407
445
  ): Promise<any> {
408
446
  try {
409
- const localCached = await getQueryLocalCacheQuery(target);
447
+ const localCached = await getQueryLocalCacheQuery(target, options);
410
448
  if (localCached) {
411
449
  return onfulfilled?.(localCached);
412
450
  }
@@ -416,7 +454,7 @@ async function handleCachedQuery(
416
454
  }
417
455
  const rows = await target.execute();
418
456
  const transformed = applyFromDriverTransform(rows, selections, aliasMap);
419
- await saveQueryLocalCacheQuery(target, transformed);
457
+ await saveQueryLocalCacheQuery(target, transformed, options);
420
458
  await setCacheResult(target, options, transformed, cacheTtl).catch((cacheError) => {
421
459
  // Log cache error but don't fail the query
422
460
  console.warn("Cache set error:", cacheError);
@@ -432,6 +470,7 @@ async function handleCachedQuery(
432
470
  * Handles non-cached query execution.
433
471
  *
434
472
  * @param target - The query target
473
+ * @param options - ForgeSQL ORM options
435
474
  * @param selections - Field selections
436
475
  * @param aliasMap - Field alias mapping
437
476
  * @param onfulfilled - Success callback
@@ -440,19 +479,20 @@ async function handleCachedQuery(
440
479
  */
441
480
  async function handleNonCachedQuery(
442
481
  target: any,
482
+ options: any,
443
483
  selections: any,
444
484
  aliasMap: any,
445
485
  onfulfilled?: any,
446
486
  onrejected?: any,
447
487
  ): Promise<any> {
448
488
  try {
449
- const localCached = await getQueryLocalCacheQuery(target);
489
+ const localCached = await getQueryLocalCacheQuery(target, options);
450
490
  if (localCached) {
451
491
  return onfulfilled?.(localCached);
452
492
  }
453
493
  const rows = await target.execute();
454
494
  const transformed = applyFromDriverTransform(rows, selections, aliasMap);
455
- await saveQueryLocalCacheQuery(target, transformed);
495
+ await saveQueryLocalCacheQuery(target, transformed, options);
456
496
  return onfulfilled?.(transformed);
457
497
  } catch (error) {
458
498
  return onrejected?.(error);
@@ -505,7 +545,14 @@ function createAliasedSelectBuilder<TSelection extends SelectedFields>(
505
545
  onrejected,
506
546
  );
507
547
  } else {
508
- return handleNonCachedQuery(target, selections, aliasMap, onfulfilled, onrejected);
548
+ return handleNonCachedQuery(
549
+ target,
550
+ options,
551
+ selections,
552
+ aliasMap,
553
+ onfulfilled,
554
+ onrejected,
555
+ );
509
556
  }
510
557
  };
511
558
  }
@@ -553,34 +600,36 @@ const DEFAULT_OPTIONS: ForgeSqlOrmOptions = {
553
600
  // QUERY BUILDER FACTORIES
554
601
  // ============================================================================
555
602
 
556
-
557
603
  /**
558
604
  * Creates a raw SQL query executor with caching support
559
605
  */
560
606
  function createRawQueryExecutor(
561
607
  db: MySqlRemoteDatabase<any>,
562
608
  options: ForgeSqlOrmOptions,
563
- useGlobalCache: boolean = false
609
+ useGlobalCache: boolean = false,
564
610
  ) {
565
611
  return async function <T extends { [column: string]: any }>(
566
612
  query: SQLWrapper | string,
567
- cacheTtl?: number
613
+ cacheTtl?: number,
568
614
  ): Promise<MySqlRawQueryResult> {
569
615
  let sql: Query;
570
-
616
+
571
617
  if (isSQLWrapper(query)) {
572
618
  const sqlWrapper = query as SQLWrapper;
573
- sql = sqlWrapper.getSQL()
574
- .toQuery(((db as unknown as { dialect: MySqlDialect }).dialect) as unknown as BuildQueryConfig);
619
+ sql = sqlWrapper
620
+ .getSQL()
621
+ .toQuery(
622
+ (db as unknown as { dialect: MySqlDialect }).dialect as unknown as BuildQueryConfig,
623
+ );
575
624
  } else {
576
625
  sql = {
577
626
  sql: query,
578
- params: []
627
+ params: [],
579
628
  };
580
629
  }
581
630
 
582
631
  // Check local cache first
583
- const localCacheResult = await getQueryLocalCacheQuery(sql);
632
+ const localCacheResult = await getQueryLocalCacheQuery(sql, options);
584
633
  if (localCacheResult) {
585
634
  return localCacheResult as MySqlRawQueryResult;
586
635
  }
@@ -595,20 +644,20 @@ function createRawQueryExecutor(
595
644
 
596
645
  // Execute query
597
646
  const results = await db.execute<T>(query);
598
-
647
+
599
648
  // Save to local cache
600
- await saveQueryLocalCacheQuery(sql, results);
601
-
649
+ await saveQueryLocalCacheQuery(sql, results, options);
650
+
602
651
  // Save to global cache if enabled
603
652
  if (useGlobalCache) {
604
653
  await setCacheResult(
605
- { toSQL: () => sql },
606
- options,
607
- results,
608
- cacheTtl ?? options.cacheTTL ?? 120
654
+ { toSQL: () => sql },
655
+ options,
656
+ results,
657
+ cacheTtl ?? options.cacheTTL ?? 120,
609
658
  );
610
659
  }
611
-
660
+
612
661
  return results;
613
662
  };
614
663
  }
@@ -821,7 +870,7 @@ export function patchDbWithSelectAliased(
821
870
  * ```typescript
822
871
  * // Using SQLWrapper
823
872
  * const result = await db.executeQuery(sql`SELECT * FROM users WHERE id = ${userId}`);
824
- *
873
+ *
825
874
  * // Using string
826
875
  * const result = await db.executeQuery("SELECT * FROM users WHERE status = 'active'");
827
876
  * ```
@@ -841,7 +890,7 @@ export function patchDbWithSelectAliased(
841
890
  * ```typescript
842
891
  * // Using SQLWrapper with custom TTL
843
892
  * const result = await db.executeQueryCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
844
- *
893
+ *
845
894
  * // Using string with default TTL
846
895
  * const result = await db.executeQueryCacheable("SELECT * FROM users WHERE status = 'active'");
847
896
  * ```
@@ -1,12 +1,17 @@
1
1
  import {
2
- DeleteAndEvictCacheType, ExecuteQuery, ExecuteQueryCacheable,
3
- InsertAndEvictCacheType,
4
- SelectAliasedCacheableType,
5
- SelectAliasedDistinctCacheableType,
6
- SelectAliasedDistinctType,
7
- SelectAliasedType, SelectAllDistinctFromAliasedType,
8
- SelectAllDistinctFromCacheableAliasedType, SelectAllFromAliasedType, SelectAllFromCacheableAliasedType,
9
- UpdateAndEvictCacheType,
2
+ DeleteAndEvictCacheType,
3
+ ExecuteQuery,
4
+ ExecuteQueryCacheable,
5
+ InsertAndEvictCacheType,
6
+ SelectAliasedCacheableType,
7
+ SelectAliasedDistinctCacheableType,
8
+ SelectAliasedDistinctType,
9
+ SelectAliasedType,
10
+ SelectAllDistinctFromAliasedType,
11
+ SelectAllDistinctFromCacheableAliasedType,
12
+ SelectAllFromAliasedType,
13
+ SelectAllFromCacheableAliasedType,
14
+ UpdateAndEvictCacheType,
10
15
  } from "./additionalActions";
11
16
 
12
17
  declare module "drizzle-orm/mysql-proxy" {
@@ -25,7 +30,7 @@ declare module "drizzle-orm/mysql-proxy" {
25
30
  * Select with field aliasing support for all table columns
26
31
  */
27
32
  selectFrom: SelectAllFromAliasedType;
28
-
33
+
29
34
  /**
30
35
  * Select distinct with field aliasing support for all table columns
31
36
  */
@@ -50,12 +55,12 @@ declare module "drizzle-orm/mysql-proxy" {
50
55
  * Select with field aliasing and caching support for all table columns
51
56
  */
52
57
  selectFromCacheable: SelectAllFromCacheableAliasedType;
53
-
58
+
54
59
  /**
55
60
  * Select distinct with field aliasing and caching support for all table columns
56
61
  */
57
62
  selectDistinctFromCacheable: SelectAllDistinctFromCacheableAliasedType;
58
-
63
+
59
64
  /**
60
65
  * Execute raw SQL query with both local and global cache support
61
66
  */
@@ -78,6 +78,7 @@ export async function saveTableIfInsideCacheContext<T extends AnyMySqlTable>(
78
78
  *
79
79
  * @param query - The Drizzle query to cache
80
80
  * @param rows - The query result data to cache
81
+ * @param options - ForgeSqlOrm options
81
82
  * @returns Promise that resolves when the data is saved to local cache
82
83
  *
83
84
  * @example
@@ -89,7 +90,7 @@ export async function saveTableIfInsideCacheContext<T extends AnyMySqlTable>(
89
90
  */
90
91
  export async function saveQueryLocalCacheQuery<
91
92
  T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>,
92
- >(query: T, rows: unknown[]): Promise<void> {
93
+ >(query: T, rows: unknown[], options: ForgeSqlOrmOptions): Promise<void> {
93
94
  const context = localCacheApplicationContext.getStore();
94
95
  if (context) {
95
96
  if (!context.cache) {
@@ -101,6 +102,12 @@ export async function saveQueryLocalCacheQuery<
101
102
  sql: sql.toSQL().sql.toLowerCase(),
102
103
  data: rows,
103
104
  };
105
+ if (options.logRawSqlQuery) {
106
+ const q = sql.toSQL();
107
+ console.debug(
108
+ `[forge-sql-orm][local-cache][SAVE] Stored result in cache. sql="${q.sql}", params=${JSON.stringify(q.params)}`,
109
+ );
110
+ }
104
111
  }
105
112
  }
106
113
 
@@ -109,6 +116,7 @@ export async function saveQueryLocalCacheQuery<
109
116
  * This function checks if a query result is already cached in memory.
110
117
  *
111
118
  * @param query - The Drizzle query to check for cached results
119
+ * @param options - Option Property
112
120
  * @returns Promise that resolves to cached data if found, undefined otherwise
113
121
  *
114
122
  * @example
@@ -123,7 +131,7 @@ export async function saveQueryLocalCacheQuery<
123
131
  */
124
132
  export async function getQueryLocalCacheQuery<
125
133
  T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>,
126
- >(query: T): Promise<unknown[] | undefined> {
134
+ >(query: T, options: ForgeSqlOrmOptions): Promise<unknown[] | undefined> {
127
135
  const context = localCacheApplicationContext.getStore();
128
136
  if (context) {
129
137
  if (!context.cache) {
@@ -132,14 +140,18 @@ export async function getQueryLocalCacheQuery<
132
140
  const sql = query as { toSQL: () => Query };
133
141
  const key = hashKey(sql.toSQL());
134
142
  if (context.cache[key] && context.cache[key].sql === sql.toSQL().sql.toLowerCase()) {
143
+ if (options.logRawSqlQuery) {
144
+ const q = sql.toSQL();
145
+ console.debug(
146
+ `[forge-sql-orm][local-cache][HIT] Returned cached result. sql="${q.sql}", params=${JSON.stringify(q.params)}`,
147
+ );
148
+ }
135
149
  return context.cache[key].data;
136
150
  }
137
151
  }
138
152
  return undefined;
139
153
  }
140
154
 
141
-
142
-
143
155
  /**
144
156
  * Evicts cached queries from the local cache context that involve the specified table.
145
157
  * This function removes cached query results that contain the given table name.
@@ -287,7 +287,9 @@ export async function clearExpiredCache(options: ForgeSqlOrmOptions): Promise<vo
287
287
  );
288
288
  } finally {
289
289
  const duration = DateTime.now().toSeconds() - startTime.toSeconds();
290
- console.info(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
290
+ if (options?.logRawSqlQuery) {
291
+ console.debug(`Cleared ${totalRecords} expired cache records in ${duration} seconds`);
292
+ }
291
293
  }
292
294
  }
293
295
 
@@ -13,27 +13,22 @@ export const forgeDriver = async (
13
13
  insertId?: number;
14
14
  affectedRows?: number;
15
15
  }> => {
16
- try {
17
- if (method == "execute") {
18
- const sqlStatement = sql.prepare<UpdateQueryResponse>(query);
19
- if (params) {
20
- sqlStatement.bindParams(...params);
21
- }
22
- const updateQueryResponseResults = await sqlStatement.execute();
23
- let result = updateQueryResponseResults.rows as any;
24
- return { ...result, rows: [result] };
25
- } else {
26
- const sqlStatement = await sql.prepare<unknown>(query);
27
- if (params) {
28
- await sqlStatement.bindParams(...params);
29
- }
30
- const result = (await sqlStatement.execute()) as ForgeSQLResult;
31
- let rows;
32
- rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));
33
- return { rows: rows };
16
+ if (method == "execute") {
17
+ const sqlStatement = sql.prepare<UpdateQueryResponse>(query);
18
+ if (params) {
19
+ sqlStatement.bindParams(...params);
34
20
  }
35
- } catch (error) {
36
- console.error("SQL Error:", JSON.stringify(error));
37
- throw error;
21
+ const updateQueryResponseResults = await sqlStatement.execute();
22
+ let result = updateQueryResponseResults.rows as any;
23
+ return { ...result, rows: [result] };
24
+ } else {
25
+ const sqlStatement = await sql.prepare<unknown>(query);
26
+ if (params) {
27
+ await sqlStatement.bindParams(...params);
28
+ }
29
+ const result = (await sqlStatement.execute()) as ForgeSQLResult;
30
+ let rows;
31
+ rows = (result.rows as any[]).map((r) => Object.values(r as Record<string, unknown>));
32
+ return { rows: rows };
38
33
  }
39
34
  };
@@ -19,9 +19,16 @@ export function createForgeDriverProxy(options?: SqlHints, logRawSqlQuery?: bool
19
19
  const modifiedQuery = injectSqlHints(query, options);
20
20
 
21
21
  if (options && logRawSqlQuery && modifiedQuery !== query) {
22
- console.warn("modified query: " + modifiedQuery);
22
+ console.debug("injected Hints: " + modifiedQuery);
23
+ }
24
+ try {
25
+ // Call the original forgeDriver with the modified query
26
+ return await forgeDriver(modifiedQuery, params, method);
27
+ } catch (error) {
28
+ if (logRawSqlQuery) {
29
+ console.debug("SQL Error:", JSON.stringify(error));
30
+ }
31
+ throw error;
23
32
  }
24
- // Call the original forgeDriver with the modified query
25
- return forgeDriver(modifiedQuery, params, method);
26
33
  };
27
34
  }