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.
- package/README.md +135 -53
- package/dist/ForgeSQLORM.js +572 -231
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +572 -231
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts +91 -3
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +89 -2
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/core/SystemTables.d.ts +3654 -0
- package/dist/core/SystemTables.d.ts.map +1 -1
- package/dist/lib/drizzle/extensions/additionalActions.d.ts +2 -2
- package/dist/lib/drizzle/extensions/additionalActions.d.ts.map +1 -1
- package/dist/utils/forgeDriver.d.ts +61 -14
- package/dist/utils/forgeDriver.d.ts.map +1 -1
- package/dist/utils/metadataContextUtils.d.ts +1 -1
- package/dist/utils/metadataContextUtils.d.ts.map +1 -1
- package/dist/utils/requestTypeContextUtils.d.ts +8 -0
- package/dist/utils/requestTypeContextUtils.d.ts.map +1 -0
- package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts +90 -65
- package/dist/webtriggers/topSlowestStatementLastHourTrigger.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/core/ForgeSQLCrudOperations.ts +3 -3
- package/src/core/ForgeSQLORM.ts +334 -124
- package/src/core/ForgeSQLQueryBuilder.ts +116 -20
- package/src/core/ForgeSQLSelectOperations.ts +2 -2
- package/src/core/SystemTables.ts +16 -0
- package/src/lib/drizzle/extensions/additionalActions.ts +24 -22
- package/src/utils/cacheContextUtils.ts +2 -2
- package/src/utils/cacheUtils.ts +12 -12
- package/src/utils/forgeDriver.ts +219 -40
- package/src/utils/forgeDriverProxy.ts +2 -2
- package/src/utils/metadataContextUtils.ts +11 -13
- package/src/utils/requestTypeContextUtils.ts +11 -0
- package/src/utils/sqlUtils.ts +1 -1
- package/src/webtriggers/applyMigrationsWebTrigger.ts +9 -9
- package/src/webtriggers/clearCacheSchedulerTrigger.ts +1 -1
- package/src/webtriggers/dropMigrationWebTrigger.ts +2 -2
- package/src/webtriggers/dropTablesMigrationWebTrigger.ts +2 -2
- package/src/webtriggers/fetchSchemaWebTrigger.ts +1 -1
- package/src/webtriggers/topSlowestStatementLastHourTrigger.ts +511 -308
package/src/core/ForgeSQLORM.ts
CHANGED
|
@@ -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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
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
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
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(
|
|
981
|
-
|
|
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.
|
|
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
|
* );
|