@ignisia/sql 0.2.2 → 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 (130) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/column/constants.d.cts +58 -5
  3. package/dist/cjs/column/constants.js +79 -22
  4. package/dist/cjs/column/index.d.cts +1 -0
  5. package/dist/cjs/column/index.js +31 -18
  6. package/dist/cjs/column/utils.d.cts +133 -0
  7. package/dist/cjs/column/utils.js +34 -0
  8. package/dist/cjs/database/alter.d.cts +3 -2
  9. package/dist/cjs/database/alter.js +15 -15
  10. package/dist/cjs/database/column.d.cts +3 -2
  11. package/dist/cjs/database/column.js +9 -7
  12. package/dist/cjs/database/contract.d.cts +3 -2
  13. package/dist/cjs/database/index.d.cts +3 -2
  14. package/dist/cjs/database/index.js +15 -2
  15. package/dist/cjs/database/table.d.cts +3 -2
  16. package/dist/cjs/database/table.js +12 -4
  17. package/dist/cjs/database/types.d.cts +2 -1
  18. package/dist/cjs/database/wrapper.d.cts +17 -21
  19. package/dist/cjs/database/wrapper.js +28 -52
  20. package/dist/cjs/index-CHxuUiO4.d.cts +472 -0
  21. package/dist/cjs/{index---zaMa69.d.cts → index-CZhrzE5r.d.cts} +5 -3
  22. package/dist/cjs/index.d.cts +3 -2
  23. package/dist/cjs/migration/index.d.cts +3 -2
  24. package/dist/cjs/migration/runner.js +1 -1
  25. package/dist/cjs/migration/type.d.cts +3 -2
  26. package/dist/cjs/query/builder.d.cts +3 -2
  27. package/dist/cjs/query/builder.js +1 -1
  28. package/dist/cjs/query/condition/common.d.cts +41 -0
  29. package/dist/cjs/query/condition/common.js +62 -0
  30. package/dist/cjs/query/condition/core.d.cts +8 -0
  31. package/dist/cjs/query/condition/core.js +57 -0
  32. package/dist/cjs/query/condition/index.d.cts +10 -0
  33. package/dist/cjs/query/condition/index.js +33 -0
  34. package/dist/cjs/query/condition/not.d.cts +34 -0
  35. package/dist/cjs/query/condition/not.js +51 -0
  36. package/dist/cjs/query/condition/raw.d.cts +8 -0
  37. package/dist/cjs/query/condition/raw.js +54 -0
  38. package/dist/cjs/query/constants.d.cts +27 -1
  39. package/dist/cjs/query/constants.js +28 -2
  40. package/dist/cjs/query/contract.d.cts +4 -3
  41. package/dist/cjs/query/explain.d.cts +12 -0
  42. package/dist/cjs/query/explain.js +65 -0
  43. package/dist/cjs/query/helper.d.cts +3 -2
  44. package/dist/cjs/query/helper.js +1 -1
  45. package/dist/cjs/query/index.d.cts +3 -2
  46. package/dist/cjs/query/index.js +69 -65
  47. package/dist/cjs/query/join.d.cts +18 -5
  48. package/dist/cjs/query/join.js +38 -9
  49. package/dist/cjs/query/sql.d.cts +9 -6
  50. package/dist/cjs/query/sql.js +80 -21
  51. package/dist/cjs/query/types.d.cts +2 -1
  52. package/dist/cjs/query/utilities.d.cts +7 -3
  53. package/dist/cjs/query/utilities.js +86 -5
  54. package/dist/cjs/table/constants.d.cts +1 -0
  55. package/dist/cjs/table/constants.js +1 -0
  56. package/dist/cjs/table/index.d.cts +3 -2
  57. package/dist/cjs/table/index.js +29 -9
  58. package/dist/cjs/table/types.d.cts +3 -2
  59. package/dist/cjs/table/utilities.d.cts +2 -1
  60. package/dist/cjs/types.d.cts +5 -1
  61. package/dist/cjs/utilities.d.cts +2 -1
  62. package/dist/cjs/utilities.js +22 -0
  63. package/dist/esm/column/constants.d.ts +58 -5
  64. package/dist/esm/column/constants.js +78 -23
  65. package/dist/esm/column/index.d.ts +1 -0
  66. package/dist/esm/column/index.js +31 -18
  67. package/dist/esm/column/utils.d.ts +133 -0
  68. package/dist/esm/column/utils.js +32 -0
  69. package/dist/esm/database/alter.d.ts +3 -2
  70. package/dist/esm/database/alter.js +15 -15
  71. package/dist/esm/database/column.d.ts +3 -2
  72. package/dist/esm/database/column.js +9 -7
  73. package/dist/esm/database/contract.d.ts +3 -2
  74. package/dist/esm/database/index.d.ts +3 -2
  75. package/dist/esm/database/index.js +17 -4
  76. package/dist/esm/database/table.d.ts +3 -2
  77. package/dist/esm/database/table.js +12 -4
  78. package/dist/esm/database/types.d.ts +2 -1
  79. package/dist/esm/database/wrapper.d.ts +17 -21
  80. package/dist/esm/database/wrapper.js +27 -53
  81. package/dist/esm/index-CjurLJdK.d.ts +472 -0
  82. package/dist/esm/{index-DFrpzXEn.d.ts → index-DgOs61lH.d.ts} +5 -3
  83. package/dist/esm/index.d.ts +3 -2
  84. package/dist/esm/migration/index.d.ts +3 -2
  85. package/dist/esm/migration/runner.js +1 -1
  86. package/dist/esm/migration/type.d.ts +3 -2
  87. package/dist/esm/query/builder.d.ts +3 -2
  88. package/dist/esm/query/builder.js +1 -1
  89. package/dist/esm/query/condition/common.d.ts +41 -0
  90. package/dist/esm/query/condition/common.js +56 -0
  91. package/dist/esm/query/condition/core.d.ts +8 -0
  92. package/dist/esm/query/condition/core.js +55 -0
  93. package/dist/esm/query/condition/index.d.ts +10 -0
  94. package/dist/esm/query/condition/index.js +4 -0
  95. package/dist/esm/query/condition/not.d.ts +34 -0
  96. package/dist/esm/query/condition/not.js +46 -0
  97. package/dist/esm/query/condition/raw.d.ts +8 -0
  98. package/dist/esm/query/condition/raw.js +50 -0
  99. package/dist/esm/query/constants.d.ts +27 -1
  100. package/dist/esm/query/constants.js +27 -3
  101. package/dist/esm/query/contract.d.ts +4 -3
  102. package/dist/esm/query/explain.d.ts +12 -0
  103. package/dist/esm/query/explain.js +64 -0
  104. package/dist/esm/query/helper.d.ts +3 -2
  105. package/dist/esm/query/helper.js +2 -2
  106. package/dist/esm/query/index.d.ts +3 -2
  107. package/dist/esm/query/index.js +72 -68
  108. package/dist/esm/query/join.d.ts +18 -5
  109. package/dist/esm/query/join.js +37 -9
  110. package/dist/esm/query/sql.d.ts +9 -6
  111. package/dist/esm/query/sql.js +80 -23
  112. package/dist/esm/query/types.d.ts +2 -1
  113. package/dist/esm/query/utilities.d.ts +7 -3
  114. package/dist/esm/query/utilities.js +86 -6
  115. package/dist/esm/table/constants.d.ts +1 -0
  116. package/dist/esm/table/constants.js +1 -0
  117. package/dist/esm/table/index.d.ts +3 -2
  118. package/dist/esm/table/index.js +29 -9
  119. package/dist/esm/table/types.d.ts +3 -2
  120. package/dist/esm/table/utilities.d.ts +2 -1
  121. package/dist/esm/types.d.ts +5 -1
  122. package/dist/esm/utilities.d.ts +2 -1
  123. package/dist/esm/utilities.js +22 -1
  124. package/package.json +8 -2
  125. package/dist/cjs/index-CwiFQh0I.d.cts +0 -358
  126. package/dist/cjs/query/condition.d.cts +0 -7
  127. package/dist/cjs/query/condition.js +0 -106
  128. package/dist/esm/index-FMT0YEO7.d.ts +0 -358
  129. package/dist/esm/query/condition.d.ts +0 -7
  130. package/dist/esm/query/condition.js +0 -98
