forj 0.1.5 → 0.1.7

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.
@@ -1,21 +1,27 @@
1
+ import { Timestamp } from 't0n'
1
2
  import ClauseBuilder from './clause-builder'
2
3
  import {
4
+ types,
3
5
  isOperator,
4
6
  parseColumn, parseSelectColumn,
5
7
  formatValue,
6
8
  isJoinCompare,
7
9
  zSame, zType,
10
+ sqlName,
8
11
  } from './utils'
9
12
  import type {
10
- IJoinBuilder, IClauseBuilder,
11
13
  OrderDirection,
12
14
  JoinType,
13
15
  WhereArgs,
14
- Values,
16
+ Value, Values,
15
17
  Item,
16
18
  JoinArgs,
17
19
  DBSchema,
18
20
  Pipe,
21
+ QueryType,
22
+ TableOpts,
23
+ WhereFn,
24
+ Operator,
19
25
  } from './types'
20
26
 
21
27
  export default class QueryBuilder<
@@ -26,9 +32,13 @@ export default class QueryBuilder<
26
32
  // T, // = any,,
27
33
  // C extends keyof T = keyof T
28
34
  // > {
29
- > implements IJoinBuilder<S>, IClauseBuilder<T> {
35
+ > {
30
36
  #table!: string
31
37
  #schema?: DBSchema
38
+ #type: number = 1
39
+ // #data: Partial<Record<C, Value>> = {}
40
+ #keys: string[] = []
41
+ #values: Value[] = []
32
42
  #selects: string[] = []
33
43
  #clauses!: ClauseBuilder<T>
34
44
  #groups: string[] = []
@@ -42,6 +52,7 @@ export default class QueryBuilder<
42
52
  #joins: string[] = []
43
53
 
44
54
  #pipe?: Pipe<S, T, C>
55
+ #opts: TableOpts = {}
45
56
 
46
57
  constructor(
47
58
  table: string,
@@ -54,6 +65,11 @@ export default class QueryBuilder<
54
65
  this.#clauses = new ClauseBuilder<T>(table, schema)
55
66
  }
56
67
 
68
+ opts(opts: TableOpts) {
69
+ this.#opts = opts
70
+ return this
71
+ }
72
+
57
73
  async run() {
58
74
  if (!this.#pipe?.run)
59
75
  throw new Error(`No database connection.`)
@@ -61,6 +77,34 @@ export default class QueryBuilder<
61
77
  return await this.#pipe?.run(this)
62
78
  }
63
79
 
80
+ #setType(type: QueryType, data?: Partial<Record<C, Value>>) {
81
+ this.#type = type
82
+ if (data) {
83
+ this.#keys = Object.keys(data)
84
+ this.#values = Object.values(data)
85
+ }
86
+
87
+ return this
88
+ }
89
+
90
+ insert(data: Partial<Record<C, Value>>) {
91
+ if (this.#opts.timestamps || this.#opts.createdAt) // @ts-ignore
92
+ data.created_at = Timestamp.now()
93
+
94
+ return this.#setType(types.INSERT, data)
95
+ }
96
+
97
+ update(data: Partial<Record<C, Value>>) {
98
+ if (this.#opts.timestamps || this.#opts.updatedAt) // @ts-ignore
99
+ data.updated_at = Timestamp.now()
100
+
101
+ return this.#setType(types.UPDATE, data)
102
+ }
103
+
104
+ delete() {
105
+ return this.#setType(types.DELETE)
106
+ }
107
+
64
108
  async first<K extends keyof T>(...columns: K[] | K[][]): Promise<null | Item<T, C>> {
65
109
  columns?.length && this.select(...columns)
66
110
  const resp = await this.run()
@@ -74,6 +118,7 @@ export default class QueryBuilder<
74
118
  }
75
119
 
76
120
  select<K extends keyof T>(...columns: K[] | K[][]): QueryBuilder<S, T, K> {
121
+ this.#type = types.SELECT
77
122
  this.#selects.push(...columns.flat(Infinity) as string[])
78
123
  return this as any
79
124
  }
@@ -89,7 +134,7 @@ export default class QueryBuilder<
89
134
  ...args: JoinArgs<S, J>
90
135
  ) {
91
136
  this.#hasJoin = true
92
- const query = (type ? type + ' ' : '') + `JOIN ${table as string} ON `
137
+ const query = (type ? type + ' ' : '') + `JOIN ${sqlName(table as string)} ON `
93
138
 
94
139
  if (typeof args[0] == 'function') {
95
140
  const join = new ClauseBuilder<S[J]>(table as string, this.#schema)
@@ -107,7 +152,6 @@ export default class QueryBuilder<
107
152
  value = operator
108
153
  operator = '='
109
154
  } else if (length == 3 && !isOperator(operator)) { // @ts-ignore
110
- // console.log(column, operator, value, value2) // @ts-ignore
111
155
  value = parseColumn(value as string, operator as string) // TODO: check if value is a valid column
112
156
 
113
157
  if (this.#schema && !isJoinCompare(value, this.#schema))
@@ -115,16 +159,16 @@ export default class QueryBuilder<
115
159
 
116
160
  operator = '='
117
161
  } else if (length == 4) { // @ts-ignore
118
- // console.log(column, operator, value, value2) // @ts-ignore
119
162
  value = parseColumn(value2 as string, value as string)
120
163
  operator = '='
121
164
  }
122
165
 
123
166
  const col = parseColumn(String(column), String(table))
124
- if (this.#schema && !zSame(col, value, this.#schema))
125
- throw new Error(`Table column '${col}' of type '${zType(col, this.#schema)}' is not assignable as type of '${typeof value}'.`)
126
167
 
127
- if (!isJoinCompare(value, this.#schema)) { // @ts-ignore
168
+ if (!isJoinCompare(value, this.#schema)) {
169
+ if (this.#schema && !zSame(col.replace(/"/g, ''), value, this.#schema))
170
+ throw new Error(`Table column '${col.replace(/"/g, '')}' of type '${zType(col.replace(/"/g, ''), this.#schema)}' is not assignable as type of '${typeof value}'.`)
171
+ // @ts-ignore
128
172
  this.#clauses.args = [value] // @ts-ignore // TODO: https://developers.cloudflare.com/d1/worker-api/#type-conversion
129
173
  value = '?'
130
174
  }
@@ -134,135 +178,272 @@ export default class QueryBuilder<
134
178
  return this
135
179
  }
136
180
 
181
+ join<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
182
+ join<
183
+ J extends keyof S,
184
+ T extends S[J],
185
+ K extends keyof T
186
+ >(table: J, column: K, value: T[K]): this
187
+ join<
188
+ J extends keyof S,
189
+ T extends S[J],
190
+ K extends keyof T
191
+ >(table: J, column: K, operator: Operator, value: T[K]): this
192
+ join<
193
+ J extends keyof S,
194
+ T extends S[J],
195
+ K extends keyof T,
196
+ J2 extends keyof S,
197
+ K2 extends keyof S[J2],
198
+ >(table: J, column: K, table2: J2, column2: K2): this
199
+ join<
200
+ J extends keyof S,
201
+ T extends S[J],
202
+ K extends keyof T,
203
+ J2 extends keyof S,
204
+ K2 extends keyof S[J2],
205
+ >(table: J, column: K, operator: Operator, table2: J2, column2: K2): this
137
206
  join<J extends keyof S>(table: J, ...args: JoinArgs<S, J>) {
138
207
  return this.#join(undefined, table, ...args)
139
208
  }
140
209
 
210
+ innerJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
211
+ innerJoin<
212
+ J extends keyof S,
213
+ T extends S[J],
214
+ K extends keyof T
215
+ >(table: J, column: K, value: T[K]): this
216
+ innerJoin<
217
+ J extends keyof S,
218
+ T extends S[J],
219
+ K extends keyof T
220
+ >(table: J, column: K, operator: Operator, value: T[K]): this
221
+ innerJoin<
222
+ J extends keyof S,
223
+ T extends S[J],
224
+ K extends keyof T,
225
+ J2 extends keyof S,
226
+ K2 extends keyof S[J2],
227
+ >(table: J, column: K, table2: J2, column2: K2): this
228
+ innerJoin<
229
+ J extends keyof S,
230
+ T extends S[J],
231
+ K extends keyof T,
232
+ J2 extends keyof S,
233
+ K2 extends keyof S[J2],
234
+ >(table: J, column: K, operator: Operator, table2: J2, column2: K2): this
141
235
  innerJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>) {
142
236
  return this.#join('INNER', table, ...args)
143
237
  }
144
238
 
239
+ leftJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
240
+ leftJoin<
241
+ J extends keyof S,
242
+ T extends S[J],
243
+ K extends keyof T
244
+ >(table: J, column: K, value: T[K]): this
245
+ leftJoin<
246
+ J extends keyof S,
247
+ T extends S[J],
248
+ K extends keyof T
249
+ >(table: J, column: K, operator: Operator, value: T[K]): this
250
+ leftJoin<
251
+ J extends keyof S,
252
+ T extends S[J],
253
+ K extends keyof T,
254
+ J2 extends keyof S,
255
+ K2 extends keyof S[J2],
256
+ >(table: J, column: K, table2: J2, column2: K2): this
257
+ leftJoin<
258
+ J extends keyof S,
259
+ T extends S[J],
260
+ K extends keyof T,
261
+ J2 extends keyof S,
262
+ K2 extends keyof S[J2],
263
+ >(table: J, column: K, operator: Operator, table2: J2, column2: K2): this
145
264
  leftJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>) {
146
265
  return this.#join('LEFT', table, ...args)
147
266
  }
148
267
 
268
+ rightJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
269
+ rightJoin<
270
+ J extends keyof S,
271
+ T extends S[J],
272
+ K extends keyof T
273
+ >(table: J, column: K, value: T[K]): this
274
+ rightJoin<
275
+ J extends keyof S,
276
+ T extends S[J],
277
+ K extends keyof T
278
+ >(table: J, column: K, operator: Operator, value: T[K]): this
279
+ rightJoin<
280
+ J extends keyof S,
281
+ T extends S[J],
282
+ K extends keyof T,
283
+ J2 extends keyof S,
284
+ K2 extends keyof S[J2],
285
+ >(table: J, column: K, table2: J2, column2: K2): this
286
+ rightJoin<
287
+ J extends keyof S,
288
+ T extends S[J],
289
+ K extends keyof T,
290
+ J2 extends keyof S,
291
+ K2 extends keyof S[J2],
292
+ >(table: J, column: K, operator: Operator, table2: J2, column2: K2): this
149
293
  rightJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>) {
150
294
  return this.#join('RIGHT', table, ...args)
151
295
  }
152
296
 
297
+ crossJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
298
+ crossJoin<
299
+ J extends keyof S,
300
+ T extends S[J],
301
+ K extends keyof T
302
+ >(table: J, column: K, value: T[K]): this
303
+ crossJoin<
304
+ J extends keyof S,
305
+ T extends S[J],
306
+ K extends keyof T
307
+ >(table: J, column: K, operator: Operator, value: T[K]): this
308
+ crossJoin<
309
+ J extends keyof S,
310
+ T extends S[J],
311
+ K extends keyof T,
312
+ J2 extends keyof S,
313
+ K2 extends keyof S[J2],
314
+ >(table: J, column: K, table2: J2, column2: K2): this
315
+ crossJoin<
316
+ J extends keyof S,
317
+ T extends S[J],
318
+ K extends keyof T,
319
+ J2 extends keyof S,
320
+ K2 extends keyof S[J2],
321
+ >(table: J, column: K, operator: Operator, table2: J2, column2: K2): this
153
322
  crossJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>) {
154
323
  return this.#join('CROSS', table, ...args)
155
324
  }
156
325
 
326
+ where(fn: WhereFn<T>): this
327
+ where<K extends keyof T>(column: K, value: T[K]): this
328
+ where<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
157
329
  where(...args: WhereArgs<T>) {
158
330
  this.#clauses.where(...args)
159
331
  return this
160
332
  }
161
- on(...args: WhereArgs<T>) {
333
+ on(fn: WhereFn<T>): this
334
+ on<K extends keyof T>(column: K, value: T[K]): this
335
+ on<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
336
+ on(...args: WhereArgs<T>) { // @ts-ignore
162
337
  return this.where(...args)
163
338
  }
164
339
 
340
+ orWhere(fn: WhereFn<T>): this
341
+ orWhere<K extends keyof T>(column: K, value: T[K]): this
342
+ orWhere<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
165
343
  orWhere(...args: WhereArgs<T>) {
166
344
  this.#clauses.orWhere(...args)
167
345
  return this
168
346
  }
169
- orOn(...args: WhereArgs<T>) {
347
+ orOn(fn: WhereFn<T>): this
348
+ orOn<K extends keyof T>(column: K, value: T[K]): this
349
+ orOn<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
350
+ orOn(...args: WhereArgs<T>) { // @ts-ignore
170
351
  return this.orWhere(...args)
171
352
  }
172
353
 
173
- whereIn(column: C, values: T[C][]) {
354
+ whereIn<K extends keyof T>(column: K, values: T[K][]) {
174
355
  this.#clauses.whereIn(column, values)
175
356
  return this
176
357
  }
177
- in(column: C, values: T[C][]) {
358
+ in<K extends keyof T>(column: K, values: T[K][]) {
178
359
  return this.whereIn(column, values)
179
360
  }
180
361
 
181
- whereNotIn(column: C, values: T[C][]) {
362
+ whereNotIn<K extends keyof T>(column: K, values: T[K][]) {
182
363
  this.#clauses.whereNotIn(column, values)
183
364
  return this
184
365
  }
185
- notIn(column: C, values: T[C][]) {
366
+ notIn<K extends keyof T>(column: K, values: T[K][]) {
186
367
  return this.whereNotIn(column, values)
187
368
  }
188
369
 
189
- orWhereIn(column: C, values: T[C][]) {
370
+ orWhereIn<K extends keyof T>(column: K, values: T[K][]) {
190
371
  this.#clauses.orWhereIn(column, values)
191
372
  return this
192
373
  }
193
- orIn(column: C, values: T[C][]) {
374
+ orIn<K extends keyof T>(column: K, values: T[K][]) {
194
375
  return this.orWhereIn(column, values)
195
376
  }
196
377
 
197
- orWhereNotIn(column: C, values: T[C][]) {
378
+ orWhereNotIn<K extends keyof T>(column: K, values: T[K][]) {
198
379
  this.#clauses.orWhereNotIn(column, values)
199
380
  return this
200
381
  }
201
- orNotIn(column: C, values: T[C][]) {
382
+ orNotIn<K extends keyof T>(column: K, values: T[K][]) {
202
383
  return this.orWhereNotIn(column, values)
203
384
  }
204
385
 
205
- whereBetween(column: C, one: T[C], two: T[C]) {
386
+ whereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
206
387
  this.#clauses.whereBetween(column, one, two)
207
388
  return this
208
389
  }
209
- between(column: C, one: T[C], two: T[C]) {
390
+ between<K extends keyof T>(column: K, one: T[K], two: T[K]) {
210
391
  return this.whereBetween(column, one, two)
211
392
  }
212
393
 
213
- orWhereBetween(column: C, one: T[C], two: T[C]) {
394
+ orWhereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
214
395
  this.#clauses.orWhereBetween(column, one, two)
215
396
  return this
216
397
  }
217
- orBetween(column: C, one: T[C], two: T[C]) {
398
+ orBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
218
399
  return this.orWhereBetween(column, one, two)
219
400
  }
220
401
 
221
- whereNotBetween(column: C, one: T[C], two: T[C]) {
402
+ whereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
222
403
  this.#clauses.whereNotBetween(column, one, two)
223
404
  return this
224
405
  }
225
- notBetween(column: C, one: T[C], two: T[C]) {
406
+ notBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
226
407
  return this.whereNotBetween(column, one, two)
227
408
  }
228
409
 
229
- orWhereNotBetween(column: C, one: T[C], two: T[C]) {
410
+ orWhereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
230
411
  this.#clauses.orWhereNotBetween(column, one, two)
231
412
  return this
232
413
  }
233
- orNotBetween(column: C, one: T[C], two: T[C]) {
414
+ orNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
234
415
  return this.orWhereNotBetween(column, one, two)
235
416
  }
236
417
 
237
- whereNull(column: C) {
418
+ whereNull<K extends keyof T>(column: K) {
238
419
  this.#clauses.whereNull(column)
239
420
  return this
240
421
  }
241
- onNull(column: C) {
422
+ onNull<K extends keyof T>(column: K) {
242
423
  return this.whereNull(column)
243
424
  }
244
425
 
245
- orWhereNull(column: C) {
426
+ orWhereNull<K extends keyof T>(column: K) {
246
427
  this.#clauses.orWhereNull(column)
247
428
  return this
248
429
  }
249
- orOnNull(column: C) {
430
+ orOnNull<K extends keyof T>(column: K) {
250
431
  return this.orWhereNull(column)
251
432
  }
252
433
 
253
- whereNotNull(column: C) {
434
+ whereNotNull<K extends keyof T>(column: K) {
254
435
  this.#clauses.whereNotNull(column)
255
436
  return this
256
437
  }
257
- onNotNull(column: C) {
438
+ onNotNull<K extends keyof T>(column: K) {
258
439
  return this.whereNotNull(column)
259
440
  }
260
441
 
261
- orWhereNotNull(column: C) {
442
+ orWhereNotNull<K extends keyof T>(column: K) {
262
443
  this.#clauses.orWhereNotNull(column)
263
444
  return this
264
445
  }
265
- orNotNull(column: C) {
446
+ orNotNull<K extends keyof T>(column: K) {
266
447
  return this.orWhereNotNull(column)
267
448
  }
268
449
 
@@ -317,6 +498,9 @@ export default class QueryBuilder<
317
498
  }
318
499
 
319
500
  get args() {
501
+ if (this.#values.length)
502
+ return [...this.#values, ...this.#clauses.args]
503
+
320
504
  return this.#clauses.args
321
505
  }
322
506
  get arguments() {
@@ -329,25 +513,43 @@ export default class QueryBuilder<
329
513
  get query() {
330
514
  let sql = ''
331
515
 
332
- const selects = new Set<string>()
333
- this.#selects.forEach(column => {
334
- column = parseSelectColumn(column, this.#table, this.#hasJoin)
335
- !selects.has(column) && selects.add(column)
336
- })
516
+ switch (this.#type) {
517
+ case types.SELECT:
518
+ const selects = new Set<string>()
519
+ this.#selects.forEach(column => {
520
+ column = parseSelectColumn(column, this.#table, this.#hasJoin)
521
+ !selects.has(column) && selects.add(column)
522
+ })
337
523
 
338
- sql += `SELECT ${this.#distinct ? 'DISTINCT ' : ''}${
339
- selects.size ? [...selects].join(', ') : '*'
340
- }`
524
+ sql += `SELECT ${this.#distinct ? 'DISTINCT ' : ''}${
525
+ selects.size ? [...selects].join(', ') : '*'
526
+ }`
341
527
 
342
- sql += ' FROM '+ this.#table
528
+ sql += ' FROM '+ this.#table
343
529
 
344
- if (this.#joins.length)
345
- sql += ' '+ this.#joins.join(' ')
530
+ if (this.#joins.length)
531
+ sql += ' '+ this.#joins.join(' ')
532
+
533
+ break
534
+ case types.INSERT:
535
+ sql += `INSERT INTO ${this.#table} (${this.#keys.map(key => sqlName(key)).join(', ')})`
536
+ sql += ` VALUES (${Array.from({ length: this.#keys.length }, () => '?').join(', ')})`
537
+
538
+ break
539
+ case types.UPDATE:
540
+ sql += `UPDATE ${this.#table} SET ${this.#keys.map(key => key + ` = ?`).join(', ')}`
541
+
542
+ break
543
+ case types.DELETE:
544
+ sql += `DELETE FROM ` + this.#table
545
+
546
+ break
547
+ }
346
548
 
347
549
  if (this.#clauses.length)
348
550
  sql += ' WHERE '+ this.#clauses.clauses.join(' ')
349
551
 
350
- if (this.#groups.length)
552
+ if (this.#type == types.SELECT && this.#groups.length)
351
553
  sql += ' GROUP BY '+ this.#groups.join(', ')
352
554
 
353
555
  if (this.#orders.length)
@@ -363,7 +565,7 @@ export default class QueryBuilder<
363
565
  }
364
566
 
365
567
  get sql() {
366
- return this.#bind(this.query, this.#clauses.args)
568
+ return this.#bind(this.query, this.args)
367
569
  }
368
570
  get raw() {
369
571
  return this.sql