supalite 0.5.1 β 0.5.2
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.js +53 -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.js
CHANGED
|
@@ -245,6 +245,7 @@ class QueryBuilder {
|
|
|
245
245
|
case 'SELECT': {
|
|
246
246
|
if (this.headOption) {
|
|
247
247
|
query = `SELECT COUNT(*) FROM ${schemaTable}`;
|
|
248
|
+
query += this.buildWhereClause();
|
|
248
249
|
values = [...this.whereValues];
|
|
249
250
|
break;
|
|
250
251
|
}
|
|
@@ -258,7 +259,6 @@ class QueryBuilder {
|
|
|
258
259
|
const joinSubqueries = await Promise.all(this.joinClauses.map(async (join) => {
|
|
259
260
|
const fk = await this.client.getForeignKey(String(this.schema), String(this.table), join.foreignTable);
|
|
260
261
|
if (!fk) {
|
|
261
|
-
// In a real scenario, you might want to throw an error or handle this case
|
|
262
262
|
console.warn(`[SupaLite WARNING] No foreign key found from ${join.foreignTable} to ${String(this.table)}`);
|
|
263
263
|
return null;
|
|
264
264
|
}
|
|
@@ -276,12 +276,15 @@ class QueryBuilder {
|
|
|
276
276
|
if (validSubqueries) {
|
|
277
277
|
selectClause += `, ${validSubqueries}`;
|
|
278
278
|
}
|
|
279
|
-
|
|
279
|
+
let baseQuery = `SELECT ${selectClause} FROM ${schemaTable}`;
|
|
280
|
+
baseQuery += this.buildWhereClause();
|
|
281
|
+
values = [...this.whereValues];
|
|
280
282
|
if (this.countOption === 'exact') {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
query = `SELECT *, COUNT(*) OVER() as exact_count FROM (${baseQuery}) subquery`;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
query = baseQuery;
|
|
283
287
|
}
|
|
284
|
-
values = [...this.whereValues];
|
|
285
288
|
break;
|
|
286
289
|
}
|
|
287
290
|
case 'INSERT':
|
|
@@ -388,17 +391,19 @@ class QueryBuilder {
|
|
|
388
391
|
break;
|
|
389
392
|
}
|
|
390
393
|
}
|
|
394
|
+
// Append clauses that apply to the outermost query
|
|
391
395
|
if (this.queryType === 'SELECT') {
|
|
392
|
-
query
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
396
|
+
// WHERE is already in the query or subquery
|
|
397
|
+
// ORDER BY, LIMIT, and OFFSET always apply to the outer query
|
|
398
|
+
if (this.orderByColumns.length > 0) {
|
|
399
|
+
query += ` ORDER BY ${this.orderByColumns.join(', ')}`;
|
|
400
|
+
}
|
|
401
|
+
if (this.limitValue !== undefined) {
|
|
402
|
+
query += ` LIMIT ${this.limitValue}`;
|
|
403
|
+
}
|
|
404
|
+
if (this.offsetValue !== undefined) {
|
|
405
|
+
query += ` OFFSET ${this.offsetValue}`;
|
|
406
|
+
}
|
|
402
407
|
}
|
|
403
408
|
return { query, values };
|
|
404
409
|
}
|
|
@@ -437,27 +442,49 @@ class QueryBuilder {
|
|
|
437
442
|
statusText: 'Created',
|
|
438
443
|
};
|
|
439
444
|
}
|
|
445
|
+
let countResult = null;
|
|
446
|
+
let dataResult = result.rows;
|
|
447
|
+
if (this.headOption) {
|
|
448
|
+
countResult = Number(result.rows[0].count);
|
|
449
|
+
dataResult = [];
|
|
450
|
+
}
|
|
451
|
+
else if (this.countOption === 'exact') {
|
|
452
|
+
if (result.rows.length > 0) {
|
|
453
|
+
countResult = Number(result.rows[0].exact_count);
|
|
454
|
+
// exact_count μ΄μ λͺ¨λ λ°μ΄ν° κ°μ²΄μμ μ κ±°
|
|
455
|
+
dataResult = result.rows.map(row => {
|
|
456
|
+
const newRow = { ...row };
|
|
457
|
+
delete newRow.exact_count;
|
|
458
|
+
return newRow;
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
countResult = 0;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
countResult = result.rowCount;
|
|
467
|
+
}
|
|
440
468
|
if (this.singleMode) {
|
|
441
|
-
if (
|
|
469
|
+
if (dataResult.length > 1) {
|
|
442
470
|
return {
|
|
443
471
|
data: null,
|
|
444
|
-
error: new errors_1.PostgresError('PGRST114: Multiple rows returned'),
|
|
445
|
-
count:
|
|
446
|
-
status: 406,
|
|
472
|
+
error: new errors_1.PostgresError('PGRST114: Multiple rows returned'),
|
|
473
|
+
count: countResult,
|
|
474
|
+
status: 406,
|
|
447
475
|
statusText: 'Not Acceptable. Expected a single row but found multiple.',
|
|
448
476
|
};
|
|
449
477
|
}
|
|
450
|
-
if (
|
|
478
|
+
if (dataResult.length === 0) {
|
|
451
479
|
if (this.singleMode === 'strict') {
|
|
452
480
|
return {
|
|
453
481
|
data: null,
|
|
454
|
-
error: new errors_1.PostgresError('PGRST116: No rows found'),
|
|
482
|
+
error: new errors_1.PostgresError('PGRST116: No rows found'),
|
|
455
483
|
count: 0,
|
|
456
|
-
status: 404,
|
|
484
|
+
status: 404,
|
|
457
485
|
statusText: 'Not Found. Expected a single row but found no rows.',
|
|
458
486
|
};
|
|
459
487
|
}
|
|
460
|
-
// this.singleMode === 'maybe'
|
|
461
488
|
return {
|
|
462
489
|
data: null,
|
|
463
490
|
error: null,
|
|
@@ -466,9 +493,8 @@ class QueryBuilder {
|
|
|
466
493
|
statusText: 'OK',
|
|
467
494
|
};
|
|
468
495
|
}
|
|
469
|
-
// result.rows.length === 1
|
|
470
496
|
return {
|
|
471
|
-
data:
|
|
497
|
+
data: dataResult[0],
|
|
472
498
|
error: null,
|
|
473
499
|
count: 1,
|
|
474
500
|
status: 200,
|
|
@@ -476,9 +502,9 @@ class QueryBuilder {
|
|
|
476
502
|
};
|
|
477
503
|
}
|
|
478
504
|
return {
|
|
479
|
-
data:
|
|
505
|
+
data: dataResult,
|
|
480
506
|
error: null,
|
|
481
|
-
count:
|
|
507
|
+
count: countResult,
|
|
482
508
|
status: 200,
|
|
483
509
|
statusText: 'OK',
|
|
484
510
|
};
|