@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
@@ -1,9 +1,9 @@
1
1
  import { quoteIdentifier } from '../utilities.js';
2
- import { rawWhere, rawHaving, rawOr, where, having, or } from './condition.js';
2
+ import { rawWhere, rawHaving, rawOr, where, having, or, on, whereGroup, orGroup, orNotGroup, whereNotGroup, orNot, havingNot, whereNot } from './condition/index.js';
3
3
  import { AcceptedJoin, QueryType } from './constants.js';
4
4
  import { alias, clone, aggregateCol, col } from './helper.js';
5
- import { addJoin } from './join.js';
6
- import { toQuery, toString, exec } from './sql.js';
5
+ import { prepareJoin, addNoOnJoin } from './join.js';
6
+ import { toQuery, toString, toDebugString, explain, exec } from './sql.js';
7
7
  import { getTimestamp, getParanoid } from './utilities.js';
8
8
 
9
9
  // src/query/index.ts
@@ -16,6 +16,8 @@ var QueryBuilder = class {
16
16
  clone;
17
17
  toQuery;
18
18
  toString;
19
+ toDebugString;
20
+ explain;
19
21
  exec;
20
22
  rawWhere;
21
23
  rawAnd;
@@ -24,33 +26,23 @@ var QueryBuilder = class {
24
26
  where;
25
27
  and;
26
28
  or;
29
+ on;
27
30
  having;
31
+ whereGroup;
32
+ orGroup;
33
+ not;
28
34
  constructor(table) {
29
35
  this.hooks = {};
30
36
  this.table = table;
31
37
  this.definition = {
32
- queryType: null,
33
- select: null,
34
- having: null,
35
- where: null,
36
- params: null,
37
- limit: null,
38
- offset: null,
39
- groupBy: null,
40
- insertValues: null,
41
- updateValues: null,
42
- orderBy: null,
43
- aggregates: null,
44
- joins: null,
45
- distinct: null,
46
- baseAlias: table.name,
47
- joinedTables: null,
48
- withDeleted: null
38
+ baseAlias: table.name
49
39
  };
50
40
  this.alias = alias.bind(this);
51
41
  this.clone = clone.bind(this);
52
42
  this.toQuery = toQuery.bind(this);
53
43
  this.toString = toString.bind(this);
44
+ this.toDebugString = toDebugString.bind(this);
45
+ this.explain = explain.bind(this);
54
46
  this.exec = exec.bind(this);
55
47
  this.rawWhere = rawWhere.bind(this);
56
48
  this.rawHaving = rawHaving.bind(this);
@@ -60,46 +52,36 @@ var QueryBuilder = class {
60
52
  this.having = having.bind(this);
61
53
  this.and = this.where;
62
54
  this.or = or.bind(this);
55
+ this.on = on.bind(this);
56
+ this.whereGroup = whereGroup.bind(this);
57
+ this.orGroup = orGroup.bind(this);
58
+ this.not = {
59
+ where: whereNot.bind(this),
60
+ having: havingNot.bind(this),
61
+ or: orNot.bind(this),
62
+ whereGroup: whereNotGroup.bind(
63
+ this
64
+ ),
65
+ orGroup: orNotGroup.bind(this)
66
+ };
63
67
  }
64
- leftJoin(joinTable, alias2, baseColumn, joinColumn) {
65
- return addJoin(
66
- this,
67
- AcceptedJoin.LEFT,
68
- alias2,
69
- joinTable,
70
- baseColumn,
71
- joinColumn
72
- );
68
+ leftJoin(joinTable, alias2) {
69
+ return prepareJoin(this, AcceptedJoin.LEFT, joinTable, alias2);
73
70
  }
74
- rightJoin(joinTable, alias2, baseColumn, joinColumn) {
75
- return addJoin(
76
- this,
77
- AcceptedJoin.RIGHT,
78
- alias2,
79
- joinTable,
80
- baseColumn,
81
- joinColumn
82
- );
71
+ rightJoin(joinTable, alias2) {
72
+ return prepareJoin(this, AcceptedJoin.RIGHT, joinTable, alias2);
83
73
  }
84
- innerJoin(joinTable, alias2, baseColumn, joinColumn) {
85
- return addJoin(
86
- this,
87
- AcceptedJoin.INNER,
88
- alias2,
89
- joinTable,
90
- baseColumn,
91
- joinColumn
92
- );
74
+ innerJoin(joinTable, alias2) {
75
+ return prepareJoin(this, AcceptedJoin.INNER, joinTable, alias2);
93
76
  }
94
- naturalJoin(joinTable, alias2, baseColumn, joinColumn) {
95
- return addJoin(
96
- this,
97
- AcceptedJoin.NATURAL,
98
- alias2,
99
- joinTable,
100
- baseColumn,
101
- joinColumn
102
- );
77
+ fullJoin(joinTable, alias2) {
78
+ return prepareJoin(this, AcceptedJoin.FULL, joinTable, alias2);
79
+ }
80
+ crossJoin(joinTable, alias2) {
81
+ return addNoOnJoin(this, AcceptedJoin.CROSS, joinTable, alias2);
82
+ }
83
+ naturalJoin(joinTable, alias2) {
84
+ return prepareJoin(this, AcceptedJoin.NATURAL, joinTable, alias2);
103
85
  }
104
86
  distinct() {
105
87
  this.definition.distinct = true;
@@ -161,17 +143,19 @@ var QueryBuilder = class {
161
143
  updatedAt,
162
144
  timestamp
163
145
  } = getTimestamp(this.table);
164
- if (isWithTimestamp) {
165
- values = values.map((row) => ({
166
- ...row,
167
- ...isHasCreatedAt && {
168
- [createdAt]: row[createdAt] ?? timestamp
169
- },
170
- ...isHasUpdatedAt && {
171
- [updatedAt]: row[updatedAt] ?? timestamp
172
- }
173
- }));
174
- }
146
+ values = values.map((row) => {
147
+ const fields = {};
148
+ for (const key in this.table.columns) {
149
+ fields[key] = row[key] ?? null;
150
+ }
151
+ if (isWithTimestamp && isHasCreatedAt) {
152
+ fields[createdAt] = row[createdAt] ?? timestamp;
153
+ }
154
+ if (isWithTimestamp && isHasUpdatedAt) {
155
+ fields[updatedAt] = row[updatedAt] ?? timestamp;
156
+ }
157
+ return fields;
158
+ });
175
159
  this.definition.insertValues = values;
176
160
  return this;
177
161
  }
@@ -197,6 +181,17 @@ var QueryBuilder = class {
197
181
  this.definition.queryType = QueryType.DELETE;
198
182
  return this;
199
183
  }
184
+ paginate(page, size) {
185
+ if (page < 1) {
186
+ throw new Error("Page number must be at least 1");
187
+ }
188
+ if (size < 1) {
189
+ throw new Error("Page size must be at least 1");
190
+ }
191
+ this.definition.limit = size;
192
+ this.definition.offset = (page - 1) * size;
193
+ return this;
194
+ }
200
195
  infer() {
201
196
  return null;
202
197
  }
@@ -1,17 +1,29 @@
1
- import { T as Table, Q as QueryDefinition, C as ColumnSelector, e as StrictColumnSelector, f as QueryBuilder } from '../index-BdpoD4zk.js';
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-CjurLJdK.js';
2
2
  import { Column } from '../column/index.js';
3
3
  import { AcceptedJoin } from './constants.js';
4
- import '../column/constants.js';
5
- import '../types.js';
6
4
  import 'bun';
5
+ import '../types.js';
6
+ import '../column/constants.js';
7
7
  import '../table/constants.js';
8
8
  import '../column/types.js';
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,17 +1,45 @@
1
+ import { QueryBuilder } from './index.js';
2
+
1
3
  // src/query/join.ts
2
- function addJoin(query, joinType, alias, joinTable, baseColumn, joinColumn) {
4
+ function addNoOnJoin(query, joinType, joinTable, alias) {
3
5
  if (!query.definition.joins) query.definition.joins = [];
4
- query.definition.joins.push(
5
- `${joinType} JOIN ${joinTable.name} AS ${alias} ON ${baseColumn} = ${joinColumn}`
6
- );
6
+ query.definition.joins.push(`${joinType} JOIN ${joinTable.name} AS ${alias}`);
7
7
  if (!query.definition.joinedTables) {
8
8
  query.definition.joinedTables = {};
9
9
  }
10
- query.definition.joinedTables = {
11
- ...query.definition.joinedTables,
12
- [alias]: joinTable
13
- };
10
+ query.definition.joinedTables[alias] = joinTable;
14
11
  return query;
15
12
  }
13
+ function prepareJoin(query, joinType, joinTable, alias) {
14
+ return {
15
+ on(callback) {
16
+ const sub = callback(new QueryBuilder(query.table));
17
+ const subDef = sub.definition;
18
+ if (!subDef.where?.length) {
19
+ return query;
20
+ }
21
+ const grouped = `(${subDef.where.join(" ")})`;
22
+ if (!query.definition.joins) query.definition.joins = [];
23
+ query.definition.joins.push(
24
+ `${joinType} JOIN ${joinTable.name} AS ${alias} ON ${grouped}`
25
+ );
26
+ if (subDef.joins?.length) {
27
+ query.definition.joins.push(...subDef.joins);
28
+ }
29
+ if (subDef.params?.length) {
30
+ if (!query.definition.params) query.definition.params = [];
31
+ query.definition.params.push(...subDef.params);
32
+ }
33
+ if (!query.definition.joinedTables) {
34
+ query.definition.joinedTables = {};
35
+ }
36
+ query.definition.joinedTables[alias] = joinTable;
37
+ if (subDef.joinedTables) {
38
+ Object.assign(query.definition.joinedTables, subDef.joinedTables);
39
+ }
40
+ return query;
41
+ }
42
+ };
43
+ }
16
44
 
17
- export { addJoin };
45
+ export { addNoOnJoin, 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-BdpoD4zk.js';
2
+ import { T as Table, Q as QueryDefinition, C as ColumnSelector, k as StrictColumnSelector, l as QueryBuilder, E as ExplainOptions } from '../index-CjurLJdK.js';
3
3
  import { Column } from '../column/index.js';
4
4
  import { Dialect } from '../table/constants.js';
5
- import '../column/constants.js';
6
5
  import '../types.js';
7
6
  import './constants.js';
7
+ import '../column/constants.js';
8
8
  import '../column/types.js';
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 };
@@ -1,7 +1,8 @@
1
1
  import { Dialect } from '../table/constants.js';
2
2
  import { buildDeleteQuery, buildUpdateQuery, buildInsertQuery, buildSelectQuery } from './builder.js';
3
3
  import { QueryType, QueryHooksType } from './constants.js';
4
- import { getWhereConditions, getGroupByConditions, parseAliasedRow } from './utilities.js';
4
+ import { buildExplainQuery } from './explain.js';
5
+ import { getWhereConditions, getGroupByConditions, sanitizeParams, parseAliasedRow } from './utilities.js';
5
6
 
6
7
  // src/query/sql.ts
7
8
  function buildQuery(query) {
@@ -12,61 +13,89 @@ function buildQuery(query) {
12
13
  });
13
14
  }
14
15
  function toQuery(dialect) {
15
- let sql = "";
16
+ const parts = [];
16
17
  switch (this.definition.queryType) {
17
18
  case QueryType.SELECT:
18
- sql = buildSelectQuery(this);
19
+ parts.push(buildSelectQuery(this));
19
20
  break;
20
21
  case QueryType.INSERT:
21
- sql = buildInsertQuery(this);
22
+ parts.push(buildInsertQuery(this));
22
23
  break;
23
24
  case QueryType.UPDATE:
24
- sql = buildUpdateQuery(this);
25
+ parts.push(buildUpdateQuery(this));
25
26
  break;
26
27
  case QueryType.DELETE:
27
- sql = buildDeleteQuery(this);
28
+ parts.push(buildDeleteQuery(this));
28
29
  break;
29
30
  default:
30
31
  throw new Error("No query type defined");
31
32
  }
32
33
  if (this.definition?.joins?.length) {
33
- sql += ` ${this.definition.joins.join(" ")}`;
34
+ parts.push(this.definition.joins.join(" "));
34
35
  }
35
36
  const whereConditions = getWhereConditions(this);
36
37
  if (whereConditions.length) {
37
- sql += ` WHERE ${whereConditions.join(" ")}`;
38
+ parts.push(`WHERE ${whereConditions.join(" ")}`);
38
39
  }
39
40
  const groupByConditions = getGroupByConditions(this);
40
41
  if (groupByConditions.length) {
41
- sql += ` GROUP BY ${groupByConditions.join(", ")}`;
42
+ parts.push(`GROUP BY ${groupByConditions.join(", ")}`);
42
43
  }
43
44
  if (this.definition?.having?.length) {
44
- sql += ` HAVING ${this.definition.having.join(" ")}`;
45
+ parts.push(`HAVING ${this.definition.having.join(" ")}`);
45
46
  }
46
47
  if (this.definition?.orderBy?.length) {
47
- sql += ` ORDER BY ${this.definition.orderBy.map((order) => [order.column, order.direction].join(" ")).join(", ")}`;
48
+ parts.push(
49
+ `ORDER BY ${this.definition.orderBy.map((order) => `${order.column} ${order.direction}`).join(", ")}`
50
+ );
48
51
  }
49
52
  if (this.definition?.limit !== null) {
50
- sql += ` LIMIT ?`;
53
+ parts.push("LIMIT ?");
51
54
  if (!this.definition.params) this.definition.params = [];
52
55
  this.definition.params.push(this.definition.limit);
53
56
  }
54
57
  if (this.definition?.offset !== null) {
55
- sql += ` OFFSET ?`;
58
+ parts.push("OFFSET ?");
56
59
  if (!this.definition.params) this.definition.params = [];
57
60
  this.definition.params.push(this.definition.offset);
58
61
  }
59
62
  if (this.definition.queryType === QueryType.UPDATE || this.definition.queryType === QueryType.DELETE) {
60
63
  if (dialect !== Dialect.MYSQL) {
61
- sql += ` RETURNING *`;
64
+ parts.push("RETURNING *");
62
65
  }
63
66
  }
64
- sql = buildQuery(sql);
65
- return { query: sql + ";", params: this.definition.params };
67
+ const sql = buildQuery(parts.join(" "));
68
+ return { query: `${sql};`, params: this.definition.params };
66
69
  }
67
70
  function toString() {
68
71
  return this.toQuery().query;
69
72
  }
73
+ function toDebugString() {
74
+ const { query, params } = this.toQuery();
75
+ if (!params || params.length === 0) {
76
+ return query;
77
+ }
78
+ let debugQuery = query;
79
+ sanitizeParams(params).forEach((param, index) => {
80
+ const value = param === null ? "NULL" : `'${String(param).replace(/'/g, "''")}'`;
81
+ debugQuery = debugQuery.replace(
82
+ new RegExp(`\\$${index + 1}\\b`, "g"),
83
+ value
84
+ );
85
+ });
86
+ return debugQuery;
87
+ }
88
+ function explain(options = {}) {
89
+ const { query, params } = this.toQuery();
90
+ const explainPrefix = buildExplainQuery(this, options);
91
+ if (!this.table.client) {
92
+ throw new Error("Database client not defined");
93
+ }
94
+ return this.table.client.exec({
95
+ sql: `${explainPrefix}${query}`,
96
+ params
97
+ });
98
+ }
70
99
  async function exec(tx) {
71
100
  const client = this.table.client;
72
101
  const dialect = this.table.dialect;
@@ -125,4 +154,4 @@ async function exec(tx) {
125
154
  );
126
155
  }
127
156
 
128
- export { buildQuery, exec, toQuery, toString };
157
+ export { buildQuery, exec, explain, toDebugString, toQuery, toString };
@@ -1,8 +1,8 @@
1
+ import 'bun';
1
2
  import '../column/index.js';
2
3
  import '../column/constants.js';
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-BdpoD4zk.js';
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-CjurLJdK.js';
4
5
  import '../types.js';
5
6
  import './constants.js';
6
7
  import '../table/constants.js';
7
8
  import '../column/types.js';
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-BdpoD4zk.js';
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-CjurLJdK.js';
2
2
  import { Column } from '../column/index.js';
3
3
  import { Dialect } from '../table/constants.js';
4
4
  import { AcceptedOperator } from './constants.js';
5
- import '../column/constants.js';
6
- import '../types.js';
7
5
  import 'bun';
6
+ import '../types.js';
7
+ import '../column/constants.js';
8
8
  import '../column/types.js';
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 };
@@ -54,6 +54,58 @@ function getCondition(dialect, column, operator, value) {
54
54
  return `${column} BETWEEN ? AND ?`;
55
55
  case AcceptedOperator.NOT_BETWEEN:
56
56
  return `${column} NOT BETWEEN ? AND ?`;
57
+ case AcceptedOperator.STARTS_WITH:
58
+ return `${column} LIKE ?`;
59
+ case AcceptedOperator.ENDS_WITH:
60
+ return `${column} LIKE ?`;
61
+ case AcceptedOperator.REG_EXP: {
62
+ switch (dialect) {
63
+ case Dialect.POSTGRES:
64
+ return `${column} ~ ?`;
65
+ case Dialect.MYSQL:
66
+ return `${column} REGEXP ?`;
67
+ case Dialect.SQLITE:
68
+ return `${column} GLOB ?`;
69
+ default:
70
+ throw new Error("Operator not supported");
71
+ }
72
+ }
73
+ case AcceptedOperator.NOT_REG_EXP: {
74
+ switch (dialect) {
75
+ case Dialect.POSTGRES:
76
+ return `${column} !~ ?`;
77
+ case Dialect.MYSQL:
78
+ return `${column} NOT REGEXP ?`;
79
+ case Dialect.SQLITE:
80
+ return `${column} NOT GLOB ?`;
81
+ default:
82
+ throw new Error("Operator not supported");
83
+ }
84
+ }
85
+ case AcceptedOperator.RLIKE: {
86
+ switch (dialect) {
87
+ case Dialect.POSTGRES:
88
+ return `${column} ~* ?`;
89
+ case Dialect.MYSQL:
90
+ return `${column} RLIKE ?`;
91
+ case Dialect.SQLITE:
92
+ return `${column} GLOB ?`;
93
+ default:
94
+ throw new Error("Operator not supported");
95
+ }
96
+ }
97
+ case AcceptedOperator.NOT_RLIKE: {
98
+ switch (dialect) {
99
+ case Dialect.POSTGRES:
100
+ return `${column} !~* ?`;
101
+ case Dialect.MYSQL:
102
+ return `${column} NOT RLIKE ?`;
103
+ case Dialect.SQLITE:
104
+ return `${column} NOT GLOB ?`;
105
+ default:
106
+ throw new Error("Operator not supported");
107
+ }
108
+ }
57
109
  default:
58
110
  throw new Error("Invalid operator");
59
111
  }
@@ -71,13 +123,13 @@ function getTimestamp(table) {
71
123
  if (typeof table.timestamp.createdAt === "string") {
72
124
  createdAt = table.timestamp.createdAt;
73
125
  }
74
- isHasCreatedAt = table.timestamp.createdAt === false;
126
+ isHasCreatedAt = table.timestamp.createdAt !== false;
75
127
  }
76
128
  if (isCustomTimestamp) {
77
129
  if (typeof table.timestamp.updatedAt === "string") {
78
130
  updatedAt = table.timestamp.updatedAt;
79
131
  }
80
- isHasUpdatedAt = table.timestamp.updatedAt === false;
132
+ isHasUpdatedAt = table.timestamp.updatedAt !== false;
81
133
  }
82
134
  }
83
135
  return {
@@ -182,5 +234,23 @@ function parseAliasedRow({
182
234
  }
183
235
  return result;
184
236
  }
237
+ function sanitizeParams(params) {
238
+ return params.map((param) => {
239
+ if (param === null || typeof param === "string" || typeof param === "number" || typeof param === "boolean" || typeof param === "bigint") {
240
+ return param;
241
+ }
242
+ if (param === void 0) {
243
+ return null;
244
+ }
245
+ if (param instanceof Date) {
246
+ return param.toISOString();
247
+ }
248
+ try {
249
+ return JSON.stringify(param);
250
+ } catch {
251
+ return null;
252
+ }
253
+ });
254
+ }
185
255
 
186
- export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow };
256
+ export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow, sanitizeParams };
@@ -1,8 +1,8 @@
1
- export { T as Table } from '../index-BdpoD4zk.js';
1
+ export { T as Table } from '../index-CjurLJdK.js';
2
2
  import '../column/index.js';
3
3
  import './constants.js';
4
- import '../column/constants.js';
4
+ import 'bun';
5
5
  import '../types.js';
6
6
  import '../query/constants.js';
7
- import 'bun';
7
+ import '../column/constants.js';
8
8
  import '../column/types.js';
@@ -1,8 +1,8 @@
1
1
  import 'bun';
2
- export { E as ExecOptions, M as MergeTimestampParanoid, x as TableOptions, y as TableOutput, a as TimestampOptions } from '../index-BdpoD4zk.js';
2
+ export { X as ExecOptions, M as MergeTimestampParanoid, U as TableOptions, V as TableOutput, f as TimestampOptions } from '../index-CjurLJdK.js';
3
3
  import '../column/index.js';
4
4
  import './constants.js';
5
- import '../column/constants.js';
6
5
  import '../types.js';
7
6
  import '../query/constants.js';
7
+ import '../column/constants.js';
8
8
  import '../column/types.js';
@@ -1,8 +1,8 @@
1
1
  import '../column/constants.js';
2
2
  import '../column/index.js';
3
3
  import './constants.js';
4
- export { t as createdAt, w as defineColumns, v as deletedAt, u as updatedAt } from '../index-BdpoD4zk.js';
4
+ export { K as createdAt, O as defineColumns, N as deletedAt, L as updatedAt } from '../index-CjurLJdK.js';
5
5
  import '../column/types.js';
6
+ import 'bun';
6
7
  import '../types.js';
7
8
  import '../query/constants.js';
8
- import 'bun';
@@ -1,3 +1,7 @@
1
1
  type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
2
+ type BuildTuple<N extends number, T extends unknown[] = []> = T['length'] extends N ? T : BuildTuple<N, [...T, unknown]>;
3
+ type Add<A extends number, B extends number, Result extends unknown[] = [...BuildTuple<A>, ...BuildTuple<B>]> = Result['length'] extends number ? Result['length'] : never;
4
+ type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest] ? Rest['length'] : never;
5
+ type Multiply<A extends number, B extends number, Result extends unknown[] = []> = B extends 0 ? Result['length'] : Multiply<A, Subtract<B, 1>, [...Result, ...BuildTuple<A>]>;
2
6
 
3
- export type { UnionToIntersection };
7
+ export type { Add, BuildTuple, Multiply, Subtract, UnionToIntersection };
@@ -1,4 +1,5 @@
1
1
  declare function deepClone<T>(obj: T): T;
2
+ declare function cloneDefinition<T extends Record<string, unknown>>(def: T): T;
2
3
  declare function quoteIdentifier<T extends string, U extends `"${T}"`>(identifier: T): U;
3
4
 
4
- export { deepClone, quoteIdentifier };
5
+ export { cloneDefinition, deepClone, quoteIdentifier };
@@ -12,8 +12,29 @@ function deepClone(obj) {
12
12
  }
13
13
  return obj;
14
14
  }
15
+ function cloneArray(arr) {
16
+ if (arr.length === 0) return [];
17
+ if (typeof arr[0] === "object" && arr[0] !== null) {
18
+ return arr.map((item) => ({ ...item }));
19
+ }
20
+ return arr.slice();
21
+ }
22
+ function cloneDefinition(def) {
23
+ const clone = {};
24
+ for (const key in def) {
25
+ const val = def[key];
26
+ if (val === null || typeof val !== "object") {
27
+ clone[key] = val;
28
+ } else if (Array.isArray(val)) {
29
+ clone[key] = cloneArray(val);
30
+ } else {
31
+ clone[key] = { ...val };
32
+ }
33
+ }
34
+ return clone;
35
+ }
15
36
  function quoteIdentifier(identifier) {
16
37
  return `"${identifier.replace(/"/g, '""')}"`;
17
38
  }
18
39
 
19
- export { deepClone, quoteIdentifier };
40
+ export { cloneDefinition, deepClone, quoteIdentifier };