pqb 0.3.2 → 0.3.4
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/index.d.ts +1239 -1342
- package/dist/index.esm.js +482 -432
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +484 -434
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnType.test.ts +2 -1
- package/src/columnSchema/columnsSchema.ts +20 -60
- package/src/db.test.ts +1 -1
- package/src/db.ts +27 -20
- package/src/query.ts +36 -32
- package/src/queryDataUtils.ts +0 -7
- package/src/queryMethods/aggregate.ts +2 -3
- package/src/queryMethods/clear.ts +3 -4
- package/src/queryMethods/delete.ts +3 -3
- package/src/queryMethods/from.test.ts +2 -3
- package/src/queryMethods/get.ts +0 -1
- package/src/queryMethods/index.ts +1 -0
- package/src/queryMethods/insert.ts +14 -13
- package/src/queryMethods/json.ts +7 -3
- package/src/queryMethods/merge.test.ts +471 -0
- package/src/queryMethods/merge.ts +67 -0
- package/src/queryMethods/queryMethods.test.ts +14 -59
- package/src/queryMethods/queryMethods.ts +18 -33
- package/src/queryMethods/select.test.ts +4 -0
- package/src/queryMethods/select.ts +4 -2
- package/src/queryMethods/then.ts +3 -3
- package/src/queryMethods/update.ts +21 -14
- package/src/sql/fromAndAs.ts +2 -3
- package/src/sql/select.ts +1 -2
- package/src/sql/toSql.ts +4 -3
- package/src/sql/types.ts +7 -3
- package/src/sql/window.ts +1 -1
- package/src/sql/with.ts +25 -20
- package/src/utils.test.ts +0 -18
- package/src/utils.ts +0 -40
- package/src/columnSchema/columnsSchema.test.ts +0 -32
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
useTestDatabase,
|
|
11
11
|
} from '../test-utils';
|
|
12
12
|
import { createDb } from '../db';
|
|
13
|
+
import { columnTypes } from './columnTypes';
|
|
13
14
|
|
|
14
15
|
describe('column base', () => {
|
|
15
16
|
useTestDatabase();
|
|
@@ -107,7 +108,7 @@ describe('column base', () => {
|
|
|
107
108
|
});
|
|
108
109
|
|
|
109
110
|
it('should return column data as returned from db if not set', async () => {
|
|
110
|
-
const db = createDb({ adapter });
|
|
111
|
+
const db = createDb({ adapter, columnTypes });
|
|
111
112
|
|
|
112
113
|
const UserWithPlainTimestamp = db('user', (t) => ({
|
|
113
114
|
createdAt: t.timestamp(),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ColumnInput, ColumnOutput, ColumnType } from './columnType';
|
|
2
2
|
import { Operators } from '../columnsOperators';
|
|
3
|
-
import { SetOptional, SomeIsTrue
|
|
3
|
+
import { SetOptional, SomeIsTrue } from '../utils';
|
|
4
|
+
import { StringKey } from '../common';
|
|
4
5
|
|
|
5
6
|
export type ColumnsShape = Record<string, ColumnType>;
|
|
6
7
|
|
|
@@ -53,63 +54,22 @@ export abstract class PluckResultColumnType<
|
|
|
53
54
|
C extends ColumnType,
|
|
54
55
|
> extends ColumnType<C['type'][], typeof Operators.any> {}
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
? UnionToArray<
|
|
75
|
-
S,
|
|
76
|
-
Exclude<T, PopKeyofColumnShapeUnion<S, T>>,
|
|
77
|
-
[PopKeyofColumnShapeUnion<S, T>, ...A]
|
|
78
|
-
>
|
|
79
|
-
: [T, ...A];
|
|
80
|
-
|
|
81
|
-
type GetPrimaryKeys<S extends ColumnsShape> = UnionToArray<
|
|
82
|
-
S,
|
|
83
|
-
{ [K in keyof S]: S[K] extends { isPrimaryKey: true } ? K : never }[keyof S]
|
|
57
|
+
// resolves in string literal of single primary key
|
|
58
|
+
// if table has two or more primary keys it will resolve in never
|
|
59
|
+
export type SinglePrimaryKey<Shape extends ColumnsShape> = StringKey<
|
|
60
|
+
{
|
|
61
|
+
[K in keyof Shape]: Shape[K]['isPrimaryKey'] extends true
|
|
62
|
+
? [
|
|
63
|
+
{
|
|
64
|
+
[S in keyof Shape]: Shape[S]['isPrimaryKey'] extends true
|
|
65
|
+
? S extends K
|
|
66
|
+
? never
|
|
67
|
+
: S
|
|
68
|
+
: never;
|
|
69
|
+
}[keyof Shape],
|
|
70
|
+
] extends [never]
|
|
71
|
+
? K
|
|
72
|
+
: never
|
|
73
|
+
: never;
|
|
74
|
+
}[keyof Shape]
|
|
84
75
|
>;
|
|
85
|
-
|
|
86
|
-
type GetPrimaryTypes<
|
|
87
|
-
S extends ColumnsShape,
|
|
88
|
-
Keys extends [...(keyof S | string)[]] = GetPrimaryKeys<S>,
|
|
89
|
-
> = GetTypesFromKeys<S, Keys>;
|
|
90
|
-
|
|
91
|
-
type GetTypesFromKeys<
|
|
92
|
-
S extends ColumnsShape,
|
|
93
|
-
T extends [...(keyof S)[]],
|
|
94
|
-
> = T extends [
|
|
95
|
-
infer Head extends keyof S,
|
|
96
|
-
...infer Tail extends [...(keyof S)[]],
|
|
97
|
-
]
|
|
98
|
-
? [GetTypeFromKey<S, Head>, ...GetTypesFromKeys<S, Tail>]
|
|
99
|
-
: [];
|
|
100
|
-
|
|
101
|
-
type GetTypeFromKey<S extends ColumnsShape, T extends keyof S> = S[T]['type'];
|
|
102
|
-
|
|
103
|
-
export class TableSchema<Shape extends ColumnsShape> {
|
|
104
|
-
primaryKeys: string extends keyof Shape ? string[] : GetPrimaryKeys<Shape>;
|
|
105
|
-
primaryTypes!: GetPrimaryTypes<Shape>;
|
|
106
|
-
|
|
107
|
-
constructor(public shape: Shape) {
|
|
108
|
-
this.primaryKeys = Object.entries(this.shape)
|
|
109
|
-
.filter(([, column]) => {
|
|
110
|
-
return column.isPrimaryKey;
|
|
111
|
-
})
|
|
112
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
-
.map(([key]) => key) as any;
|
|
114
|
-
}
|
|
115
|
-
}
|
package/src/db.test.ts
CHANGED
|
@@ -30,7 +30,7 @@ describe('db', () => {
|
|
|
30
30
|
it('should return date as string by default', async () => {
|
|
31
31
|
await User.insert(userData);
|
|
32
32
|
|
|
33
|
-
const db = createDb({ adapter });
|
|
33
|
+
const db = createDb({ adapter, columnTypes });
|
|
34
34
|
const table = db('user', (t) => ({
|
|
35
35
|
createdAt: t.timestamp(),
|
|
36
36
|
}));
|
package/src/db.ts
CHANGED
|
@@ -17,13 +17,11 @@ import { QueryData, SelectQueryData, Sql, ToSqlOptions } from './sql';
|
|
|
17
17
|
import { AdapterOptions, Adapter } from './adapter';
|
|
18
18
|
import {
|
|
19
19
|
ColumnsShape,
|
|
20
|
-
columnTypes,
|
|
21
20
|
ColumnShapeOutput,
|
|
22
|
-
TableSchema,
|
|
23
21
|
ColumnShapeInput,
|
|
24
|
-
ColumnTypes,
|
|
25
22
|
ColumnTypesBase,
|
|
26
23
|
getColumnTypes,
|
|
24
|
+
SinglePrimaryKey,
|
|
27
25
|
} from './columnSchema';
|
|
28
26
|
import { applyMixins, pushOrNewArray } from './utils';
|
|
29
27
|
import { StringKey } from './common';
|
|
@@ -46,23 +44,20 @@ export interface Db<
|
|
|
46
44
|
): this;
|
|
47
45
|
|
|
48
46
|
adapter: Adapter;
|
|
47
|
+
columns: (keyof ColumnShapeOutput<Shape>)[];
|
|
48
|
+
|
|
49
49
|
queryBuilder: Db;
|
|
50
50
|
whereQueryBuilder: Query['whereQueryBuilder'];
|
|
51
|
+
onQueryBuilder: Query['onQueryBuilder'];
|
|
51
52
|
table: Table;
|
|
52
53
|
shape: Shape;
|
|
53
|
-
|
|
54
|
+
singlePrimaryKey: SinglePrimaryKey<Shape>;
|
|
55
|
+
primaryKeys: Query['primaryKeys'];
|
|
54
56
|
type: ColumnShapeOutput<Shape>;
|
|
55
57
|
inputType: ColumnShapeInput<Shape>;
|
|
56
|
-
returnType: 'all';
|
|
57
|
-
then: ThenResult<
|
|
58
|
-
Pick<ColumnShapeOutput<Shape>, DefaultSelectColumns<Shape>[number]>[]
|
|
59
|
-
>;
|
|
60
58
|
query: QueryData;
|
|
61
|
-
columns: (keyof ColumnShapeOutput<Shape>)[];
|
|
62
|
-
defaultSelectColumns: DefaultSelectColumns<Shape>;
|
|
63
|
-
columnsParsers?: ColumnsParsers;
|
|
64
59
|
result: Pick<Shape, DefaultSelectColumns<Shape>[number]>;
|
|
65
|
-
hasSelect:
|
|
60
|
+
hasSelect: Query['hasSelect'];
|
|
66
61
|
hasWhere: boolean;
|
|
67
62
|
selectable: { [K in keyof Shape]: { as: K; column: Shape[K] } } & {
|
|
68
63
|
[K in keyof Shape as `${Table}.${StringKey<K>}`]: {
|
|
@@ -70,11 +65,17 @@ export interface Db<
|
|
|
70
65
|
column: Shape[K];
|
|
71
66
|
};
|
|
72
67
|
};
|
|
68
|
+
returnType: Query['returnType'];
|
|
69
|
+
then: ThenResult<
|
|
70
|
+
Pick<ColumnShapeOutput<Shape>, DefaultSelectColumns<Shape>[number]>[]
|
|
71
|
+
>;
|
|
73
72
|
tableAlias: undefined;
|
|
74
|
-
windows: PropertyKey[];
|
|
75
|
-
withData: Query['withData'];
|
|
76
73
|
joinedTables: Query['joinedTables'];
|
|
74
|
+
windows: Query['windows'];
|
|
75
|
+
defaultSelectColumns: DefaultSelectColumns<Shape>;
|
|
76
|
+
columnsParsers?: ColumnsParsers;
|
|
77
77
|
relations: Relations;
|
|
78
|
+
withData: Query['withData'];
|
|
78
79
|
[defaultsKey]: Record<
|
|
79
80
|
{
|
|
80
81
|
[K in keyof Shape]: Shape[K]['hasDefault'] extends true ? K : never;
|
|
@@ -105,7 +106,6 @@ export class Db<
|
|
|
105
106
|
this.query = {
|
|
106
107
|
adapter,
|
|
107
108
|
handleResult: handleResult,
|
|
108
|
-
returnType: 'all',
|
|
109
109
|
logger,
|
|
110
110
|
log: logParamToLogObject(logger, options.log),
|
|
111
111
|
} as QueryData;
|
|
@@ -114,7 +114,14 @@ export class Db<
|
|
|
114
114
|
this.query.schema = options.schema;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
this.
|
|
117
|
+
this.primaryKeys = Object.keys(shape).filter(
|
|
118
|
+
(key) => shape[key].isPrimaryKey,
|
|
119
|
+
);
|
|
120
|
+
if (this.primaryKeys.length === 1) {
|
|
121
|
+
this.singlePrimaryKey = this
|
|
122
|
+
.primaryKeys[0] as unknown as SinglePrimaryKey<Shape>;
|
|
123
|
+
}
|
|
124
|
+
|
|
118
125
|
const columns = Object.keys(
|
|
119
126
|
shape,
|
|
120
127
|
) as unknown as (keyof ColumnShapeOutput<Shape>)[];
|
|
@@ -176,18 +183,18 @@ type DbResult<CT extends ColumnTypesBase> = Db & {
|
|
|
176
183
|
close: Adapter['close'];
|
|
177
184
|
};
|
|
178
185
|
|
|
179
|
-
export type DbOptions<CT extends ColumnTypesBase
|
|
186
|
+
export type DbOptions<CT extends ColumnTypesBase> = (
|
|
180
187
|
| { adapter: Adapter }
|
|
181
188
|
| Omit<AdapterOptions, 'log'>
|
|
182
189
|
) &
|
|
183
190
|
QueryLogOptions & {
|
|
184
|
-
columnTypes
|
|
191
|
+
columnTypes: CT;
|
|
185
192
|
};
|
|
186
193
|
|
|
187
|
-
export const createDb = <CT extends ColumnTypesBase
|
|
194
|
+
export const createDb = <CT extends ColumnTypesBase>({
|
|
188
195
|
log,
|
|
189
196
|
logger,
|
|
190
|
-
columnTypes: ct
|
|
197
|
+
columnTypes: ct,
|
|
191
198
|
...options
|
|
192
199
|
}: DbOptions<CT>): DbResult<CT> => {
|
|
193
200
|
const adapter = 'adapter' in options ? options.adapter : new Adapter(options);
|
package/src/query.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { QueryMethods } from './queryMethods/queryMethods';
|
|
2
|
-
import { QueryData } from './sql';
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
QueryMethods,
|
|
3
|
+
ThenResult,
|
|
4
|
+
ColumnInfo,
|
|
5
|
+
WhereQueryBuilder,
|
|
6
|
+
OnQueryBuilder,
|
|
7
|
+
GetArg,
|
|
8
|
+
getValueKey,
|
|
9
|
+
} from './queryMethods';
|
|
10
|
+
import { QueryData } from './sql';
|
|
11
|
+
import { ColumnShapeOutput, ColumnsShape, ColumnType } from './columnSchema';
|
|
12
|
+
import { EmptyObject, Spread } from './utils';
|
|
10
13
|
import { AliasOrTable, RawExpression, StringKey } from './common';
|
|
11
|
-
import { ThenResult } from './queryMethods/then';
|
|
12
14
|
import { Db } from './db';
|
|
13
|
-
import { ColumnInfo } from './queryMethods/columnInfo';
|
|
14
15
|
import { RelationQueryBase, RelationsBase } from './relations';
|
|
15
|
-
import { WhereQueryBuilder } from './queryMethods/where';
|
|
16
|
-
import { OnQueryBuilder } from './queryMethods/join';
|
|
17
|
-
import { GetArg, getValueKey } from './queryMethods/get';
|
|
18
16
|
|
|
19
17
|
export type ColumnParser = (input: unknown) => unknown;
|
|
20
18
|
export type ColumnsParsers = Record<string | getValueKey, ColumnParser>;
|
|
@@ -48,12 +46,8 @@ export type Query = QueryMethods & {
|
|
|
48
46
|
onQueryBuilder: typeof OnQueryBuilder;
|
|
49
47
|
table?: string;
|
|
50
48
|
shape: ColumnsShape;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
primaryKeys: any[];
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
-
primaryTypes: any[];
|
|
56
|
-
};
|
|
49
|
+
singlePrimaryKey: string;
|
|
50
|
+
primaryKeys: string[];
|
|
57
51
|
type: Record<string, unknown>;
|
|
58
52
|
inputType: Record<string, unknown>;
|
|
59
53
|
query: QueryData;
|
|
@@ -65,7 +59,7 @@ export type Query = QueryMethods & {
|
|
|
65
59
|
then: ThenResult<unknown>;
|
|
66
60
|
tableAlias: string | undefined;
|
|
67
61
|
joinedTables: Record<string, Pick<Query, 'result' | 'tableAlias' | 'table'>>;
|
|
68
|
-
windows:
|
|
62
|
+
windows: EmptyObject;
|
|
69
63
|
defaultSelectColumns: string[];
|
|
70
64
|
columnsParsers?: ColumnsParsers;
|
|
71
65
|
relations: RelationsBase;
|
|
@@ -93,15 +87,26 @@ export type QueryReturnType =
|
|
|
93
87
|
| 'rowCount'
|
|
94
88
|
| 'void';
|
|
95
89
|
|
|
90
|
+
export const queryTypeWithLimitOne = {
|
|
91
|
+
one: true,
|
|
92
|
+
oneOrThrow: true,
|
|
93
|
+
} as Record<QueryReturnType, true | undefined>;
|
|
94
|
+
|
|
96
95
|
export type JoinedTablesBase = Record<
|
|
97
96
|
string,
|
|
98
97
|
Pick<Query, 'result' | 'tableAlias' | 'table'>
|
|
99
98
|
>;
|
|
100
99
|
|
|
101
|
-
type
|
|
100
|
+
export type QueryReturnsAll<T extends QueryReturnType> = (
|
|
101
|
+
QueryReturnType extends T ? 'all' : T
|
|
102
|
+
) extends 'all'
|
|
103
|
+
? true
|
|
104
|
+
: false;
|
|
105
|
+
|
|
106
|
+
export type QueryThen<
|
|
102
107
|
ReturnType extends QueryReturnType,
|
|
103
108
|
Result extends ColumnsShape,
|
|
104
|
-
> = ReturnType extends
|
|
109
|
+
> = QueryReturnsAll<ReturnType> extends true
|
|
105
110
|
? ThenResult<ColumnShapeOutput<Result>[]>
|
|
106
111
|
: ReturnType extends 'one'
|
|
107
112
|
? ThenResult<ColumnShapeOutput<Result> | undefined>
|
|
@@ -130,15 +135,15 @@ type QueryThen<
|
|
|
130
135
|
export type AddQuerySelect<
|
|
131
136
|
T extends Pick<Query, 'hasSelect' | 'result' | 'then' | 'returnType'>,
|
|
132
137
|
Result extends ColumnsShape,
|
|
133
|
-
> = T['hasSelect'] extends
|
|
134
|
-
? Omit<T, '
|
|
138
|
+
> = T['hasSelect'] extends true
|
|
139
|
+
? Omit<T, 'result' | 'then'> & {
|
|
140
|
+
result: Spread<[T['result'], Result]>;
|
|
141
|
+
then: QueryThen<T['returnType'], Spread<[T['result'], Result]>>;
|
|
142
|
+
}
|
|
143
|
+
: Omit<T, 'result' | 'then'> & {
|
|
135
144
|
hasSelect: true;
|
|
136
145
|
result: Result;
|
|
137
146
|
then: QueryThen<T['returnType'], Result>;
|
|
138
|
-
}
|
|
139
|
-
: Omit<T, 'result' | 'then'> & {
|
|
140
|
-
result: Spread<[T['result'], Result]>;
|
|
141
|
-
then: QueryThen<T['returnType'], Spread<[T['result'], Result]>>;
|
|
142
147
|
};
|
|
143
148
|
|
|
144
149
|
export type QuerySelectAll<T extends Query> = Omit<
|
|
@@ -288,7 +293,6 @@ export type AddQueryWith<
|
|
|
288
293
|
With extends WithDataItem,
|
|
289
294
|
> = SetQueryWith<T, Spread<[T['withData'], { [K in With['table']]: With }]>>;
|
|
290
295
|
|
|
291
|
-
export type SetQueryWindows<T extends Query, W extends
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
> & { windows: W };
|
|
296
|
+
export type SetQueryWindows<T extends Query, W extends EmptyObject> = T & {
|
|
297
|
+
windows: W;
|
|
298
|
+
};
|
package/src/queryDataUtils.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { Query } from './query';
|
|
2
1
|
import { QueryData } from './sql';
|
|
3
2
|
import { pushOrNewArrayToObject } from './utils';
|
|
4
3
|
|
|
5
|
-
// TODO: remove
|
|
6
|
-
export const removeFromQuery = <T extends Query>(q: T, key: string): T => {
|
|
7
|
-
if (q.query) delete q.query[key as keyof typeof q.query];
|
|
8
|
-
return q;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
4
|
export const pushQueryArray = <T extends { query: QueryData }>(
|
|
12
5
|
q: T,
|
|
13
6
|
key: string,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
StringExpression,
|
|
8
8
|
} from '../common';
|
|
9
9
|
import { AddQuerySelect, Query, SetQueryReturnsValue } from '../query';
|
|
10
|
-
import { pushQueryValue
|
|
10
|
+
import { pushQueryValue } from '../queryDataUtils';
|
|
11
11
|
import {
|
|
12
12
|
ArrayColumn,
|
|
13
13
|
BooleanColumn,
|
|
@@ -42,7 +42,7 @@ export type AggregateOptions<
|
|
|
42
42
|
filter?: WhereArg<T>;
|
|
43
43
|
filterOr?: WhereArg<T>[];
|
|
44
44
|
withinGroup?: boolean;
|
|
45
|
-
over?: T['windows']
|
|
45
|
+
over?: keyof T['windows'] | WindowArgDeclaration<T>;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
// 1 in the name means only methods which takes 1 argument are listed here
|
|
@@ -130,7 +130,6 @@ const get = <T extends Query, Column extends ColumnType>(
|
|
|
130
130
|
q: Query,
|
|
131
131
|
): SetQueryReturnsValue<T, Column> => {
|
|
132
132
|
q.query.returnType = 'valueOrThrow';
|
|
133
|
-
removeFromQuery(q, 'take');
|
|
134
133
|
|
|
135
134
|
const select = q.query.select as SelectItem[];
|
|
136
135
|
if (select.length > 1) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Query } from '../query';
|
|
2
|
-
import { removeFromQuery } from '../queryDataUtils';
|
|
3
2
|
import { isRaw } from '../common';
|
|
4
3
|
|
|
5
4
|
export type ClearStatement =
|
|
@@ -24,8 +23,8 @@ export class Clear {
|
|
|
24
23
|
_clear<T extends Query>(this: T, ...clears: ClearStatement[]): T {
|
|
25
24
|
clears.forEach((clear) => {
|
|
26
25
|
if (clear === 'where') {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
delete this.query.and;
|
|
27
|
+
delete this.query.or;
|
|
29
28
|
} else if (clear === 'counters') {
|
|
30
29
|
if ('type' in this.query && this.query.type === 'update') {
|
|
31
30
|
this.query.updateData = this.query.updateData.filter((item) => {
|
|
@@ -50,7 +49,7 @@ export class Clear {
|
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
} else {
|
|
53
|
-
|
|
52
|
+
delete (this.query as Record<string, unknown>)[clear];
|
|
54
53
|
}
|
|
55
54
|
});
|
|
56
55
|
return this;
|
|
@@ -4,9 +4,9 @@ type DeleteArgs<T extends Query> = T['hasWhere'] extends true
|
|
|
4
4
|
? [forceAll?: boolean]
|
|
5
5
|
: [true];
|
|
6
6
|
|
|
7
|
-
type DeleteResult<T extends Query> = T['hasSelect'] extends
|
|
8
|
-
?
|
|
9
|
-
: T
|
|
7
|
+
type DeleteResult<T extends Query> = T['hasSelect'] extends true
|
|
8
|
+
? T
|
|
9
|
+
: SetQueryReturnsRowCount<T>;
|
|
10
10
|
|
|
11
11
|
const del = <T extends Query>(
|
|
12
12
|
self: T,
|
|
@@ -50,16 +50,15 @@ describe('from', () => {
|
|
|
50
50
|
it('should not insert sub query and alias if provided query is simple', () => {
|
|
51
51
|
const q = User.all();
|
|
52
52
|
expectSql(
|
|
53
|
-
|
|
53
|
+
User.select('name').from(User).toSql(),
|
|
54
54
|
'SELECT "user"."name" FROM "user"',
|
|
55
55
|
);
|
|
56
56
|
expectQueryNotMutated(q);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
it('should add ONLY keyword when `only` parameter is provided', () => {
|
|
60
|
-
const q = User.all();
|
|
61
60
|
expectSql(
|
|
62
|
-
|
|
61
|
+
User.select('id').from(User, { only: true }).toSql(),
|
|
63
62
|
'SELECT "user"."id" FROM ONLY "user"',
|
|
64
63
|
);
|
|
65
64
|
});
|
package/src/queryMethods/get.ts
CHANGED
|
@@ -39,7 +39,6 @@ const _get = <
|
|
|
39
39
|
arg: Arg,
|
|
40
40
|
): R extends 'value' ? GetOptionalResult<T, Arg> : GetResult<T, Arg> => {
|
|
41
41
|
q.query.returnType = returnType;
|
|
42
|
-
q.query.take = true;
|
|
43
42
|
|
|
44
43
|
if (typeof arg === 'object' && isRaw(arg)) {
|
|
45
44
|
addParserForRawExpression(q, getValueKey, arg);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defaultsKey,
|
|
3
3
|
Query,
|
|
4
|
+
QueryReturnsAll,
|
|
4
5
|
QueryReturnType,
|
|
5
6
|
SetQueryReturnsAll,
|
|
6
7
|
SetQueryReturnsOne,
|
|
@@ -136,19 +137,19 @@ type InsertHasManyData<
|
|
|
136
137
|
|
|
137
138
|
type InsertRawData = { columns: string[]; values: RawExpression };
|
|
138
139
|
|
|
139
|
-
type InsertOneResult<T extends Query> = T['hasSelect'] extends
|
|
140
|
-
?
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
: T
|
|
140
|
+
type InsertOneResult<T extends Query> = T['hasSelect'] extends true
|
|
141
|
+
? QueryReturnsAll<T['returnType']> extends true
|
|
142
|
+
? SetQueryReturnsOne<T>
|
|
143
|
+
: T['returnType'] extends 'one'
|
|
144
|
+
? SetQueryReturnsOne<T>
|
|
145
|
+
: T
|
|
146
|
+
: SetQueryReturnsRowCount<T>;
|
|
146
147
|
|
|
147
|
-
type InsertManyResult<T extends Query> = T['hasSelect'] extends
|
|
148
|
-
?
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
: T
|
|
148
|
+
type InsertManyResult<T extends Query> = T['hasSelect'] extends true
|
|
149
|
+
? T['returnType'] extends 'one' | 'oneOrThrow'
|
|
150
|
+
? SetQueryReturnsAll<T>
|
|
151
|
+
: T
|
|
152
|
+
: SetQueryReturnsRowCount<T>;
|
|
152
153
|
|
|
153
154
|
type OnConflictArg<T extends Query> =
|
|
154
155
|
| keyof T['shape']
|
|
@@ -223,7 +224,7 @@ const createInsertCtx = (q: Query): InsertCtx => ({
|
|
|
223
224
|
});
|
|
224
225
|
|
|
225
226
|
const getInsertSingleReturnType = (q: Query) => {
|
|
226
|
-
const { select, returnType } = q.query;
|
|
227
|
+
const { select, returnType = 'all' } = q.query;
|
|
227
228
|
if (select) {
|
|
228
229
|
return returnType === 'all' ? 'one' : returnType;
|
|
229
230
|
} else {
|
package/src/queryMethods/json.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AddQuerySelect,
|
|
3
|
+
Query,
|
|
4
|
+
queryTypeWithLimitOne,
|
|
5
|
+
SetQueryReturnsValueOptional,
|
|
6
|
+
} from '../query';
|
|
2
7
|
import { pushQueryValue } from '../queryDataUtils';
|
|
3
8
|
import { ColumnType, StringColumn } from '../columnSchema';
|
|
4
9
|
import { JsonItem } from '../sql';
|
|
@@ -51,12 +56,11 @@ export class Json {
|
|
|
51
56
|
const q = this._wrap(this.__model.clone()) as T;
|
|
52
57
|
q._getOptional(
|
|
53
58
|
raw<StringColumn>(
|
|
54
|
-
this.query.
|
|
59
|
+
queryTypeWithLimitOne[this.query.returnType]
|
|
55
60
|
? `row_to_json("t".*)`
|
|
56
61
|
: `COALESCE(json_agg(row_to_json("t".*)), '[]')`,
|
|
57
62
|
),
|
|
58
63
|
);
|
|
59
|
-
delete q.query.take;
|
|
60
64
|
return q as unknown as SetQueryReturnsValueOptional<T, StringColumn>;
|
|
61
65
|
}
|
|
62
66
|
|