metal-orm 1.0.51 → 1.0.53

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.
@@ -533,16 +533,74 @@ export class SelectQueryBuilder<T = unknown, TTable extends TableDef = TableDef>
533
533
  * @param ctx - ORM session context
534
534
  * @returns Promise of entity instances
535
535
  */
536
- async execute(ctx: OrmSession): Promise<EntityInstance<TTable>[]> {
537
- return executeHydrated(ctx, this);
538
- }
539
-
540
- /**
541
- * Executes the query with provided execution and hydration contexts
542
- * @param execCtx - Execution context
543
- * @param hydCtx - Hydration context
544
- * @returns Promise of entity instances
545
- */
536
+ async execute(ctx: OrmSession): Promise<EntityInstance<TTable>[]> {
537
+ return executeHydrated(ctx, this);
538
+ }
539
+
540
+ private withAst(ast: SelectQueryNode): SelectQueryBuilder<T, TTable> {
541
+ const nextState = new SelectQueryState(this.env.table as TTable, ast);
542
+ const nextContext: SelectQueryBuilderContext = {
543
+ ...this.context,
544
+ state: nextState
545
+ };
546
+ return this.clone(nextContext);
547
+ }
548
+
549
+ async count(session: OrmSession): Promise<number> {
550
+ const unpagedAst: SelectQueryNode = {
551
+ ...this.context.state.ast,
552
+ orderBy: undefined,
553
+ limit: undefined,
554
+ offset: undefined
555
+ };
556
+
557
+ const subAst = this.withAst(unpagedAst).getAST();
558
+
559
+ const countQuery: SelectQueryNode = {
560
+ type: 'SelectQuery',
561
+ from: derivedTable(subAst, '__metal_count'),
562
+ columns: [{ type: 'Function', name: 'COUNT', args: [], alias: 'total' } as FunctionNode],
563
+ joins: []
564
+ };
565
+
566
+ const execCtx = session.getExecutionContext();
567
+ const compiled = execCtx.dialect.compileSelect(countQuery);
568
+ const results = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
569
+ const value = results[0]?.values?.[0]?.[0];
570
+
571
+ if (typeof value === 'number') return value;
572
+ if (typeof value === 'bigint') return Number(value);
573
+ if (typeof value === 'string') return Number(value);
574
+ return value === null || value === undefined ? 0 : Number(value);
575
+ }
576
+
577
+ async executePaged(
578
+ session: OrmSession,
579
+ options: { page: number; pageSize: number }
580
+ ): Promise<{ items: EntityInstance<TTable>[]; totalItems: number }> {
581
+ const { page, pageSize } = options;
582
+ if (!Number.isInteger(page) || page < 1) {
583
+ throw new Error('executePaged: page must be an integer >= 1');
584
+ }
585
+ if (!Number.isInteger(pageSize) || pageSize < 1) {
586
+ throw new Error('executePaged: pageSize must be an integer >= 1');
587
+ }
588
+
589
+ const offset = (page - 1) * pageSize;
590
+ const [items, totalItems] = await Promise.all([
591
+ this.limit(pageSize).offset(offset).execute(session),
592
+ this.count(session)
593
+ ]);
594
+
595
+ return { items, totalItems };
596
+ }
597
+
598
+ /**
599
+ * Executes the query with provided execution and hydration contexts
600
+ * @param execCtx - Execution context
601
+ * @param hydCtx - Hydration context
602
+ * @returns Promise of entity instances
603
+ */
546
604
  async executeWithContexts(execCtx: ExecutionContext, hydCtx: HydrationContext): Promise<EntityInstance<TTable>[]> {
547
605
  return executeHydratedWithContexts(execCtx, hydCtx, this);
548
606
  }
@@ -137,10 +137,11 @@ export class UpdateQueryBuilder<T> {
137
137
  * @param session - The ORM session to execute the query with
138
138
  * @returns A promise that resolves to the query results
139
139
  */
140
- async execute(session: OrmSession): Promise<QueryResult[]> {
141
- const compiled = this.compile(session.dialect);
142
- return session.executor.executeSql(compiled.sql, compiled.params);
143
- }
140
+ async execute(session: OrmSession): Promise<QueryResult[]> {
141
+ const execCtx = session.getExecutionContext();
142
+ const compiled = this.compile(execCtx.dialect);
143
+ return execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
144
+ }
144
145
 
145
146
  /**
146
147
  * Returns the Abstract Syntax Tree (AST) representation of the query