pqb 0.4.6 → 0.4.8
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 +25 -11
- package/dist/index.esm.js +78 -40
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +79 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnType.test.ts +220 -0
- package/src/columnSchema/columnType.ts +7 -0
- package/src/columnSchema/columnTypes.test.ts +55 -53
- package/src/columnSchema/dateTime.ts +11 -0
- package/src/columnSchema/timestamps.test.ts +3 -4
- package/src/columnSchema/timestamps.ts +1 -1
- package/src/columnsOperators.test.ts +18 -19
- package/src/columnsOperators.ts +1 -1
- package/src/common.ts +17 -30
- package/src/db.ts +23 -9
- package/src/errors.test.ts +2 -4
- package/src/index.ts +1 -1
- package/src/query.ts +7 -1
- package/src/queryMethods/aggregate.test.ts +9 -7
- package/src/queryMethods/create.test.ts +48 -5
- package/src/queryMethods/create.ts +28 -6
- package/src/queryMethods/for.test.ts +1 -2
- package/src/queryMethods/for.ts +1 -1
- package/src/queryMethods/from.test.ts +2 -3
- package/src/queryMethods/get.test.ts +5 -5
- package/src/queryMethods/having.test.ts +6 -5
- package/src/queryMethods/index.ts +1 -0
- package/src/queryMethods/json.ts +2 -2
- package/src/queryMethods/merge.test.ts +10 -4
- package/src/queryMethods/queryMethods.test.ts +10 -12
- package/src/queryMethods/queryMethods.ts +7 -4
- package/src/queryMethods/raw.test.ts +19 -0
- package/src/queryMethods/raw.ts +27 -0
- package/src/queryMethods/select.test.ts +4 -4
- package/src/queryMethods/then.test.ts +2 -4
- package/src/queryMethods/union.test.ts +11 -6
- package/src/queryMethods/update.test.ts +21 -3
- package/src/queryMethods/update.ts +11 -1
- package/src/queryMethods/where.test.ts +65 -56
- package/src/queryMethods/where.ts +1 -1
- package/src/queryMethods/with.test.ts +5 -6
- package/src/sql/common.ts +0 -1
- package/src/sql/fromAndAs.ts +1 -1
- package/src/sql/insert.ts +1 -1
- package/src/sql/join.ts +1 -1
- package/src/sql/orderBy.ts +1 -1
- package/src/sql/select.ts +1 -2
- package/src/sql/toSql.ts +1 -1
- package/src/sql/update.ts +1 -1
- package/src/sql/where.ts +1 -1
- package/src/sql/window.ts +3 -4
- package/src/sql/with.ts +1 -1
package/package.json
CHANGED
|
@@ -125,4 +125,224 @@ describe('column base', () => {
|
|
|
125
125
|
});
|
|
126
126
|
});
|
|
127
127
|
});
|
|
128
|
+
|
|
129
|
+
describe('as', () => {
|
|
130
|
+
const numberTimestamp = columnTypes
|
|
131
|
+
.timestamp()
|
|
132
|
+
.encode((input: number) => new Date(input))
|
|
133
|
+
.parse(Date.parse)
|
|
134
|
+
.as(columnTypes.integer());
|
|
135
|
+
|
|
136
|
+
const dateTimestamp = columnTypes
|
|
137
|
+
.timestamp()
|
|
138
|
+
.parse((input) => new Date(input));
|
|
139
|
+
|
|
140
|
+
const db = createDb({
|
|
141
|
+
adapter,
|
|
142
|
+
columnTypes: {
|
|
143
|
+
...columnTypes,
|
|
144
|
+
numberTimestamp: () => numberTimestamp,
|
|
145
|
+
dateTimestamp: () => dateTimestamp,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const UserWithCustomTimestamps = db('user', (t) => ({
|
|
150
|
+
id: t.serial().primaryKey(),
|
|
151
|
+
name: t.text(),
|
|
152
|
+
password: t.text(),
|
|
153
|
+
createdAt: t.numberTimestamp(),
|
|
154
|
+
updatedAt: t.dateTimestamp(),
|
|
155
|
+
}));
|
|
156
|
+
|
|
157
|
+
it('should accept only column of same type and input type', () => {
|
|
158
|
+
columnTypes
|
|
159
|
+
.timestamp()
|
|
160
|
+
.encode((input: number) => input.toString())
|
|
161
|
+
// @ts-expect-error should have both encode and parse with matching types
|
|
162
|
+
.as(columnTypes.integer());
|
|
163
|
+
|
|
164
|
+
// @ts-expect-error should have both encode and parse with matching types
|
|
165
|
+
columnTypes.timestamp().parse(Date.parse).as(columnTypes.integer());
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should return same column with overridden type', () => {
|
|
169
|
+
const timestamp = columnTypes
|
|
170
|
+
.timestamp()
|
|
171
|
+
.encode((input: number) => new Date(input))
|
|
172
|
+
.parse(Date.parse);
|
|
173
|
+
|
|
174
|
+
const column = timestamp.as(columnTypes.integer());
|
|
175
|
+
|
|
176
|
+
expect(column).toBe(timestamp);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should parse correctly', async () => {
|
|
180
|
+
const id = await User.get('id').create(userData);
|
|
181
|
+
|
|
182
|
+
const user = await UserWithCustomTimestamps.find(id);
|
|
183
|
+
|
|
184
|
+
expect(typeof user.createdAt).toBe('number');
|
|
185
|
+
expect(user.updatedAt).toBeInstanceOf(Date);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should encode columns when creating', () => {
|
|
189
|
+
const createdAt = Date.now();
|
|
190
|
+
const updatedAt = new Date();
|
|
191
|
+
|
|
192
|
+
const query = UserWithCustomTimestamps.create({
|
|
193
|
+
...userData,
|
|
194
|
+
createdAt,
|
|
195
|
+
updatedAt,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
expectSql(
|
|
199
|
+
query.toSql(),
|
|
200
|
+
`
|
|
201
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
202
|
+
VALUES ($1, $2, $3, $4)
|
|
203
|
+
RETURNING *
|
|
204
|
+
`,
|
|
205
|
+
[userData.name, userData.password, new Date(createdAt), updatedAt],
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should encode columns when update', async () => {
|
|
210
|
+
const id = await User.get('id').create(userData);
|
|
211
|
+
const createdAt = Date.now();
|
|
212
|
+
const updatedAt = new Date();
|
|
213
|
+
|
|
214
|
+
const query = UserWithCustomTimestamps.find(id).update({
|
|
215
|
+
createdAt,
|
|
216
|
+
updatedAt,
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
expectSql(
|
|
220
|
+
query.toSql(),
|
|
221
|
+
`
|
|
222
|
+
UPDATE "user"
|
|
223
|
+
SET "createdAt" = $1, "updatedAt" = $2
|
|
224
|
+
WHERE "user"."id" = $3
|
|
225
|
+
`,
|
|
226
|
+
[new Date(createdAt), updatedAt, id],
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe('timestamp().asNumber()', () => {
|
|
232
|
+
it('should parse and encode timestamp as a number', async () => {
|
|
233
|
+
const UserWithNumberTimestamp = db('user', (t) => ({
|
|
234
|
+
id: t.serial().primaryKey(),
|
|
235
|
+
name: t.text(),
|
|
236
|
+
password: t.text(),
|
|
237
|
+
createdAt: t.timestamp().asNumber(),
|
|
238
|
+
updatedAt: t.timestamp().asNumber(),
|
|
239
|
+
}));
|
|
240
|
+
|
|
241
|
+
const now = Date.now();
|
|
242
|
+
|
|
243
|
+
const createQuery = UserWithNumberTimestamp.create({
|
|
244
|
+
...userData,
|
|
245
|
+
createdAt: now,
|
|
246
|
+
updatedAt: now,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
expectSql(
|
|
250
|
+
createQuery.toSql(),
|
|
251
|
+
`
|
|
252
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
253
|
+
VALUES ($1, $2, $3, $4)
|
|
254
|
+
RETURNING *
|
|
255
|
+
`,
|
|
256
|
+
[userData.name, userData.password, new Date(now), new Date(now)],
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const { id } = await createQuery;
|
|
260
|
+
const user = await UserWithNumberTimestamp.select(
|
|
261
|
+
'createdAt',
|
|
262
|
+
'updatedAt',
|
|
263
|
+
).find(id);
|
|
264
|
+
|
|
265
|
+
assertType<typeof user, { createdAt: number; updatedAt: number }>();
|
|
266
|
+
|
|
267
|
+
expect(typeof user.createdAt).toBe('number');
|
|
268
|
+
expect(typeof user.updatedAt).toBe('number');
|
|
269
|
+
|
|
270
|
+
const updateQuery = UserWithNumberTimestamp.find(id).update({
|
|
271
|
+
createdAt: now,
|
|
272
|
+
updatedAt: now,
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
expectSql(
|
|
276
|
+
updateQuery.toSql(),
|
|
277
|
+
`
|
|
278
|
+
UPDATE "user"
|
|
279
|
+
SET "createdAt" = $1, "updatedAt" = $2
|
|
280
|
+
WHERE "user"."id" = $3
|
|
281
|
+
`,
|
|
282
|
+
[new Date(now), new Date(now), id],
|
|
283
|
+
);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
describe('timestamp().asDate()', () => {
|
|
288
|
+
it('should parse and encode timestamp as a number', async () => {
|
|
289
|
+
columnTypes
|
|
290
|
+
.text()
|
|
291
|
+
.encode((input: number) => input)
|
|
292
|
+
.parse((text) => parseInt(text))
|
|
293
|
+
.as(columnTypes.integer());
|
|
294
|
+
|
|
295
|
+
const UserWithNumberTimestamp = db('user', (t) => ({
|
|
296
|
+
id: t.serial().primaryKey(),
|
|
297
|
+
name: t.text(),
|
|
298
|
+
password: t.text(),
|
|
299
|
+
createdAt: columnTypes.timestamp().asDate(),
|
|
300
|
+
updatedAt: columnTypes.timestamp().asDate(),
|
|
301
|
+
}));
|
|
302
|
+
|
|
303
|
+
const now = new Date();
|
|
304
|
+
|
|
305
|
+
const createQuery = UserWithNumberTimestamp.create({
|
|
306
|
+
...userData,
|
|
307
|
+
createdAt: now,
|
|
308
|
+
updatedAt: now,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
expectSql(
|
|
312
|
+
createQuery.toSql(),
|
|
313
|
+
`
|
|
314
|
+
INSERT INTO "user"("name", "password", "createdAt", "updatedAt")
|
|
315
|
+
VALUES ($1, $2, $3, $4)
|
|
316
|
+
RETURNING *
|
|
317
|
+
`,
|
|
318
|
+
[userData.name, userData.password, new Date(now), new Date(now)],
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const { id } = await createQuery;
|
|
322
|
+
const user = await UserWithNumberTimestamp.select(
|
|
323
|
+
'createdAt',
|
|
324
|
+
'updatedAt',
|
|
325
|
+
).find(id);
|
|
326
|
+
|
|
327
|
+
assertType<typeof user, { createdAt: Date; updatedAt: Date }>();
|
|
328
|
+
|
|
329
|
+
expect(user.createdAt).toBeInstanceOf(Date);
|
|
330
|
+
expect(user.updatedAt).toBeInstanceOf(Date);
|
|
331
|
+
|
|
332
|
+
const updateQuery = UserWithNumberTimestamp.find(id).update({
|
|
333
|
+
createdAt: now,
|
|
334
|
+
updatedAt: now,
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
expectSql(
|
|
338
|
+
updateQuery.toSql(),
|
|
339
|
+
`
|
|
340
|
+
UPDATE "user"
|
|
341
|
+
SET "createdAt" = $1, "updatedAt" = $2
|
|
342
|
+
WHERE "user"."id" = $3
|
|
343
|
+
`,
|
|
344
|
+
[now, now, id],
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
128
348
|
});
|
|
@@ -221,6 +221,13 @@ export abstract class ColumnType<
|
|
|
221
221
|
return this as unknown as Omit<T, 'type'> & { type: Output };
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
as<
|
|
225
|
+
T extends ColumnType,
|
|
226
|
+
C extends ColumnType<T['type'], Operators, T['inputType']>,
|
|
227
|
+
>(this: T, _: C) {
|
|
228
|
+
return this as unknown as C;
|
|
229
|
+
}
|
|
230
|
+
|
|
224
231
|
toSQL() {
|
|
225
232
|
return this.dataType;
|
|
226
233
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { assertType, db } from '../test-utils';
|
|
2
|
-
import { raw } from '../common';
|
|
3
2
|
import { columnTypes } from './columnTypes';
|
|
4
3
|
import { TimeInterval } from './dateTime';
|
|
5
4
|
|
|
@@ -7,7 +6,7 @@ describe('column types', () => {
|
|
|
7
6
|
describe('numeric types', () => {
|
|
8
7
|
describe('smallint', () => {
|
|
9
8
|
it('should output number', async () => {
|
|
10
|
-
const result = await db.get(raw(
|
|
9
|
+
const result = await db.get(db.raw((t) => t.smallint(), '1::smallint'));
|
|
11
10
|
expect(result).toBe(1);
|
|
12
11
|
|
|
13
12
|
assertType<typeof result, number>();
|
|
@@ -16,7 +15,7 @@ describe('column types', () => {
|
|
|
16
15
|
|
|
17
16
|
describe('integer', () => {
|
|
18
17
|
it('should output number', async () => {
|
|
19
|
-
const result = await db.get(raw(
|
|
18
|
+
const result = await db.get(db.raw((t) => t.integer(), '1::integer'));
|
|
20
19
|
expect(result).toBe(1);
|
|
21
20
|
|
|
22
21
|
assertType<typeof result, number>();
|
|
@@ -25,7 +24,7 @@ describe('column types', () => {
|
|
|
25
24
|
|
|
26
25
|
describe('bigint', () => {
|
|
27
26
|
it('should output string', async () => {
|
|
28
|
-
const result = await db.get(raw(
|
|
27
|
+
const result = await db.get(db.raw((t) => t.bigint(), '1::bigint'));
|
|
29
28
|
expect(result).toBe('1');
|
|
30
29
|
|
|
31
30
|
assertType<typeof result, string>();
|
|
@@ -34,7 +33,7 @@ describe('column types', () => {
|
|
|
34
33
|
|
|
35
34
|
describe('numeric', () => {
|
|
36
35
|
it('should output string', async () => {
|
|
37
|
-
const result = await db.get(raw(
|
|
36
|
+
const result = await db.get(db.raw((t) => t.numeric(), '1::numeric'));
|
|
38
37
|
expect(result).toBe('1');
|
|
39
38
|
|
|
40
39
|
assertType<typeof result, string>();
|
|
@@ -43,7 +42,7 @@ describe('column types', () => {
|
|
|
43
42
|
|
|
44
43
|
describe('decimal', () => {
|
|
45
44
|
it('should output string', async () => {
|
|
46
|
-
const result = await db.get(raw(
|
|
45
|
+
const result = await db.get(db.raw((t) => t.decimal(), '1::decimal'));
|
|
47
46
|
expect(result).toBe('1');
|
|
48
47
|
|
|
49
48
|
assertType<typeof result, string>();
|
|
@@ -52,7 +51,7 @@ describe('column types', () => {
|
|
|
52
51
|
|
|
53
52
|
describe('real', () => {
|
|
54
53
|
it('should output number', async () => {
|
|
55
|
-
const result = await db.get(raw(
|
|
54
|
+
const result = await db.get(db.raw((t) => t.real(), '1::real'));
|
|
56
55
|
expect(result).toBe(1);
|
|
57
56
|
|
|
58
57
|
assertType<typeof result, number>();
|
|
@@ -62,7 +61,7 @@ describe('column types', () => {
|
|
|
62
61
|
describe('doublePrecision', () => {
|
|
63
62
|
it('should output number', async () => {
|
|
64
63
|
const result = await db.get(
|
|
65
|
-
raw(
|
|
64
|
+
db.raw((t) => t.real(), '1::double precision'),
|
|
66
65
|
);
|
|
67
66
|
expect(result).toBe(1);
|
|
68
67
|
|
|
@@ -73,7 +72,7 @@ describe('column types', () => {
|
|
|
73
72
|
describe('smallSerial', () => {
|
|
74
73
|
it('should output number', async () => {
|
|
75
74
|
const result = await db.get(
|
|
76
|
-
raw(
|
|
75
|
+
db.raw((t) => t.smallSerial(), '1::smallint'),
|
|
77
76
|
);
|
|
78
77
|
expect(result).toBe(1);
|
|
79
78
|
|
|
@@ -83,7 +82,7 @@ describe('column types', () => {
|
|
|
83
82
|
|
|
84
83
|
describe('serial', () => {
|
|
85
84
|
it('should output number', async () => {
|
|
86
|
-
const result = await db.get(raw(
|
|
85
|
+
const result = await db.get(db.raw((t) => t.serial(), '1::integer'));
|
|
87
86
|
expect(result).toBe(1);
|
|
88
87
|
|
|
89
88
|
assertType<typeof result, number>();
|
|
@@ -92,7 +91,7 @@ describe('column types', () => {
|
|
|
92
91
|
|
|
93
92
|
describe('bigSerial', () => {
|
|
94
93
|
it('should output string', async () => {
|
|
95
|
-
const result = await db.get(raw(
|
|
94
|
+
const result = await db.get(db.raw((t) => t.bigSerial(), '1::bigint'));
|
|
96
95
|
expect(result).toBe('1');
|
|
97
96
|
|
|
98
97
|
assertType<typeof result, string>();
|
|
@@ -104,7 +103,7 @@ describe('column types', () => {
|
|
|
104
103
|
describe('varchar', () => {
|
|
105
104
|
it('should output string', async () => {
|
|
106
105
|
const result = await db.get(
|
|
107
|
-
raw(
|
|
106
|
+
db.raw((t) => t.varchar(), `'text'::varchar(4)`),
|
|
108
107
|
);
|
|
109
108
|
expect(result).toBe('text');
|
|
110
109
|
|
|
@@ -114,7 +113,7 @@ describe('column types', () => {
|
|
|
114
113
|
|
|
115
114
|
describe('char', () => {
|
|
116
115
|
it('should output string', async () => {
|
|
117
|
-
const result = await db.get(raw(
|
|
116
|
+
const result = await db.get(db.raw((t) => t.char(), `'text'::char(4)`));
|
|
118
117
|
expect(result).toBe('text');
|
|
119
118
|
|
|
120
119
|
assertType<typeof result, string>();
|
|
@@ -123,7 +122,7 @@ describe('column types', () => {
|
|
|
123
122
|
|
|
124
123
|
describe('text', () => {
|
|
125
124
|
it('should output string', async () => {
|
|
126
|
-
const result = await db.get(raw(
|
|
125
|
+
const result = await db.get(db.raw((t) => t.text(), `'text'::text`));
|
|
127
126
|
expect(result).toBe('text');
|
|
128
127
|
|
|
129
128
|
assertType<typeof result, string>();
|
|
@@ -132,7 +131,7 @@ describe('column types', () => {
|
|
|
132
131
|
|
|
133
132
|
describe('string', () => {
|
|
134
133
|
it('should be an alias for the text', async () => {
|
|
135
|
-
const result = await db.get(raw(
|
|
134
|
+
const result = await db.get(db.raw((t) => t.string(), `'text'::text`));
|
|
136
135
|
expect(result).toBe('text');
|
|
137
136
|
|
|
138
137
|
assertType<typeof result, string>();
|
|
@@ -143,7 +142,7 @@ describe('column types', () => {
|
|
|
143
142
|
describe('binary data type', () => {
|
|
144
143
|
describe('bytea', () => {
|
|
145
144
|
it('should output Buffer', async () => {
|
|
146
|
-
const result = await db.get(raw(
|
|
145
|
+
const result = await db.get(db.raw((t) => t.bytea(), `'text'::bytea`));
|
|
147
146
|
expect(result instanceof Buffer).toBe(true);
|
|
148
147
|
expect(result.toString()).toBe('text');
|
|
149
148
|
|
|
@@ -156,7 +155,7 @@ describe('column types', () => {
|
|
|
156
155
|
describe('date', () => {
|
|
157
156
|
it('should output string', async () => {
|
|
158
157
|
const result = await db.get(
|
|
159
|
-
raw(
|
|
158
|
+
db.raw((t) => t.date(), `'1999-01-08'::date`),
|
|
160
159
|
);
|
|
161
160
|
expect(result).toBe('1999-01-08');
|
|
162
161
|
|
|
@@ -167,7 +166,10 @@ describe('column types', () => {
|
|
|
167
166
|
describe('timestamp', () => {
|
|
168
167
|
it('should output string', async () => {
|
|
169
168
|
const result = await db.get(
|
|
170
|
-
raw(
|
|
169
|
+
db.raw(
|
|
170
|
+
() => columnTypes.timestamp(),
|
|
171
|
+
`'1999-01-08 04:05:06'::timestamp`,
|
|
172
|
+
),
|
|
171
173
|
);
|
|
172
174
|
expect(result).toBe('1999-01-08 04:05:06');
|
|
173
175
|
|
|
@@ -178,8 +180,8 @@ describe('column types', () => {
|
|
|
178
180
|
describe('timestamp with time zone', () => {
|
|
179
181
|
it('should output string', async () => {
|
|
180
182
|
const result = await db.get(
|
|
181
|
-
raw(
|
|
182
|
-
|
|
183
|
+
db.raw(
|
|
184
|
+
(t) => t.timestampWithTimeZone(),
|
|
183
185
|
`'1999-01-08 04:05:06 +0'::timestamptz AT TIME ZONE 'UTC'`,
|
|
184
186
|
),
|
|
185
187
|
);
|
|
@@ -191,7 +193,7 @@ describe('column types', () => {
|
|
|
191
193
|
|
|
192
194
|
describe('time', () => {
|
|
193
195
|
it('should output string', async () => {
|
|
194
|
-
const result = await db.get(raw(
|
|
196
|
+
const result = await db.get(db.raw((t) => t.time(), `'12:00'::time`));
|
|
195
197
|
expect(result).toBe('12:00:00');
|
|
196
198
|
|
|
197
199
|
assertType<typeof result, string>();
|
|
@@ -201,8 +203,8 @@ describe('column types', () => {
|
|
|
201
203
|
describe('time with time zone', () => {
|
|
202
204
|
it('should output string', async () => {
|
|
203
205
|
const result = await db.get(
|
|
204
|
-
raw(
|
|
205
|
-
|
|
206
|
+
db.raw(
|
|
207
|
+
(t) => t.timeWithTimeZone(),
|
|
206
208
|
`'12:00 +0'::timetz AT TIME ZONE 'UTC'`,
|
|
207
209
|
),
|
|
208
210
|
);
|
|
@@ -215,8 +217,8 @@ describe('column types', () => {
|
|
|
215
217
|
describe('interval', () => {
|
|
216
218
|
it('should output string', async () => {
|
|
217
219
|
const result = await db.get(
|
|
218
|
-
raw(
|
|
219
|
-
|
|
220
|
+
db.raw(
|
|
221
|
+
(t) => t.interval(),
|
|
220
222
|
`'1 year 2 months 3 days 4 hours 5 minutes 6 seconds'::interval`,
|
|
221
223
|
),
|
|
222
224
|
);
|
|
@@ -237,7 +239,7 @@ describe('column types', () => {
|
|
|
237
239
|
describe('boolean type', () => {
|
|
238
240
|
describe('boolean', () => {
|
|
239
241
|
it('should output boolean', async () => {
|
|
240
|
-
const result = await db.get(raw(
|
|
242
|
+
const result = await db.get(db.raw((t) => t.boolean(), `true`));
|
|
241
243
|
expect(result).toBe(true);
|
|
242
244
|
|
|
243
245
|
assertType<typeof result, boolean>();
|
|
@@ -260,8 +262,8 @@ describe('column types', () => {
|
|
|
260
262
|
|
|
261
263
|
it('should output proper union', async () => {
|
|
262
264
|
const result = await db.get(
|
|
263
|
-
raw(
|
|
264
|
-
|
|
265
|
+
db.raw(
|
|
266
|
+
(t) => t.enum('mood', ['sad', 'ok', 'happy']),
|
|
265
267
|
`'happy'::mood`,
|
|
266
268
|
),
|
|
267
269
|
);
|
|
@@ -276,7 +278,7 @@ describe('column types', () => {
|
|
|
276
278
|
describe('point', () => {
|
|
277
279
|
it('should output string', async () => {
|
|
278
280
|
const result = await db.get(
|
|
279
|
-
raw(
|
|
281
|
+
db.raw((t) => t.point(), `'(1, 2)'::point`),
|
|
280
282
|
);
|
|
281
283
|
expect(result).toBe('(1,2)');
|
|
282
284
|
|
|
@@ -287,7 +289,7 @@ describe('column types', () => {
|
|
|
287
289
|
describe('line', () => {
|
|
288
290
|
it('should output string', async () => {
|
|
289
291
|
const result = await db.get(
|
|
290
|
-
raw(
|
|
292
|
+
db.raw((t) => t.line(), `'{1, 2, 3}'::line`),
|
|
291
293
|
);
|
|
292
294
|
expect(result).toBe('{1,2,3}');
|
|
293
295
|
|
|
@@ -298,7 +300,7 @@ describe('column types', () => {
|
|
|
298
300
|
describe('lseg', () => {
|
|
299
301
|
it('should output string', async () => {
|
|
300
302
|
const result = await db.get(
|
|
301
|
-
raw(
|
|
303
|
+
db.raw((t) => t.lseg(), `'[(1, 2), (3, 4)]'::lseg`),
|
|
302
304
|
);
|
|
303
305
|
expect(result).toBe('[(1,2),(3,4)]');
|
|
304
306
|
|
|
@@ -309,7 +311,7 @@ describe('column types', () => {
|
|
|
309
311
|
describe('box', () => {
|
|
310
312
|
it('should output string', async () => {
|
|
311
313
|
const result = await db.get(
|
|
312
|
-
raw(
|
|
314
|
+
db.raw((t) => t.box(), `'((3, 4), (1, 2))'::box`),
|
|
313
315
|
);
|
|
314
316
|
expect(result).toBe('(3,4),(1,2)');
|
|
315
317
|
|
|
@@ -320,7 +322,7 @@ describe('column types', () => {
|
|
|
320
322
|
describe('path', () => {
|
|
321
323
|
it('should output string', async () => {
|
|
322
324
|
const result = await db.get(
|
|
323
|
-
raw(
|
|
325
|
+
db.raw((t) => t.path(), `'((1, 2), (3, 4))'::path`),
|
|
324
326
|
);
|
|
325
327
|
expect(result).toBe('((1,2),(3,4))');
|
|
326
328
|
|
|
@@ -331,7 +333,7 @@ describe('column types', () => {
|
|
|
331
333
|
describe('polygon', () => {
|
|
332
334
|
it('should output string', async () => {
|
|
333
335
|
const result = await db.get(
|
|
334
|
-
raw(
|
|
336
|
+
db.raw((t) => t.polygon(), `'((1, 2), (3, 4))'::polygon`),
|
|
335
337
|
);
|
|
336
338
|
expect(result).toBe('((1,2),(3,4))');
|
|
337
339
|
|
|
@@ -342,7 +344,7 @@ describe('column types', () => {
|
|
|
342
344
|
describe('circle', () => {
|
|
343
345
|
it('should output string', async () => {
|
|
344
346
|
const result = await db.get(
|
|
345
|
-
raw(
|
|
347
|
+
db.raw((t) => t.circle(), `'<(1,2),3>'::circle`),
|
|
346
348
|
);
|
|
347
349
|
expect(result).toBe('<(1,2),3>');
|
|
348
350
|
|
|
@@ -355,7 +357,7 @@ describe('column types', () => {
|
|
|
355
357
|
describe('cidr', () => {
|
|
356
358
|
it('should output string', async () => {
|
|
357
359
|
const result = await db.get(
|
|
358
|
-
raw(
|
|
360
|
+
db.raw((t) => t.cidr(), `'192.168.100.128/25'::cidr`),
|
|
359
361
|
);
|
|
360
362
|
expect(result).toBe('192.168.100.128/25');
|
|
361
363
|
|
|
@@ -366,7 +368,7 @@ describe('column types', () => {
|
|
|
366
368
|
describe('inet', () => {
|
|
367
369
|
it('should output string', async () => {
|
|
368
370
|
const result = await db.get(
|
|
369
|
-
raw(
|
|
371
|
+
db.raw((t) => t.inet(), `'192.168.100.128/25'::inet`),
|
|
370
372
|
);
|
|
371
373
|
expect(result).toBe('192.168.100.128/25');
|
|
372
374
|
|
|
@@ -377,7 +379,7 @@ describe('column types', () => {
|
|
|
377
379
|
describe('macaddr', () => {
|
|
378
380
|
it('should output string', async () => {
|
|
379
381
|
const result = await db.get(
|
|
380
|
-
raw(
|
|
382
|
+
db.raw((t) => t.macaddr(), `'08:00:2b:01:02:03'::macaddr`),
|
|
381
383
|
);
|
|
382
384
|
expect(result).toBe('08:00:2b:01:02:03');
|
|
383
385
|
|
|
@@ -388,7 +390,7 @@ describe('column types', () => {
|
|
|
388
390
|
describe('macaddr8', () => {
|
|
389
391
|
it('should output string', async () => {
|
|
390
392
|
const result = await db.get(
|
|
391
|
-
raw(
|
|
393
|
+
db.raw((t) => t.macaddr8(), `'08:00:2b:ff:fe:01:02:03'::macaddr8`),
|
|
392
394
|
);
|
|
393
395
|
expect(result).toBe('08:00:2b:ff:fe:01:02:03');
|
|
394
396
|
|
|
@@ -400,7 +402,7 @@ describe('column types', () => {
|
|
|
400
402
|
describe('bit string types', () => {
|
|
401
403
|
describe('bit', () => {
|
|
402
404
|
it('should output string', async () => {
|
|
403
|
-
const result = await db.get(raw(
|
|
405
|
+
const result = await db.get(db.raw((t) => t.bit(3), `B'101'`));
|
|
404
406
|
expect(result).toBe('101');
|
|
405
407
|
|
|
406
408
|
assertType<typeof result, string>();
|
|
@@ -410,7 +412,7 @@ describe('column types', () => {
|
|
|
410
412
|
describe('bit varying', () => {
|
|
411
413
|
it('should output string', async () => {
|
|
412
414
|
const result = await db.get(
|
|
413
|
-
raw(
|
|
415
|
+
db.raw((t) => t.bitVarying(), `'10101'::bit varying(5)`),
|
|
414
416
|
);
|
|
415
417
|
expect(result).toBe('10101');
|
|
416
418
|
|
|
@@ -423,8 +425,8 @@ describe('column types', () => {
|
|
|
423
425
|
describe('tsvector', () => {
|
|
424
426
|
it('should output string', async () => {
|
|
425
427
|
const result = await db.get(
|
|
426
|
-
raw(
|
|
427
|
-
|
|
428
|
+
db.raw(
|
|
429
|
+
(t) => t.tsvector(),
|
|
428
430
|
`'a fat cat sat on a mat and ate a fat rat'::tsvector`,
|
|
429
431
|
),
|
|
430
432
|
);
|
|
@@ -439,7 +441,7 @@ describe('column types', () => {
|
|
|
439
441
|
describe('tsquery', () => {
|
|
440
442
|
it('should output string', async () => {
|
|
441
443
|
const result = await db.get(
|
|
442
|
-
raw(
|
|
444
|
+
db.raw((t) => t.tsquery(), `'fat & rat'::tsquery`),
|
|
443
445
|
);
|
|
444
446
|
expect(result).toBe(`'fat' & 'rat'`);
|
|
445
447
|
|
|
@@ -452,8 +454,8 @@ describe('column types', () => {
|
|
|
452
454
|
describe('uuid', () => {
|
|
453
455
|
it('should output string', async () => {
|
|
454
456
|
const result = await db.get(
|
|
455
|
-
raw(
|
|
456
|
-
|
|
457
|
+
db.raw(
|
|
458
|
+
(t) => t.uuid(),
|
|
457
459
|
`'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid`,
|
|
458
460
|
),
|
|
459
461
|
);
|
|
@@ -468,8 +470,8 @@ describe('column types', () => {
|
|
|
468
470
|
describe('array', () => {
|
|
469
471
|
it('should output nested array of numbers', async () => {
|
|
470
472
|
const result = await db.get(
|
|
471
|
-
raw(
|
|
472
|
-
|
|
473
|
+
db.raw(
|
|
474
|
+
(t) => t.array(t.array(t.integer())),
|
|
473
475
|
`'{{1, 2, 3}, {4, 5, 6}}'::integer[][]`,
|
|
474
476
|
),
|
|
475
477
|
);
|
|
@@ -483,8 +485,8 @@ describe('column types', () => {
|
|
|
483
485
|
|
|
484
486
|
it('should output nested array of strings', async () => {
|
|
485
487
|
const result = await db.get(
|
|
486
|
-
raw(
|
|
487
|
-
|
|
488
|
+
db.raw(
|
|
489
|
+
(t) => t.array(t.array(t.text())),
|
|
488
490
|
`'{{"a", "b"}, {"c", "d"}}'::text[][]`,
|
|
489
491
|
),
|
|
490
492
|
);
|
|
@@ -498,8 +500,8 @@ describe('column types', () => {
|
|
|
498
500
|
|
|
499
501
|
it('should output nested array of booleans', async () => {
|
|
500
502
|
const result = await db.get(
|
|
501
|
-
raw(
|
|
502
|
-
|
|
503
|
+
db.raw(
|
|
504
|
+
(t) => t.array(t.array(t.boolean())),
|
|
503
505
|
`'{{true}, {false}}'::text[][]`,
|
|
504
506
|
),
|
|
505
507
|
);
|
|
@@ -514,7 +516,7 @@ describe('column types', () => {
|
|
|
514
516
|
describe('money', () => {
|
|
515
517
|
it('should output number', async () => {
|
|
516
518
|
const result = await db.get(
|
|
517
|
-
raw(
|
|
519
|
+
db.raw((t) => t.money(), `'1234567890.42'::money`),
|
|
518
520
|
);
|
|
519
521
|
expect(result).toBe(1234567890.42);
|
|
520
522
|
|
|
@@ -3,6 +3,7 @@ import { Operators } from '../columnsOperators';
|
|
|
3
3
|
import { joinTruthy } from '../utils';
|
|
4
4
|
import { dateTypeMethods } from './commonMethods';
|
|
5
5
|
import { assignMethodsToClass } from './utils';
|
|
6
|
+
import { IntegerColumn } from './number';
|
|
6
7
|
|
|
7
8
|
export type DateColumnData = ColumnData & {
|
|
8
9
|
min?: Date;
|
|
@@ -22,6 +23,16 @@ export abstract class DateBaseColumn extends ColumnType<
|
|
|
22
23
|
> {
|
|
23
24
|
data = {} as DateColumnData;
|
|
24
25
|
operators = Operators.date;
|
|
26
|
+
|
|
27
|
+
asNumber() {
|
|
28
|
+
return this.encode((input: number) => new Date(input)).parse(
|
|
29
|
+
Date.parse,
|
|
30
|
+
) as unknown as IntegerColumn;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
asDate<T extends ColumnType>(this: T) {
|
|
34
|
+
return this.parse((input) => new Date(input as string));
|
|
35
|
+
}
|
|
25
36
|
}
|
|
26
37
|
|
|
27
38
|
assignMethodsToClass(DateBaseColumn, dateTypeMethods);
|