-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathForgeSQLSelectOperations.ts
More file actions
94 lines (88 loc) · 3.43 KB
/
ForgeSQLSelectOperations.ts
File metadata and controls
94 lines (88 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { sql, UpdateQueryResponse } from "@forge/sql";
import { ForgeSqlOrmOptions, SchemaSqlForgeSql } from "./ForgeSQLQueryBuilder";
import {
AnyMySqlSelectQueryBuilder,
MySqlSelectDynamic,
} from "drizzle-orm/mysql-core/query-builders/select.types";
import { SqlParameters } from "@forge/sql/out/sql-statement";
/**
* Class implementing SQL select operations for ForgeSQL ORM.
* Provides methods for executing queries and mapping results to entity types.
*/
export class ForgeSQLSelectOperations implements SchemaSqlForgeSql {
private readonly options: ForgeSqlOrmOptions;
/**
* Creates a new instance of ForgeSQLSelectOperations.
* @param {ForgeSqlOrmOptions} options - Configuration options for the ORM
*/
constructor(options: ForgeSqlOrmOptions) {
this.options = options;
}
/**
* Executes a Drizzle query and returns a single result.
* Throws an error if more than one record is returned.
*
* @template T - The type of the query builder
* @param {T} query - The Drizzle query to execute
* @returns {Promise<Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined>} A single result object or undefined
* @throws {Error} If more than one record is returned
*/
async executeQueryOnlyOne<T extends MySqlSelectDynamic<AnyMySqlSelectQueryBuilder>>(
query: T,
): Promise<
Awaited<T> extends Array<any> ? Awaited<T>[number] | undefined : Awaited<T> | undefined
> {
const results: Awaited<T> = await query;
const datas = results as unknown[];
if (!datas.length) {
return undefined;
}
if (datas.length > 1) {
throw new Error(`Expected 1 record but returned ${datas.length}`);
}
return datas[0] as Awaited<T> extends Array<any> ? Awaited<T>[number] : Awaited<T>;
}
/**
* Executes a raw SQL query and returns the results.
* Logs the query if logging is enabled.
*
* @template T - The type of the result objects
* @param {string} query - The raw SQL query to execute
* @param {SqlParameters[]} [params] - Optional SQL parameters
* @returns {Promise<T[]>} A list of results as objects
*/
async executeRawSQL<T>(query: string, params?: SqlParameters[]): Promise<T[]> {
if (this.options.logRawSqlQuery) {
const paramsStr = params ? `, with params: ${JSON.stringify(params)}` : "";
// eslint-disable-next-line no-console
console.debug(`Executing with SQL ${query}${paramsStr}`);
}
const sqlStatement = sql.prepare<T>(query);
if (params) {
sqlStatement.bindParams(...params);
}
const result = await sqlStatement.execute();
return result.rows as T[];
}
/**
* Executes a raw SQL update query.
* @param {string} query - The raw SQL update query
* @param {SqlParameters[]} [params] - Optional SQL parameters
* @returns {Promise<UpdateQueryResponse>} The update response containing affected rows
*/
async executeRawUpdateSQL(query: string, params?: unknown[]): Promise<UpdateQueryResponse> {
const sqlStatement = sql.prepare<UpdateQueryResponse>(query);
if (params) {
sqlStatement.bindParams(...params);
}
if (this.options.logRawSqlQuery) {
// eslint-disable-next-line no-console
console.debug(
`Executing Update with SQL ${query}` +
(params ? `, with params: ${JSON.stringify(params)}` : ""),
);
}
const updateQueryResponseResults = await sqlStatement.execute();
return updateQueryResponseResults.rows;
}
}