pqb 0.0.1

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.
Files changed (122) hide show
  1. package/dist/index.d.ts +3630 -0
  2. package/dist/index.esm.js +4587 -0
  3. package/dist/index.esm.js.map +1 -0
  4. package/dist/index.js +4691 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +59 -0
  7. package/rollup.config.js +35 -0
  8. package/src/adapter.test.ts +10 -0
  9. package/src/adapter.ts +171 -0
  10. package/src/columnSchema/array.ts +21 -0
  11. package/src/columnSchema/boolean.ts +10 -0
  12. package/src/columnSchema/columnType.test.ts +129 -0
  13. package/src/columnSchema/columnType.ts +77 -0
  14. package/src/columnSchema/columnTypes.ts +145 -0
  15. package/src/columnSchema/columnsSchema.test.ts +32 -0
  16. package/src/columnSchema/columnsSchema.ts +100 -0
  17. package/src/columnSchema/commonMethods.ts +130 -0
  18. package/src/columnSchema/dateTime.ts +104 -0
  19. package/src/columnSchema/enum.ts +13 -0
  20. package/src/columnSchema/index.ts +11 -0
  21. package/src/columnSchema/json/array.ts +55 -0
  22. package/src/columnSchema/json/discriminatedUnion.ts +91 -0
  23. package/src/columnSchema/json/enum.ts +29 -0
  24. package/src/columnSchema/json/instanceOf.ts +16 -0
  25. package/src/columnSchema/json/intersection.ts +23 -0
  26. package/src/columnSchema/json/lazy.ts +22 -0
  27. package/src/columnSchema/json/literal.ts +12 -0
  28. package/src/columnSchema/json/map.ts +29 -0
  29. package/src/columnSchema/json/nativeEnum.ts +30 -0
  30. package/src/columnSchema/json/nullable.ts +33 -0
  31. package/src/columnSchema/json/nullish.ts +30 -0
  32. package/src/columnSchema/json/object.ts +206 -0
  33. package/src/columnSchema/json/optional.ts +28 -0
  34. package/src/columnSchema/json/record.ts +40 -0
  35. package/src/columnSchema/json/scalarTypes.ts +117 -0
  36. package/src/columnSchema/json/set.ts +34 -0
  37. package/src/columnSchema/json/tuple.ts +40 -0
  38. package/src/columnSchema/json/typeBase.ts +202 -0
  39. package/src/columnSchema/json/union.ts +16 -0
  40. package/src/columnSchema/json.ts +64 -0
  41. package/src/columnSchema/number.ts +122 -0
  42. package/src/columnSchema/string.ts +222 -0
  43. package/src/columnSchema/utils.ts +27 -0
  44. package/src/common.ts +86 -0
  45. package/src/db.test.ts +67 -0
  46. package/src/db.ts +212 -0
  47. package/src/errors.ts +7 -0
  48. package/src/index.ts +18 -0
  49. package/src/operators.test.ts +608 -0
  50. package/src/operators.ts +177 -0
  51. package/src/query.ts +292 -0
  52. package/src/queryDataUtils.ts +50 -0
  53. package/src/queryMethods/aggregate.test.ts +583 -0
  54. package/src/queryMethods/aggregate.ts +878 -0
  55. package/src/queryMethods/callbacks.test.ts +69 -0
  56. package/src/queryMethods/callbacks.ts +55 -0
  57. package/src/queryMethods/clear.test.ts +64 -0
  58. package/src/queryMethods/clear.ts +58 -0
  59. package/src/queryMethods/columnInfo.test.ts +45 -0
  60. package/src/queryMethods/columnInfo.ts +67 -0
  61. package/src/queryMethods/delete.test.ts +135 -0
  62. package/src/queryMethods/delete.ts +50 -0
  63. package/src/queryMethods/for.test.ts +57 -0
  64. package/src/queryMethods/for.ts +99 -0
  65. package/src/queryMethods/from.test.ts +66 -0
  66. package/src/queryMethods/from.ts +58 -0
  67. package/src/queryMethods/get.test.ts +66 -0
  68. package/src/queryMethods/get.ts +88 -0
  69. package/src/queryMethods/having.test.ts +247 -0
  70. package/src/queryMethods/having.ts +99 -0
  71. package/src/queryMethods/insert.test.ts +555 -0
  72. package/src/queryMethods/insert.ts +453 -0
  73. package/src/queryMethods/join.test.ts +150 -0
  74. package/src/queryMethods/join.ts +508 -0
  75. package/src/queryMethods/json.test.ts +398 -0
  76. package/src/queryMethods/json.ts +259 -0
  77. package/src/queryMethods/log.test.ts +172 -0
  78. package/src/queryMethods/log.ts +123 -0
  79. package/src/queryMethods/queryMethods.test.ts +629 -0
  80. package/src/queryMethods/queryMethods.ts +428 -0
  81. package/src/queryMethods/select.test.ts +479 -0
  82. package/src/queryMethods/select.ts +249 -0
  83. package/src/queryMethods/then.ts +236 -0
  84. package/src/queryMethods/transaction.test.ts +66 -0
  85. package/src/queryMethods/transaction.ts +66 -0
  86. package/src/queryMethods/union.test.ts +59 -0
  87. package/src/queryMethods/union.ts +89 -0
  88. package/src/queryMethods/update.test.ts +417 -0
  89. package/src/queryMethods/update.ts +350 -0
  90. package/src/queryMethods/upsert.test.ts +56 -0
  91. package/src/queryMethods/upsert.ts +43 -0
  92. package/src/queryMethods/where.test.ts +1594 -0
  93. package/src/queryMethods/where.ts +450 -0
  94. package/src/queryMethods/window.test.ts +66 -0
  95. package/src/queryMethods/window.ts +108 -0
  96. package/src/queryMethods/with.test.ts +191 -0
  97. package/src/queryMethods/with.ts +92 -0
  98. package/src/quote.ts +36 -0
  99. package/src/relations.ts +194 -0
  100. package/src/sql/aggregate.ts +80 -0
  101. package/src/sql/columnInfo.ts +22 -0
  102. package/src/sql/common.ts +42 -0
  103. package/src/sql/delete.ts +41 -0
  104. package/src/sql/distinct.ts +19 -0
  105. package/src/sql/fromAndAs.ts +51 -0
  106. package/src/sql/having.ts +140 -0
  107. package/src/sql/index.ts +2 -0
  108. package/src/sql/insert.ts +102 -0
  109. package/src/sql/join.ts +242 -0
  110. package/src/sql/orderBy.ts +41 -0
  111. package/src/sql/select.ts +153 -0
  112. package/src/sql/toSql.ts +153 -0
  113. package/src/sql/truncate.ts +13 -0
  114. package/src/sql/types.ts +355 -0
  115. package/src/sql/update.ts +62 -0
  116. package/src/sql/where.ts +314 -0
  117. package/src/sql/window.ts +38 -0
  118. package/src/sql/with.ts +32 -0
  119. package/src/test-utils.ts +172 -0
  120. package/src/utils.ts +140 -0
  121. package/tsconfig.build.json +6 -0
  122. package/tsconfig.json +8 -0
