xcraft-core-pickaxe 0.1.29 → 0.1.30

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.
@@ -3,6 +3,7 @@
3
3
  const {isAnyPick, BasePick} = require('./picks.js');
4
4
 
5
5
  /**
6
+ * @typedef {import("./query-builder.js").DbTable} DbTable
6
7
  * @typedef {import("./operators.js").Expression} Expression
7
8
  */
8
9
 
@@ -103,6 +104,14 @@ const operators = {
103
104
  return `LENGTH(${sql(value, context)})`;
104
105
  },
105
106
 
107
+ lower({value}, context) {
108
+ return `LOWER(${sql(value, context)})`;
109
+ },
110
+
111
+ upper({value}, context) {
112
+ return `UPPER(${sql(value, context)})`;
113
+ },
114
+
106
115
  substr({value, start, length}, context) {
107
116
  const valueSql = sql(value, context);
108
117
  const startSql = sql(start, context);
@@ -343,6 +352,7 @@ function getExpression(expressionOrPick) {
343
352
  /**
344
353
  * @typedef {{
345
354
  * values: any[] | null,
355
+ * tablesUsed: DbTable[],
346
356
  * scope?: any,
347
357
  * useTableNames?: boolean,
348
358
  * equalOperator: 'IS' | '=',
@@ -366,6 +376,7 @@ function sql(expressionOrPick, context) {
366
376
  function expressionToSql(operator) {
367
377
  const context = {
368
378
  values: [],
379
+ tablesUsed: [],
369
380
  };
370
381
  return {
371
382
  sql: sql(operator, context),
package/lib/operators.js CHANGED
@@ -90,6 +90,20 @@ const operators = {
90
90
  });
91
91
  },
92
92
 
93
+ lower(value) {
94
+ return /** @type {const} */ ({
95
+ operator: 'lower',
96
+ value: op(value),
97
+ });
98
+ },
99
+
100
+ upper(value) {
101
+ return /** @type {const} */ ({
102
+ operator: 'upper',
103
+ value: op(value),
104
+ });
105
+ },
106
+
93
107
  substr(value, start, length) {
94
108
  value = op(value);
95
109
  start = op(start);
package/lib/picks.js CHANGED
@@ -86,6 +86,14 @@ class ValuePick extends BasePick {
86
86
  super(type, expression);
87
87
  }
88
88
 
89
+ /**
90
+ * @template {AnyTypeOrShape} T
91
+ * @param {T} type
92
+ */
93
+ as(type) {
94
+ return makePick(type, this.expression);
95
+ }
96
+
89
97
  /**
90
98
  * @template {AnyObjectShape} T
91
99
  * @param {T} shape
@@ -179,6 +187,14 @@ class StringPick extends ValuePick {
179
187
  return new NumberPick(number, $o.stringLength(this.expression));
180
188
  }
181
189
 
190
+ lower() {
191
+ return new StringPick(this.type, $o.lower(this.expression));
192
+ }
193
+
194
+ upper() {
195
+ return new StringPick(this.type, $o.upper(this.expression));
196
+ }
197
+
182
198
  /**
183
199
  * @param {number | BasePick<NumberType>} start
184
200
  * @param {number | BasePick<NumberType>} [length]
@@ -1,5 +1,6 @@
1
1
  // @ts-check
2
2
 
3
+ const path = require('node:path');
3
4
  const {
4
5
  ObjectType,
5
6
  ArrayType,
@@ -43,11 +44,15 @@ const partialObjectShape = require('./partial-object-shape.js');
43
44
  */
44
45
 
45
46
  /**
46
- * @typedef {{db?: string, table: string, alias?: string} | {db?: undefined, table: Subquery, alias?: string}} TableAndAlias
47
+ * @typedef {{db?: string, dbId?: string, table: string, alias?: string}} DbTable
47
48
  */
48
49
 
49
50
  /**
50
- * @typedef {string | Subquery | TableAndAlias} QueryTable
51
+ * @typedef {{db?: undefined, dbId?: undefined, table: Subquery, alias?: string}} SubqueryAndAlias
52
+ */
53
+
54
+ /**
55
+ * @typedef {string | Subquery | DbTable | SubqueryAndAlias} QueryTable
51
56
  */
52
57
 
53
58
  /**
@@ -55,6 +60,7 @@ const partialObjectShape = require('./partial-object-shape.js');
55
60
  * @template {AnyObjectShape} U
56
61
  * @typedef {{
57
62
  * db?: string,
63
+ * dbId?: string,
58
64
  * table: string,
59
65
  * alias?: string,
60
66
  * shape?: T,
@@ -281,9 +287,15 @@ function getTableName(table) {
281
287
  * @template {AnyObjectShape} T
282
288
  * @param {AnyTableSchema} tableSchema
283
289
  * @param {T} shape
284
- * @returns {{pick: RowPick<GetShape<T>>, condition: BooleanPick | null}}
290
+ * @returns {{table: DbTable, pick: RowPick<GetShape<T>>, condition: BooleanPick | null}}
285
291
  */
286
292
  function useTableSchema(tableSchema, shape) {
293
+ const table = {
294
+ db: tableSchema.db,
295
+ dbId: tableSchema.dbId,
296
+ table: tableSchema.table,
297
+ alias: tableSchema.alias,
298
+ };
287
299
  const type = toObjectType(shape);
288
300
  const tableName = getTableName(tableSchema);
289
301
  let pick = rowPick(type, tableName);
@@ -295,7 +307,7 @@ function useTableSchema(tableSchema, shape) {
295
307
  }
296
308
  pick = tableSchema.scope(basePick).toRowPick();
297
309
  }
298
- return {pick, condition};
310
+ return {table, pick, condition};
299
311
  }
300
312
 
301
313
  /**
@@ -456,6 +468,15 @@ class FinalQuery {
456
468
  return queryToSql(this.#queryParts, null).sql;
457
469
  }
458
470
 
471
+ json() {
472
+ const {sql, values, tables} = queryToSql(this.#queryParts);
473
+ return {sql, values, tables};
474
+ }
475
+
476
+ getMapRow() {
477
+ return this.#getMapRow();
478
+ }
479
+
459
480
  /**
460
481
  * @returns {R | undefined}
461
482
  */
@@ -693,14 +714,14 @@ class FromQuery {
693
714
  */
694
715
  _join(joinOperator, tableName, shape, joinFct, mergePicks) {
695
716
  const tableSchema = this.#getTableSchema(tableName, shape);
696
- const {pick, condition} = useTableSchema(tableSchema, shape);
717
+ const {table, pick, condition} = useTableSchema(tableSchema, shape);
697
718
 
698
719
  const joinCondition = joinFct(...this.#picks, pick, pickOperators);
699
720
  const queryParts = {
700
721
  ...this.#queryParts,
701
722
  joins: mergeJoin(this.#queryParts.joins, {
702
723
  operator: joinOperator,
703
- table: tableSchema,
724
+ table,
704
725
  constraint: condition
705
726
  ? pickOperators.and(condition, joinCondition)
706
727
  : joinCondition,
@@ -945,12 +966,11 @@ class QueryBuilder {
945
966
  */
946
967
  from(tableName, shape) {
947
968
  const tableSchema = this.#getTableSchema(tableName, shape);
948
- const from = tableSchema;
969
+ const {table, pick, condition} = useTableSchema(tableSchema, shape);
949
970
  const queryParts = {
950
- from,
971
+ from: table,
951
972
  withs: this.#withs,
952
973
  };
953
- const {pick, condition} = useTableSchema(tableSchema, shape);
954
974
  if (condition) {
955
975
  queryParts.where = condition;
956
976
  }
@@ -966,4 +986,5 @@ class QueryBuilder {
966
986
  module.exports = {
967
987
  QueryBuilder,
968
988
  FromQuery,
989
+ FinalQuery,
969
990
  };
@@ -1,5 +1,6 @@
1
1
  // @ts-check
2
2
  /**
3
+ * @typedef {import("./query-builder.js").DbTable} DbTable
3
4
  * @typedef {import("./query-builder.js").QueryObj} QueryObj
4
5
  * @typedef {import("./operator-to-sql.js").ExpressionToSqlContext} ExpressionToSqlContext
5
6
  */
@@ -21,7 +22,8 @@ function withSql(withs, context) {
21
22
  .map(({name, query}) => {
22
23
  let sql = '';
23
24
  sql += `${name} AS (\n`;
24
- sql += queryToSql(query, context.values).sql;
25
+ sql += queryToSql(query, context.values, {tablesUsed: context.tablesUsed})
26
+ .sql;
25
27
  sql += '\n)';
26
28
  return sql;
27
29
  })
@@ -37,6 +39,7 @@ function withSql(withs, context) {
37
39
  function tableSql(table, context) {
38
40
  // Note: table is not validated
39
41
  if (typeof table === 'string') {
42
+ context.tablesUsed.push({table});
40
43
  return table;
41
44
  }
42
45
  if (!('table' in table)) {
@@ -44,6 +47,7 @@ function tableSql(table, context) {
44
47
  }
45
48
  let resultSql = '';
46
49
  if (typeof table.table === 'string') {
50
+ context.tablesUsed.push(table);
47
51
  if (typeof table.db === 'string') {
48
52
  resultSql += `${table.db}.`;
49
53
  }
@@ -123,12 +127,13 @@ function groupByFields(groupBy, context) {
123
127
  * @param {QueryObj} query
124
128
  * @param {any[] | null} [values]
125
129
  * @param {Partial<ExpressionToSqlContext>} [options]
126
- * @returns {{sql: string, values: any[] | null}}
130
+ * @returns {{sql: string, values: any[] | null, tables: DbTable[]}}
127
131
  */
128
132
  function queryToSql(query, values = [], options = {}) {
129
133
  /** @type {ExpressionToSqlContext} */
130
134
  const context = {
131
135
  values,
136
+ tablesUsed: [],
132
137
  scope: query.scope,
133
138
  useTableNames: query.joins && query.joins.length > 0,
134
139
  equalOperator: 'IS',
@@ -169,7 +174,7 @@ function queryToSql(query, values = [], options = {}) {
169
174
  }
170
175
  result += '\n' + `OFFSET ${query.offset}`;
171
176
  }
172
- return {sql: result, values};
177
+ return {sql: result, values, tables: context.tablesUsed};
173
178
  }
174
179
 
175
180
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xcraft-core-pickaxe",
3
- "version": "0.1.29",
3
+ "version": "0.1.30",
4
4
  "description": "Query builder",
5
5
  "main": "index.js",
6
6
  "scripts": {