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.
@@ -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').insert(userData);
26
- await Profile.insert({ ...profileData, userId: id });
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').insert(userData);
198
+ const userId = await User.get('id').create(userData);
199
199
  const now = new Date();
200
- await Profile.insert({ userId, updatedAt: now, createdAt: now });
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').insert(userData);
276
- const { id: chatId } = await Chat.select('id').insert(chatData);
277
- await Message.insert({
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,
@@ -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.beforeInsert;
84
- afterCallbacks = q.query.afterInsert;
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').insertMany([userData, userData]);
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').insert(userData);
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').insert(userData);
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').insert(userData);
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').insert(userData);
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').insertMany([userData, userData]);
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').insertMany([userData, userData]);
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').insert(userData);
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 { InsertData } from './insert';
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: InsertData<Rel['nestedCreateQuery']>;
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: InsertData<Rel['nestedCreateQuery']>;
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: InsertData<Rel['nestedCreateQuery']>;
66
+ create: CreateData<Rel['nestedCreateQuery']>;
67
67
  };
68
68
  }
69
69
  | {
70
- create: InsertData<Rel['nestedCreateQuery']>;
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?: InsertData<Rel['nestedCreateQuery']>[];
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?: InsertData<Rel['nestedCreateQuery']>[];
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 { InsertData } from './insert';
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: InsertData<T>;
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).insert(data.create as InsertData<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.insertMany([
23
+ await User.createMany([
24
24
  { ...userData, age: 20 },
25
25
  { ...userData, age: 20 },
26
26
  ]);
27
- await User.insertMany([
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
- RelationName extends PropertyKey = string,
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
- Q extends RelationQueryBase = Omit<T, 'tableAlias'> & {
194
- tableAlias: RelationName extends string ? RelationName : never;
195
- [isRequiredRelationKey]: Required;
196
- [relationQueryKey]: string;
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
- `INSERT INTO ${quotedAs}(${quotedColumns.join(', ')}) VALUES ${
19
- isRaw(query.values)
20
- ? getRaw(query.values, ctx.values)
21
- : query.values
22
- .map(
23
- (row) =>
24
- `(${row
25
- .map((value) =>
26
- value === undefined
27
- ? 'DEFAULT'
28
- : addValue(ctx.values, value),
29
- )
30
- .join(', ')})`,
31
- )
32
- .join(', ')
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
- beforeInsert?: BeforeCallback[];
117
- afterInsert?: AfterCallback[];
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 = { connectionString: process.env.DATABASE_URL };
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