forge-sql-orm 2.1.0 → 2.1.2
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 +424 -34
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +425 -35
- 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 +149 -2
- 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 +4 -2
- 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 +319 -13
- package/src/core/ForgeSQLQueryBuilder.ts +218 -0
- package/src/lib/drizzle/extensions/additionalActions.ts +387 -34
- package/src/lib/drizzle/extensions/types.d.ts +36 -0
- package/src/utils/cacheContextUtils.ts +16 -2
- package/src/utils/sqlUtils.ts +34 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-sql-orm",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Drizzle ORM integration for Atlassian @forge/sql. Provides a custom driver, schema migration, two levels of caching (local and global via @forge/kvs), optimistic locking, and query analysis.",
|
|
5
5
|
"main": "dist/ForgeSQLORM.js",
|
|
6
6
|
"module": "dist/ForgeSQLORM.mjs",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@eslint/js": "^9.35.0",
|
|
36
36
|
"@types/luxon": "^3.7.1",
|
|
37
|
-
"@types/node": "^24.
|
|
37
|
+
"@types/node": "^24.4.0",
|
|
38
38
|
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
|
39
39
|
"@typescript-eslint/parser": "^8.43.0",
|
|
40
40
|
"@vitest/coverage-v8": "^3.2.4",
|
package/src/core/ForgeSQLORM.ts
CHANGED
|
@@ -36,6 +36,8 @@ import {
|
|
|
36
36
|
} from "drizzle-orm/mysql-core/query-builders";
|
|
37
37
|
import { cacheApplicationContext, localCacheApplicationContext } from "../utils/cacheContextUtils";
|
|
38
38
|
import { clearTablesCache } from "../utils/cacheUtils";
|
|
39
|
+
import { SQLWrapper } from "drizzle-orm/sql/sql";
|
|
40
|
+
import { WithSubquery } from "drizzle-orm/subquery";
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* Implementation of ForgeSQLORM that uses Drizzle ORM for query building.
|
|
@@ -142,16 +144,19 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
142
144
|
async executeWithCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {
|
|
143
145
|
return await this.executeWithLocalCacheContextAndReturnValue(
|
|
144
146
|
async () =>
|
|
145
|
-
await cacheApplicationContext.run(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
147
|
+
await cacheApplicationContext.run(
|
|
148
|
+
cacheApplicationContext.getStore() ?? { tables: new Set<string>() },
|
|
149
|
+
async () => {
|
|
150
|
+
try {
|
|
151
|
+
return await cacheContext();
|
|
152
|
+
} finally {
|
|
153
|
+
await clearTablesCache(
|
|
154
|
+
Array.from(cacheApplicationContext.getStore()?.tables ?? []),
|
|
155
|
+
this.options,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
),
|
|
155
160
|
);
|
|
156
161
|
}
|
|
157
162
|
/**
|
|
@@ -162,9 +167,12 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
162
167
|
* @returns Promise that resolves to the return value of the cacheContext function
|
|
163
168
|
*/
|
|
164
169
|
async executeWithLocalCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T> {
|
|
165
|
-
return await localCacheApplicationContext.run(
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
return await localCacheApplicationContext.run(
|
|
171
|
+
localCacheApplicationContext.getStore() ?? { cache: {} },
|
|
172
|
+
async () => {
|
|
173
|
+
return await cacheContext();
|
|
174
|
+
},
|
|
175
|
+
);
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
/**
|
|
@@ -440,6 +448,155 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
440
448
|
}
|
|
441
449
|
return this.drizzle.selectAliasedDistinctCacheable(fields, cacheTTL);
|
|
442
450
|
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
454
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
455
|
+
*
|
|
456
|
+
* @template T - The type of the table
|
|
457
|
+
* @param table - The table to select from
|
|
458
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
459
|
+
* @example
|
|
460
|
+
* ```typescript
|
|
461
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
462
|
+
* ```
|
|
463
|
+
*/
|
|
464
|
+
selectFrom<T extends MySqlTable>(table: T) {
|
|
465
|
+
return this.drizzle.selectFrom(table);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
470
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
471
|
+
*
|
|
472
|
+
* @template T - The type of the table
|
|
473
|
+
* @param table - The table to select from
|
|
474
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
475
|
+
* @example
|
|
476
|
+
* ```typescript
|
|
477
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
selectDistinctFrom<T extends MySqlTable>(table: T) {
|
|
481
|
+
return this.drizzle.selectDistinctFrom(table);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
486
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
487
|
+
*
|
|
488
|
+
* @template T - The type of the table
|
|
489
|
+
* @param table - The table to select from
|
|
490
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
491
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
492
|
+
* @example
|
|
493
|
+
* ```typescript
|
|
494
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
selectCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {
|
|
498
|
+
return this.drizzle.selectFromCacheable(table, cacheTTL);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
503
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
504
|
+
*
|
|
505
|
+
* @template T - The type of the table
|
|
506
|
+
* @param table - The table to select from
|
|
507
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
508
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
selectDistinctCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {
|
|
515
|
+
return this.drizzle.selectDistinctFromCacheable(table, cacheTTL);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Executes a raw SQL query with local cache support.
|
|
520
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
521
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
522
|
+
*
|
|
523
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
524
|
+
* @returns Promise with query results
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* // Using SQLWrapper
|
|
528
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
529
|
+
*
|
|
530
|
+
* // Using string
|
|
531
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
execute(query: SQLWrapper | string) {
|
|
535
|
+
return this.drizzle.executeQuery(query);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
540
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
541
|
+
* - Local cache: Within the current invocation context
|
|
542
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
543
|
+
*
|
|
544
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
545
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
546
|
+
* @returns Promise with query results
|
|
547
|
+
* @example
|
|
548
|
+
* ```typescript
|
|
549
|
+
* // Using SQLWrapper with custom TTL
|
|
550
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
551
|
+
*
|
|
552
|
+
* // Using string with default TTL
|
|
553
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
executeCacheable(query: SQLWrapper | string, cacheTtl?: number) {
|
|
557
|
+
return this.drizzle.executeQueryCacheable(query, cacheTtl);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
562
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
563
|
+
*
|
|
564
|
+
* @returns WithBuilder for creating CTEs
|
|
565
|
+
* @example
|
|
566
|
+
* ```typescript
|
|
567
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
568
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
569
|
+
* .from(users)
|
|
570
|
+
* .groupBy(users.id)
|
|
571
|
+
* );
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
get $with() {
|
|
575
|
+
return this.drizzle.$with;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
580
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
581
|
+
*
|
|
582
|
+
* @param queries - Array of CTE queries created with $with()
|
|
583
|
+
* @returns Query builder with CTE support
|
|
584
|
+
* @example
|
|
585
|
+
* ```typescript
|
|
586
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
587
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
588
|
+
* .from(users)
|
|
589
|
+
* .groupBy(users.id)
|
|
590
|
+
* );
|
|
591
|
+
*
|
|
592
|
+
* const result = await forgeSQL.with(withQuery)
|
|
593
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
594
|
+
* .from(withQuery);
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
597
|
+
with(...queries: WithSubquery[]) {
|
|
598
|
+
return this.drizzle.with(...queries);
|
|
599
|
+
}
|
|
443
600
|
}
|
|
444
601
|
|
|
445
602
|
/**
|
|
@@ -467,6 +624,72 @@ class ForgeSQLORM implements ForgeSqlOperation {
|
|
|
467
624
|
return this.ormInstance.selectDistinctCacheable(fields, cacheTTL);
|
|
468
625
|
}
|
|
469
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
629
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
630
|
+
*
|
|
631
|
+
* @template T - The type of the table
|
|
632
|
+
* @param table - The table to select from
|
|
633
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
634
|
+
* @example
|
|
635
|
+
* ```typescript
|
|
636
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
selectFrom<T extends MySqlTable>(table: T) {
|
|
640
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFrom(table);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
645
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
646
|
+
*
|
|
647
|
+
* @template T - The type of the table
|
|
648
|
+
* @param table - The table to select from
|
|
649
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
650
|
+
* @example
|
|
651
|
+
* ```typescript
|
|
652
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
653
|
+
* ```
|
|
654
|
+
*/
|
|
655
|
+
selectDistinctFrom<T extends MySqlTable>(table: T) {
|
|
656
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFrom(table);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
661
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
662
|
+
*
|
|
663
|
+
* @template T - The type of the table
|
|
664
|
+
* @param table - The table to select from
|
|
665
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
666
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
667
|
+
* @example
|
|
668
|
+
* ```typescript
|
|
669
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
selectCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {
|
|
673
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectFromCacheable(table, cacheTTL);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
678
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
679
|
+
*
|
|
680
|
+
* @template T - The type of the table
|
|
681
|
+
* @param table - The table to select from
|
|
682
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
683
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
684
|
+
* @example
|
|
685
|
+
* ```typescript
|
|
686
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
687
|
+
* ```
|
|
688
|
+
*/
|
|
689
|
+
selectDistinctCacheableFrom<T extends MySqlTable>(table: T, cacheTTL?: number) {
|
|
690
|
+
return this.ormInstance.getDrizzleQueryBuilder().selectDistinctFromCacheable(table, cacheTTL);
|
|
691
|
+
}
|
|
692
|
+
|
|
470
693
|
executeWithCacheContext(cacheContext: () => Promise<void>): Promise<void> {
|
|
471
694
|
return this.ormInstance.executeWithCacheContext(cacheContext);
|
|
472
695
|
}
|
|
@@ -669,6 +892,89 @@ class ForgeSQLORM implements ForgeSqlOperation {
|
|
|
669
892
|
getDrizzleQueryBuilder() {
|
|
670
893
|
return this.ormInstance.getDrizzleQueryBuilder();
|
|
671
894
|
}
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Executes a raw SQL query with local cache support.
|
|
898
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
899
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
900
|
+
*
|
|
901
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
902
|
+
* @returns Promise with query results
|
|
903
|
+
* @example
|
|
904
|
+
* ```typescript
|
|
905
|
+
* // Using SQLWrapper
|
|
906
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
907
|
+
*
|
|
908
|
+
* // Using string
|
|
909
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
910
|
+
* ```
|
|
911
|
+
*/
|
|
912
|
+
execute(query: SQLWrapper | string) {
|
|
913
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQuery(query);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
918
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
919
|
+
* - Local cache: Within the current invocation context
|
|
920
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
921
|
+
*
|
|
922
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
923
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
924
|
+
* @returns Promise with query results
|
|
925
|
+
* @example
|
|
926
|
+
* ```typescript
|
|
927
|
+
* // Using SQLWrapper with custom TTL
|
|
928
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
929
|
+
*
|
|
930
|
+
* // Using string with default TTL
|
|
931
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
932
|
+
* ```
|
|
933
|
+
*/
|
|
934
|
+
executeCacheable(query: SQLWrapper | string, cacheTtl?: number) {
|
|
935
|
+
return this.ormInstance.getDrizzleQueryBuilder().executeQueryCacheable(query, cacheTtl);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
940
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
941
|
+
*
|
|
942
|
+
* @returns WithBuilder for creating CTEs
|
|
943
|
+
* @example
|
|
944
|
+
* ```typescript
|
|
945
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
946
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
947
|
+
* .from(users)
|
|
948
|
+
* .groupBy(users.id)
|
|
949
|
+
* );
|
|
950
|
+
* ```
|
|
951
|
+
*/
|
|
952
|
+
get $with() {
|
|
953
|
+
return this.ormInstance.getDrizzleQueryBuilder().$with;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
958
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
959
|
+
*
|
|
960
|
+
* @param queries - Array of CTE queries created with $with()
|
|
961
|
+
* @returns Query builder with CTE support
|
|
962
|
+
* @example
|
|
963
|
+
* ```typescript
|
|
964
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
965
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
966
|
+
* .from(users)
|
|
967
|
+
* .groupBy(users.id)
|
|
968
|
+
* );
|
|
969
|
+
*
|
|
970
|
+
* const result = await forgeSQL.with(withQuery)
|
|
971
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
972
|
+
* .from(withQuery);
|
|
973
|
+
* ```
|
|
974
|
+
*/
|
|
975
|
+
with(...queries: WithSubquery[]) {
|
|
976
|
+
return this.ormInstance.getDrizzleQueryBuilder().with(...queries);
|
|
977
|
+
}
|
|
672
978
|
}
|
|
673
979
|
|
|
674
980
|
export default ForgeSQLORM;
|
|
@@ -23,19 +23,34 @@ import {
|
|
|
23
23
|
import { ForgeSQLCacheOperations } from "./ForgeSQLCacheOperations";
|
|
24
24
|
import {
|
|
25
25
|
DeleteAndEvictCacheType,
|
|
26
|
+
ExecuteQuery,
|
|
27
|
+
ExecuteQueryCacheable,
|
|
26
28
|
InsertAndEvictCacheType,
|
|
27
29
|
SelectAliasedCacheableType,
|
|
28
30
|
SelectAliasedDistinctCacheableType,
|
|
29
31
|
SelectAliasedDistinctType,
|
|
30
32
|
SelectAliasedType,
|
|
33
|
+
SelectAllDistinctFromAliasedType,
|
|
34
|
+
SelectAllDistinctFromCacheableAliasedType,
|
|
35
|
+
SelectAllFromAliasedType,
|
|
36
|
+
SelectAllFromCacheableAliasedType,
|
|
31
37
|
UpdateAndEvictCacheType,
|
|
32
38
|
} from "..";
|
|
33
39
|
import {
|
|
34
40
|
MySqlDeleteBase,
|
|
35
41
|
MySqlInsertBuilder,
|
|
42
|
+
MySqlSelectBase,
|
|
36
43
|
MySqlUpdateBuilder,
|
|
37
44
|
} from "drizzle-orm/mysql-core/query-builders";
|
|
38
45
|
import { MySqlRemoteQueryResultHKT } from "drizzle-orm/mysql-proxy";
|
|
46
|
+
import {
|
|
47
|
+
GetSelectTableName,
|
|
48
|
+
GetSelectTableSelection,
|
|
49
|
+
} from "drizzle-orm/query-builders/select.types";
|
|
50
|
+
import { SQLWrapper } from "drizzle-orm/sql/sql";
|
|
51
|
+
import type { MySqlQueryResultKind } from "drizzle-orm/mysql-core/session";
|
|
52
|
+
import type { WithBuilder } from "drizzle-orm/mysql-core/subquery";
|
|
53
|
+
import { WithSubquery } from "drizzle-orm/subquery";
|
|
39
54
|
|
|
40
55
|
/**
|
|
41
56
|
* Core interface for ForgeSQL operations.
|
|
@@ -55,14 +70,20 @@ export interface ForgeSqlOperation extends QueryBuilderForgeSql {
|
|
|
55
70
|
getDrizzleQueryBuilder(): MySqlRemoteDatabase<Record<string, unknown>> & {
|
|
56
71
|
selectAliased: SelectAliasedType;
|
|
57
72
|
selectAliasedDistinct: SelectAliasedDistinctType;
|
|
73
|
+
executeQuery: ExecuteQuery;
|
|
58
74
|
selectAliasedCacheable: SelectAliasedCacheableType;
|
|
59
75
|
selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;
|
|
76
|
+
executeQueryCacheable: ExecuteQueryCacheable;
|
|
60
77
|
insertWithCacheContext: InsertAndEvictCacheType;
|
|
61
78
|
insertAndEvictCache: InsertAndEvictCacheType;
|
|
62
79
|
updateAndEvictCache: UpdateAndEvictCacheType;
|
|
63
80
|
updateWithCacheContext: UpdateAndEvictCacheType;
|
|
64
81
|
deleteAndEvictCache: DeleteAndEvictCacheType;
|
|
65
82
|
deleteWithCacheContext: DeleteAndEvictCacheType;
|
|
83
|
+
selectFrom: SelectAllFromAliasedType;
|
|
84
|
+
selectDistinctFrom: SelectAllDistinctFromAliasedType;
|
|
85
|
+
selectFromCacheable: SelectAllFromCacheableAliasedType;
|
|
86
|
+
selectDistinctFromCacheable: SelectAllDistinctFromCacheableAliasedType;
|
|
66
87
|
};
|
|
67
88
|
|
|
68
89
|
/**
|
|
@@ -115,8 +136,10 @@ export interface QueryBuilderForgeSql {
|
|
|
115
136
|
getDrizzleQueryBuilder(): MySqlRemoteDatabase<Record<string, unknown>> & {
|
|
116
137
|
selectAliased: SelectAliasedType;
|
|
117
138
|
selectAliasedDistinct: SelectAliasedDistinctType;
|
|
139
|
+
executeQuery: ExecuteQuery;
|
|
118
140
|
selectAliasedCacheable: SelectAliasedCacheableType;
|
|
119
141
|
selectAliasedDistinctCacheable: SelectAliasedDistinctCacheableType;
|
|
142
|
+
executeQueryCacheable: ExecuteQueryCacheable;
|
|
120
143
|
insertWithCacheContext: InsertAndEvictCacheType;
|
|
121
144
|
insertAndEvictCache: InsertAndEvictCacheType;
|
|
122
145
|
updateAndEvictCache: UpdateAndEvictCacheType;
|
|
@@ -145,6 +168,31 @@ export interface QueryBuilderForgeSql {
|
|
|
145
168
|
fields: TSelection,
|
|
146
169
|
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
147
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Creates a select query builder for all columns from a table with field aliasing support.
|
|
173
|
+
* This is a convenience method that automatically selects all columns from the specified table.
|
|
174
|
+
*
|
|
175
|
+
* @template T - The type of the table
|
|
176
|
+
* @param table - The table to select from
|
|
177
|
+
* @returns Select query builder with all table columns and field aliasing support
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const users = await forgeSQL.selectFrom(userTable).where(eq(userTable.id, 1));
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
selectFrom<T extends MySqlTable>(
|
|
184
|
+
table: T,
|
|
185
|
+
): MySqlSelectBase<
|
|
186
|
+
GetSelectTableName<T>,
|
|
187
|
+
T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
|
|
188
|
+
T["_"]["columns"] extends undefined ? "single" : "partial",
|
|
189
|
+
MySqlRemotePreparedQueryHKT,
|
|
190
|
+
GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
|
|
191
|
+
false,
|
|
192
|
+
never,
|
|
193
|
+
any
|
|
194
|
+
>;
|
|
195
|
+
|
|
148
196
|
/**
|
|
149
197
|
* Creates a distinct select query with unique field aliases to prevent field name collisions in joins.
|
|
150
198
|
* This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
|
|
@@ -164,6 +212,30 @@ export interface QueryBuilderForgeSql {
|
|
|
164
212
|
selectDistinct<TSelection extends SelectedFields>(
|
|
165
213
|
fields: TSelection,
|
|
166
214
|
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
215
|
+
/**
|
|
216
|
+
* Creates a select distinct query builder for all columns from a table with field aliasing support.
|
|
217
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table.
|
|
218
|
+
*
|
|
219
|
+
* @template T - The type of the table
|
|
220
|
+
* @param table - The table to select from
|
|
221
|
+
* @returns Select distinct query builder with all table columns and field aliasing support
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const uniqueUsers = await forgeSQL.selectDistinctFrom(userTable).where(eq(userTable.status, 'active'));
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
selectDistinctFrom<T extends MySqlTable>(
|
|
228
|
+
table: T,
|
|
229
|
+
): MySqlSelectBase<
|
|
230
|
+
GetSelectTableName<T>,
|
|
231
|
+
T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
|
|
232
|
+
T["_"]["columns"] extends undefined ? "single" : "partial",
|
|
233
|
+
MySqlRemotePreparedQueryHKT,
|
|
234
|
+
GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
|
|
235
|
+
false,
|
|
236
|
+
never,
|
|
237
|
+
any
|
|
238
|
+
>;
|
|
167
239
|
|
|
168
240
|
/**
|
|
169
241
|
* Creates a cacheable select query with unique field aliases to prevent field name collisions in joins.
|
|
@@ -187,6 +259,33 @@ export interface QueryBuilderForgeSql {
|
|
|
187
259
|
cacheTTL?: number,
|
|
188
260
|
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
189
261
|
|
|
262
|
+
/**
|
|
263
|
+
* Creates a cacheable select query builder for all columns from a table with field aliasing and caching support.
|
|
264
|
+
* This is a convenience method that automatically selects all columns from the specified table with caching enabled.
|
|
265
|
+
*
|
|
266
|
+
* @template T - The type of the table
|
|
267
|
+
* @param table - The table to select from
|
|
268
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
269
|
+
* @returns Select query builder with all table columns, field aliasing, and caching support
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* const users = await forgeSQL.selectCacheableFrom(userTable, 300).where(eq(userTable.id, 1));
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
selectCacheableFrom<T extends MySqlTable>(
|
|
276
|
+
table: T,
|
|
277
|
+
cacheTTL?: number,
|
|
278
|
+
): MySqlSelectBase<
|
|
279
|
+
GetSelectTableName<T>,
|
|
280
|
+
T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
|
|
281
|
+
T["_"]["columns"] extends undefined ? "single" : "partial",
|
|
282
|
+
MySqlRemotePreparedQueryHKT,
|
|
283
|
+
GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
|
|
284
|
+
false,
|
|
285
|
+
never,
|
|
286
|
+
any
|
|
287
|
+
>;
|
|
288
|
+
|
|
190
289
|
/**
|
|
191
290
|
* Creates a cacheable distinct select query with unique field aliases to prevent field name collisions in joins.
|
|
192
291
|
* This is particularly useful when working with Atlassian Forge SQL, which collapses fields with the same name in joined tables.
|
|
@@ -209,6 +308,33 @@ export interface QueryBuilderForgeSql {
|
|
|
209
308
|
cacheTTL?: number,
|
|
210
309
|
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
211
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Creates a cacheable select distinct query builder for all columns from a table with field aliasing and caching support.
|
|
313
|
+
* This is a convenience method that automatically selects all distinct columns from the specified table with caching enabled.
|
|
314
|
+
*
|
|
315
|
+
* @template T - The type of the table
|
|
316
|
+
* @param table - The table to select from
|
|
317
|
+
* @param cacheTTL - Optional cache TTL override (defaults to global cache TTL)
|
|
318
|
+
* @returns Select distinct query builder with all table columns, field aliasing, and caching support
|
|
319
|
+
* @example
|
|
320
|
+
* ```typescript
|
|
321
|
+
* const uniqueUsers = await forgeSQL.selectDistinctCacheableFrom(userTable, 300).where(eq(userTable.status, 'active'));
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
selectDistinctCacheableFrom<T extends MySqlTable>(
|
|
325
|
+
table: T,
|
|
326
|
+
cacheTTL?: number,
|
|
327
|
+
): MySqlSelectBase<
|
|
328
|
+
GetSelectTableName<T>,
|
|
329
|
+
T["_"]["columns"] extends undefined ? GetSelectTableSelection<T> : T["_"]["columns"],
|
|
330
|
+
T["_"]["columns"] extends undefined ? "single" : "partial",
|
|
331
|
+
MySqlRemotePreparedQueryHKT,
|
|
332
|
+
GetSelectTableName<T> extends string ? Record<string & GetSelectTableName<T>, "not-null"> : {},
|
|
333
|
+
false,
|
|
334
|
+
never,
|
|
335
|
+
any
|
|
336
|
+
>;
|
|
337
|
+
|
|
212
338
|
/**
|
|
213
339
|
* Creates an insert query builder.
|
|
214
340
|
*
|
|
@@ -366,6 +492,98 @@ export interface QueryBuilderForgeSql {
|
|
|
366
492
|
* ```
|
|
367
493
|
*/
|
|
368
494
|
executeWithLocalCacheContextAndReturnValue<T>(cacheContext: () => Promise<T>): Promise<T>;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Executes a raw SQL query with local cache support.
|
|
498
|
+
* This method provides local caching for raw SQL queries within the current invocation context.
|
|
499
|
+
* Results are cached locally and will be returned from cache on subsequent identical queries.
|
|
500
|
+
*
|
|
501
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
502
|
+
* @returns Promise with query results
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* // Using SQLWrapper
|
|
506
|
+
* const result = await forgeSQL.execute(sql`SELECT * FROM users WHERE id = ${userId}`);
|
|
507
|
+
*
|
|
508
|
+
* // Using string
|
|
509
|
+
* const result = await forgeSQL.execute("SELECT * FROM users WHERE status = 'active'");
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
execute(
|
|
513
|
+
query: SQLWrapper | string,
|
|
514
|
+
): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Executes a raw SQL query with both local and global cache support.
|
|
518
|
+
* This method provides comprehensive caching for raw SQL queries:
|
|
519
|
+
* - Local cache: Within the current invocation context
|
|
520
|
+
* - Global cache: Cross-invocation caching using @forge/kvs
|
|
521
|
+
*
|
|
522
|
+
* @param query - The SQL query to execute (SQLWrapper or string)
|
|
523
|
+
* @param cacheTtl - Optional cache TTL override (defaults to global cache TTL)
|
|
524
|
+
* @returns Promise with query results
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* // Using SQLWrapper with custom TTL
|
|
528
|
+
* const result = await forgeSQL.executeCacheable(sql`SELECT * FROM users WHERE id = ${userId}`, 300);
|
|
529
|
+
*
|
|
530
|
+
* // Using string with default TTL
|
|
531
|
+
* const result = await forgeSQL.executeCacheable("SELECT * FROM users WHERE status = 'active'");
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
executeCacheable(
|
|
535
|
+
query: SQLWrapper | string,
|
|
536
|
+
cacheTtl?: number,
|
|
537
|
+
): Promise<MySqlQueryResultKind<MySqlRemoteQueryResultHKT, unknown>>;
|
|
538
|
+
/**
|
|
539
|
+
* Creates a Common Table Expression (CTE) builder for complex queries.
|
|
540
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
541
|
+
*
|
|
542
|
+
* @returns WithBuilder for creating CTEs
|
|
543
|
+
* @example
|
|
544
|
+
* ```typescript
|
|
545
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
546
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
547
|
+
* .from(users)
|
|
548
|
+
* .groupBy(users.id)
|
|
549
|
+
* );
|
|
550
|
+
* ```
|
|
551
|
+
*/
|
|
552
|
+
$with: WithBuilder;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Creates a query builder that uses Common Table Expressions (CTEs).
|
|
556
|
+
* CTEs allow you to define temporary named result sets that exist within the scope of a single query.
|
|
557
|
+
*
|
|
558
|
+
* @param queries - Array of CTE queries created with $with()
|
|
559
|
+
* @returns Query builder with CTE support
|
|
560
|
+
* @example
|
|
561
|
+
* ```typescript
|
|
562
|
+
* const withQuery = forgeSQL.$with('userStats').as(
|
|
563
|
+
* forgeSQL.select({ userId: users.id, count: sql<number>`count(*)` })
|
|
564
|
+
* .from(users)
|
|
565
|
+
* .groupBy(users.id)
|
|
566
|
+
* );
|
|
567
|
+
*
|
|
568
|
+
* const result = await forgeSQL.with(withQuery)
|
|
569
|
+
* .select({ userId: withQuery.userId, count: withQuery.count })
|
|
570
|
+
* .from(withQuery);
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
with(...queries: WithSubquery[]): {
|
|
574
|
+
select: {
|
|
575
|
+
(): MySqlSelectBuilder<undefined, MySqlRemotePreparedQueryHKT>;
|
|
576
|
+
<TSelection extends SelectedFields>(
|
|
577
|
+
fields: TSelection,
|
|
578
|
+
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
579
|
+
};
|
|
580
|
+
selectDistinct: {
|
|
581
|
+
(): MySqlSelectBuilder<undefined, MySqlRemotePreparedQueryHKT>;
|
|
582
|
+
<TSelection extends SelectedFields>(
|
|
583
|
+
fields: TSelection,
|
|
584
|
+
): MySqlSelectBuilder<TSelection, MySqlRemotePreparedQueryHKT>;
|
|
585
|
+
};
|
|
586
|
+
};
|
|
369
587
|
}
|
|
370
588
|
|
|
371
589
|
/**
|