@@ -0,0 +1,172 @@
1
+ import { createDb } from '../db';
2
+ import { adapter, dbOptions, userData, useTestDatabase } from '../test-utils';
3
+ import { logColors } from './log';
4
+ import { noop } from '../utils';
5
+
6
+ describe('query log', () => {
7
+ useTestDatabase();
8
+
9
+ it('should not have `log` query object by default', () => {
10
+ const db = createDb(dbOptions);
11
+
12
+ expect(db('user').query.log).toBe(undefined);
13
+ });
14
+
15
+ it('should set `log` query object when configuring db instance', () => {
16
+ const db = createDb({
17
+ ...dbOptions,
18
+ log: true,
19
+ });
20
+
21
+ expect(db('user').query.log).toBeTruthy();
22
+ });
23
+
24
+ it('should set `log` query object for a table', () => {
25
+ const db = createDb(dbOptions);
26
+ const table = db('user', undefined, { log: true });
27
+
28
+ expect(table.query.log).toBeTruthy();
29
+ });
30
+
31
+ it('should set `log` query object with query method', () => {
32
+ const db = createDb(dbOptions);
33
+ const table = db('user');
34
+
35
+ expect(table.log().query.log).toBeTruthy();
36
+ });
37
+
38
+ it('should log elapsed time, sql and binding values', async () => {
39
+ const hrtime = jest.spyOn(process, 'hrtime');
40
+ hrtime.mockReturnValueOnce([0, 0]);
41
+ hrtime.mockReturnValueOnce([1, 1000000]);
42
+
43
+ const logger = {
44
+ log: jest.fn(),
45
+ error: jest.fn(),
46
+ };
47
+
48
+ const db = createDb({ adapter, log: true, logger });
49
+
50
+ await db('user').where({ name: 'name' });
51
+
52
+ expect(logger.log.mock.calls).toEqual([
53
+ [
54
+ `${logColors.boldCyanBright('(1s 1.0ms)')} ${logColors.boldBlue(
55
+ `SELECT * FROM "user" WHERE "user"."name" = $1`,
56
+ )} ${logColors.boldYellow(`['name']`)}`,
57
+ ],
58
+ ]);
59
+ });
60
+
61
+ it('should log elapsed time, sql and binding values without colors', async () => {
62
+ const hrtime = jest.spyOn(process, 'hrtime');
63
+ hrtime.mockReturnValueOnce([0, 0]);
64
+ hrtime.mockReturnValueOnce([1, 1000000]);
65
+
66
+ const logger = {
67
+ log: jest.fn(),
68
+ error: jest.fn(),
69
+ };
70
+
71
+ const db = createDb({ adapter, log: { colors: false }, logger });
72
+
73
+ await db('user').where({ name: 'name' });
74
+
75
+ expect(logger.log.mock.calls).toEqual([
76
+ [`(1s 1.0ms) SELECT * FROM "user" WHERE "user"."name" = $1 ['name']`],
77
+ ]);
78
+ });
79
+
80
+ it('should log in red in case of error', async () => {
81
+ const hrtime = jest.spyOn(process, 'hrtime');
82
+ hrtime.mockReturnValueOnce([0, 0]);
83
+ hrtime.mockReturnValueOnce([1, 1000000]);
84
+
85
+ const logger = {
86
+ log: jest.fn(),
87
+ error: jest.fn(),
88
+ };
89
+
90
+ const db = createDb({ adapter, log: true, logger });
91
+
92
+ await db('user').where({ wrongColumn: 'value' }).then(noop, noop);
93
+
94
+ expect(logger.error.mock.calls).toEqual([
95
+ [
96
+ `${logColors.boldMagenta('(1s 1.0ms)')} ${logColors.boldRed(
97
+ `SELECT * FROM "user" WHERE "user"."wrongColumn" = $1`,
98
+ )} ${logColors.boldYellow(`['value']`)} ${logColors.boldRed(
99
+ 'Error: column user.wrongColumn does not exist',
100
+ )}`,
101
+ ],
102
+ ]);
103
+ });
104
+
105
+ it('should log in red in case of error without colors', async () => {
106
+ const hrtime = jest.spyOn(process, 'hrtime');
107
+ hrtime.mockReturnValueOnce([0, 0]);
108
+ hrtime.mockReturnValueOnce([1, 1000000]);
109
+
110
+ const logger = {
111
+ log: jest.fn(),
112
+ error: jest.fn(),
113
+ };
114
+
115
+ const db = createDb({ adapter, log: { colors: false }, logger });
116
+
117
+ await db('user').where({ wrongColumn: 'value' }).then(noop, noop);
118
+
119
+ expect(logger.error.mock.calls).toEqual([
120
+ [
121
+ `(1s 1.0ms) SELECT * FROM "user" WHERE "user"."wrongColumn" = $1 ['value'] Error: column user.wrongColumn does not exist`,
122
+ ],
123
+ ]);
124
+ });
125
+
126
+ it('should log successful transaction', async () => {
127
+ const hrtime = jest.spyOn(process, 'hrtime');
128
+ hrtime.mockReturnValue([0, 0]);
129
+ hrtime.mockReturnValue([1, 1000000]);
130
+
131
+ const logger = {
132
+ log: jest.fn(),
133
+ error: jest.fn(),
134
+ };
135
+
136
+ const db = createDb({ adapter, log: { colors: false }, logger });
137
+
138
+ await db.transaction(async (q) => {
139
+ await db('user').transacting(q).insert(userData);
140
+ });
141
+
142
+ expect(logger.log.mock.calls).toEqual([
143
+ ['(1s 1.0ms) BEGIN'],
144
+ [expect.stringContaining('INSERT INTO "user"')],
145
+ ['(1s 1.0ms) COMMIT'],
146
+ ]);
147
+ });
148
+
149
+ it('should log failed transaction', async () => {
150
+ const hrtime = jest.spyOn(process, 'hrtime');
151
+ hrtime.mockReturnValue([0, 0]);
152
+ hrtime.mockReturnValue([1, 1000000]);
153
+
154
+ const logger = {
155
+ log: jest.fn(),
156
+ error: jest.fn(),
157
+ };
158
+
159
+ const db = createDb({ adapter, log: { colors: false }, logger });
160
+
161
+ await expect(
162
+ db.transaction(async (q) => {
163
+ await db('user').transacting(q).insert({ name: 'name' });
164
+ }),
165
+ ).rejects.toThrow();
166
+
167
+ expect(logger.log.mock.calls).toEqual([
168
+ ['(1s 1.0ms) BEGIN'],
169
+ ['(1s 1.0ms) ROLLBACK'],
170
+ ]);
171
+ });
172
+ });
@@ -0,0 +1,123 @@
1
+ import { Query } from '../query';
2
+ import { Sql } from '../sql';
3
+ import { quote } from '../quote';
4
+
5
+ export type QueryLogObject = {
6
+ colors: boolean;
7
+ beforeQuery(q: Query, sql: Sql): unknown;
8
+ afterQuery(q: Query, sql: Sql, logData: unknown): void;
9
+ onError(error: Error, q: Query, sql: Sql, logData: unknown): void;
10
+ };
11
+
12
+ export type QueryLogger = {
13
+ log(message: string): void;
14
+ error(message: string): void;
15
+ };
16
+
17
+ export type QueryLogOptions = {
18
+ log?: boolean | Partial<QueryLogObject>;
19
+ logger?: QueryLogger;
20
+ };
21
+
22
+ export const logColors = {
23
+ boldCyanBright: (message: string) =>
24
+ `\u001b[1m\u001b[96m${message}\u001b[39m\u001b[22m`,
25
+
26
+ boldBlue: (message: string) =>
27
+ `\u001b[1m\u001b[34m${message}\u001b[39m\u001b[22m`,
28
+
29
+ boldYellow: (message: string) =>
30
+ `\u001b[1m\u001b[33m${message}\u001b[39m\u001b[22m`,
31
+
32
+ boldMagenta: (message: string) =>
33
+ `\u001b[1m\u001b[33m${message}\u001b[39m\u001b[22m`,
34
+
35
+ boldRed: (message: string) =>
36
+ `\u001b[1m\u001b[31m${message}\u001b[39m\u001b[22m`,
37
+ };
38
+
39
+ const makeMessage = (
40
+ colors: boolean,
41
+ timeColor: (message: string) => string,
42
+ time: [number, number],
43
+ sqlColor: (message: string) => string,
44
+ sql: string,
45
+ valuesColor: (message: string) => string,
46
+ values: unknown[],
47
+ ): string => {
48
+ const elapsed = process.hrtime(time);
49
+ const formattedTime = `(${elapsed[0] ? `${elapsed[0]}s ` : ''}${(
50
+ elapsed[1] / 1000000
51
+ ).toFixed(1)}ms)`;
52
+
53
+ const result = `${colors ? timeColor(formattedTime) : formattedTime} ${
54
+ colors ? sqlColor(sql) : sql
55
+ }`;
56
+
57
+ if (!values.length) {
58
+ return result;
59
+ }
60
+
61
+ const formattedValues = `[${values.map(quote).join(', ')}]`;
62
+
63
+ return `${result} ${colors ? valuesColor(formattedValues) : formattedValues}`;
64
+ };
65
+
66
+ export const logParamToLogObject = (
67
+ logger: QueryLogger,
68
+ log: QueryLogOptions['log'],
69
+ ): QueryLogObject | undefined => {
70
+ if (!log) return;
71
+ const logObject = Object.assign(
72
+ {
73
+ colors: true,
74
+ beforeQuery() {
75
+ return process.hrtime();
76
+ },
77
+ afterQuery(_, sql, time: [number, number]) {
78
+ logger.log(
79
+ makeMessage(
80
+ colors,
81
+ logColors.boldCyanBright,
82
+ time,
83
+ logColors.boldBlue,
84
+ sql.text,
85
+ logColors.boldYellow,
86
+ sql.values,
87
+ ),
88
+ );
89
+ },
90
+ onError(error, _, sql, time: [number, number]) {
91
+ const message = `Error: ${error.message}`;
92
+
93
+ logger.error(
94
+ `${makeMessage(
95
+ colors,
96
+ logColors.boldMagenta,
97
+ time,
98
+ logColors.boldRed,
99
+ sql.text,
100
+ logColors.boldYellow,
101
+ sql.values,
102
+ )} ${colors ? logColors.boldRed(message) : message}`,
103
+ );
104
+ },
105
+ } as QueryLogObject,
106
+ log === true ? {} : log,
107
+ );
108
+
109
+ const colors = logObject.colors;
110
+
111
+ return logObject;
112
+ };
113
+
114
+ export class QueryLog {
115
+ log<T extends Query>(this: T, log = true): T {
116
+ return this.clone()._log(log);
117
+ }
118
+
119
+ _log<T extends Query>(this: T, log = true): T {
120
+ this.query.log = logParamToLogObject(this.query.logger, log);
121
+ return this;
122
+ }
123
+ }