@@ -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;
@@ -153,22 +135,33 @@ var QueryBuilder = class {
153
135
  insert(...values) {
154
136
  this.definition.queryType = QueryType.INSERT;
155
137
  if (!this.definition.insertValues) this.definition.insertValues = [];
156
- const { isWithTimestamp, createdAt, updatedAt, timestamp } = getTimestamp(
157
- this.table
158
- );
159
- if (isWithTimestamp) {
160
- values = values.map((row) => ({
161
- ...row,
162
- [createdAt]: row[createdAt] ?? timestamp,
163
- [updatedAt]: row[updatedAt] ?? timestamp
164
- }));
165
- }
138
+ const {
139
+ isWithTimestamp,
140
+ isHasCreatedAt,
141
+ isHasUpdatedAt,
142
+ createdAt,
143
+ updatedAt,
144
+ timestamp
145
+ } = getTimestamp(this.table);
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
+ });
166
159
  this.definition.insertValues = values;
167
160
  return this;
168
161
  }
169
162
  update(values) {
170
- const { isWithTimestamp, updatedAt, timestamp } = getTimestamp(this.table);
171
- if (isWithTimestamp) {
163
+ const { isWithTimestamp, isHasUpdatedAt, updatedAt, timestamp } = getTimestamp(this.table);
164
+ if (isWithTimestamp && isHasUpdatedAt) {
172
165
  values = {
173
166
  ...values,
174
167
  [updatedAt]: values[updatedAt] ?? timestamp
@@ -188,6 +181,17 @@ var QueryBuilder = class {
188
181
  this.definition.queryType = QueryType.DELETE;
189
182
  return this;
190
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
+ }
191
195
  infer() {
192
196
  return null;
193
197
  }
@@ -1,16 +1,29 @@
1
- import { T as Table, Q as QueryDefinition, C as ColumnSelector, c as StrictColumnSelector, d as QueryBuilder } from '../index-FMT0YEO7.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';
4
+ import 'bun';
5
5
  import '../types.js';
6
+ import '../column/constants.js';
6
7
  import '../table/constants.js';
7
8
  import '../column/types.js';
8
9
 
9
- 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 & {
10
11
  [K in JoinAlias]: JoinTable;
11
- }>(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"> & {
12
13
  joins: string[];
13
14
  joinedTables: FinalJoinedTables;
14
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
+ };
15
28
 
16
- 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,17 +1,20 @@
1
- import { T as Table, Q as QueryDefinition, C as ColumnSelector, c as StrictColumnSelector, d as QueryBuilder } from '../index-FMT0YEO7.js';
1
+ import { TransactionSQL } from 'bun';
2
+ import { T as Table, Q as QueryDefinition, C as ColumnSelector, k as StrictColumnSelector, l as QueryBuilder, E as ExplainOptions } from '../index-CjurLJdK.js';
2
3
  import { Column } from '../column/index.js';
3
- import '../column/constants.js';
4
+ import { Dialect } from '../table/constants.js';
4
5
  import '../types.js';
5
6
  import './constants.js';
6
- import '../table/constants.js';
7
+ import '../column/constants.js';
7
8
  import '../column/types.js';
8
9
 
9
10
  declare function buildQuery(query: string): string;
10
- declare function toQuery<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): {
11
+ declare function toQuery<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, dialect?: Dialect | null): {
11
12
  query: string;
12
13
  params: unknown[] | null | undefined;
13
14
  };
14
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;
15
- 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): Promise<Output>;
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>;
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>;
16
19
 
17
- export { buildQuery, exec, toQuery, toString };
20
+ export { buildQuery, exec, explain, toDebugString, toQuery, toString };
@@ -1,6 +1,8 @@
1
+ import { Dialect } from '../table/constants.js';
1
2
  import { buildDeleteQuery, buildUpdateQuery, buildInsertQuery, buildSelectQuery } from './builder.js';
2
3
  import { QueryType, QueryHooksType } from './constants.js';
3
- import { getWhereConditions, getGroupByConditions, parseAliasedRow } from './utilities.js';
4
+ import { buildExplainQuery } from './explain.js';
5
+ import { getWhereConditions, getGroupByConditions, sanitizeParams, parseAliasedRow } from './utilities.js';
4
6
 
5
7
  // src/query/sql.ts
6
8
  function buildQuery(query) {
@@ -10,80 +12,135 @@ function buildQuery(query) {
10
12
  return `$${index}`;
11
13
  });
12
14
  }
13
- function toQuery() {
14
- let sql = "";
15
+ function toQuery(dialect) {
16
+ const parts = [];
15
17
  switch (this.definition.queryType) {
16
18
  case QueryType.SELECT:
17
- sql = buildSelectQuery(this);
19
+ parts.push(buildSelectQuery(this));
18
20
  break;
19
21
  case QueryType.INSERT:
20
- sql = buildInsertQuery(this);
22
+ parts.push(buildInsertQuery(this));
21
23
  break;
22
24
  case QueryType.UPDATE:
23
- sql = buildUpdateQuery(this);
25
+ parts.push(buildUpdateQuery(this));
24
26
  break;
25
27
  case QueryType.DELETE:
26
- sql = buildDeleteQuery(this);
28
+ parts.push(buildDeleteQuery(this));
27
29
  break;
28
30
  default:
29
31
  throw new Error("No query type defined");
30
32
  }
31
33
  if (this.definition?.joins?.length) {
32
- sql += ` ${this.definition.joins.join(" ")}`;
34
+ parts.push(this.definition.joins.join(" "));
33
35
  }
34
36
  const whereConditions = getWhereConditions(this);
35
37
  if (whereConditions.length) {
36
- sql += ` WHERE ${whereConditions.join(" ")}`;
38
+ parts.push(`WHERE ${whereConditions.join(" ")}`);
37
39
  }
38
40
  const groupByConditions = getGroupByConditions(this);
39
41
  if (groupByConditions.length) {
40
- sql += ` GROUP BY ${groupByConditions.join(", ")}`;
42
+ parts.push(`GROUP BY ${groupByConditions.join(", ")}`);
41
43
  }
42
44
  if (this.definition?.having?.length) {
43
- sql += ` HAVING ${this.definition.having.join(" ")}`;
45
+ parts.push(`HAVING ${this.definition.having.join(" ")}`);
44
46
  }
45
47
  if (this.definition?.orderBy?.length) {
46
- 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
+ );
47
51
  }
48
52
  if (this.definition?.limit !== null) {
49
- sql += ` LIMIT ?`;
53
+ parts.push("LIMIT ?");
50
54
  if (!this.definition.params) this.definition.params = [];
51
55
  this.definition.params.push(this.definition.limit);
52
56
  }
53
57
  if (this.definition?.offset !== null) {
54
- sql += ` OFFSET ?`;
58
+ parts.push("OFFSET ?");
55
59
  if (!this.definition.params) this.definition.params = [];
56
60
  this.definition.params.push(this.definition.offset);
57
61
  }
58
62
  if (this.definition.queryType === QueryType.UPDATE || this.definition.queryType === QueryType.DELETE) {
59
- sql += ` RETURNING *`;
63
+ if (dialect !== Dialect.MYSQL) {
64
+ parts.push("RETURNING *");
65
+ }
60
66
  }
61
- sql = buildQuery(sql);
62
- return { query: sql + ";", params: this.definition.params };
67
+ const sql = buildQuery(parts.join(" "));
68
+ return { query: `${sql};`, params: this.definition.params };
63
69
  }
64
70
  function toString() {
65
71
  return this.toQuery().query;
66
72
  }
67
- async function exec() {
68
- if (!this.table.client) throw new Error("Database client not defined");
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 = {}) {
69
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
+ }
99
+ async function exec(tx) {
100
+ const client = this.table.client;
101
+ const dialect = this.table.dialect;
102
+ const queryType = this.definition.queryType;
103
+ const isUpdate = queryType === QueryType.UPDATE;
104
+ const isDelete = queryType === QueryType.DELETE;
105
+ const isReturning = isUpdate || isDelete;
106
+ const isMySQL = dialect === Dialect.MYSQL;
107
+ if (!client) {
108
+ throw new Error("Database client not defined");
109
+ }
110
+ if (!queryType) {
111
+ throw new Error("No query type defined");
112
+ }
113
+ const { query, params } = this.toQuery(dialect);
70
114
  if (this.hooks?.before?.size) {
71
115
  for (const hook of this.hooks.before.values()) {
72
116
  hook({
73
117
  query,
74
118
  params,
75
- type: this.definition.queryType,
119
+ type: queryType,
76
120
  hook: QueryHooksType.BEFORE
77
121
  });
78
122
  }
79
123
  }
80
- const result = await this.table.client.exec(query, params);
124
+ let result = await client.exec({
125
+ sql: query,
126
+ params,
127
+ tx
128
+ });
129
+ if (isMySQL && isReturning) {
130
+ const query2 = this.clone();
131
+ query2.definition.queryType = QueryType.SELECT;
132
+ result = await client.exec({
133
+ sql: query2.toQuery().query,
134
+ params,
135
+ tx
136
+ });
137
+ }
81
138
  if (this.hooks?.after?.size) {
82
139
  for (const hook of this.hooks.after.values()) {
83
140
  hook({
84
141
  query,
85
142
  params,
86
- type: this.definition.queryType,
143
+ type: queryType,
87
144
  hook: QueryHooksType.AFTER
88
145
  });
89
146
  }
@@ -97,4 +154,4 @@ async function exec() {
97
154
  );
98
155
  }
99
156
 
100
- export { buildQuery, exec, toQuery, toString };
157
+ export { buildQuery, exec, explain, toDebugString, toQuery, toString };
@@ -1,6 +1,7 @@
1
+ import 'bun';
1
2
  import '../column/index.js';
2
3
  import '../column/constants.js';
3
- export { j as AcceptedInsertValues, i as AcceptedOrderBy, k as AcceptedUpdateValues, l as AggregateColumn, A as AliasedColumn, C as ColumnSelector, f as QuerHooks, Q as QueryDefinition, n as QueryOutput, h as QueryRunHooks, o as QueryRunHooksOptions, R as RawColumn, m as SelectQueryOutput, e as SelectableColumn, c as StrictColumnSelector, W as WhereValue } from '../index-FMT0YEO7.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';
@@ -1,9 +1,10 @@
1
- import { T as Table, W as WhereValue, Q as QueryDefinition, C as ColumnSelector, c as StrictColumnSelector, d as QueryBuilder, A as AliasedColumn, e as SelectableColumn } from '../index-FMT0YEO7.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';
5
+ import 'bun';
6
6
  import '../types.js';
7
+ import '../column/constants.js';
7
8
  import '../column/types.js';
8
9
 
9
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): {
@@ -16,6 +17,8 @@ declare function getTimestamp<TableRef extends Table<string, Record<string, Colu
16
17
  timestamp: Date;
17
18
  createdAt: string;
18
19
  updatedAt: string;
20
+ isHasUpdatedAt: boolean;
21
+ isHasCreatedAt: boolean;
19
22
  };
20
23
  declare function getParanoid<TableRef extends Table<string, Record<string, Column>>>(table: TableRef): {
21
24
  isWithParanoid: boolean;
@@ -30,5 +33,6 @@ declare function parseAliasedRow({ row, selects, root, }: {
30
33
  selects: SelectableColumn<string>[];
31
34
  root?: string | null;
32
35
  }): Record<string, any>;
36
+ declare function sanitizeParams(params: unknown[]): (string | number | bigint | boolean | null)[];
33
37
 
34
- 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
  }
@@ -61,22 +113,32 @@ function getCondition(dialect, column, operator, value) {
61
113
  function getTimestamp(table) {
62
114
  const isWithTimestamp = !!table.timestamp;
63
115
  const timestamp = /* @__PURE__ */ new Date();
116
+ let isHasCreatedAt = true;
117
+ let isHasUpdatedAt = true;
64
118
  let createdAt = "createdAt";
65
119
  let updatedAt = "updatedAt";
66
120
  if (isWithTimestamp) {
67
121
  const isCustomTimestamp = typeof table.timestamp === "object";
68
- if (isCustomTimestamp && table.timestamp.createdAt) {
69
- createdAt = table.timestamp.createdAt;
122
+ if (isCustomTimestamp) {
123
+ if (typeof table.timestamp.createdAt === "string") {
124
+ createdAt = table.timestamp.createdAt;
125
+ }
126
+ isHasCreatedAt = table.timestamp.createdAt !== false;
70
127
  }
71
- if (isCustomTimestamp && table.timestamp.updatedAt) {
72
- updatedAt = table.timestamp.updatedAt;
128
+ if (isCustomTimestamp) {
129
+ if (typeof table.timestamp.updatedAt === "string") {
130
+ updatedAt = table.timestamp.updatedAt;
131
+ }
132
+ isHasUpdatedAt = table.timestamp.updatedAt !== false;
73
133
  }
74
134
  }
75
135
  return {
76
136
  isWithTimestamp,
77
137
  timestamp,
78
138
  createdAt,
79
- updatedAt
139
+ updatedAt,
140
+ isHasUpdatedAt,
141
+ isHasCreatedAt
80
142
  };
81
143
  }
82
144
  function getParanoid(table) {
@@ -172,5 +234,23 @@ function parseAliasedRow({
172
234
  }
173
235
  return result;
174
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
+ }
175
255
 
176
- export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow };
256
+ export { getCondition, getGroupByConditions, getParanoid, getTableColumnNames, getTableSelectName, getTimestamp, getWhereConditions, parseAliasedRow, sanitizeParams };
@@ -1,5 +1,6 @@
1
1
  declare const Dialect: {
2
2
  readonly POSTGRES: "postgres";
3
+ readonly MYSQL: "mysql";
3
4
  readonly SQLITE: "sqlite";
4
5
  };
5
6
  type Dialect = (typeof Dialect)[keyof typeof Dialect];