forge-sql-orm 2.1.5 → 2.1.7

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 (41) hide show
  1. package/README.md +135 -53
  2. package/dist/ForgeSQLORM.js +572 -231
  3. package/dist/ForgeSQLORM.js.map +1 -1
  4. package/dist/ForgeSQLORM.mjs +572 -231
  5. package/dist/ForgeSQLORM.mjs.map +1 -1
  6. package/dist/core/ForgeSQLORM.d.ts +91 -3
  7. package/dist/core/ForgeSQLORM.d.ts.map +1 -1
  8. package/dist/core/ForgeSQLQueryBuilder.d.ts +89 -2
  9. package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
  10. package/dist/core/SystemTables.d.ts +3654 -0
  11. package/dist/core/SystemTables.d.ts.map +1 -1
  12. package/dist/lib/drizzle/extensions/additionalActions.d.ts +2 -2
  13. package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
  14. package/dist/utils/forgeDriver.d.ts +61 -14
  15. package/dist/utils/forgeDriver.d.ts.map +1 -1
  16. package/dist/utils/metadataContextUtils.d.ts +1 -1
  17. package/dist/utils/metadataContextUtils.d.ts.map +1 -1
  18. package/dist/utils/requestTypeContextUtils.d.ts +8 -0
  19. package/dist/utils/requestTypeContextUtils.d.ts.map +1 -0
  20. package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts +90 -65
  21. package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts.map +1 -1
  22. package/package.json +9 -9
  23. package/src/core/ForgeSQLCrudOperations.ts +3 -3
  24. package/src/core/ForgeSQLORM.ts +334 -124
  25. package/src/core/ForgeSQLQueryBuilder.ts +116 -20
  26. package/src/core/ForgeSQLSelectOperations.ts +2 -2
  27. package/src/core/SystemTables.ts +16 -0
  28. package/src/lib/drizzle/extensions/additionalActions.ts +24 -22
  29. package/src/utils/cacheContextUtils.ts +2 -2
  30. package/src/utils/cacheUtils.ts +12 -12
  31. package/src/utils/forgeDriver.ts +219 -40
  32. package/src/utils/forgeDriverProxy.ts +2 -2
  33. package/src/utils/metadataContextUtils.ts +11 -13
  34. package/src/utils/requestTypeContextUtils.ts +11 -0
  35. package/src/utils/sqlUtils.ts +1 -1
  36. package/src/webtriggers/applyMigrationsWebTrigger.ts +9 -9
  37. package/src/webtriggers/clearCacheSchedulerTrigger.ts +1 -1
  38. package/src/webtriggers/dropMigrationWebTrigger.ts +2 -2
  39. package/src/webtriggers/dropTablesMigrationWebTrigger.ts +2 -2
  40. package/src/webtriggers/fetchSchemaWebTrigger.ts +1 -1
  41. package/src/webtriggers/topSlowestStatementLastHourTrigger.ts +511 -308
@@ -39,7 +39,9 @@ import { clearTablesCache } from "../utils/cacheUtils";
39
39
  import { SQLWrapper } from "drizzle-orm/sql/sql";
40
40
  import { WithSubquery } from "drizzle-orm/subquery";
41
41
  import { ForgeSQLMetadata } from "../utils/forgeDriver";
42
- import {getLastestMetadata, metadataQueryContext} from "../utils/metadataContextUtils";
42
+ import { getLastestMetadata, metadataQueryContext } from "../utils/metadataContextUtils";
43
+ import { operationTypeQueryContext } from "../utils/requestTypeContextUtils";
44
+ import type { MySqlQueryResultKind } from "drizzle-orm/mysql-core/session";
43
45
 
44
46
  /**
45
47
  * Implementation of ForgeSQLORM that uses Drizzle ORM for query building.
@@ -47,100 +49,113 @@ import {getLastestMetadata, metadataQueryContext} from "../utils/metadataContext
47
49
  * to use Drizzle's query builder while executing queries through Forge SQL.
48
50
  */
