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,19 @@
1
+ import { SelectQueryData } from './types';
2
+ import { expressionToSql } from './common';
3
+
4
+ export const pushDistinctSql = (
5
+ sql: string[],
6
+ values: unknown[],
7
+ distinct: Exclude<SelectQueryData['distinct'], undefined>,
8
+ quotedAs?: string,
9
+ ) => {
10
+ sql.push('DISTINCT');
11
+
12
+ if (distinct.length) {
13
+ const columns: string[] = [];
14
+ distinct?.forEach((item) => {
15
+ columns.push(expressionToSql(item, values, quotedAs));
16
+ });
17
+ sql.push(`ON (${columns.join(', ')})`);
18
+ }
19
+ };
@@ -0,0 +1,51 @@
1
+ import { getRaw, isRaw } from '../common';
2
+ import { quoteSchemaAndTable } from './common';
3
+ import { Query } from '../query';
4
+ import { queryKeysOfNotSimpleQuery, SelectQueryData } from './types';
5
+
6
+ export const pushFromAndAs = (
7
+ sql: string[],
8
+ model: Query,
9
+ query: SelectQueryData,
10
+ values: unknown[],
11
+ quotedAs?: string,
12
+ ) => {
13
+ sql.push('FROM');
14
+ if (query.fromOnly) sql.push('ONLY');
15
+
16
+ const from = getFrom(model, query, values);
17
+ sql.push(from);
18
+
19
+ if (query.as && quotedAs && quotedAs !== from) {
20
+ sql.push('AS', quotedAs as string);
21
+ }
22
+ };
23
+
24
+ const getFrom = (model: Query, query: SelectQueryData, values: unknown[]) => {
25
+ if (query.from) {
26
+ if (typeof query.from === 'object') {
27
+ if (isRaw(query.from)) {
28
+ return getRaw(query.from, values);
29
+ }
30
+
31
+ if (!query.from.table) {
32
+ const sql = query.from.toSql(values);
33
+ return `(${sql.text})`;
34
+ }
35
+
36
+ const q = query.from.query;
37
+ const keys = Object.keys(q) as (keyof SelectQueryData)[];
38
+ // if query contains more than just schema return (SELECT ...)
39
+ if (keys.some((key) => queryKeysOfNotSimpleQuery.includes(key))) {
40
+ const sql = query.from.toSql(values);
41
+ return `(${sql.text})`;
42
+ }
43
+
44
+ return quoteSchemaAndTable(q.schema, query.from.table);
45
+ }
46
+
47
+ return quoteSchemaAndTable(query.schema, query.from);
48
+ }
49
+
50
+ return quoteSchemaAndTable(query.schema, model.table as string);
51
+ };
@@ -0,0 +1,140 @@
1
+ import { AggregateItemOptions, HavingItem, SelectQueryData } from './types';
2
+ import { EMPTY_OBJECT, getRaw, isRaw, RawExpression } from '../common';
3
+ import { Operator } from '../operators';
4
+ import { aggregateToSql } from './aggregate';
5
+ import { Query } from '../query';
6
+ import { addValue, q } from './common';
7
+
8
+ const aggregateOptionNames: (keyof AggregateItemOptions)[] = [
9
+ 'distinct',
10
+ 'order',
11
+ 'filter',
12
+ 'filterOr',
13
+ 'withinGroup',
14
+ ];
15
+
16
+ export const pushHavingSql = (
17
+ sql: string[],
18
+ model: Pick<
19
+ Query,
20
+ 'whereQueryBuilder' | 'onQueryBuilder' | 'as' | 'shape' | 'relations'
21
+ >,
22
+ query: SelectQueryData,
23
+ values: unknown[],
24
+ quotedAs?: string,
25
+ ) => {
26
+ const conditions = havingToSql(model, query, values, quotedAs);
27
+ if (conditions.length) sql.push('HAVING', conditions);
28
+ };
29
+
30
+ export const havingToSql = (
31
+ model: Pick<
32
+ Query,
33
+ 'whereQueryBuilder' | 'onQueryBuilder' | 'as' | 'shape' | 'relations'
34
+ >,
35
+ query: SelectQueryData,
36
+ values: unknown[],
37
+ quotedAs?: string,
38
+ ): string => {
39
+ const or =
40
+ query.having && query.havingOr
41
+ ? [query.having, ...query.havingOr]
42
+ : query.having
43
+ ? [query.having]
44
+ : query.havingOr;
45
+ if (!or?.length) return '';
46
+
47
+ const ors: string[] = [];
48
+ or.forEach((and) => {
49
+ const ands: string[] = [];
50
+ and.forEach((item) => {
51
+ if ('prototype' in item || '__model' in item) {
52
+ const query = item as Query;
53
+ const sql = havingToSql(
54
+ query,
55
+ query.query as SelectQueryData,
56
+ values,
57
+ query.table && q(query.table),
58
+ );
59
+ if (sql.length) ands.push(`(${sql})`);
60
+ return;
61
+ }
62
+
63
+ if (isRaw(item)) {
64
+ ands.push(getRaw(item, values));
65
+ return;
66
+ }
67
+
68
+ for (const key in item) {
69
+ const columns = item[key as keyof Exclude<HavingItem, RawExpression>];
70
+ if (typeof columns === 'object') {
71
+ for (const column in columns) {
72
+ const valueOrOptions = columns[column as keyof typeof columns];
73
+ if (
74
+ typeof valueOrOptions === 'object' &&
75
+ valueOrOptions !== null &&
76
+ valueOrOptions !== undefined
77
+ ) {
78
+ for (const op in valueOrOptions) {
79
+ if (
80
+ !aggregateOptionNames.includes(
81
+ op as keyof AggregateItemOptions,
82
+ )
83
+ ) {
84
+ const operator = model.shape[column].operators[
85
+ op
86
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
+ ] as Operator<any>;
88
+ if (!operator) {
89
+ // TODO: custom error classes
90
+ throw new Error(
91
+ `Unknown operator ${op} provided to condition`,
92
+ );
93
+ }
94
+
95
+ const expression = aggregateToSql(
96
+ model,
97
+ values,
98
+ {
99
+ function: key,
100
+ arg: column,
101
+ options: valueOrOptions as AggregateItemOptions,
102
+ },
103
+ quotedAs,
104
+ );
105
+
106
+ ands.push(
107
+ operator(
108
+ expression,
109
+ valueOrOptions[op as keyof typeof valueOrOptions],
110
+ values,
111
+ ),
112
+ );
113
+ }
114
+ }
115
+ } else {
116
+ ands.push(
117
+ `${aggregateToSql(
118
+ model,
119
+ values,
120
+ {
121
+ function: key,
122
+ arg: column,
123
+ options: EMPTY_OBJECT,
124
+ },
125
+ quotedAs,
126
+ )} = ${addValue(values, valueOrOptions)}`,
127
+ );
128
+ }
129
+ }
130
+ } else {
131
+ ands.push(`${key}(*) = ${columns}`);
132
+ }
133
+ }
134
+ });
135
+
136
+ ors.push(ands.join(' AND '));
137
+ });
138
+
139
+ return ors.join(' OR ');
140
+ };
@@ -0,0 +1,2 @@
1
+ export * from './toSql';
2
+ export * from './types';
@@ -0,0 +1,102 @@
1
+ import { InsertQueryData, QueryData } from './types';
2
+ import { addValue, q } from './common';
3
+ import { getRaw, isRaw } from '../common';
4
+ import { pushWhereSql } from './where';
5
+ import { Query } from '../query';
6
+ import { selectToSql } from './select';
7
+
8
+ export const pushInsertSql = (
9
+ sql: string[],
10
+ values: unknown[],
11
+ model: Pick<
12
+ Query,
13
+ 'whereQueryBuilder' | 'onQueryBuilder' | 'as' | 'shape' | 'relations'
14
+ >,
15
+ query: InsertQueryData,
16
+ quotedAs: string,
17
+ ) => {
18
+ const quotedColumns = query.columns.map(q);
19
+
20
+ sql.push(
21
+ `INSERT INTO ${quotedAs}(${quotedColumns.join(', ')}) VALUES ${
22
+ isRaw(query.values)
23
+ ? getRaw(query.values, values)
24
+ : query.values
25
+ .map(
26
+ (row) =>
27
+ `(${row
28
+ .map((value) =>
29
+ value === undefined ? 'DEFAULT' : addValue(values, value),
30
+ )
31
+ .join(', ')})`,
32
+ )
33
+ .join(', ')
34
+ }`,
35
+ );
36
+
37
+ if (query.onConflict) {
38
+ sql.push('ON CONFLICT');
39
+
40
+ const { expr, type } = query.onConflict;
41
+ if (expr) {
42
+ if (typeof expr === 'string') {
43
+ sql.push(`(${q(expr)})`);
44
+ } else if (Array.isArray(expr)) {
45
+ sql.push(`(${expr.map(q).join(', ')})`);
46
+ } else {
47
+ sql.push(getRaw(expr, values));
48
+ }
49
+ } else {
50
+ sql.push(`(${quotedColumns.join(', ')})`);
51
+ }
52
+
53
+ if (type === 'ignore') {
54
+ sql.push('DO NOTHING');
55
+ } else if (type === 'merge') {
56
+ let set: string;
57
+
58
+ const { update } = query.onConflict;
59
+ if (update) {
60
+ if (typeof update === 'string') {
61
+ set = `${q(update)} = excluded.${q(update)}`;
62
+ } else if (Array.isArray(update)) {
63
+ set = update
64
+ .map((column) => `${q(column)} = excluded.${q(column)}`)
65
+ .join(', ');
66
+ } else if (isRaw(update)) {
67
+ set = getRaw(update, values);
68
+ } else {
69
+ const arr: string[] = [];
70
+ for (const key in update) {
71
+ arr.push(`${q(key)} = ${addValue(values, update[key])}`);
72
+ }
73
+ set = arr.join(', ');
74
+ }
75
+ } else {
76
+ set = quotedColumns
77
+ .map((column) => `${column} = excluded.${column}`)
78
+ .join(', ');
79
+ }
80
+
81
+ sql.push('DO UPDATE SET', set);
82
+ }
83
+ }
84
+
85
+ pushWhereSql(sql, model, query, values, quotedAs);
86
+ pushReturningSql(sql, model, query, values, quotedAs);
87
+ };
88
+
89
+ export const pushReturningSql = (
90
+ sql: string[],
91
+ model: Pick<
92
+ Query,
93
+ 'whereQueryBuilder' | 'onQueryBuilder' | 'as' | 'shape' | 'relations'
94
+ >,
95
+ query: QueryData,
96
+ values: unknown[],
97
+ quotedAs: string,
98
+ ) => {
99
+ if (query.select) {
100
+ sql.push(`RETURNING ${selectToSql(model, query, values, quotedAs)}`);
101
+ }
102
+ };
@@ -0,0 +1,242 @@
1
+ import { q, quoteFullColumn, quoteSchemaAndTable } from './common';
2
+ import { getRaw, isRaw, RawExpression } from '../common';
3
+ import { JoinItem, QueryData } from './types';
4
+ import { Query, QueryBase } from '../query';
5
+ import { whereToSql } from './where';
6
+ import { Relation } from '../relations';
7
+
8
+ type ItemOf3Or4Length =
9
+ | [
10
+ _: unknown,
11
+ leftColumn: string | RawExpression,
12
+ rightColumn: string | RawExpression,
13
+ ]
14
+ | [
15
+ _: unknown,
16
+ leftColumn: string | RawExpression,
17
+ op: string,
18
+ rightColumn?: string | RawExpression,
19
+ ];
20
+
21
+ export const processJoinItem = (
22
+ model: Pick<
23
+ Query,
24
+ 'whereQueryBuilder' | 'onQueryBuilder' | 'table' | 'shape' | 'relations'
25
+ >,
26
+ query: Pick<QueryData, 'as'>,
27
+ values: unknown[],
28
+ args: JoinItem['args'],
29
+ quotedAs?: string,
30
+ ): { target: string; conditions?: string } => {
31
+ const [first] = args;
32
+ if (typeof first === 'string') {
33
+ if (first in model.relations) {
34
+ const { key, joinQuery } = (model.relations as Record<string, Relation>)[
35
+ first
36
+ ];
37
+
38
+ const table = (
39
+ typeof joinQuery.query.from === 'string'
40
+ ? joinQuery.query.from
41
+ : joinQuery.table
42
+ ) as string;
43
+
44
+ let target = quoteSchemaAndTable(joinQuery.query.schema, table);
45
+
46
+ const as = joinQuery.query.as || key;
47
+ if (as !== table) {
48
+ target += ` AS ${q(as as string)}`;
49
+ }
50
+
51
+ const queryData = {
52
+ and: [],
53
+ or: [],
54
+ } as {
55
+ and: Exclude<QueryData['and'], undefined>;
56
+ or: Exclude<QueryData['or'], undefined>;
57
+ };
58
+
59
+ if (joinQuery.query.and) queryData.and.push(...joinQuery.query.and);
60
+ if (joinQuery.query.or) queryData.or.push(...joinQuery.query.or);
61
+
62
+ const arg = (args[1] as ((q: unknown) => QueryBase) | undefined)?.(
63
+ new model.onQueryBuilder({ table: model.table, query }, args[0]),
64
+ ).query;
65
+
66
+ if (arg) {
67
+ if (arg.and) queryData.and.push(...arg.and);
68
+ if (arg.or) queryData.or.push(...arg.or);
69
+ }
70
+
71
+ const joinAs = q(as as string);
72
+ const onConditions = whereToSql(
73
+ joinQuery,
74
+ queryData,
75
+ values,
76
+ quotedAs,
77
+ joinAs,
78
+ );
79
+ const conditions = onConditions ? onConditions : undefined;
80
+
81
+ return { target, conditions };
82
+ }
83
+
84
+ const target = q(first);
85
+ let conditions: string | undefined;
86
+
87
+ if (args.length === 2) {
88
+ const arg = args[1];
89
+ if (typeof arg === 'function') {
90
+ const joinQuery = arg(
91
+ new model.onQueryBuilder({ table: model.table, query }, args[0]),
92
+ );
93
+ const onConditions = whereToSql(
94
+ model,
95
+ joinQuery.query,
96
+ values,
97
+ quotedAs,
98
+ target,
99
+ );
100
+ if (onConditions) conditions = onConditions;
101
+ } else {
102
+ conditions = getObjectOrRawConditions(arg, values, quotedAs, target);
103
+ }
104
+ } else if (args.length >= 3) {
105
+ conditions = getConditionsFor3Or4LengthItem(
106
+ target,
107
+ values,
108
+ quotedAs,
109
+ args as ItemOf3Or4Length,
110
+ );
111
+ }
112
+
113
+ return { target, conditions };
114
+ }
115
+
116
+ const joinTarget = first;
117
+ const joinQuery = joinTarget.query;
118
+
119
+ const quotedFrom =
120
+ typeof joinQuery?.from === 'string' ? q(joinQuery.from) : undefined;
121
+
122
+ let target =
123
+ quotedFrom || quoteSchemaAndTable(joinQuery?.schema, joinTarget.table);
124
+
125
+ let joinAs = quotedFrom || q(joinTarget.table);
126
+ if (joinQuery?.as) {
127
+ const quoted = q(joinQuery.as);
128
+ if (quoted !== joinAs) {
129
+ joinAs = quoted;
130
+ target += ` AS ${quoted}`;
131
+ }
132
+ }
133
+
134
+ let conditions: string | undefined;
135
+
136
+ if (args.length === 2) {
137
+ const arg = args[1];
138
+ if (typeof arg === 'function') {
139
+ const joinQuery = arg(
140
+ new model.onQueryBuilder({ table: model.table, query }, args[0]),
141
+ );
142
+ const onConditions = whereToSql(
143
+ model,
144
+ joinQuery.query,
145
+ values,
146
+ quotedAs,
147
+ joinAs,
148
+ );
149
+ if (onConditions) conditions = onConditions;
150
+ } else {
151
+ conditions = getObjectOrRawConditions(arg, values, quotedAs, joinAs);
152
+ }
153
+ } else if (args.length >= 3) {
154
+ conditions = getConditionsFor3Or4LengthItem(
155
+ joinAs,
156
+ values,
157
+ quotedAs,
158
+ args as ItemOf3Or4Length,
159
+ );
160
+ }
161
+
162
+ if (joinQuery) {
163
+ const whereSql = whereToSql(model, joinQuery, values, joinAs, quotedAs);
164
+ if (whereSql) {
165
+ if (conditions) conditions += ` AND ${whereSql}`;
166
+ else conditions = whereSql;
167
+ }
168
+ }
169
+
170
+ return { target, conditions };
171
+ };
172
+
173
+ const getConditionsFor3Or4LengthItem = (
174
+ target: string,
175
+ values: unknown[],
176
+ quotedAs: string | undefined,
177
+ args: ItemOf3Or4Length,
178
+ ): string => {
179
+ const [, leftColumn, opOrRightColumn, maybeRightColumn] = args;
180
+
181
+ const op = maybeRightColumn ? opOrRightColumn : '=';
182
+ const rightColumn = maybeRightColumn ? maybeRightColumn : opOrRightColumn;
183
+
184
+ return `${
185
+ typeof leftColumn === 'string'
186
+ ? quoteFullColumn(leftColumn, target)
187
+ : getRaw(leftColumn, values)
188
+ } ${op} ${
189
+ typeof rightColumn === 'string'
190
+ ? quoteFullColumn(rightColumn, quotedAs)
191
+ : getRaw(rightColumn, values)
192
+ }`;
193
+ };
194
+
195
+ const getObjectOrRawConditions = (
196
+ data: Record<string, string | RawExpression> | RawExpression,
197
+ values: unknown[],
198
+ quotedAs: string | undefined,
199
+ joinAs: string | undefined,
200
+ ): string => {
201
+ if (isRaw(data)) {
202
+ return getRaw(data, values);
203
+ } else {
204
+ const pairs: string[] = [];
205
+ for (const key in data) {
206
+ const value = data[key];
207
+
208
+ pairs.push(
209
+ `${quoteFullColumn(key, joinAs)} = ${
210
+ typeof value === 'string'
211
+ ? quoteFullColumn(value, quotedAs)
212
+ : getRaw(value, values)
213
+ }`,
214
+ );
215
+ }
216
+
217
+ return pairs.join(', ');
218
+ }
219
+ };
220
+
221
+ export const pushJoinSql = (
222
+ sql: string[],
223
+ model: Query,
224
+ query: QueryData & {
225
+ join: JoinItem[];
226
+ },
227
+ values: unknown[],
228
+ quotedAs?: string,
229
+ ) => {
230
+ query.join.forEach((item) => {
231
+ const { target, conditions } = processJoinItem(
232
+ model,
233
+ query,
234
+ values,
235
+ item.args,
236
+ quotedAs,
237
+ );
238
+
239
+ sql.push(item.type, target);
240
+ if (conditions) sql.push('ON', conditions);
241
+ });
242
+ };
@@ -0,0 +1,41 @@
1
+ import { OrderItem, SelectQueryData } from './types';
2
+ import { getRaw, isRaw } from '../common';
3
+ import { qc } from './common';
4
+
5
+ export const pushOrderBySql = (
6
+ sql: string[],
7
+ values: unknown[],
8
+ quotedAs: string | undefined,
9
+ order: Exclude<SelectQueryData['order'], undefined>,
10
+ ) => {
11
+ sql.push(
12
+ `ORDER BY ${order
13
+ .map((item) => orderByToSql(item, values, quotedAs))
14
+ .join(', ')}`,
15
+ );
16
+ };
17
+
18
+ export const orderByToSql = (
19
+ order: OrderItem,
20
+ values: unknown[],
21
+ quotedAs?: string,
22
+ ) => {
23
+ if (typeof order === 'string') {
24
+ return `${qc(order, quotedAs)} ASC`;
25
+ }
26
+
27
+ if (isRaw(order)) {
28
+ return getRaw(order, values);
29
+ }
30
+
31
+ const sql: string[] = [];
32
+ for (const key in order) {
33
+ const value = order[key];
34
+ if (typeof value === 'string') {
35
+ sql.push(`${qc(key, quotedAs)} ${value}`);
36
+ } else if (value) {
37
+ sql.push(`${qc(key, quotedAs)} ${value.dir} NULLS ${value.nulls}`);
38
+ }
39
+ }
40
+ return sql.join(', ');
41
+ };