durcno 1.0.0-alpha.15 → 1.0.0-alpha.17
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/dist/bin.cjs +4 -2
- package/dist/src/columns/common.d.mts +1 -1
- package/dist/src/constraints/check.d.mts +1 -1
- package/dist/src/constraints/foreign-key.d.mts +61 -0
- package/dist/src/constraints/foreign-key.mjs +74 -0
- package/dist/src/cte.d.mts +16 -0
- package/dist/src/cte.mjs +5 -0
- package/dist/src/db.d.mts +24 -1
- package/dist/src/db.mjs +10 -1
- package/dist/src/filters/array.d.mts +1 -1
- package/dist/src/filters/index.d.mts +1 -1
- package/dist/src/filters/index.mjs +1 -1
- package/dist/src/filters/string.d.mts +1 -1
- package/dist/src/functions/aggregate.d.mts +24 -8
- package/dist/src/functions/aggregate.mjs +68 -9
- package/dist/src/functions/arithmetic.d.mts +67 -0
- package/dist/src/functions/arithmetic.mjs +123 -0
- package/dist/src/functions/index.d.mts +15 -18
- package/dist/src/functions/index.mjs +19 -23
- package/dist/src/functions/numeric.d.mts +16 -1
- package/dist/src/functions/numeric.mjs +45 -0
- package/dist/src/functions/pgvector.d.mts +4 -1
- package/dist/src/functions/pgvector.mjs +9 -0
- package/dist/src/functions/postgis.d.mts +3 -0
- package/dist/src/functions/postgis.mjs +9 -0
- package/dist/src/functions/string.d.mts +22 -1
- package/dist/src/functions/string.mjs +63 -0
- package/dist/src/index.d.mts +8 -5
- package/dist/src/index.mjs +3 -1
- package/dist/src/migration/snapshot.mjs +13 -0
- package/dist/src/query-builders/aggregates.d.mts +1 -1
- package/dist/src/query-builders/count.d.mts +1 -1
- package/dist/src/query-builders/delete.d.mts +14 -7
- package/dist/src/query-builders/delete.mjs +26 -9
- package/dist/src/query-builders/distinct.d.mts +1 -1
- package/dist/src/query-builders/exists.d.mts +1 -1
- package/dist/src/query-builders/first.d.mts +1 -1
- package/dist/src/query-builders/helpers.mjs +28 -0
- package/dist/src/query-builders/insert.d.mts +9 -5
- package/dist/src/query-builders/insert.mjs +19 -7
- package/dist/src/query-builders/orderby-clause.d.mts +1 -1
- package/dist/src/query-builders/pre.d.mts +1 -1
- package/dist/src/query-builders/query-promise.d.mts +2 -2
- package/dist/src/query-builders/query.d.mts +2 -1
- package/dist/src/query-builders/rq.d.mts +2 -2
- package/dist/src/query-builders/select.d.mts +14 -6
- package/dist/src/query-builders/select.mjs +37 -13
- package/dist/src/query-builders/update.d.mts +15 -8
- package/dist/src/query-builders/update.mjs +22 -9
- package/dist/src/query-builders/with.d.mts +51 -0
- package/dist/src/query-builders/with.mjs +47 -0
- package/dist/src/table.d.mts +5 -1
- package/dist/src/table.mjs +2 -2
- package/dist/src/virtual-table.d.mts +51 -0
- package/dist/src/virtual-table.mjs +55 -0
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -9631,7 +9631,9 @@ function orderTables(tables, order) {
|
|
|
9631
9631
|
Object.entries(tables).map(([tableName, table]) => {
|
|
9632
9632
|
const references = Object.values(table.columns).map(
|
|
9633
9633
|
(column) => column.references ? `${column.references.schema}.${column.references.table}` : void 0
|
|
9634
|
-
).filter(
|
|
9634
|
+
).filter(
|
|
9635
|
+
(table2) => table2 !== void 0 && table2 !== tableName
|
|
9636
|
+
);
|
|
9635
9637
|
return [tableName, references];
|
|
9636
9638
|
})
|
|
9637
9639
|
);
|
|
@@ -10455,7 +10457,7 @@ async function status(options) {
|
|
|
10455
10457
|
}
|
|
10456
10458
|
|
|
10457
10459
|
// src/cli/index.ts
|
|
10458
|
-
program.version("1.0.0-alpha.
|
|
10460
|
+
program.version("1.0.0-alpha.16");
|
|
10459
10461
|
var Options = {
|
|
10460
10462
|
config: ["--config <path>", "Path to the config file"]
|
|
10461
10463
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { AnyFilter } from "../filters/index.mjs";
|
|
1
2
|
import { CheckExpression } from "../constraints/check.mjs";
|
|
2
3
|
import { entityType } from "../symbols.mjs";
|
|
3
4
|
import { AnyColumn, StdTable, StdTableColumn } from "../table.mjs";
|
|
4
|
-
import { AnyFilter } from "../filters/index.mjs";
|
|
5
5
|
import { Arg } from "../query-builders/pre.mjs";
|
|
6
6
|
import { Query, QueryContext } from "../query-builders/query.mjs";
|
|
7
7
|
import { Sql } from "../sql.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnyColumn, TableAnyColumn } from "../table.mjs";
|
|
2
1
|
import { AnyFilter, Filter } from "../filters/index.mjs";
|
|
2
|
+
import { AnyColumn, TableAnyColumn } from "../table.mjs";
|
|
3
3
|
import { QueryContext } from "../query-builders/query.mjs";
|
|
4
4
|
import { Sql } from "../sql.mjs";
|
|
5
5
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Column, OnDeleteAction } from "../columns/common.mjs";
|
|
2
|
+
import { AnyColumn, StdTableColumn } from "../table.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/constraints/foreign-key.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Intermediate builder returned by `fk(column)`.
|
|
7
|
+
* Call `.references(refColumn)` to finalise into a `ForeignKey`.
|
|
8
|
+
*/
|
|
9
|
+
declare class ForeignKeyBuilder<TCol extends AnyColumn> {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(column: StdTableColumn<TCol>);
|
|
12
|
+
/**
|
|
13
|
+
* Specify the referenced column.
|
|
14
|
+
* The referenced column's value type must match the source column's value type.
|
|
15
|
+
*/
|
|
16
|
+
references<TRefCol extends Column<any, TCol["ValType"]>>(ref: StdTableColumn<TRefCol>): ForeignKey;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Represents a finalised table-level foreign key constraint.
|
|
20
|
+
* Created via `fk(column).references(refColumn)`.
|
|
21
|
+
*/
|
|
22
|
+
declare class ForeignKey {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(column: StdTableColumn, reference: StdTableColumn, onDelete: OnDeleteAction);
|
|
25
|
+
/**
|
|
26
|
+
* Override the default `CASCADE` delete action.
|
|
27
|
+
*
|
|
28
|
+
* @param action - The `ON DELETE` action to apply.
|
|
29
|
+
* @returns `this` for chaining.
|
|
30
|
+
*/
|
|
31
|
+
onDelete(action: OnDeleteAction): this;
|
|
32
|
+
_: {
|
|
33
|
+
/** Returns the source column of the foreign key. */getColumn: () => StdTableColumn; /** Returns the referenced column of the foreign key. */
|
|
34
|
+
getReference: () => StdTableColumn; /** Returns the configured `ON DELETE` action. */
|
|
35
|
+
getOnDelete: () => OnDeleteAction;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Entry point for defining a table-level foreign key constraint.
|
|
40
|
+
* Use inside the `foreignKeys` callback in `TableExtra`.
|
|
41
|
+
*
|
|
42
|
+
* Because `foreignKeys` receives the fully-constructed table as a typed
|
|
43
|
+
* parameter `t`, column references are already resolved — no thunk needed.
|
|
44
|
+
*
|
|
45
|
+
* @param column - The source column on this table.
|
|
46
|
+
* @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* table("public", "comments", { ... }, {
|
|
51
|
+
* foreignKeys: (t, fk) => [
|
|
52
|
+
* fk(t.parentId).references(t.id).onDelete("SET NULL"),
|
|
53
|
+
* ],
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function fk<TCol extends AnyColumn>(column: StdTableColumn<TCol>): ForeignKeyBuilder<TCol>;
|
|
58
|
+
/** The type of the `fk` helper injected into the `foreignKeys` callback. */
|
|
59
|
+
type ForeignKeyFn = typeof fk;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { ForeignKey, ForeignKeyFn };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//#region src/constraints/foreign-key.ts
|
|
2
|
+
/**
|
|
3
|
+
* Intermediate builder returned by `fk(column)`.
|
|
4
|
+
* Call `.references(refColumn)` to finalise into a `ForeignKey`.
|
|
5
|
+
*/
|
|
6
|
+
var ForeignKeyBuilder = class {
|
|
7
|
+
#column;
|
|
8
|
+
constructor(column) {
|
|
9
|
+
this.#column = column;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Specify the referenced column.
|
|
13
|
+
* The referenced column's value type must match the source column's value type.
|
|
14
|
+
*/
|
|
15
|
+
references(ref) {
|
|
16
|
+
return new ForeignKey(this.#column, ref, "CASCADE");
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Represents a finalised table-level foreign key constraint.
|
|
21
|
+
* Created via `fk(column).references(refColumn)`.
|
|
22
|
+
*/
|
|
23
|
+
var ForeignKey = class {
|
|
24
|
+
#column;
|
|
25
|
+
#reference;
|
|
26
|
+
#onDelete;
|
|
27
|
+
constructor(column, reference, onDelete) {
|
|
28
|
+
this.#column = column;
|
|
29
|
+
this.#reference = reference;
|
|
30
|
+
this.#onDelete = onDelete;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Override the default `CASCADE` delete action.
|
|
34
|
+
*
|
|
35
|
+
* @param action - The `ON DELETE` action to apply.
|
|
36
|
+
* @returns `this` for chaining.
|
|
37
|
+
*/
|
|
38
|
+
onDelete(action) {
|
|
39
|
+
this.#onDelete = action;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
_ = {
|
|
43
|
+
/** Returns the source column of the foreign key. */
|
|
44
|
+
getColumn: () => this.#column,
|
|
45
|
+
/** Returns the referenced column of the foreign key. */
|
|
46
|
+
getReference: () => this.#reference,
|
|
47
|
+
/** Returns the configured `ON DELETE` action. */
|
|
48
|
+
getOnDelete: () => this.#onDelete
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Entry point for defining a table-level foreign key constraint.
|
|
53
|
+
* Use inside the `foreignKeys` callback in `TableExtra`.
|
|
54
|
+
*
|
|
55
|
+
* Because `foreignKeys` receives the fully-constructed table as a typed
|
|
56
|
+
* parameter `t`, column references are already resolved — no thunk needed.
|
|
57
|
+
*
|
|
58
|
+
* @param column - The source column on this table.
|
|
59
|
+
* @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* table("public", "comments", { ... }, {
|
|
64
|
+
* foreignKeys: (t, fk) => [
|
|
65
|
+
* fk(t.parentId).references(t.id).onDelete("SET NULL"),
|
|
66
|
+
* ],
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
function fk(column) {
|
|
71
|
+
return new ForeignKeyBuilder(column);
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { fk };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { VirtualTable } from "./virtual-table.mjs";
|
|
2
|
+
import { AnyColumn } from "./table.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/cte.d.ts
|
|
5
|
+
declare class Cte<TName extends string, TColumns extends Record<string, AnyColumn>> extends VirtualTable<TName, TColumns> {
|
|
6
|
+
/** Phantom type — extracts `TName` safely through `CteWithColumns` intersections. */
|
|
7
|
+
readonly $cteName: TName;
|
|
8
|
+
}
|
|
9
|
+
type CteWithColumns<TName extends string, TColumns extends Record<string, AnyColumn>> = Cte<TName, TColumns> & TColumns;
|
|
10
|
+
type AnyCteWithColumns = CteWithColumns<any, Record<any, any>>;
|
|
11
|
+
/** Maps a tuple of `CteWithColumns` to an object keyed by CTE name. */
|
|
12
|
+
type CtesByName<TCtes extends AnyCteWithColumns[]> = { [K in TCtes[number] as K extends {
|
|
13
|
+
$cteName: infer TName extends string;
|
|
14
|
+
} ? TName : never]: K };
|
|
15
|
+
//#endregion
|
|
16
|
+
export { AnyCteWithColumns, Cte, CteWithColumns, CtesByName };
|
package/dist/src/cte.mjs
ADDED
package/dist/src/db.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { CamelToSnake, Valueof } from "./types.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { AnySubquery, InferQueryColumns } from "./virtual-table.mjs";
|
|
3
3
|
import { SelectBuilder } from "./query-builders/select.mjs";
|
|
4
4
|
import { FilterExpression } from "./filters/index.mjs";
|
|
5
|
+
import { AnyColumn, AnyRelations, IsTableWC, Relations, TableWCorNever, TableWithColumns } from "./table.mjs";
|
|
6
|
+
import { AnyCteWithColumns, CteWithColumns } from "./cte.mjs";
|
|
5
7
|
import { Config } from "./index.mjs";
|
|
6
8
|
import { AggregateQuery } from "./query-builders/aggregates.mjs";
|
|
7
9
|
import { CountQuery } from "./query-builders/count.mjs";
|
|
@@ -13,6 +15,7 @@ import { InsertBuilder } from "./query-builders/insert.mjs";
|
|
|
13
15
|
import { RawQuery } from "./query-builders/raw.mjs";
|
|
14
16
|
import { RelationQueryBuilder } from "./query-builders/rq.mjs";
|
|
15
17
|
import { UpdateBuilder } from "./query-builders/update.mjs";
|
|
18
|
+
import { WithStatement } from "./query-builders/with.mjs";
|
|
16
19
|
import { $Pool, QueryExecutor } from "./connectors/common.mjs";
|
|
17
20
|
|
|
18
21
|
//#region src/db.d.ts
|
|
@@ -149,6 +152,26 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
|
|
|
149
152
|
* @returns A RawQuery instance that resolves to the query result (or transformed result if handler provided)
|
|
150
153
|
*/
|
|
151
154
|
raw<TReturn = unknown>(query: string, args: (string | number | null)[] | undefined, rowsHandler: ((rows: any[]) => TReturn) | undefined): RawQuery<TReturn>;
|
|
155
|
+
/**
|
|
156
|
+
* Create a CTE definition by name.
|
|
157
|
+
* @param name The CTE name to be used in the WITH clause
|
|
158
|
+
* @returns An object with `.as()` to bind a subquery
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* const activeCte = db.with("activeUsers").as(db.from(Users).select(...));
|
|
162
|
+
*/
|
|
163
|
+
with<TCteName extends string>(name: TCteName): {
|
|
164
|
+
as: <TQuery extends AnySubquery>(query: TQuery) => CteWithColumns<TCteName, InferQueryColumns<TCteName, TQuery>>;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Attach one or more CTEs to a statement.
|
|
168
|
+
* @param ctes One or more CTE instances created via `db.with("name").as(...)`
|
|
169
|
+
* @returns A `WithStatement` to build the SELECT/INSERT/UPDATE/DELETE against
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* const rows = await db.with(activeCte).from(ctes => ctes.activeUsers).select();
|
|
173
|
+
*/
|
|
174
|
+
with<TCtes extends [AnyCteWithColumns, ...AnyCteWithColumns[]]>(...ctes: TCtes): WithStatement<TCtes, TPrepare>;
|
|
152
175
|
}
|
|
153
176
|
declare class DB<TTName extends string, TTables extends Record<TTName, TableWithColumns<string, string, Record<string, AnyColumn>>>, TAllRelations extends Record<StdTableFullName, AnyRelations>> extends Base<TTName, TTables, TAllRelations, false> {
|
|
154
177
|
#private;
|
package/dist/src/db.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Query } from "./query-builders/query.mjs";
|
|
2
2
|
import { is } from "./entity.mjs";
|
|
3
|
+
import { Relations, Table } from "./table.mjs";
|
|
4
|
+
import { bindVirtualTableColumns } from "./virtual-table.mjs";
|
|
5
|
+
import { Cte } from "./cte.mjs";
|
|
3
6
|
import { AggregateQuery } from "./query-builders/aggregates.mjs";
|
|
4
7
|
import { CountQuery } from "./query-builders/count.mjs";
|
|
5
8
|
import { DeleteQuery } from "./query-builders/delete.mjs";
|
|
@@ -11,7 +14,7 @@ import { RawQuery } from "./query-builders/raw.mjs";
|
|
|
11
14
|
import { RelationQueryBuilder } from "./query-builders/rq.mjs";
|
|
12
15
|
import { SelectBuilder } from "./query-builders/select.mjs";
|
|
13
16
|
import { UpdateBuilder } from "./query-builders/update.mjs";
|
|
14
|
-
import {
|
|
17
|
+
import { WithStatement } from "./query-builders/with.mjs";
|
|
15
18
|
//#region src/db.ts
|
|
16
19
|
var Base = class {
|
|
17
20
|
#allRelations;
|
|
@@ -119,6 +122,12 @@ var Base = class {
|
|
|
119
122
|
raw(query, args = [], rowsHandler) {
|
|
120
123
|
return new RawQuery(query, args, rowsHandler, this.#getExecutor());
|
|
121
124
|
}
|
|
125
|
+
with(nameOrFirstCte, ...restCtes) {
|
|
126
|
+
if (typeof nameOrFirstCte === "string") return { as: (query) => {
|
|
127
|
+
return bindVirtualTableColumns(new Cte(nameOrFirstCte, query.getResolvedColumns(), query));
|
|
128
|
+
} };
|
|
129
|
+
return new WithStatement([nameOrFirstCte, ...restCtes], this.#getExecutor(), this.$.pre);
|
|
130
|
+
}
|
|
122
131
|
};
|
|
123
132
|
var DB = class extends Base {
|
|
124
133
|
#pool;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BasicTypes, Or } from "../types.mjs";
|
|
2
|
-
import { AnyColumn } from "../table.mjs";
|
|
3
2
|
import { AnyScalarSqlFn } from "../functions/index.mjs";
|
|
4
3
|
import { SelectQuery } from "../query-builders/select.mjs";
|
|
4
|
+
import { AnyColumn } from "../table.mjs";
|
|
5
5
|
import { Arg, IsArg } from "../query-builders/pre.mjs";
|
|
6
6
|
import { Query, QueryContext } from "../query-builders/query.mjs";
|
|
7
7
|
import { Sql } from "../sql.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnyColumn } from "../table.mjs";
|
|
2
1
|
import { AnyScalarSqlFn, ExprColumns, HasArg, SqlFn } from "./index.mjs";
|
|
2
|
+
import { AnyColumn } from "../table.mjs";
|
|
3
3
|
import { Query, QueryContext } from "../query-builders/query.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/functions/aggregate.d.ts
|
|
@@ -36,6 +36,9 @@ declare class CountFn<TExpr extends AnyColumn> extends SqlFn<TExpr, false, "aggr
|
|
|
36
36
|
private readonly expr;
|
|
37
37
|
readonly isAggregate = true;
|
|
38
38
|
constructor(expr: TExpr);
|
|
39
|
+
toDriverValue(value: number | null): unknown;
|
|
40
|
+
toSQLValue(value: number | null): string;
|
|
41
|
+
fromDriverValue(value: unknown): number | null;
|
|
39
42
|
/** Appends `count(expr)` to the query SQL. */
|
|
40
43
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
41
44
|
}
|
|
@@ -50,6 +53,9 @@ declare class CountFn<TExpr extends AnyColumn> extends SqlFn<TExpr, false, "aggr
|
|
|
50
53
|
*/
|
|
51
54
|
declare class CountStarFn extends SqlFn<never, false, "aggregate", "numeric", number> {
|
|
52
55
|
readonly isAggregate = true;
|
|
56
|
+
toDriverValue(value: number | null): unknown;
|
|
57
|
+
toSQLValue(value: number | null): string;
|
|
58
|
+
fromDriverValue(value: unknown): number | null;
|
|
53
59
|
/** Appends `count(*)` to the query SQL. */
|
|
54
60
|
toQuery(query: Query, _ctx?: QueryContext): void;
|
|
55
61
|
}
|
|
@@ -66,6 +72,9 @@ declare class CountDistinctFn<TExpr extends AnyColumn> extends SqlFn<TExpr, fals
|
|
|
66
72
|
private readonly expr;
|
|
67
73
|
readonly isAggregate = true;
|
|
68
74
|
constructor(expr: TExpr);
|
|
75
|
+
toDriverValue(value: number | null): unknown;
|
|
76
|
+
toSQLValue(value: number | null): string;
|
|
77
|
+
fromDriverValue(value: unknown): number | null;
|
|
69
78
|
/** Appends `count(DISTINCT expr)` to the query SQL. */
|
|
70
79
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
71
80
|
}
|
|
@@ -111,6 +120,9 @@ declare class SumFn<TExpr extends NumericAggregateInput> extends SqlFn<ExprColum
|
|
|
111
120
|
private readonly expr;
|
|
112
121
|
readonly isAggregate = true;
|
|
113
122
|
constructor(expr: TExpr);
|
|
123
|
+
toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
|
|
124
|
+
toSQLValue(value: TExpr["$"]["TsType"] | null): string;
|
|
125
|
+
fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
|
|
114
126
|
/** Appends `sum(expr)` to the query SQL. */
|
|
115
127
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
116
128
|
}
|
|
@@ -140,12 +152,12 @@ declare class AvgFn<TExpr extends NumericAggregateInput> extends SqlFn<ExprColum
|
|
|
140
152
|
private readonly expr;
|
|
141
153
|
readonly isAggregate = true;
|
|
142
154
|
constructor(expr: TExpr);
|
|
155
|
+
toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
|
|
156
|
+
toSQLValue(value: TExpr["$"]["TsType"] | null): string;
|
|
143
157
|
/**
|
|
144
158
|
* Preserves the raw PostgreSQL `numeric` string (e.g. `"2.5000000000"`).
|
|
145
|
-
* The default `SqlFn.fromDriver` would coerce numeric strings to `number`,
|
|
146
|
-
* which contradicts the declared `string | null` return type.
|
|
147
159
|
*/
|
|
148
|
-
|
|
160
|
+
fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
|
|
149
161
|
/** Appends `avg(expr)` to the query SQL. */
|
|
150
162
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
151
163
|
}
|
|
@@ -176,11 +188,13 @@ declare class MinFn<TExpr extends AggregateInput> extends SqlFn<ExprColumns<TExp
|
|
|
176
188
|
private readonly expr;
|
|
177
189
|
readonly isAggregate = true;
|
|
178
190
|
constructor(expr: TExpr);
|
|
191
|
+
toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
|
|
192
|
+
toSQLValue(value: TExpr["$"]["TsType"] | null): string;
|
|
179
193
|
/**
|
|
180
|
-
* Delegates to the inner expression's own
|
|
194
|
+
* Delegates to the inner expression's own conversion so that the result
|
|
181
195
|
* is deserialized to the same TypeScript type as the wrapped column/function.
|
|
182
196
|
*/
|
|
183
|
-
|
|
197
|
+
fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
|
|
184
198
|
/** Appends `min(expr)` to the query SQL. */
|
|
185
199
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
186
200
|
}
|
|
@@ -211,11 +225,13 @@ declare class MaxFn<TExpr extends AggregateInput> extends SqlFn<ExprColumns<TExp
|
|
|
211
225
|
private readonly expr;
|
|
212
226
|
readonly isAggregate = true;
|
|
213
227
|
constructor(expr: TExpr);
|
|
228
|
+
toDriverValue(value: TExpr["$"]["TsType"] | null): unknown;
|
|
229
|
+
toSQLValue(value: TExpr["$"]["TsType"] | null): string;
|
|
214
230
|
/**
|
|
215
|
-
* Delegates to the inner expression's own
|
|
231
|
+
* Delegates to the inner expression's own conversion so that the result
|
|
216
232
|
* is deserialized to the same TypeScript type as the wrapped column/function.
|
|
217
233
|
*/
|
|
218
|
-
|
|
234
|
+
fromDriverValue(value: unknown): TExpr["$"]["TsType"] | null;
|
|
219
235
|
/** Appends `max(expr)` to the query SQL. */
|
|
220
236
|
toQuery(query: Query, ctx?: QueryContext): void;
|
|
221
237
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SqlFn } from "./index.mjs";
|
|
2
|
+
import { isCol } from "../entity.mjs";
|
|
2
3
|
//#region src/functions/aggregate.ts
|
|
3
4
|
/**
|
|
4
5
|
* SQL aggregate expression: `count(col)`
|
|
@@ -17,6 +18,15 @@ var CountFn = class extends SqlFn {
|
|
|
17
18
|
super();
|
|
18
19
|
this.expr = expr;
|
|
19
20
|
}
|
|
21
|
+
toDriverValue(value) {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
toSQLValue(value) {
|
|
25
|
+
return SqlFn._numericToSQL(value);
|
|
26
|
+
}
|
|
27
|
+
fromDriverValue(value) {
|
|
28
|
+
return SqlFn._numericFromDriver(value);
|
|
29
|
+
}
|
|
20
30
|
/** Appends `count(expr)` to the query SQL. */
|
|
21
31
|
toQuery(query, ctx) {
|
|
22
32
|
query.sql += "count(";
|
|
@@ -35,6 +45,15 @@ var CountFn = class extends SqlFn {
|
|
|
35
45
|
*/
|
|
36
46
|
var CountStarFn = class extends SqlFn {
|
|
37
47
|
isAggregate = true;
|
|
48
|
+
toDriverValue(value) {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
toSQLValue(value) {
|
|
52
|
+
return SqlFn._numericToSQL(value);
|
|
53
|
+
}
|
|
54
|
+
fromDriverValue(value) {
|
|
55
|
+
return SqlFn._numericFromDriver(value);
|
|
56
|
+
}
|
|
38
57
|
/** Appends `count(*)` to the query SQL. */
|
|
39
58
|
toQuery(query, _ctx) {
|
|
40
59
|
query.sql += "count(*)";
|
|
@@ -55,6 +74,15 @@ var CountDistinctFn = class extends SqlFn {
|
|
|
55
74
|
super();
|
|
56
75
|
this.expr = expr;
|
|
57
76
|
}
|
|
77
|
+
toDriverValue(value) {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
toSQLValue(value) {
|
|
81
|
+
return SqlFn._numericToSQL(value);
|
|
82
|
+
}
|
|
83
|
+
fromDriverValue(value) {
|
|
84
|
+
return SqlFn._numericFromDriver(value);
|
|
85
|
+
}
|
|
58
86
|
/** Appends `count(DISTINCT expr)` to the query SQL. */
|
|
59
87
|
toQuery(query, ctx) {
|
|
60
88
|
query.sql += "count(DISTINCT ";
|
|
@@ -96,6 +124,17 @@ var SumFn = class extends SqlFn {
|
|
|
96
124
|
super();
|
|
97
125
|
this.expr = expr;
|
|
98
126
|
}
|
|
127
|
+
toDriverValue(value) {
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
toSQLValue(value) {
|
|
131
|
+
return SqlFn._numericToSQL(value);
|
|
132
|
+
}
|
|
133
|
+
fromDriverValue(value) {
|
|
134
|
+
if (value === null) return null;
|
|
135
|
+
if (typeof value === "bigint") return value;
|
|
136
|
+
return Number(value);
|
|
137
|
+
}
|
|
99
138
|
/** Appends `sum(expr)` to the query SQL. */
|
|
100
139
|
toQuery(query, ctx) {
|
|
101
140
|
query.sql += "sum(";
|
|
@@ -133,12 +172,16 @@ var AvgFn = class extends SqlFn {
|
|
|
133
172
|
super();
|
|
134
173
|
this.expr = expr;
|
|
135
174
|
}
|
|
175
|
+
toDriverValue(value) {
|
|
176
|
+
return value;
|
|
177
|
+
}
|
|
178
|
+
toSQLValue(value) {
|
|
179
|
+
return SqlFn._stringToSQL(value);
|
|
180
|
+
}
|
|
136
181
|
/**
|
|
137
182
|
* Preserves the raw PostgreSQL `numeric` string (e.g. `"2.5000000000"`).
|
|
138
|
-
* The default `SqlFn.fromDriver` would coerce numeric strings to `number`,
|
|
139
|
-
* which contradicts the declared `string | null` return type.
|
|
140
183
|
*/
|
|
141
|
-
|
|
184
|
+
fromDriverValue(value) {
|
|
142
185
|
if (value === null) return null;
|
|
143
186
|
return value;
|
|
144
187
|
}
|
|
@@ -180,13 +223,21 @@ var MinFn = class extends SqlFn {
|
|
|
180
223
|
super();
|
|
181
224
|
this.expr = expr;
|
|
182
225
|
}
|
|
226
|
+
toDriverValue(value) {
|
|
227
|
+
return value;
|
|
228
|
+
}
|
|
229
|
+
toSQLValue(value) {
|
|
230
|
+
if (isCol(this.expr)) return this.expr.toSQLScalar(value);
|
|
231
|
+
return this.expr.toSQLValue(value);
|
|
232
|
+
}
|
|
183
233
|
/**
|
|
184
|
-
* Delegates to the inner expression's own
|
|
234
|
+
* Delegates to the inner expression's own conversion so that the result
|
|
185
235
|
* is deserialized to the same TypeScript type as the wrapped column/function.
|
|
186
236
|
*/
|
|
187
|
-
|
|
237
|
+
fromDriverValue(value) {
|
|
188
238
|
if (value === null) return null;
|
|
189
|
-
return this.expr.
|
|
239
|
+
if (isCol(this.expr)) return this.expr.fromDriverScalar(value);
|
|
240
|
+
return this.expr.fromDriverValue(value);
|
|
190
241
|
}
|
|
191
242
|
/** Appends `min(expr)` to the query SQL. */
|
|
192
243
|
toQuery(query, ctx) {
|
|
@@ -226,13 +277,21 @@ var MaxFn = class extends SqlFn {
|
|
|
226
277
|
super();
|
|
227
278
|
this.expr = expr;
|
|
228
279
|
}
|
|
280
|
+
toDriverValue(value) {
|
|
281
|
+
return value;
|
|
282
|
+
}
|
|
283
|
+
toSQLValue(value) {
|
|
284
|
+
if (isCol(this.expr)) return this.expr.toSQLScalar(value);
|
|
285
|
+
return this.expr.toSQLValue(value);
|
|
286
|
+
}
|
|
229
287
|
/**
|
|
230
|
-
* Delegates to the inner expression's own
|
|
288
|
+
* Delegates to the inner expression's own conversion so that the result
|
|
231
289
|
* is deserialized to the same TypeScript type as the wrapped column/function.
|
|
232
290
|
*/
|
|
233
|
-
|
|
291
|
+
fromDriverValue(value) {
|
|
234
292
|
if (value === null) return null;
|
|
235
|
-
return this.expr.
|
|
293
|
+
if (isCol(this.expr)) return this.expr.fromDriverScalar(value);
|
|
294
|
+
return this.expr.fromDriverValue(value);
|
|
236
295
|
}
|
|
237
296
|
/** Appends `max(expr)` to the query SQL. */
|
|
238
297
|
toQuery(query, ctx) {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Or } from "../types.mjs";
|
|
2
|
+
import { AnySqlFn, ExprColumns, HasArg, SqlFn } from "./index.mjs";
|
|
3
|
+
import { AnyScalarColumn } from "../table.mjs";
|
|
4
|
+
import { Arg, IsArg } from "../query-builders/pre.mjs";
|
|
5
|
+
import { Query, QueryContext } from "../query-builders/query.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/functions/arithmetic.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Union of every valid operand for arithmetic operators:
|
|
10
|
+
* a numeric column or SqlFn, a plain number literal, or an `Arg<number>`.
|
|
11
|
+
*/
|
|
12
|
+
type NumericOperand = ((AnyScalarColumn | AnySqlFn) & {
|
|
13
|
+
$: {
|
|
14
|
+
PgType: "numeric";
|
|
15
|
+
};
|
|
16
|
+
}) | number | Arg<number>;
|
|
17
|
+
/**
|
|
18
|
+
* Computes the `THasArg` slot for a two-operand arithmetic expression.
|
|
19
|
+
* Resolves to `true` if either operand embeds an `Arg` or is itself an `Arg`.
|
|
20
|
+
*/
|
|
21
|
+
type BinaryOpHasArg<TLeft extends NumericOperand, TRight extends NumericOperand> = Or<Or<HasArg<TLeft>, IsArg<TLeft>>, Or<HasArg<TRight>, IsArg<TRight>>>;
|
|
22
|
+
declare class AddFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
|
|
23
|
+
private readonly left;
|
|
24
|
+
private readonly right;
|
|
25
|
+
constructor(left: TLeft, right: TRight);
|
|
26
|
+
toDriverValue(value: number | null): unknown;
|
|
27
|
+
toSQLValue(value: number | null): string;
|
|
28
|
+
fromDriverValue(value: unknown): number | null;
|
|
29
|
+
toQuery(query: Query, ctx?: QueryContext): void;
|
|
30
|
+
}
|
|
31
|
+
/** Returns the sum of two numeric expressions. */
|
|
32
|
+
declare function add<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): AddFn<TLeft, TRight>;
|
|
33
|
+
declare class SubFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
|
|
34
|
+
private readonly left;
|
|
35
|
+
private readonly right;
|
|
36
|
+
constructor(left: TLeft, right: TRight);
|
|
37
|
+
toDriverValue(value: number | null): unknown;
|
|
38
|
+
toSQLValue(value: number | null): string;
|
|
39
|
+
fromDriverValue(value: unknown): number | null;
|
|
40
|
+
toQuery(query: Query, ctx?: QueryContext): void;
|
|
41
|
+
}
|
|
42
|
+
/** Returns the difference of two numeric expressions. */
|
|
43
|
+
declare function sub<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): SubFn<TLeft, TRight>;
|
|
44
|
+
declare class MulFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
|
|
45
|
+
private readonly left;
|
|
46
|
+
private readonly right;
|
|
47
|
+
constructor(left: TLeft, right: TRight);
|
|
48
|
+
toDriverValue(value: number | null): unknown;
|
|
49
|
+
toSQLValue(value: number | null): string;
|
|
50
|
+
fromDriverValue(value: unknown): number | null;
|
|
51
|
+
toQuery(query: Query, ctx?: QueryContext): void;
|
|
52
|
+
}
|
|
53
|
+
/** Returns the product of two numeric expressions. */
|
|
54
|
+
declare function mul<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): MulFn<TLeft, TRight>;
|
|
55
|
+
declare class DivFn<TLeft extends NumericOperand, TRight extends NumericOperand> extends SqlFn<ExprColumns<TLeft> | ExprColumns<TRight>, BinaryOpHasArg<TLeft, TRight>, "scalar", "numeric", number> {
|
|
56
|
+
private readonly left;
|
|
57
|
+
private readonly right;
|
|
58
|
+
constructor(left: TLeft, right: TRight);
|
|
59
|
+
toDriverValue(value: number | null): unknown;
|
|
60
|
+
toSQLValue(value: number | null): string;
|
|
61
|
+
fromDriverValue(value: unknown): number | null;
|
|
62
|
+
toQuery(query: Query, ctx?: QueryContext): void;
|
|
63
|
+
}
|
|
64
|
+
/** Returns the quotient of two numeric expressions. */
|
|
65
|
+
declare function div<TLeft extends NumericOperand, TRight extends NumericOperand>(left: TLeft, right: TRight): DivFn<TLeft, TRight>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { add, div, mul, sub };
|