@ignisia/sql 0.3.0 → 0.4.0

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 (104) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/column/index.js +2 -9
  3. package/dist/cjs/database/alter.d.cts +2 -2
  4. package/dist/cjs/database/column.d.cts +2 -2
  5. package/dist/cjs/database/contract.d.cts +2 -2
  6. package/dist/cjs/database/index.d.cts +2 -2
  7. package/dist/cjs/database/index.js +1 -1
  8. package/dist/cjs/database/table.d.cts +2 -2
  9. package/dist/cjs/database/types.d.cts +1 -1
  10. package/dist/cjs/database/wrapper.d.cts +3 -3
  11. package/dist/cjs/database/wrapper.js +1 -17
  12. package/dist/cjs/{index-CnQVnCEI.d.cts → index-CHxuUiO4.d.cts} +178 -98
  13. package/dist/cjs/{index-2jl8MRfX.d.cts → index-CZhrzE5r.d.cts} +2 -2
  14. package/dist/cjs/index.d.cts +2 -2
  15. package/dist/cjs/migration/index.d.cts +2 -2
  16. package/dist/cjs/migration/type.d.cts +2 -2
  17. package/dist/cjs/query/builder.d.cts +3 -3
  18. package/dist/cjs/query/builder.js +1 -1
  19. package/dist/cjs/query/condition/common.d.cts +41 -0
  20. package/dist/cjs/query/condition/common.js +62 -0
  21. package/dist/cjs/query/condition/core.d.cts +8 -0
  22. package/dist/cjs/query/condition/core.js +57 -0
  23. package/dist/cjs/query/condition/index.d.cts +10 -0
  24. package/dist/cjs/query/condition/index.js +33 -0
  25. package/dist/cjs/query/condition/not.d.cts +34 -0
  26. package/dist/cjs/query/condition/not.js +51 -0
  27. package/dist/cjs/query/condition/raw.d.cts +8 -0
  28. package/dist/cjs/query/condition/raw.js +54 -0
  29. package/dist/cjs/query/constants.d.cts +27 -1
  30. package/dist/cjs/query/constants.js +28 -2
  31. package/dist/cjs/query/contract.d.cts +2 -2
  32. package/dist/cjs/query/explain.d.cts +12 -0
  33. package/dist/cjs/query/explain.js +65 -0
  34. package/dist/cjs/query/helper.d.cts +3 -3
  35. package/dist/cjs/query/helper.js +1 -1
  36. package/dist/cjs/query/index.d.cts +2 -2
  37. package/dist/cjs/query/index.js +59 -64
  38. package/dist/cjs/query/join.d.cts +18 -6
  39. package/dist/cjs/query/join.js +38 -9
  40. package/dist/cjs/query/sql.d.cts +5 -3
  41. package/dist/cjs/query/sql.js +46 -15
  42. package/dist/cjs/query/types.d.cts +2 -2
  43. package/dist/cjs/query/utilities.d.cts +5 -4
  44. package/dist/cjs/query/utilities.js +73 -2
  45. package/dist/cjs/table/index.d.cts +3 -3
  46. package/dist/cjs/table/types.d.cts +2 -2
  47. package/dist/cjs/table/utilities.d.cts +2 -2
  48. package/dist/cjs/types.d.cts +5 -1
  49. package/dist/cjs/utilities.d.cts +2 -1
  50. package/dist/cjs/utilities.js +22 -0
  51. package/dist/esm/column/index.js +3 -10
  52. package/dist/esm/database/alter.d.ts +2 -2
  53. package/dist/esm/database/column.d.ts +2 -2
  54. package/dist/esm/database/contract.d.ts +2 -2
  55. package/dist/esm/database/index.d.ts +2 -2
  56. package/dist/esm/database/index.js +2 -2
  57. package/dist/esm/database/table.d.ts +2 -2
  58. package/dist/esm/database/types.d.ts +1 -1
  59. package/dist/esm/database/wrapper.d.ts +3 -3
  60. package/dist/esm/database/wrapper.js +1 -17
  61. package/dist/esm/{index-BdpoD4zk.d.ts → index-CjurLJdK.d.ts} +178 -98
  62. package/dist/esm/{index-BXOAxB_h.d.ts → index-DgOs61lH.d.ts} +2 -2
  63. package/dist/esm/index.d.ts +2 -2
  64. package/dist/esm/migration/index.d.ts +2 -2
  65. package/dist/esm/migration/type.d.ts +2 -2
  66. package/dist/esm/query/builder.d.ts +3 -3
  67. package/dist/esm/query/builder.js +1 -1
  68. package/dist/esm/query/condition/common.d.ts +41 -0
  69. package/dist/esm/query/condition/common.js +56 -0
  70. package/dist/esm/query/condition/core.d.ts +8 -0
  71. package/dist/esm/query/condition/core.js +55 -0
  72. package/dist/esm/query/condition/index.d.ts +10 -0
  73. package/dist/esm/query/condition/index.js +4 -0
  74. package/dist/esm/query/condition/not.d.ts +34 -0
  75. package/dist/esm/query/condition/not.js +46 -0
  76. package/dist/esm/query/condition/raw.d.ts +8 -0
  77. package/dist/esm/query/condition/raw.js +50 -0
  78. package/dist/esm/query/constants.d.ts +27 -1
  79. package/dist/esm/query/constants.js +27 -3
  80. package/dist/esm/query/contract.d.ts +2 -2
  81. package/dist/esm/query/explain.d.ts +12 -0
  82. package/dist/esm/query/explain.js +64 -0
  83. package/dist/esm/query/helper.d.ts +3 -3
  84. package/dist/esm/query/helper.js +2 -2
  85. package/dist/esm/query/index.d.ts +2 -2
  86. package/dist/esm/query/index.js +62 -67
  87. package/dist/esm/query/join.d.ts +18 -6
  88. package/dist/esm/query/join.js +37 -9
  89. package/dist/esm/query/sql.d.ts +5 -3
  90. package/dist/esm/query/sql.js +46 -17
  91. package/dist/esm/query/types.d.ts +2 -2
  92. package/dist/esm/query/utilities.d.ts +5 -4
  93. package/dist/esm/query/utilities.js +73 -3
  94. package/dist/esm/table/index.d.ts +3 -3
  95. package/dist/esm/table/types.d.ts +2 -2
  96. package/dist/esm/table/utilities.d.ts +2 -2
  97. package/dist/esm/types.d.ts +5 -1
  98. package/dist/esm/utilities.d.ts +2 -1
  99. package/dist/esm/utilities.js +22 -1
  100. package/package.json +8 -2
  101. package/dist/cjs/query/condition.d.cts +0 -8
  102. package/dist/cjs/query/condition.js +0 -109
  103. package/dist/esm/query/condition.d.ts +0 -8
  104. package/dist/esm/query/condition.js +0 -101
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ var constants = require('../table/constants');
4
+ var constants$1 = require('./constants');
5
+
6
+ function buildPostgresExplainQuery(options) {
7
+ const clauses = [];
8
+ if (options?.format) {
9
+ clauses.push(`${constants$1.ExplainClause.FORMAT} ${options.format}`);
10
+ }
11
+ if (options?.analyze) {
12
+ clauses.push(constants$1.ExplainClause.ANALYZE);
13
+ if (options?.summary != null) {
14
+ clauses.push(
15
+ `${constants$1.ExplainClause.SUMMARY} ${options.summary ? "ON" : "OFF"}`
16
+ );
17
+ }
18
+ if (options?.timing != null)
19
+ clauses.push(`${constants$1.ExplainClause.TIMING} ${options.timing ? "ON" : "OFF"}`);
20
+ }
21
+ if (options?.verbose) {
22
+ clauses.push(`${constants$1.ExplainClause.VERBOSE} ${options.verbose ? "ON" : "OFF"}`);
23
+ }
24
+ if (options?.costs != null) {
25
+ clauses.push(`${constants$1.ExplainClause.COSTS} ${options.costs ? "ON" : "OFF"}`);
26
+ }
27
+ if (options?.buffers != null) {
28
+ clauses.push(`${constants$1.ExplainClause.BUFFERS} ${options.buffers ? "ON" : "OFF"}`);
29
+ }
30
+ if (clauses.length === 0) {
31
+ return "EXPLAIN ";
32
+ }
33
+ return `EXPLAIN (${clauses.join(", ")})`;
34
+ }
35
+ function buildMySqlExplainQuery(options) {
36
+ const clauses = [];
37
+ if (options.analyze) {
38
+ clauses.push(constants$1.ExplainClause.ANALYZE);
39
+ }
40
+ if (options.format) {
41
+ clauses.push(`${constants$1.ExplainClause.FORMAT}=${options.format}`);
42
+ }
43
+ if (clauses.length > 1) {
44
+ throw new Error("Only one explain clause is allowed");
45
+ }
46
+ return `EXPLAIN ${clauses.join(" ")}`;
47
+ }
48
+ function buildSqliteExplainQuery() {
49
+ const clauses = ["QUERY PLAN"];
50
+ return `EXPLAIN ${clauses.join(" ")}`;
51
+ }
52
+ function buildExplainQuery(q, options) {
53
+ switch (q.table.dialect) {
54
+ case constants.Dialect.POSTGRES:
55
+ return buildPostgresExplainQuery(options);
56
+ case constants.Dialect.MYSQL:
57
+ return buildMySqlExplainQuery(options);
58
+ case constants.Dialect.SQLITE:
59
+ return buildSqliteExplainQuery();
60
+ default:
61
+ throw new Error(`Dialect ${q.table.dialect} is not supported`);
62
+ }
63
+ }
64
+
65
+ exports.buildExplainQuery = buildExplainQuery;
@@ -1,8 +1,8 @@
1
- export { H as aggregateCol, z as alias, B as clone, G as col, F as rawCol } from '../index-CnQVnCEI.cjs';
1
+ export { I as aggregateCol, B as alias, F as clone, H as col, G as rawCol } from '../index-CHxuUiO4.cjs';
2
2
  import '../column/index.cjs';
