kysely
Version:
Type safe SQL query builder
260 lines (259 loc) • 8.92 kB
TypeScript
import { AggregateFunctionNode } from '../operation-node/aggregate-function-node.js';
import { AliasNode } from '../operation-node/alias-node.js';
import { OverBuilder } from './over-builder.js';
import { AliasableExpression, AliasedExpression, Expression } from '../expression/expression.js';
import { ReferenceExpression } from '../parser/reference-parser.js';
import { ComparisonOperatorExpression, OperandValueExpressionOrList } from '../parser/binary-operation-parser.js';
import { SqlBool } from '../util/type-utils.js';
import { ExpressionOrFactory } from '../parser/expression-parser.js';
export declare class AggregateFunctionBuilder<DB, TB extends keyof DB, O = unknown> implements AliasableExpression<O> {
#private;
constructor(props: AggregateFunctionBuilderProps);
/** @private */
/**
* All expressions need to have this getter for complicated type-related reasons.
* Simply add this getter for your expression and always return `undefined` from it:
*
* ```ts
* class SomeExpression<T> implements Expression<T> {
* get expressionType(): T | undefined {
* return undefined
* }
* }
* ```
*
* The getter is needed to make the expression assignable to another expression only
* if the types `T` are assignable. Without this property (or some other property
* that references `T`), you could assing `Expression<string>` to `Expression<number>`.
*/
get expressionType(): O | undefined;
/**
* Returns an aliased version of the function.
*
* In addition to slapping `as "the_alias"` to the end of the SQL,
* this method also provides strict typing:
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select(
* (eb) => eb.fn.count<number>('id').as('person_count')
* )
* .executeTakeFirstOrThrow()
*
* // `person_count: number` field exists in the result type.
* console.log(result.person_count)
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select count("id") as "person_count"
* from "person"
* ```
*/
as<A extends string>(alias: A): AliasedAggregateFunctionBuilder<DB, TB, O, A>;
/**
* Adds a `distinct` clause inside the function.
*
* ### Examples
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select((eb) =>
* eb.fn.count<number>('first_name').distinct().as('first_name_count')
* )
* .executeTakeFirstOrThrow()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select count(distinct "first_name") as "first_name_count"
* from "person"
* ```
*/
distinct(): AggregateFunctionBuilder<DB, TB, O>;
/**
* Adds a `filter` clause with a nested `where` clause after the function.
*
* Similar to {@link WhereInterface}'s `where` method.
*
* Also see {@link filterWhereRef}.
*
* ### Examples
*
* Count by gender:
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select((eb) => [
* eb.fn
* .count<number>('id')
* .filterWhere('gender', '=', 'female')
* .as('female_count'),
* eb.fn
* .count<number>('id')
* .filterWhere('gender', '=', 'male')
* .as('male_count'),
* eb.fn
* .count<number>('id')
* .filterWhere('gender', '=', 'other')
* .as('other_count'),
* ])
* .executeTakeFirstOrThrow()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select
* count("id") filter(where "gender" = $1) as "female_count",
* count("id") filter(where "gender" = $2) as "male_count",
* count("id") filter(where "gender" = $3) as "other_count"
* from "person"
* ```
*/
filterWhere<RE extends ReferenceExpression<DB, TB>, VE extends OperandValueExpressionOrList<DB, TB, RE>>(lhs: RE, op: ComparisonOperatorExpression, rhs: VE): AggregateFunctionBuilder<DB, TB, O>;
filterWhere<E extends ExpressionOrFactory<DB, TB, SqlBool>>(expression: E): AggregateFunctionBuilder<DB, TB, O>;
/**
* Adds a `filter` clause with a nested `where` clause after the function, where
* both sides of the operator are references to columns.
*
* Similar to {@link WhereInterface}'s `whereRef` method.
*
* ### Examples
*
* Count people with same first and last names versus general public:
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select((eb) => [
* eb.fn
* .count<number>('id')
* .filterWhereRef('first_name', '=', 'last_name')
* .as('repeat_name_count'),
* eb.fn.count<number>('id').as('total_count'),
* ])
* .executeTakeFirstOrThrow()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select
* count("id") filter(where "first_name" = "last_name") as "repeat_name_count",
* count("id") as "total_count"
* from "person"
* ```
*/
filterWhereRef<LRE extends ReferenceExpression<DB, TB>, RRE extends ReferenceExpression<DB, TB>>(lhs: LRE, op: ComparisonOperatorExpression, rhs: RRE): AggregateFunctionBuilder<DB, TB, O>;
/**
* Adds an `over` clause (window functions) after the function.
*
* ### Examples
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select(
* (eb) => eb.fn.avg<number>('age').over().as('average_age')
* )
* .execute()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select avg("age") over() as "average_age"
* from "person"
* ```
*
* Also supports passing a callback that returns an over builder,
* allowing to add partition by and sort by clauses inside over.
*
* ```ts
* const result = await db
* .selectFrom('person')
* .select(
* (eb) => eb.fn.avg<number>('age').over(
* ob => ob.partitionBy('last_name').orderBy('first_name', 'asc')
* ).as('average_age')
* )
* .execute()
* ```
*
* The generated SQL (PostgreSQL):
*
* ```sql
* select avg("age") over(partition by "last_name" order by "first_name" asc) as "average_age"
* from "person"
* ```
*/
over(over?: OverBuilderCallback<DB, TB>): AggregateFunctionBuilder<DB, TB, O>;
/**
* Simply calls the provided function passing `this` as the only argument. `$call` returns
* what the provided function returns.
*/
$call<T>(func: (qb: this) => T): T;
/**
* Casts the expression to the given type.
*
* This method call doesn't change the SQL in any way. This methods simply
* returns a copy of this `AggregateFunctionBuilder` with a new output type.
*/
$castTo<C>(): AggregateFunctionBuilder<DB, TB, C>;
/**
* Omit null from the expression's type.
*
* This function can be useful in cases where you know an expression can't be
* null, but Kysely is unable to infer it.
*
* This method call doesn't change the SQL in any way. This methods simply
* returns a copy of `this` with a new output type.
*/
$notNull(): AggregateFunctionBuilder<DB, TB, Exclude<O, null>>;
/**
* Creates the OperationNode that describes how to compile this expression into SQL.
*
* If you are creating a custom expression, it's often easiest to use the {@link sql}
* template tag to build the node:
*
* ```ts
* class SomeExpression<T> implements Expression<T> {
* toOperationNode(): OperationNode {
* return sql`some sql here`.toOperationNode()
* }
* }
* ```
*/
toOperationNode(): AggregateFunctionNode;
}
/**
* {@link AggregateFunctionBuilder} with an alias. The result of calling {@link AggregateFunctionBuilder.as}.
*/
export declare class AliasedAggregateFunctionBuilder<DB, TB extends keyof DB, O = unknown, A extends string = never> implements AliasedExpression<O, A> {
#private;
constructor(aggregateFunctionBuilder: AggregateFunctionBuilder<DB, TB, O>, alias: A);
/** @private */
/**
* Returns the aliased expression.
*/
get expression(): Expression<O>;
/** @private */
/**
* Returns the alias.
*/
get alias(): A;
/**
* Creates the OperationNode that describes how to compile this expression into SQL.
*/
toOperationNode(): AliasNode;
}
export interface AggregateFunctionBuilderProps {
aggregateFunctionNode: AggregateFunctionNode;
}
export type OverBuilderCallback<DB, TB extends keyof DB> = (builder: OverBuilder<DB, TB>) => OverBuilder<any, any>;