pqb 0.4.0 → 0.4.2
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 +61 -48
- package/dist/index.esm.js +136 -117
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +136 -117
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnType.test.ts +1 -1
- package/src/db.test.ts +2 -2
- package/src/errors.test.ts +4 -4
- package/src/queryMethods/aggregate.test.ts +11 -11
- package/src/queryMethods/aggregate.ts +5 -3
- package/src/queryMethods/callbacks.test.ts +6 -6
- package/src/queryMethods/callbacks.ts +8 -8
- package/src/queryMethods/columnInfo.ts +13 -19
- package/src/queryMethods/{insert.test.ts → create.test.ts} +108 -98
- package/src/queryMethods/{insert.ts → create.ts} +139 -118
- package/src/queryMethods/delete.test.ts +2 -2
- package/src/queryMethods/get.test.ts +2 -2
- package/src/queryMethods/index.ts +1 -1
- package/src/queryMethods/json.test.ts +1 -1
- package/src/queryMethods/log.test.ts +29 -8
- package/src/queryMethods/merge.test.ts +3 -3
- package/src/queryMethods/queryMethods.test.ts +4 -4
- package/src/queryMethods/queryMethods.ts +3 -3
- package/src/queryMethods/select.test.ts +7 -7
- package/src/queryMethods/then.ts +2 -2
- package/src/queryMethods/update.test.ts +8 -8
- package/src/queryMethods/update.ts +7 -7
- package/src/queryMethods/upsert.ts +3 -3
- package/src/queryMethods/window.test.ts +2 -2
- package/src/relations.ts +18 -7
- package/src/sql/insert.ts +31 -19
- package/src/sql/types.ts +3 -2
- package/src/test-utils.ts +4 -1
|
@@ -22,8 +22,8 @@ import { addQueryOn } from './join';
|
|
|
22
22
|
import { RelationQuery, relationQueryKey } from '../relations';
|
|
23
23
|
|
|
24
24
|
const insertUserAndProfile = async () => {
|
|
25
|
-
const id = await User.get('id').
|
|
26
|
-
await Profile.
|
|
25
|
+
const id = await User.get('id').create(userData);
|
|
26
|
+
await Profile.create({ ...profileData, userId: id });
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
describe('selectMethods', () => {
|
|
@@ -195,9 +195,9 @@ describe('selectMethods', () => {
|
|
|
195
195
|
});
|
|
196
196
|
|
|
197
197
|
it('should parse columns in single relation record result', async () => {
|
|
198
|
-
const userId = await User.get('id').
|
|
198
|
+
const userId = await User.get('id').create(userData);
|
|
199
199
|
const now = new Date();
|
|
200
|
-
await Profile.
|
|
200
|
+
await Profile.create({ userId, updatedAt: now, createdAt: now });
|
|
201
201
|
|
|
202
202
|
const [record] = await User.select('id', {
|
|
203
203
|
profile: () => profileRelation,
|
|
@@ -272,9 +272,9 @@ describe('selectMethods', () => {
|
|
|
272
272
|
});
|
|
273
273
|
|
|
274
274
|
it('should parse columns in multiple relation records result', async () => {
|
|
275
|
-
const { id: authorId } = await User.select('id').
|
|
276
|
-
const { id: chatId } = await Chat.select('id').
|
|
277
|
-
await Message.
|
|
275
|
+
const { id: authorId } = await User.select('id').create(userData);
|
|
276
|
+
const { id: chatId } = await Chat.select('id').create(chatData);
|
|
277
|
+
await Message.create({
|
|
278
278
|
authorId,
|
|
279
279
|
chatId,
|
|
280
280
|
...messageData,
|
package/src/queryMethods/then.ts
CHANGED
|
@@ -80,8 +80,8 @@ const then = async (
|
|
|
80
80
|
let beforeCallbacks: BeforeCallback[] | undefined;
|
|
81
81
|
let afterCallbacks: AfterCallback[] | undefined;
|
|
82
82
|
if (q.query.type === 'insert') {
|
|
83
|
-
beforeCallbacks = q.query.
|
|
84
|
-
afterCallbacks = q.query.
|
|
83
|
+
beforeCallbacks = q.query.beforeCreate;
|
|
84
|
+
afterCallbacks = q.query.afterCreate;
|
|
85
85
|
} else if (q.query.type === 'update') {
|
|
86
86
|
beforeCallbacks = q.query.beforeUpdate;
|
|
87
87
|
afterCallbacks = q.query.afterUpdate;
|
|
@@ -35,7 +35,7 @@ describe('update', () => {
|
|
|
35
35
|
|
|
36
36
|
it('should update record with raw sql, returning updated rows count', async () => {
|
|
37
37
|
const count = 2;
|
|
38
|
-
const users = await User.select('id').
|
|
38
|
+
const users = await User.select('id').createMany([userData, userData]);
|
|
39
39
|
|
|
40
40
|
const query = User.or(...users).updateRaw(raw(`name = 'name'`));
|
|
41
41
|
expectSql(
|
|
@@ -55,7 +55,7 @@ describe('update', () => {
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
it('should update record, returning updated row count', async () => {
|
|
58
|
-
const { id } = await User.select('id').
|
|
58
|
+
const { id } = await User.select('id').create(userData);
|
|
59
59
|
|
|
60
60
|
const update = {
|
|
61
61
|
name: 'new name',
|
|
@@ -85,7 +85,7 @@ describe('update', () => {
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
it('should update record, returning value', async () => {
|
|
88
|
-
const id = await User.get('id').
|
|
88
|
+
const id = await User.get('id').create(userData);
|
|
89
89
|
|
|
90
90
|
const update = {
|
|
91
91
|
name: 'new name',
|
|
@@ -116,7 +116,7 @@ describe('update', () => {
|
|
|
116
116
|
});
|
|
117
117
|
|
|
118
118
|
it('should update one record, return selected columns', async () => {
|
|
119
|
-
const id = await User.get('id').
|
|
119
|
+
const id = await User.get('id').create(userData);
|
|
120
120
|
|
|
121
121
|
const query = User.select('id', 'name').find(id).update(update);
|
|
122
122
|
|
|
@@ -141,7 +141,7 @@ describe('update', () => {
|
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
it('should update one record, return all columns', async () => {
|
|
144
|
-
const id = await User.get('id').
|
|
144
|
+
const id = await User.get('id').create(userData);
|
|
145
145
|
|
|
146
146
|
const query = User.selectAll().find(id).update(update);
|
|
147
147
|
|
|
@@ -166,7 +166,7 @@ describe('update', () => {
|
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
it('should update multiple records, returning selected columns', async () => {
|
|
169
|
-
const ids = await User.pluck('id').
|
|
169
|
+
const ids = await User.pluck('id').createMany([userData, userData]);
|
|
170
170
|
|
|
171
171
|
const update = {
|
|
172
172
|
name: 'new name',
|
|
@@ -198,7 +198,7 @@ describe('update', () => {
|
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
it('should update multiple records, returning all columns', async () => {
|
|
201
|
-
const ids = await User.pluck('id').
|
|
201
|
+
const ids = await User.pluck('id').createMany([userData, userData]);
|
|
202
202
|
|
|
203
203
|
const update = {
|
|
204
204
|
name: 'new name',
|
|
@@ -270,7 +270,7 @@ describe('update', () => {
|
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
it('should return one record when searching for one to update', async () => {
|
|
273
|
-
const { id } = await User.select('id').
|
|
273
|
+
const { id } = await User.select('id').create(userData);
|
|
274
274
|
|
|
275
275
|
const update = {
|
|
276
276
|
name: 'new name',
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from '../relations';
|
|
14
14
|
import { WhereArg, WhereResult } from './where';
|
|
15
15
|
import { EmptyObject, MaybeArray } from '../utils';
|
|
16
|
-
import {
|
|
16
|
+
import { CreateData } from './create';
|
|
17
17
|
import { parseResult, queryMethodByReturnType } from './then';
|
|
18
18
|
import { UpdateQueryData } from '../sql';
|
|
19
19
|
|
|
@@ -41,14 +41,14 @@ type UpdateBelongsToData<T extends Query, Rel extends BelongsToRelation> =
|
|
|
41
41
|
| { delete: boolean }
|
|
42
42
|
| { update: UpdateData<Rel['model']> }
|
|
43
43
|
| {
|
|
44
|
-
create:
|
|
44
|
+
create: CreateData<Rel['nestedCreateQuery']>;
|
|
45
45
|
}
|
|
46
46
|
| (QueryReturnsAll<T['returnType']> extends true
|
|
47
47
|
? never
|
|
48
48
|
: {
|
|
49
49
|
upsert: {
|
|
50
50
|
update: UpdateData<Rel['model']>;
|
|
51
|
-
create:
|
|
51
|
+
create: CreateData<Rel['nestedCreateQuery']>;
|
|
52
52
|
};
|
|
53
53
|
});
|
|
54
54
|
|
|
@@ -63,11 +63,11 @@ type UpdateHasOneData<T extends Query, Rel extends HasOneRelation> =
|
|
|
63
63
|
| {
|
|
64
64
|
upsert: {
|
|
65
65
|
update: UpdateData<Rel['model']>;
|
|
66
|
-
create:
|
|
66
|
+
create: CreateData<Rel['nestedCreateQuery']>;
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
| {
|
|
70
|
-
create:
|
|
70
|
+
create: CreateData<Rel['nestedCreateQuery']>;
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
type UpdateHasManyData<T extends Query, Rel extends HasManyRelation> = {
|
|
@@ -81,7 +81,7 @@ type UpdateHasManyData<T extends Query, Rel extends HasManyRelation> = {
|
|
|
81
81
|
? EmptyObject
|
|
82
82
|
: {
|
|
83
83
|
set?: MaybeArray<WhereArg<Rel['model']>>;
|
|
84
|
-
create?:
|
|
84
|
+
create?: CreateData<Rel['nestedCreateQuery']>[];
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
type UpdateHasAndBelongsToManyData<Rel extends HasAndBelongsToManyRelation> = {
|
|
@@ -92,7 +92,7 @@ type UpdateHasAndBelongsToManyData<Rel extends HasAndBelongsToManyRelation> = {
|
|
|
92
92
|
where: MaybeArray<WhereArg<Rel['model']>>;
|
|
93
93
|
data: UpdateData<Rel['model']>;
|
|
94
94
|
};
|
|
95
|
-
create?:
|
|
95
|
+
create?: CreateData<Rel['nestedCreateQuery']>[];
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
type UpdateArgs<T extends Query, ForceAll extends boolean> = (
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Query, SetQueryReturnsOne, SetQueryReturnsVoid } from '../query';
|
|
2
2
|
import { UpdateData } from './update';
|
|
3
|
-
import {
|
|
3
|
+
import { CreateData } from './create';
|
|
4
4
|
import { WhereResult } from './where';
|
|
5
5
|
import { MoreThanOneRowError } from '../errors';
|
|
6
6
|
|
|
7
7
|
export type UpsertData<T extends Query> = {
|
|
8
8
|
update: UpdateData<T>;
|
|
9
|
-
create:
|
|
9
|
+
create: CreateData<T>;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type UpsertResult<T extends Query> = T['hasSelect'] extends true
|
|
@@ -29,7 +29,7 @@ export class QueryUpsert {
|
|
|
29
29
|
const { handleResult } = this.query;
|
|
30
30
|
this.query.handleResult = async (q, queryResult) => {
|
|
31
31
|
if (queryResult.rowCount === 0) {
|
|
32
|
-
return (q as Query).
|
|
32
|
+
return (q as Query).create(data.create as CreateData<Query>);
|
|
33
33
|
} else if (queryResult.rowCount > 1) {
|
|
34
34
|
throw new MoreThanOneRowError(
|
|
35
35
|
`Only one row was expected to find for upsert, found ${queryResult.rowCount} rows.`,
|
|
@@ -20,11 +20,11 @@ describe('window functions', () => {
|
|
|
20
20
|
`('$method', ({ method, functionName, results }) => {
|
|
21
21
|
it('should return array of objects with number value', async () => {
|
|
22
22
|
if (method === 'selectCumeDist') {
|
|
23
|
-
await User.
|
|
23
|
+
await User.createMany([
|
|
24
24
|
{ ...userData, age: 20 },
|
|
25
25
|
{ ...userData, age: 20 },
|
|
26
26
|
]);
|
|
27
|
-
await User.
|
|
27
|
+
await User.createMany([
|
|
28
28
|
{ ...userData, age: 30 },
|
|
29
29
|
{ ...userData, age: 30 },
|
|
30
30
|
]);
|
package/src/relations.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defaultsKey, Query, QueryBase, QueryWithTable } from './query';
|
|
2
|
-
import { WhereArg, UpdateData } from './queryMethods';
|
|
2
|
+
import { WhereArg, UpdateData, CreateMethodsNames } from './queryMethods';
|
|
3
3
|
import { MaybeArray } from './utils';
|
|
4
4
|
|
|
5
5
|
export type NestedInsertOneItem = {
|
|
@@ -184,15 +184,26 @@ export type RelationQueryBase = Query & {
|
|
|
184
184
|
[isRequiredRelationKey]: boolean;
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
+
type PrepareRelationQuery<
|
|
188
|
+
T extends Query,
|
|
189
|
+
RelationName extends PropertyKey,
|
|
190
|
+
Required extends boolean,
|
|
191
|
+
> = Omit<T, 'tableAlias'> & {
|
|
192
|
+
tableAlias: RelationName extends string ? RelationName : never;
|
|
193
|
+
[isRequiredRelationKey]: Required;
|
|
194
|
+
[relationQueryKey]: string;
|
|
195
|
+
};
|
|
196
|
+
|
|
187
197
|
export type RelationQuery<
|
|
188
|
-
|
|
198
|
+
Name extends PropertyKey = string,
|
|
189
199
|
Params extends Record<string, unknown> = never,
|
|
190
200
|
Populate extends string = never,
|
|
191
201
|
T extends Query = Query,
|
|
192
202
|
Required extends boolean = boolean,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
203
|
+
ChainedCreate extends boolean = false,
|
|
204
|
+
Q extends RelationQueryBase = ChainedCreate extends true
|
|
205
|
+
? PrepareRelationQuery<T, Name, Required>
|
|
206
|
+
: PrepareRelationQuery<T, Name, Required> & {
|
|
207
|
+
[K in CreateMethodsNames]: never;
|
|
208
|
+
},
|
|
198
209
|
> = ((params: Params) => Q & { [defaultsKey]: Record<Populate, true> }) & Q;
|
package/src/sql/insert.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { InsertQueryData, QueryData } from './types';
|
|
2
2
|
import { addValue, q } from './common';
|
|
3
|
-
import { getRaw, isRaw } from '../common';
|
|
3
|
+
import { getRaw, isRaw, raw } from '../common';
|
|
4
4
|
import { pushWhereStatementSql } from './where';
|
|
5
5
|
import { QueryBase } from '../query';
|
|
6
6
|
import { selectToSql } from './select';
|
|
7
7
|
import { ToSqlCtx } from './toSql';
|
|
8
|
+
import { pushQueryValue } from '../queryDataUtils';
|
|
8
9
|
|
|
9
10
|
export const pushInsertSql = (
|
|
10
11
|
ctx: ToSqlCtx,
|
|
@@ -14,24 +15,27 @@ export const pushInsertSql = (
|
|
|
14
15
|
) => {
|
|
15
16
|
const quotedColumns = query.columns.map(q);
|
|
16
17
|
|
|
17
|
-
ctx.sql.push(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
ctx.sql.push(`INSERT INTO ${quotedAs}(${quotedColumns.join(', ')})`);
|
|
19
|
+
|
|
20
|
+
if (query.fromQuery) {
|
|
21
|
+
const q = query.fromQuery.clone();
|
|
22
|
+
|
|
23
|
+
pushQueryValue(
|
|
24
|
+
q,
|
|
25
|
+
'select',
|
|
26
|
+
isRaw(query.values) ? query.values : raw(encodeRow(ctx, query.values[0])),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
ctx.sql.push(q.toSql({ values: ctx.values }).text);
|
|
30
|
+
} else {
|
|
31
|
+
ctx.sql.push(
|
|
32
|
+
`VALUES ${
|
|
33
|
+
isRaw(query.values)
|
|
34
|
+
? getRaw(query.values, ctx.values)
|
|
35
|
+
: query.values.map((row) => `(${encodeRow(ctx, row)})`).join(', ')
|
|
36
|
+
}`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
35
39
|
|
|
36
40
|
if (query.onConflict) {
|
|
37
41
|
ctx.sql.push('ON CONFLICT');
|
|
@@ -85,6 +89,14 @@ export const pushInsertSql = (
|
|
|
85
89
|
pushReturningSql(ctx, model, query, quotedAs);
|
|
86
90
|
};
|
|
87
91
|
|
|
92
|
+
const encodeRow = (ctx: ToSqlCtx, row: unknown[]) => {
|
|
93
|
+
return row
|
|
94
|
+
.map((value) =>
|
|
95
|
+
value === undefined ? 'DEFAULT' : addValue(ctx.values, value),
|
|
96
|
+
)
|
|
97
|
+
.join(', ');
|
|
98
|
+
};
|
|
99
|
+
|
|
88
100
|
export const pushReturningSql = (
|
|
89
101
|
ctx: ToSqlCtx,
|
|
90
102
|
model: QueryBase,
|
package/src/sql/types.ts
CHANGED
|
@@ -100,6 +100,7 @@ export type InsertQueryData = CommonQueryData & {
|
|
|
100
100
|
type: 'insert';
|
|
101
101
|
columns: string[];
|
|
102
102
|
values: unknown[][] | RawExpression;
|
|
103
|
+
fromQuery?: Query;
|
|
103
104
|
using?: JoinItem[];
|
|
104
105
|
join?: JoinItem[];
|
|
105
106
|
joinedParsers?: Record<string, ColumnsParsers>;
|
|
@@ -113,8 +114,8 @@ export type InsertQueryData = CommonQueryData & {
|
|
|
113
114
|
expr?: OnConflictItem;
|
|
114
115
|
update?: OnConflictMergeUpdate;
|
|
115
116
|
};
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
beforeCreate?: BeforeCallback[];
|
|
118
|
+
afterCreate?: AfterCallback[];
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
export type UpdateQueryDataObject = Record<
|
package/src/test-utils.ts
CHANGED
|
@@ -11,7 +11,10 @@ import { columnTypes } from './columnSchema';
|
|
|
11
11
|
import { MaybeArray, toArray } from './utils';
|
|
12
12
|
import { Adapter } from './adapter';
|
|
13
13
|
|
|
14
|
-
export const dbOptions = {
|
|
14
|
+
export const dbOptions = {
|
|
15
|
+
connectionString: process.env.DATABASE_URL,
|
|
16
|
+
columnTypes,
|
|
17
|
+
};
|
|
15
18
|
|
|
16
19
|
export const dbClient = new Client(dbOptions);
|
|
17
20
|
|