49
51
  class ForgeSQLORMImpl implements ForgeSqlOperation {
50
- private static instance: ForgeSQLORMImpl | null = null;
51
- private readonly drizzle: MySqlRemoteDatabase<any> & {
52
- selectAliased: SelectAliasedType;
53
- selectAliasedDistinct: SelectAliasedDistinctType;
54
- selectAliasedCacheable: SelectAliasedCacheableType;
55
- selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;
56
- insertWithCacheContext: InsertAndEvictCacheType;
57
- insertAndEvictCache: InsertAndEvictCacheType;
58
- updateAndEvictCache: UpdateAndEvictCacheType;
59
- updateWithCacheContext: UpdateAndEvictCacheType;
60
- deleteAndEvictCache: DeleteAndEvictCacheType;
61
- deleteWithCacheContext: DeleteAndEvictCacheType;
62
- };
63
- private readonly crudOperations: VerioningModificationForgeSQL;
64
- private readonly fetchOperations: SchemaSqlForgeSql;
65
- private readonly analyzeOperations: SchemaAnalyzeForgeSql;
66
- private readonly cacheOperations: ForgeSQLCacheOperations;
67
- private readonly options: ForgeSqlOrmOptions;
52
+ private static instance: ForgeSQLORMImpl | null = null;
53
+ private readonly drizzle: MySqlRemoteDatabase<any> & {
54
+ selectAliased: SelectAliasedType;
55
+ selectAliasedDistinct: SelectAliasedDistinctType;
56
+ selectAliasedCacheable: SelectAliasedCacheableType;
57
+ selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;
58
+ insertWithCacheContext: InsertAndEvictCacheType;
59
+ insertAndEvictCache: InsertAndEvictCacheType;
60
+ updateAndEvictCache: UpdateAndEvictCacheType;
61
+ updateWithCacheContext: UpdateAndEvictCacheType;
62
+ deleteAndEvictCache: DeleteAndEvictCacheType;
63
+ deleteWithCacheContext: DeleteAndEvictCacheType;
64
+ };
65
+ private readonly crudOperations: VerioningModificationForgeSQL;
66
+ private readonly fetchOperations: SchemaSqlForgeSql;
67
+ private readonly analyzeOperations: SchemaAnalyzeForgeSql;
68
+ private readonly cacheOperations: ForgeSQLCacheOperations;
69
+ private readonly options: ForgeSqlOrmOptions;
70
+
71
+ /**
72
+ * Private constructor to enforce singleton behavior.
73
+ * @param options - Options for configuring ForgeSQL ORM behavior.
74
+ */
75
+ private constructor(options?: ForgeSqlOrmOptions) {
76
+ try {
77
+ const newOptions: ForgeSqlOrmOptions = options ?? {
78
+ logRawSqlQuery: false,
79
+ logCache: false,
80
+ disableOptimisticLocking: false,
81
+ cacheWrapTable: true,
82
+ cacheTTL: 120,
83
+ cacheEntityQueryName: "sql",
84
+ cacheEntityExpirationName: "expiration",
85
+ cacheEntityDataName: "data",
86
+ };
87
+ this.options = newOptions;
88
+ if (newOptions.logRawSqlQuery) {
89
+ // eslint-disable-next-line no-console
90
+ console.debug("Initializing ForgeSQLORM...");
91
+ }
92
+ // Initialize Drizzle instance with our custom driver
93
+ const proxiedDriver = createForgeDriverProxy(newOptions.hints, newOptions.logRawSqlQuery);
94
+ this.drizzle = patchDbWithSelectAliased(
95
+ drizzle(proxiedDriver, { logger: newOptions.logRawSqlQuery }),
96
+ newOptions,
97
+ );
98
+ this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);
99
+ this.fetchOperations = new ForgeSQLSelectOperations(newOptions);
100
+ this.analyzeOperations = new ForgeSQLAnalyseOperation(this);
101
+ this.cacheOperations = new ForgeSQLCacheOperations(newOptions, this);
102
+ } catch (error) {
103
+ // eslint-disable-next-line no-console
104
+ console.error("ForgeSQLORM initialization failed:", error);
105
+ throw error;
106
+ }
107
+ }
68
108
 