3
3
  import './constants.cjs';
4
- import '../column/constants.cjs';
5
- import '../types.cjs';
6
4
  import 'bun';
5
+ import '../types.cjs';
6
+ import '../column/constants.cjs';
7
7
  import '../table/constants.cjs';
8
8
  import '../column/types.cjs';
@@ -9,7 +9,7 @@ function alias(alias2) {
9
9
  }
10
10
  function clone() {
11
11
  const query = new _.QueryBuilder(this.table);
12
- Object.assign(query.definition, utilities.deepClone(this.definition));
12
+ Object.assign(query.definition, utilities.cloneDefinition(this.definition));
13
13
  return query;
14
14
  }
15
15
  function rawCol(column) {
@@ -1,8 +1,8 @@
1
1
  import '../column/index.cjs';
2
- export { f as QueryBuilder } from '../index-CnQVnCEI.cjs';
2
+ export { l as QueryBuilder } from '../index-CHxuUiO4.cjs';
3
+ import '../types.cjs';
3
4
  import './constants.cjs';
4
5
  import '../table/constants.cjs';
5
6
  import '../column/constants.cjs';
6
7
  import '../column/types.cjs';
7
- import '../types.cjs';
8
8
  import 'bun';
@@ -17,6 +17,8 @@ class QueryBuilder {
17
17
  clone;
18
18
  toQuery;
19
19
  toString;
20
+ toDebugString;
21
+ explain;
20
22
  exec;
21
23
  rawWhere;
22
24
  rawAnd;
@@ -25,33 +27,23 @@ class QueryBuilder {
25
27
  where;
26
28
  and;
27
29
  or;
30
+ on;
28
31
  having;
32
+ whereGroup;
33
+ orGroup;
34
+ not;
29
35
  constructor(table) {
30
36
  this.hooks = {};
31
37
  this.table = table;
32
38
  this.definition = {
33
- queryType: null,
34
- select: null,
35
- having: null,
36
- where: null,
37
- params: null,
38
- limit: null,
39
- offset: null,
40
- groupBy: null,
41
- insertValues: null,
42
- updateValues: null,
43
- orderBy: null,
44
- aggregates: null,
45
- joins: null,
46
- distinct: null,
47
- baseAlias: table.name,
48
- joinedTables: null,
49
- withDeleted: null
39
+ baseAlias: table.name
50
40
  };
51
41
  this.alias = helper.alias.bind(this);
52
42
  this.clone = helper.clone.bind(this);
53
43
  this.toQuery = sql.toQuery.bind(this);
54
44
  this.toString = sql.toString.bind(this);
45
+ this.toDebugString = sql.toDebugString.bind(this);
46
+ this.explain = sql.explain.bind(this);
55
47
  this.exec = sql.exec.bind(this);
56
48
  this.rawWhere = condition.rawWhere.bind(this);
57
49
  this.rawHaving = condition.rawHaving.bind(this);
@@ -61,46 +53,36 @@ class QueryBuilder {
61
53
  this.having = condition.having.bind(this);
62
54
  this.and = this.where;
63
55
  this.or = condition.or.bind(this);
56
+ this.on = condition.on.bind(this);
57
+ this.whereGroup = condition.whereGroup.bind(this);
58
+ this.orGroup = condition.orGroup.bind(this);
59
+ this.not = {
60
+ where: condition.whereNot.bind(this),
61
+ having: condition.havingNot.bind(this),
62
+ or: condition.orNot.bind(this),
63
+ whereGroup: condition.whereNotGroup.bind(
64
+ this
65
+ ),
66
+ orGroup: condition.orNotGroup.bind(this)
67
+ };
64
68
  }
65
- leftJoin(joinTable, alias2, baseColumn, joinColumn) {
66
- return join.addJoin(
67
- this,
68
- constants.AcceptedJoin.LEFT,
69
- alias2,
70
- joinTable,
71
- baseColumn,
72
- joinColumn
73
- );
69
+ leftJoin(joinTable, alias2) {
70
+ return join.prepareJoin(this, constants.AcceptedJoin.LEFT, joinTable, alias2);
74
71
  }
75
- rightJoin(joinTable, alias2, baseColumn, joinColumn) {
76
- return join.addJoin(
77
- this,
78
- constants.AcceptedJoin.RIGHT,
79
- alias2,
80
- joinTable,
81
- baseColumn,
82
- joinColumn
83
- );
72
+ rightJoin(joinTable, alias2) {
73
+ return join.prepareJoin(this, constants.AcceptedJoin.RIGHT, joinTable, alias2);
84
74
  }
85
- innerJoin(joinTable, alias2, baseColumn, joinColumn) {
86
- return join.addJoin(
87
- this,
88
- constants.AcceptedJoin.INNER,
89
- alias2,
90
- joinTable,
91
- baseColumn,
92
- joinColumn
93
- );
75
+ innerJoin(joinTable, alias2) {
76
+ return join.prepareJoin(this, constants.AcceptedJoin.INNER, joinTable, alias2);
94
77
  }
95
- naturalJoin(joinTable, alias2, baseColumn, joinColumn) {
96
- return join.addJoin(
97
- this,
98
- constants.AcceptedJoin.NATURAL,
99
- alias2,
100
- joinTable,
101
- baseColumn,
102
- joinColumn
103
- );
78
+ fullJoin(joinTable, alias2) {
79
+ return join.prepareJoin(this, constants.AcceptedJoin.FULL, joinTable, alias2);
80
+ }
81
+ crossJoin(joinTable, alias2) {
82
+ return join.addNoOnJoin(this, constants.AcceptedJoin.CROSS, joinTable, alias2);
83
+ }
84
+ naturalJoin(joinTable, alias2) {
85
+ return join.prepareJoin(this, constants.AcceptedJoin.NATURAL, joinTable, alias2);
104
86
  }
105
87
  distinct() {
106
88
  this.definition.distinct = true;
@@ -162,17 +144,19 @@ class QueryBuilder {
162
144
  updatedAt,
163
145
  timestamp
164
146
  } = utilities$1.getTimestamp(this.table);
165
- if (isWithTimestamp) {
166
- values = values.map((row) => ({
167
- ...row,
168
- ...isHasCreatedAt && {
169
- [createdAt]: row[createdAt] ?? timestamp
170
- },
171
- ...isHasUpdatedAt && {
172
- [updatedAt]: row[updatedAt] ?? timestamp
173
- }
174
- }));
175
- }
147
+ values = values.map((row) => {
148
+ const fields = {};
149
+ for (const key in this.table.columns) {
150
+ fields[key] = row[key] ?? null;
151
+ }
152
+ if (isWithTimestamp && isHasCreatedAt) {
153
+ fields[createdAt] = row[createdAt] ?? timestamp;
154
+ }
155
+ if (isWithTimestamp && isHasUpdatedAt) {
156
+ fields[updatedAt] = row[updatedAt] ?? timestamp;
157
+ }
158
+ return fields;
159
+ });
176
160
  this.definition.insertValues = values;
177
161
  return this;
178
162
  }
@@ -198,6 +182,17 @@ class QueryBuilder {
198
182
  this.definition.queryType = constants.QueryType.DELETE;
199
183
  return this;
200
184
  }
185
+ paginate(page, size) {
186
+ if (page < 1) {
187
+ throw new Error("Page number must be at least 1");
188
+ }
189
+ if (size < 1) {
190
+ throw new Error("Page size must be at least 1");
191
+ }
192
+ this.definition.limit = size;
193
+ this.definition.offset = (page - 1) * size;
194
+ return this;
195
+ }
201
196
  infer() {
202
197
  return null;
203
198
  }
@@ -1,17 +1,29 @@
1
- import { T as Table, Q as QueryDefinition, C as ColumnSelector, e as StrictColumnSelector, f as QueryBuilder } from '../index-CnQVnCEI.cjs';
1
+ import { T as Table, Q as QueryDefinition, C as ColumnSelector, k as StrictColumnSelector, l as QueryBuilder, n as QueryTransformerContract, o as QueryConditionContract } from '../index-CHxuUiO4.cjs';
2
2
  import { Column } from '../column/index.cjs';
3
3
  import { AcceptedJoin } from './constants.cjs';
4
- import '../column/constants.cjs';
5
- import '../types.cjs';
6
4
  import 'bun';
5
+ import '../types.cjs';
6
+ import '../column/constants.cjs';
7
7
  import '../table/constants.cjs';
8
8
  import '../column/types.cjs';
9
9
 
10
- declare function addJoin<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, JoinType extends AcceptedJoin, JoinTable extends Table<string, Record<string, Column>>, JoinAlias extends string, BaseColName extends `${Alias}."${keyof TableRef['columns'] & string}"`, JoinColName extends `${JoinAlias}."${keyof JoinTable['columns'] & string}"`, FinalJoinedTables extends JoinedTables & {
10
+ declare function addNoOnJoin<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, JoinType extends AcceptedJoin, JoinTable extends Table<string, Record<string, Column>>, JoinAlias extends string, FinalJoinedTables extends JoinedTables & {
11
11
  [K in JoinAlias]: JoinTable;
12
- }>(query: QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>, joinType: JoinType, alias: JoinAlias, joinTable: JoinTable, baseColumn: BaseColName, joinColumn: JoinColName): QueryBuilder<Alias, TableRef, FinalJoinedTables, Omit<Definition, "joins" | "joinedTables"> & {
12
+ }>(query: QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>, joinType: JoinType, joinTable: JoinTable, alias: JoinAlias): QueryBuilder<Alias, TableRef, FinalJoinedTables, Omit<Definition, "joins" | "joinedTables"> & {
13
13
  joins: string[];
14
14
  joinedTables: FinalJoinedTables;
15
15
  }>;
16
+ declare function prepareJoin<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, JoinType extends AcceptedJoin, JoinTable extends Table<string, Record<string, Column>>, JoinAlias extends string>(query: QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>, joinType: JoinType, joinTable: JoinTable, alias: JoinAlias): {
17
+ on<FinalJoinedTables extends JoinedTables & { [K in JoinAlias]: JoinTable; }, ReturnedJoinedTables extends FinalJoinedTables = FinalJoinedTables>(callback: (q: QueryBuilder<Alias, TableRef, FinalJoinedTables>) => QueryBuilder<Alias, TableRef, ReturnedJoinedTables>): QueryBuilder<Alias, TableRef, ReturnedJoinedTables, Omit<Definition, "joins" | "joinedTables"> & {
18
+ joins: string[];
19
+ joinedTables: ReturnedJoinedTables;
20
+ }, ColumnSelector<Alias, TableRef, ReturnedJoinedTables>, StrictColumnSelector<Alias, TableRef, ReturnedJoinedTables>, QueryTransformerContract<Alias, TableRef, ReturnedJoinedTables, Omit<Definition, "joins" | "joinedTables"> & {
21
+ joins: string[];
22
+ joinedTables: ReturnedJoinedTables;
23
+ }, ColumnSelector<Alias, TableRef, ReturnedJoinedTables>, StrictColumnSelector<Alias, TableRef, ReturnedJoinedTables>>, QueryConditionContract<Alias, TableRef, ReturnedJoinedTables, Omit<Definition, "joins" | "joinedTables"> & {
24
+ joins: string[];
25
+ joinedTables: ReturnedJoinedTables;
26
+ }, ColumnSelector<Alias, TableRef, ReturnedJoinedTables>, StrictColumnSelector<Alias, TableRef, ReturnedJoinedTables>>>;
27
+ };
16
28
 
17
- export { addJoin };
29
+ export { addNoOnJoin, prepareJoin };
@@ -1,18 +1,47 @@
1
1
  'use strict';
2
2
 
3
- function addJoin(query, joinType, alias, joinTable, baseColumn, joinColumn) {
3
+ var _ = require('.');
4
+
5
+ function addNoOnJoin(query, joinType, joinTable, alias) {
4
6
  if (!query.definition.joins) query.definition.joins = [];
5
- query.definition.joins.push(
6
- `${joinType} JOIN ${joinTable.name} AS ${alias} ON ${baseColumn} = ${joinColumn}`
7
- );
7
+ query.definition.joins.push(`${joinType} JOIN ${joinTable.name} AS ${alias}`);
8
8
  if (!query.definition.joinedTables) {
9
9
  query.definition.joinedTables = {};
10
10
  }
11
- query.definition.joinedTables = {
12
- ...query.definition.joinedTables,
13
- [alias]: joinTable
14
- };
11
+ query.definition.joinedTables[alias] = joinTable;
15
12
  return query;
16
13
  }
14
+ function prepareJoin(query, joinType, joinTable, alias) {
15
+ return {
16
+ on(callback) {
17
+ const sub = callback(new _.QueryBuilder(query.table));
18
+ const subDef = sub.definition;
19
+ if (!subDef.where?.length) {
20
+ return query;
21
+ }
22
+ const grouped = `(${subDef.where.join(" ")})`;
23
+ if (!query.definition.joins) query.definition.joins = [];
24
+ query.definition.joins.push(
25
+ `${joinType} JOIN ${joinTable.name} AS ${alias} ON ${grouped}`
26
+ );
27
+ if (subDef.joins?.length) {
28
+ query.definition.joins.push(...subDef.joins);
29
+ }
30
+ if (subDef.params?.length) {
31
+ if (!query.definition.params) query.definition.params = [];
32
+ query.definition.params.push(...subDef.params);
33
+ }
34
+ if (!query.definition.joinedTables) {
35
+ query.definition.joinedTables = {};
36
+ }
37
+ query.definition.joinedTables[alias] = joinTable;
38
+ if (subDef.joinedTables) {
39
+ Object.assign(query.definition.joinedTables, subDef.joinedTables);
40
+ }
41
+ return query;
42
+ }
43
+ };
44
+ }
17
45
 
18
- exports.addJoin = addJoin;
46
+ exports.addNoOnJoin = addNoOnJoin;
47
+ exports.prepareJoin = prepareJoin;
@@ -1,10 +1,10 @@
1
1
  import { TransactionSQL } from 'bun';
2
- import { T as Table, Q as QueryDefinition, C as ColumnSelector, e as StrictColumnSelector, f as QueryBuilder } from '../index-CnQVnCEI.cjs';
2
+ import { T as Table, Q as QueryDefinition, C as ColumnSelector, k as StrictColumnSelector, l as QueryBuilder, E as ExplainOptions } from '../index-CHxuUiO4.cjs';
3
3
  import { Column } from '../column/index.cjs';
4
4
  import { Dialect } from '../table/constants.cjs';
5
- import '../column/constants.cjs';
6
5
  import '../types.cjs';
7
6
  import './constants.cjs';
7
+ import '../column/constants.cjs';
8
8
  import '../column/types.cjs';
9
9
 
10
10
  declare function buildQuery(query: string): string;
@@ -13,6 +13,8 @@ declare function toQuery<Alias extends string, TableRef extends Table<string, Re
13
13
  params: unknown[] | null | undefined;
14
14
  };
15
15
  declare function toString<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, Query extends QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>>(this: Query): string;
16
+ declare function toDebugString<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, Query extends QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>>(this: Query): string;
17
+ declare function explain<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, Query extends QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>>(this: Query, options?: ExplainOptions): Promise<unknown>;
16
18
  declare function exec<Alias extends string, TableRef extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>, Definition extends Partial<QueryDefinition<Alias, TableRef, JoinedTables>>, AllowedColumn extends ColumnSelector<Alias, TableRef, JoinedTables>, StrictAllowedColumn extends StrictColumnSelector<Alias, TableRef, JoinedTables>, Query extends QueryBuilder<Alias, TableRef, JoinedTables, Definition, AllowedColumn, StrictAllowedColumn>, Output extends Query['_output'] = Query['_output']>(this: Query, tx?: TransactionSQL | null): Promise<Output>;
17
19
 
18
- export { buildQuery, exec, toQuery, toString };
20
+ export { buildQuery, exec, explain, toDebugString, toQuery, toString };
@@ -3,6 +3,7 @@
3
3
  var constants$1 = require('../table/constants');
4
4
  var builder = require('./builder');
5
5
  var constants = require('./constants');
6
+ var explain$1 = require('./explain');
6
7
  var utilities = require('./utilities');
7
8
 
8
9
  function buildQuery(query) {
@@ -13,61 +14,89 @@ function buildQuery(query) {
13
14
  });
14
15
  }
15
16
  function toQuery(dialect) {
16
- let sql = "";
17
+ const parts = [];
17
18
  switch (this.definition.queryType) {
18
19
  case constants.QueryType.SELECT:
19
- sql = builder.buildSelectQuery(this);
20
+ parts.push(builder.buildSelectQuery(this));
20
21
  break;
21
22
  case constants.QueryType.INSERT:
22
- sql = builder.buildInsertQuery(this);
23
+ parts.push(builder.buildInsertQuery(this));
23
24
  break;
24
25
  case constants.QueryType.UPDATE:
25
- sql = builder.buildUpdateQuery(this);
26
+ parts.push(builder.buildUpdateQuery(this));
26
27
  break;
27
28
  case constants.QueryType.DELETE:
28
- sql = builder.buildDeleteQuery(this);
29
+ parts.push(builder.buildDeleteQuery(this));
29
30
  break;
30
31
  default:
31
32
  throw new Error("No query type defined");
32
33
  }
33
34
  if (this.definition?.joins?.length) {
34
- sql += ` ${this.definition.joins.join(" ")}`;
35
+ parts.push(this.definition.joins.join(" "));
35
36
  }
36
37
  const whereConditions = utilities.getWhereConditions(this);
37
38
  if (whereConditions.length) {
38
- sql += ` WHERE ${whereConditions.join(" ")}`;
39
+ parts.push(`WHERE ${whereConditions.join(" ")}`);
39
40
  }
40
41
  const groupByConditions = utilities.getGroupByConditions(this);
41
42
  if (groupByConditions.length) {
42
- sql += ` GROUP BY ${groupByConditions.join(", ")}`;
43
+ parts.push(`GROUP BY ${groupByConditions.join(", ")}`);
43
44
  }
44
45
  if (this.definition?.having?.length) {
45
- sql += ` HAVING ${this.definition.having.join(" ")}`;
46
+ parts.push(`HAVING ${this.definition.having.join(" ")}`);
46
47
  }
47
48
  if (this.definition?.orderBy?.length) {
48
- sql += ` ORDER BY ${this.definition.orderBy.map((order) => [order.column, order.direction].join(" ")).join(", ")}`;
49
+ parts.push(
50
+ `ORDER BY ${this.definition.orderBy.map((order) => `${order.column} ${order.direction}`).join(", ")}`
51
+ );
49
52
  }
50
53
  if (this.definition?.limit !== null) {
51
- sql += ` LIMIT ?`;
54
+ parts.push("LIMIT ?");
52
55
  if (!this.definition.params) this.definition.params = [];
53
56
  this.definition.params.push(this.definition.limit);
54
57
  }
55
58
  if (this.definition?.offset !== null) {
56
- sql += ` OFFSET ?`;
59
+ parts.push("OFFSET ?");
57
60
  if (!this.definition.params) this.definition.params = [];
58
61
  this.definition.params.push(this.definition.offset);
59
62
  }
60
63
  if (this.definition.queryType === constants.QueryType.UPDATE || this.definition.queryType === constants.QueryType.DELETE) {
61
64
  if (dialect !== constants$1.Dialect.MYSQL) {
62
- sql += ` RETURNING *`;
65
+ parts.push("RETURNING *");
63
66
  }
64
67
  }
65
- sql = buildQuery(sql);
66
- return { query: sql + ";", params: this.definition.params };
68
+ const sql = buildQuery(parts.join(" "));
69
+ return { query: `${sql};`, params: this.definition.params };
67
70
  }
68
71
  function toString() {
69
72
  return this.toQuery().query;
70
73
  }
74
+ function toDebugString() {
75
+ const { query, params } = this.toQuery();
76
+ if (!params || params.length === 0) {
77
+ return query;
78
+ }
79
+ let debugQuery = query;
80
+ utilities.sanitizeParams(params).forEach((param, index) => {
81
+ const value = param === null ? "NULL" : `'${String(param).replace(/'/g, "''")}'`;
82
+ debugQuery = debugQuery.replace(
83
+ new RegExp(`\\$${index + 1}\\b`, "g"),
84
+ value
85
+ );
86
+ });
87
+ return debugQuery;
88
+ }
89
+ function explain(options = {}) {
90
+ const { query, params } = this.toQuery();
91
+ const explainPrefix = explain$1.buildExplainQuery(this, options);
92
+ if (!this.table.client) {
93
+ throw new Error("Database client not defined");
94
+ }
95
+ return this.table.client.exec({
96
+ sql: `${explainPrefix}${query}`,
97
+ params
98
+ });
99
+ }
71
100
  async function exec(tx) {
72
101
  const client = this.table.client;
73
102
  const dialect = this.table.dialect;
@@ -128,5 +157,7 @@ async function exec(tx) {
128
157
 
129
158
  exports.buildQuery = buildQuery;
130
159
  exports.exec = exec;
160
+ exports.explain = explain;
161
+ exports.toDebugString = toDebugString;
131
162
  exports.toQuery = toQuery;
132
163
  exports.toString = toString;
@@ -1,8 +1,8 @@
1
+ import 'bun';
1
2
  import '../column/index.cjs';
2
3
  import '../column/constants.cjs';
3
- export { l as AcceptedInsertValues, k as AcceptedOrderBy, m as AcceptedUpdateValues, n as AggregateColumn, A as AliasedColumn, C as ColumnSelector, h as QuerHooks, Q as QueryDefinition, p as QueryOutput, j as QueryRunHooks, q as QueryRunHooksOptions, R as RawColumn, o as SelectQueryOutput, g as SelectableColumn, e as StrictColumnSelector, W as WhereValue } from '../index-CnQVnCEI.cjs';
4
+ export { u as AcceptedInsertValues, t as AcceptedOrderBy, v as AcceptedUpdateValues, w as AggregateColumn, A as AliasedColumn, C as ColumnSelector, E as ExplainOptions, Q as QueryDefinition, p as QueryHooks, y as QueryOutput, s as QueryRunHooks, z as QueryRunHooksOptions, R as RawColumn, x as SelectQueryOutput, m as SelectableColumn, k as StrictColumnSelector, W as WhereValue } from '../index-CHxuUiO4.cjs';
4
5
  import '../types.cjs';
5
6
  import './constants.cjs';
6
7
  import '../table/constants.cjs';
7
8
  import '../column/types.cjs';
8
- import 'bun';
@@ -1,10 +1,10 @@
1
- import { T as Table, W as WhereValue, Q as QueryDefinition, C as ColumnSelector, e as StrictColumnSelector, f as QueryBuilder, A as AliasedColumn, g as SelectableColumn } from '../index-CnQVnCEI.cjs';
1
+ import { T as Table, W as WhereValue, Q as QueryDefinition, C as ColumnSelector, k as StrictColumnSelector, l as QueryBuilder, A as AliasedColumn, m as SelectableColumn } from '../index-CHxuUiO4.cjs';
2
2
  import { Column } from '../column/index.cjs';
3
3
  import { Dialect } from '../table/constants.cjs';
4
4
  import { AcceptedOperator } from './constants.cjs';
5
- import '../column/constants.cjs';
6
- import '../types.cjs';
7
5
  import 'bun';
6
+ import '../types.cjs';
7
+ import '../column/constants.cjs';
8
8
  import '../column/types.cjs';
9
9
 
10
10
  declare function getTableColumnNames<ColName extends string, BaseAlias extends string, BaseTable extends Table<string, Record<string, Column>>, JoinedTables extends Record<string, Table<string, Record<string, Column>>>>(column: ColName, baseAlias: BaseAlias, baseTable: BaseTable, joinedTables: JoinedTables): {
@@ -33,5 +33,6 @@ declare function parseAliasedRow({ row, selects, root, }: {
33
33
  selects: SelectableColumn<string>[];
34
34
  root?: string | null;
35
35
  }): Record<string, any>;
36
+ declare function sanitizeParams(params: unknown[]): (string | number | bigint | boolean | null)[];
36
37
 
37
- export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow };
38
+ export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow, sanitizeParams };
@@ -55,6 +55,58 @@ function getCondition(dialect, column, operator, value) {
55
55
  return `${column} BETWEEN ? AND ?`;
56
56
  case constants.AcceptedOperator.NOT_BETWEEN:
57
57
  return `${column} NOT BETWEEN ? AND ?`;
58
+ case constants.AcceptedOperator.STARTS_WITH:
59
+ return `${column} LIKE ?`;
60
+ case constants.AcceptedOperator.ENDS_WITH:
61
+ return `${column} LIKE ?`;
62
+ case constants.AcceptedOperator.REG_EXP: {
63
+ switch (dialect) {
64
+ case constants$1.Dialect.POSTGRES:
65
+ return `${column} ~ ?`;
66
+ case constants$1.Dialect.MYSQL:
67
+ return `${column} REGEXP ?`;
68
+ case constants$1.Dialect.SQLITE:
69
+ return `${column} GLOB ?`;
70
+ default:
71
+ throw new Error("Operator not supported");
72
+ }
73
+ }
74
+ case constants.AcceptedOperator.NOT_REG_EXP: {
75
+ switch (dialect) {
76
+ case constants$1.Dialect.POSTGRES:
77
+ return `${column} !~ ?`;
78
+ case constants$1.Dialect.MYSQL:
79
+ return `${column} NOT REGEXP ?`;
80
+ case constants$1.Dialect.SQLITE:
81
+ return `${column} NOT GLOB ?`;
82
+ default:
83
+ throw new Error("Operator not supported");
84
+ }
85
+ }
86
+ case constants.AcceptedOperator.RLIKE: {
87
+ switch (dialect) {
88
+ case constants$1.Dialect.POSTGRES:
89
+ return `${column} ~* ?`;
90
+ case constants$1.Dialect.MYSQL:
91
+ return `${column} RLIKE ?`;
92
+ case constants$1.Dialect.SQLITE:
93
+ return `${column} GLOB ?`;
94
+ default:
95
+ throw new Error("Operator not supported");
96
+ }
97
+ }
98
+ case constants.AcceptedOperator.NOT_RLIKE: {
99
+ switch (dialect) {
100
+ case constants$1.Dialect.POSTGRES:
101
+ return `${column} !~* ?`;
102
+ case constants$1.Dialect.MYSQL:
103
+ return `${column} NOT RLIKE ?`;
104
+ case constants$1.Dialect.SQLITE:
105
+ return `${column} NOT GLOB ?`;
106
+ default:
107
+ throw new Error("Operator not supported");
108
+ }
109
+ }
58
110
  default:
59
111
  throw new Error("Invalid operator");
60
112
  }
@@ -72,13 +124,13 @@ function getTimestamp(table) {
72
124
  if (typeof table.timestamp.createdAt === "string") {
73
125
  createdAt = table.timestamp.createdAt;
74
126
  }
75
- isHasCreatedAt = table.timestamp.createdAt === false;
127
+ isHasCreatedAt = table.timestamp.createdAt !== false;
76
128
  }
77
129
  if (isCustomTimestamp) {
78
130
  if (typeof table.timestamp.updatedAt === "string") {
79
131
  updatedAt = table.timestamp.updatedAt;
80
132
  }
81
- isHasUpdatedAt = table.timestamp.updatedAt === false;
133
+ isHasUpdatedAt = table.timestamp.updatedAt !== false;
82
134
  }
83
135
  }
84
136
  return {
@@ -183,6 +235,24 @@ function parseAliasedRow({
183
235
  }
184
236
  return result;
185
237
  }
238
+ function sanitizeParams(params) {
239
+ return params.map((param) => {
240
+ if (param === null || typeof param === "string" || typeof param === "number" || typeof param === "boolean" || typeof param === "bigint") {
241
+ return param;
242
+ }
243
+ if (param === void 0) {
244
+ return null;
245
+ }
246
+ if (param instanceof Date) {
247
+ return param.toISOString();
248
+ }
249
+ try {
250
+ return JSON.stringify(param);
251
+ } catch {
252
+ return null;
253
+ }
254
+ });
255
+ }
186
256
 
187
257
  exports.getCondition = getCondition;
188
258
  exports.getGroupByConditions = getGroupByConditions;
@@ -192,3 +262,4 @@ exports.getTableSelectName = getTableSelectName;
192
262
  exports.getTimestamp = getTimestamp;
193
263
  exports.getWhereConditions = getWhereConditions;
194
264
  exports.parseAliasedRow = parseAliasedRow;
265
+ exports.sanitizeParams = sanitizeParams;
@@ -1,8 +1,8 @@
1
- export { T as Table } from '../index-CnQVnCEI.cjs';
1
+ export { T as Table } from '../index-CHxuUiO4.cjs';
2
2
  import '../column/index.cjs';
3
3
  import './constants.cjs';
4
- import '../column/constants.cjs';
4
+ import 'bun';
5
5
  import '../types.cjs';
6
6
  import '../query/constants.cjs';
7
- import 'bun';
7
+ import '../column/constants.cjs';
8
8
  import '../column/types.cjs';