supalite 0.5.1 β 0.5.3
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.
- package/CHANGELOG.md +11 -0
- package/README.md +2 -0
- package/dist/query-builder.d.ts +2 -0
- package/dist/query-builder.js +63 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.2] - 2025-10-16
|
|
4
|
+
|
|
5
|
+
### π Fixed
|
|
6
|
+
- `select()` λ©μλμμ `count: 'exact'` μ΅μ
μ¬μ© μ `limit()` λλ `range()`μ ν¨κ» νΈμΆλ λ μ 체 κ°μ λμ νμ΄μ§λ€μ΄μ
λ κ°μλ₯Ό λ°ννλ λ²κ·Έλ₯Ό μμ νμ΅λλ€. μ΄μ νμ μ νν μ 체 κ°μλ₯Ό λ°νν©λλ€.
|
|
7
|
+
- `select()` λ©μλμμ `count: 'exact'`μ `head: true` μ΅μ
μ ν¨κ» μ¬μ©ν λ `count`κ° `null`λ‘ λ°νλλ λ²κ·Έλ₯Ό μμ νμ΅λλ€.
|
|
8
|
+
|
|
9
|
+
## [0.5.1] - 2025-10-16
|
|
10
|
+
|
|
11
|
+
### π Fixed
|
|
12
|
+
- `select()` λ©μλμμ `count: 'exact'` μ΅μ
μ¬μ© μ `limit()` λλ `range()`μ ν¨κ» νΈμΆλ λ μ 체 κ°μ λμ νμ΄μ§λ€μ΄μ
λ κ°μλ₯Ό λ°ννλ λ²κ·Έλ₯Ό μμ νμ΅λλ€. μ΄μ νμ μ νν μ 체 κ°μλ₯Ό λ°νν©λλ€.
|
|
13
|
+
|
|
3
14
|
## [0.5.0] - 2025-07-01
|
|
4
15
|
|
|
5
16
|
### β¨ Added
|
package/README.md
CHANGED
|
@@ -268,6 +268,8 @@ const { data, error } = await client
|
|
|
268
268
|
### 쿼리 λ©μλ
|
|
269
269
|
|
|
270
270
|
- `select(columns?: string, options?: { count?: 'exact' | 'planned' | 'estimated', head?: boolean })`: μ‘°νν μ»¬λΌ μ§μ
|
|
271
|
+
- `options.count`: `'exact'`λ‘ μ€μ νλ©΄ `limit`μ μν₯μ λ°μ§ μλ μ 체 κ²°κ³Όμ κ°μλ₯Ό `count` μμ±μΌλ‘ λ°νν©λλ€.
|
|
272
|
+
- `options.head`: `true`λ‘ μ€μ νλ©΄ λ°μ΄ν° μμ΄ `count`λ§ κ°μ Έμ΅λλ€. `count` μ΅μ
κ³Ό ν¨κ» μ¬μ©νλ©΄ ν¨μ¨μ μΌλ‘ μ 체 κ°μλ§ μ‘°νν μ μμ΅λλ€.
|
|
271
273
|
- `insert(data: T['Tables'][K]['Insert'] | T['Tables'][K]['Insert'][])`: λ¨μΌ λλ λ€μ€ λ μ½λ μ½μ
|
|
272
274
|
- `update(data: T['Tables'][K]['Update'])`: λ μ½λ μ
λ°μ΄νΈ
|
|
273
275
|
- `delete()`: λ μ½λ μμ
|
package/dist/query-builder.d.ts
CHANGED
|
@@ -41,7 +41,9 @@ export declare class QueryBuilder<T extends DatabaseSchema, S extends SchemaName
|
|
|
41
41
|
not(column: string, operator: string, value: any): this;
|
|
42
42
|
contains(column: string, value: any): this;
|
|
43
43
|
in(column: string, values: any[]): this;
|
|
44
|
+
gt(column: string, value: any): this;
|
|
44
45
|
gte(column: string, value: any): this;
|
|
46
|
+
lt(column: string, value: any): this;
|
|
45
47
|
lte(column: string, value: any): this;
|
|
46
48
|
order(column: string, options?: {
|
|
47
49
|
ascending?: boolean;
|
package/dist/query-builder.js
CHANGED
|
@@ -122,11 +122,21 @@ class QueryBuilder {
|
|
|
122
122
|
this.whereValues.push(...values);
|
|
123
123
|
return this;
|
|
124
124
|
}
|
|
125
|
+
gt(column, value) {
|
|
126
|
+
this.whereConditions.push(`"${column}" > $${this.whereValues.length + 1}`);
|
|
127
|
+
this.whereValues.push(value);
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
125
130
|
gte(column, value) {
|
|
126
131
|
this.whereConditions.push(`"${column}" >= $${this.whereValues.length + 1}`);
|
|
127
132
|
this.whereValues.push(value);
|
|
128
133
|
return this;
|
|
129
134
|
}
|
|
135
|
+
lt(column, value) {
|
|
136
|
+
this.whereConditions.push(`"${column}" < $${this.whereValues.length + 1}`);
|
|
137
|
+
this.whereValues.push(value);
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
130
140
|
lte(column, value) {
|
|
131
141
|
this.whereConditions.push(`"${column}" <= $${this.whereValues.length + 1}`);
|
|
132
142
|
this.whereValues.push(value);
|
|
@@ -245,6 +255,7 @@ class QueryBuilder {
|
|
|
245
255
|
case 'SELECT': {
|
|
246
256
|
if (this.headOption) {
|
|
247
257
|
query = `SELECT COUNT(*) FROM ${schemaTable}`;
|
|
258
|
+
query += this.buildWhereClause();
|
|
248
259
|
values = [...this.whereValues];
|
|
249
260
|
break;
|
|
250
261
|
}
|
|
@@ -258,7 +269,6 @@ class QueryBuilder {
|
|
|
258
269
|
const joinSubqueries = await Promise.all(this.joinClauses.map(async (join) => {
|
|
259
270
|
const fk = await this.client.getForeignKey(String(this.schema), String(this.table), join.foreignTable);
|
|
260
271
|
if (!fk) {
|
|
261
|
-
// In a real scenario, you might want to throw an error or handle this case
|
|
262
272
|
console.warn(`[SupaLite WARNING] No foreign key found from ${join.foreignTable} to ${String(this.table)}`);
|
|
263
273
|
return null;
|
|
264
274
|
}
|
|
@@ -276,12 +286,15 @@ class QueryBuilder {
|
|
|
276
286
|
if (validSubqueries) {
|
|
277
287
|
selectClause += `, ${validSubqueries}`;
|
|
278
288
|
}
|
|
279
|
-
|
|
289
|
+
let baseQuery = `SELECT ${selectClause} FROM ${schemaTable}`;
|
|
290
|
+
baseQuery += this.buildWhereClause();
|
|
291
|
+
values = [...this.whereValues];
|
|
280
292
|
if (this.countOption === 'exact') {
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
query = `SELECT *, COUNT(*) OVER() as exact_count FROM (${baseQuery}) subquery`;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
query = baseQuery;
|
|
283
297
|
}
|
|
284
|
-
values = [...this.whereValues];
|
|
285
298
|
break;
|
|
286
299
|
}
|
|
287
300
|
case 'INSERT':
|
|
@@ -388,17 +401,19 @@ class QueryBuilder {
|
|
|
388
401
|
break;
|
|
389
402
|
}
|
|
390
403
|
}
|
|
404
|
+
// Append clauses that apply to the outermost query
|
|
391
405
|
if (this.queryType === 'SELECT') {
|
|
392
|
-
query
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
406
|
+
// WHERE is already in the query or subquery
|
|
407
|
+
// ORDER BY, LIMIT, and OFFSET always apply to the outer query
|
|
408
|
+
if (this.orderByColumns.length > 0) {
|
|
409
|
+
query += ` ORDER BY ${this.orderByColumns.join(', ')}`;
|
|
410
|
+
}
|
|
411
|
+
if (this.limitValue !== undefined) {
|
|
412
|
+
query += ` LIMIT ${this.limitValue}`;
|
|
413
|
+
}
|
|
414
|
+
if (this.offsetValue !== undefined) {
|
|
415
|
+
query += ` OFFSET ${this.offsetValue}`;
|
|
416
|
+
}
|
|
402
417
|
}
|
|
403
418
|
return { query, values };
|
|
404
419
|
}
|
|
@@ -437,27 +452,49 @@ class QueryBuilder {
|
|
|
437
452
|
statusText: 'Created',
|
|
438
453
|
};
|
|
439
454
|
}
|
|
455
|
+
let countResult = null;
|
|
456
|
+
let dataResult = result.rows;
|
|
457
|
+
if (this.headOption) {
|
|
458
|
+
countResult = Number(result.rows[0].count);
|
|
459
|
+
dataResult = [];
|
|
460
|
+
}
|
|
461
|
+
else if (this.countOption === 'exact') {
|
|
462
|
+
if (result.rows.length > 0) {
|
|
463
|
+
countResult = Number(result.rows[0].exact_count);
|
|
464
|
+
// exact_count μ΄μ λͺ¨λ λ°μ΄ν° κ°μ²΄μμ μ κ±°
|
|
465
|
+
dataResult = result.rows.map(row => {
|
|
466
|
+
const newRow = { ...row };
|
|
467
|
+
delete newRow.exact_count;
|
|
468
|
+
return newRow;
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
countResult = 0;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
countResult = result.rowCount;
|
|
477
|
+
}
|
|
440
478
|
if (this.singleMode) {
|
|
441
|
-
if (
|
|
479
|
+
if (dataResult.length > 1) {
|
|
442
480
|
return {
|
|
443
481
|
data: null,
|
|
444
|
-
error: new errors_1.PostgresError('PGRST114: Multiple rows returned'),
|
|
445
|
-
count:
|
|
446
|
-
status: 406,
|
|
482
|
+
error: new errors_1.PostgresError('PGRST114: Multiple rows returned'),
|
|
483
|
+
count: countResult,
|
|
484
|
+
status: 406,
|
|
447
485
|
statusText: 'Not Acceptable. Expected a single row but found multiple.',
|
|
448
486
|
};
|
|
449
487
|
}
|
|
450
|
-
if (
|
|
488
|
+
if (dataResult.length === 0) {
|
|
451
489
|
if (this.singleMode === 'strict') {
|
|
452
490
|
return {
|
|
453
491
|
data: null,
|
|
454
|
-
error: new errors_1.PostgresError('PGRST116: No rows found'),
|
|
492
|
+
error: new errors_1.PostgresError('PGRST116: No rows found'),
|
|
455
493
|
count: 0,
|
|
456
|
-
status: 404,
|
|
494
|
+
status: 404,
|
|
457
495
|
statusText: 'Not Found. Expected a single row but found no rows.',
|
|
458
496
|
};
|
|
459
497
|
}
|
|
460
|
-
// this.singleMode === 'maybe'
|
|
461
498
|
return {
|
|
462
499
|
data: null,
|
|
463
500
|
error: null,
|
|
@@ -466,9 +503,8 @@ class QueryBuilder {
|
|
|
466
503
|
statusText: 'OK',
|
|
467
504
|
};
|
|
468
505
|
}
|
|
469
|
-
// result.rows.length === 1
|
|
470
506
|
return {
|
|
471
|
-
data:
|
|
507
|
+
data: dataResult[0],
|
|
472
508
|
error: null,
|
|
473
509
|
count: 1,
|
|
474
510
|
status: 200,
|
|
@@ -476,9 +512,9 @@ class QueryBuilder {
|
|
|
476
512
|
};
|
|
477
513
|
}
|
|
478
514
|
return {
|
|
479
|
-
data:
|
|
515
|
+
data: dataResult,
|
|
480
516
|
error: null,
|
|
481
|
-
count:
|
|
517
|
+
count: countResult,
|
|
482
518
|
status: 200,
|
|
483
519
|
statusText: 'OK',
|
|
484
520
|
};
|