69
- /**
70
- * Private constructor to enforce singleton behavior.
71
- * @param options - Options for configuring ForgeSQL ORM behavior.
72
- */
73
- private constructor(options?: ForgeSqlOrmOptions) {
109
+ /**
110
+ * Executes a query and provides access to execution metadata.
111
+ * This method allows you to capture detailed information about query execution
112
+ * including database execution time, response size, and Forge SQL metadata.
113
+ *
114
+ * @template T - The return type of the query
115
+ * @param query - A function that returns a Promise with the query result
116
+ * @param onMetadata - Callback function that receives execution metadata
117
+ * @returns Promise with the query result
118
+ * @example
119
+ * ```typescript
120
+ * const result = await forgeSQL.executeWithMetadata(
121
+ * async () => await forgeSQL.select().from(users).where(eq(users.id, 1)),
122
+ * (dbTime, responseSize, metadata) => {
123
+ * console.log(`DB execution time: ${dbTime}ms`);
124
+ * console.log(`Response size: ${responseSize} bytes`);
125
+ * console.log('Forge metadata:', metadata);
126
+ * }
127
+ * );
128
+ * ```
129
+ */
130
+ async executeWithMetadata<T>(
131
+ query: () => Promise<T>,
132
+ onMetadata: (
133
+ totalDbExecutionTime: number,
134
+ totalResponseSize: number,
135
+ forgeMetadata: ForgeSQLMetadata,
136
+ ) => Promise<void> | void,
137
+ ): Promise<T> {
138
+ return metadataQueryContext.run(
139
+ {
140
+ totalDbExecutionTime: 0,
141
+ totalResponseSize: 0,
142
+ },
143
+ async () => {
74
144
  try {
75
- const newOptions: ForgeSqlOrmOptions = options ?? {
76
- logRawSqlQuery: false,
77
- logCache: false,
78
- disableOptimisticLocking: false,
79
- cacheWrapTable: true,
80
- cacheTTL: 120,
81
- cacheEntityQueryName: "sql",
82
- cacheEntityExpirationName: "expiration",
83
- cacheEntityDataName: "data",
84
- };
85
- this.options = newOptions;
86
- if (newOptions.logRawSqlQuery) {
87
- // eslint-disable-next-line no-console
88
- console.debug("Initializing ForgeSQLORM...");
89
- }
90
- // Initialize Drizzle instance with our custom driver
91
- const proxiedDriver = createForgeDriverProxy(newOptions.hints, newOptions.logRawSqlQuery);
92
- this.drizzle = patchDbWithSelectAliased(
93
- drizzle(proxiedDriver, {logger: newOptions.logRawSqlQuery}),
94
- newOptions,
145
+ return await query();
146
+ } finally {
147
+ const metadata = await getLastestMetadata();
148
+ if (metadata && metadata.lastMetadata) {
149
+ await onMetadata(
150
+ metadata.totalDbExecutionTime,
151
+ metadata.totalResponseSize,
152
+ metadata.lastMetadata,
95
153
  );
96
- this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);
97
- this.fetchOperations = new ForgeSQLSelectOperations(newOptions);
98
- this.analyzeOperations = new ForgeSQLAnalyseOperation(this);
99
- this.cacheOperations = new ForgeSQLCacheOperations(newOptions, this);
100
- } catch (error) {
101
- // eslint-disable-next-line no-console
102
- console.error("ForgeSQLORM initialization failed:", error);
103
- throw error;
154
+ }
104
155
  }
105
- }
106
-
107
- /**
108
- * Executes a query and provides access to execution metadata.
109
- * This method allows you to capture detailed information about query execution
110
- * including database execution time, response size, and Forge SQL metadata.
111
- *
112
- * @template T - The return type of the query
113
- * @param query - A function that returns a Promise with the query result
114
- * @param onMetadata - Callback function that receives execution metadata
115
- * @returns Promise with the query result
116
- * @example
117
- * ```typescript
118
- * const result = await forgeSQL.executeWithMetadata(
119
- * async () => await forgeSQL.select().from(users).where(eq(users.id, 1)),
120
- * (dbTime, responseSize, metadata) => {
121
- * console.log(`DB execution time: ${dbTime}ms`);
122
- * console.log(`Response size: ${responseSize} bytes`);
123
- * console.log('Forge metadata:', metadata);
124
- * }
125
- * );
126
- * ```
127
- */
128
- async executeWithMetadata<T>(query: () => Promise<T>, onMetadata: (totalDbExecutionTime: number, totalResponseSize: number, forgeMetadata: ForgeSQLMetadata) => Promise<void> | void): Promise<T> {
129
- return metadataQueryContext.run({
130
- totalDbExecutionTime: 0,
131
- totalResponseSize: 0,
132
- }, async ()=>{
133
- try {
134
- return await query();
135
- } finally {
136
- const metadata = await getLastestMetadata();
137
- if (metadata && metadata.lastMetadata){
138
- await onMetadata(metadata.totalDbExecutionTime, metadata.totalResponseSize, metadata.lastMetadata)
139
- }
140
- }
141
-
142
- })
143
- }
156
+ },
157
+ );
158
+ }
144
159
 
145
160
  /**
146
161
  * Executes operations within a cache context that collects cache eviction events.
@@ -574,8 +589,101 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
574
589
  * const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
575
590
  * ```
576
591
  */
577
- execute(query: SQLWrapper | string) {
578
- return this.drizzle.executeQuery(query);
592
+ execute<T>(query: SQLWrapper | string) {
593
+ return this.drizzle.executeQuery<T>(query);
594
+ }
595
+
596
+ /**
597
+ * Executes a Data Definition Language (DDL) SQL query.
598
+ * DDL operations include CREATE, ALTER, DROP, TRUNCATE, and other schema modification statements.
599
+ *
600
+ * This method is specifically designed for DDL operations and provides:
601
+ * - Proper operation type context for DDL queries
602
+ * - No caching (DDL operations should not be cached)
603
+ * - Direct execution without query optimization
604
+ *
605
+ * @template T - The expected return type of the query result
606
+ * @param query - The DDL SQL query to execute (SQLWrapper or string)
607
+ * @returns Promise with query results
608
+ * @throws {Error} If the DDL operation fails
609
+ *
610
+ * @example
611
+ * ```typescript
612
+ * // Create a new table
613
+ * await forgeSQL.executeDDL(`
614
+ * CREATE TABLE users (
615
+ * id INT PRIMARY KEY AUTO_INCREMENT,
616
+ * name VARCHAR(255) NOT NULL,
617
+ * email VARCHAR(255) UNIQUE
618
+ * )
619
+ * `);
620
+ *
621
+ * // Alter table structure
622
+ * await forgeSQL.executeDDL(sql`
623
+ * ALTER TABLE users
624
+ * ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
625
+ * `);
626
+ *
627
+ * // Drop a table
628
+ * await forgeSQL.executeDDL("DROP TABLE IF EXISTS old_users");
629
+ * ```
630
+ */
631
+ async executeDDL<T>(query: SQLWrapper | string) {
632
+ return this.executeDDLActions(async () => this.drizzle.executeQuery<T>(query));
633
+ }
634
+
635
+ /**
636
+ * Executes a series of actions within a DDL operation context.
637
+ * This method provides a way to execute regular SQL queries that should be treated
638
+ * as DDL operations, ensuring proper operation type context for performance monitoring.
639
+ *
640
+ * This method is useful for:
641
+ * - Executing regular SQL queries in DDL context for monitoring purposes
642
+ * - Wrapping non-DDL operations that should be treated as DDL for analysis
643
+ * - Ensuring proper operation type context for complex workflows
644
+ * - Maintaining DDL operation context across multiple function calls
645
+ *
646
+ * @template T - The return type of the actions function
647
+ * @param actions - Function containing SQL operations to execute in DDL context
648
+ * @returns Promise that resolves to the return value of the actions function
649
+ *
650
+ * @example
651
+ * ```typescript
652
+ * // Execute regular SQL queries in DDL context for monitoring
653
+ * await forgeSQL.executeDDLActions(async () => {
654
+ * const slowQueries = await forgeSQL.execute(`
655
+ * SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY
656
+ * WHERE AVG_LATENCY > 1000000
657
+ * `);
658
+ * return slowQueries;
659
+ * });
660
+ *
661
+ * // Execute complex analysis queries in DDL context
662
+ * const result = await forgeSQL.executeDDLActions(async () => {
663
+ * const tableInfo = await forgeSQL.execute("SHOW TABLES");
664
+ * const performanceData = await forgeSQL.execute(`
665
+ * SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY
666
+ * WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
667
+ * `);
668
+ * return { tableInfo, performanceData };
669
+ * });
670
+ *
671
+ * // Execute monitoring queries with error handling
672
+ * try {
673
+ * await forgeSQL.executeDDLActions(async () => {
674
+ * const metrics = await forgeSQL.execute(`
675
+ * SELECT COUNT(*) as query_count
676
+ * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY
677
+ * `);
678
+ * console.log(`Total queries: ${metrics[0].query_count}`);
679
+ * });
680
+ * } catch (error) {
681
+ * console.error("Monitoring query failed:", error);
682
+ * }
683
+ * ```
684
+ */
685
+ async executeDDLActions<T>(actions: () => Promise<T>): Promise<T> {
686
+ return operationTypeQueryContext.run({ operationType: "DDL" }, async () => actions());
579
687
  }
580
688
 
581
689
  /**
@@ -596,8 +704,8 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
596
704
  * const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
597
705
  * ```
598
706
  */
599
- executeCacheable(query: SQLWrapper | string, cacheTtl?: number) {
600
- return this.drizzle.executeQueryCacheable(query, cacheTtl);
707
+ executeCacheable<T>(query: SQLWrapper | string, cacheTtl?: number) {
708
+ return this.drizzle.executeQueryCacheable<T>(query, cacheTtl);
601
709
  }
602
710
 
603
711
  /**
@@ -653,30 +761,37 @@ class ForgeSQLORM implements ForgeSqlOperation {
653
761
  this.ormInstance = ForgeSQLORMImpl.getInstance(options);
654
762
  }
655
763
 
656
- /**
657
- * Executes a query and provides access to execution metadata.
658
- * This method allows you to capture detailed information about query execution
659
- * including database execution time, response size, and Forge SQL metadata.
660
- *
661
- * @template T - The return type of the query
662
- * @param query - A function that returns a Promise with the query result
663
- * @param onMetadata - Callback function that receives execution metadata
664
- * @returns Promise with the query result
665
- * @example
666
- * ```typescript
667
- * const result = await forgeSQL.executeWithMetadata(
668
- * async () => await forgeSQL.select().from(users).where(eq(users.id, 1)),
669
- * (dbTime, responseSize, metadata) => {
670
- * console.log(`DB execution time: ${dbTime}ms`);
671
- * console.log(`Response size: ${responseSize} bytes`);
672
- * console.log('Forge metadata:', metadata);
673
- * }
674
- * );
675
- * ```
676
- */
677
- async executeWithMetadata<T>(query: () => Promise<T>, onMetadata: (totalDbExecutionTime: number, totalResponseSize: number, forgeMetadata: ForgeSQLMetadata) => Promise<void> | void): Promise<T> {
678
- return this.ormInstance.executeWithMetadata(query, onMetadata);
679
- }
764
+ /**
765
+ * Executes a query and provides access to execution metadata.
766
+ * This method allows you to capture detailed information about query execution
767
+ * including database execution time, response size, and Forge SQL metadata.
768
+ *
769
+ * @template T - The return type of the query
770
+ * @param query - A function that returns a Promise with the query result
771
+ * @param onMetadata - Callback function that receives execution metadata
772
+ * @returns Promise with the query result
773
+ * @example
774
+ * ```typescript
775
+ * const result = await forgeSQL.executeWithMetadata(
776
+ * async () => await forgeSQL.select().from(users).where(eq(users.id, 1)),
777
+ * (dbTime, responseSize, metadata) => {
778
+ * console.log(`DB execution time: ${dbTime}ms`);
779
+ * console.log(`Response size: ${responseSize} bytes`);
780
+ * console.log('Forge metadata:', metadata);
781
+ * }
782
+ * );
783
+ * ```
784
+ */
785
+ async executeWithMetadata<T>(
786
+ query: () => Promise<T>,
787
+ onMetadata: (
788
+ totalDbExecutionTime: number,
789
+ totalResponseSize: number,
790
+ forgeMetadata: ForgeSQLMetadata,
791
+ ) => Promise<void> | void,
792
+ ): Promise<T> {
793
+ return this.ormInstance.executeWithMetadata(query, onMetadata);
794
+ }
680
795
 
681
796
  selectCacheable<TSelection extends SelectedFields>(
682
797
  fields: TSelection,
@@ -977,8 +1092,103 @@ class ForgeSQLORM implements ForgeSqlOperation {
977
1092
  * const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
978
1093
  * ```
979
1094
  */
980
- execute(query: SQLWrapper | string) {
981
- return this.ormInstance.getDrizzleQueryBuilder().executeQuery(query);
1095
+ execute<T>(
1096
+ query: SQLWrapper | string,
1097
+ ): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, T>> {
1098
+ return this.ormInstance.execute(query);
1099
+ }
1100
+
1101
+ /**
1102
+ * Executes a Data Definition Language (DDL) SQL query.
1103
+ * DDL operations include CREATE, ALTER, DROP, TRUNCATE, and other schema modification statements.
1104
+ *
1105
+ * This method is specifically designed for DDL operations and provides:
1106
+ * - Proper operation type context for DDL queries
1107
+ * - No caching (DDL operations should not be cached)
1108
+ * - Direct execution without query optimization
1109
+ *
1110
+ * @template T - The expected return type of the query result
1111
+ * @param query - The DDL SQL query to execute (SQLWrapper or string)
1112
+ * @returns Promise with query results
1113
+ * @throws {Error} If the DDL operation fails
1114
+ *
1115
+ * @example
1116
+ * ```typescript
1117
+ * // Create a new table
1118
+ * await forgeSQL.executeDDL(`
1119
+ * CREATE TABLE users (
1120
+ * id INT PRIMARY KEY AUTO_INCREMENT,
1121
+ * name VARCHAR(255) NOT NULL,
1122
+ * email VARCHAR(255) UNIQUE
1123
+ * )
1124
+ * `);
1125
+ *
1126
+ * // Alter table structure
1127
+ * await forgeSQL.executeDDL(sql`
1128
+ * ALTER TABLE users
1129
+ * ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
1130
+ * `);
1131
+ *
1132
+ * // Drop a table
1133
+ * await forgeSQL.executeDDL("DROP TABLE IF EXISTS old_users");
1134
+ * ```
1135
+ */
1136
+ executeDDL(query: SQLWrapper | string) {
1137
+ return this.ormInstance.executeDDL(query);
1138
+ }
1139
+
1140
+ /**
1141
+ * Executes a series of actions within a DDL operation context.
1142
+ * This method provides a way to execute regular SQL queries that should be treated
1143
+ * as DDL operations, ensuring proper operation type context for performance monitoring.
1144
+ *
1145
+ * This method is useful for:
1146
+ * - Executing regular SQL queries in DDL context for monitoring purposes
1147
+ * - Wrapping non-DDL operations that should be treated as DDL for analysis
1148
+ * - Ensuring proper operation type context for complex workflows
1149
+ * - Maintaining DDL operation context across multiple function calls
1150
+ *
1151
+ * @template T - The return type of the actions function
1152
+ * @param actions - Function containing SQL operations to execute in DDL context
1153
+ * @returns Promise that resolves to the return value of the actions function
1154
+ *
1155
+ * @example
1156
+ * ```typescript
1157
+ * // Execute regular SQL queries in DDL context for monitoring
1158
+ * await forgeSQL.executeDDLActions(async () => {
1159
+ * const slowQueries = await forgeSQL.execute(`
1160
+ * SELECT * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY
1161
+ * WHERE AVG_LATENCY > 1000000
1162
+ * `);
1163
+ * return slowQueries;
1164
+ * });
1165
+ *
1166
+ * // Execute complex analysis queries in DDL context
1167
+ * const result = await forgeSQL.executeDDLActions(async () => {
1168
+ * const tableInfo = await forgeSQL.execute("SHOW TABLES");
1169
+ * const performanceData = await forgeSQL.execute(`
1170
+ * SELECT * FROM INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY_HISTORY
1171
+ * WHERE SUMMARY_END_TIME > DATE_SUB(NOW(), INTERVAL 1 HOUR)
1172
+ * `);
1173
+ * return { tableInfo, performanceData };
1174
+ * });
1175
+ *
1176
+ * // Execute monitoring queries with error handling
1177
+ * try {
1178
+ * await forgeSQL.executeDDLActions(async () => {
1179
+ * const metrics = await forgeSQL.execute(`
1180
+ * SELECT COUNT(*) as query_count
1181
+ * FROM INFORMATION_SCHEMA.STATEMENTS_SUMMARY
1182
+ * `);
1183
+ * console.log(`Total queries: ${metrics[0].query_count}`);
1184
+ * });
1185
+ * } catch (error) {
1186
+ * console.error("Monitoring query failed:", error);
1187
+ * }
1188
+ * ```
1189
+ */
1190
+ executeDDLActions<T>(actions: () => Promise<T>): Promise<T> {
1191
+ return this.ormInstance.executeDDLActions(actions);
982
1192
  }
983
1193
 
984
1194
  /**
@@ -1000,7 +1210,7 @@ class ForgeSQLORM implements ForgeSqlOperation {
1000
1210
  * ```
1001
1211
  */
1002
1212
  executeCacheable(query: SQLWrapper | string, cacheTtl?: number) {
1003
- return this.ormInstance.getDrizzleQueryBuilder().executeQueryCacheable(query, cacheTtl);
1213
+ return this.ormInstance.executeCacheable(query, cacheTtl);
1004
1214
  }
1005
1215
 
1006
1216
  /**
@@ -1011,7 +1221,7 @@ class ForgeSQLORM implements ForgeSqlOperation {
1011
1221
  * @example
1012
1222
  * ```typescript
1013
1223
  * const withQuery = forgeSQL.$with('userStats').as(
1014
- * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
1224
+ * forgeSQL.getDrizzleQueryBuilder().select({ userId: users.id, count: sql<number>`count(*)` })
1015
1225
  * .from(users)
1016
1226
  * .groupBy(users.id)
1017
1227
  * );
@@ -1030,7 +1240,7 @@ class ForgeSQLORM implements ForgeSqlOperation {
1030
1240
  * @example
1031
1241
  * ```typescript
1032
1242
  * const withQuery = forgeSQL.$with('userStats').as(
1033
- * forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
1243
+ * forgeSQL.getDrizzleQueryBuilder().select({ userId: users.id, count: sql<number>`count(*)` })
1034
1244
  * .from(users)
1035
1245
  * .groupBy(users.id)
1036
1246
  * );