@pineliner/odb-client 1.0.7 → 1.0.9
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/dist/database/adapters/bun-sqlite.d.ts.map +1 -1
- package/dist/database/adapters/libsql.d.ts.map +1 -1
- package/dist/database/adapters/odblite.d.ts.map +1 -1
- package/dist/database/types.d.ts +26 -2
- package/dist/database/types.d.ts.map +1 -1
- package/dist/index.cjs +195 -29
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +194 -30
- package/dist/orm/index.d.ts +79 -1
- package/dist/orm/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/database/adapters/bun-sqlite.ts +59 -5
- package/src/database/adapters/libsql.ts +66 -6
- package/src/database/adapters/odblite.ts +79 -16
- package/src/database/types.ts +28 -2
- package/src/index.ts +1 -0
- package/src/orm/index.ts +216 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var __webpack_modules__ = {
|
|
|
6
6
|
__webpack_require__.r(__webpack_exports__);
|
|
7
7
|
__webpack_require__.d(__webpack_exports__, {
|
|
8
8
|
ORM: ()=>ORM,
|
|
9
|
+
Transaction: ()=>Transaction,
|
|
9
10
|
and: ()=>and,
|
|
10
11
|
createORM: ()=>createORM,
|
|
11
12
|
eq: ()=>eq,
|
|
@@ -296,10 +297,67 @@ var __webpack_modules__ = {
|
|
|
296
297
|
return new DeleteBuilder(this.db, this.tableName);
|
|
297
298
|
}
|
|
298
299
|
}
|
|
300
|
+
class Transaction {
|
|
301
|
+
orm;
|
|
302
|
+
isCommitted = false;
|
|
303
|
+
isRolledBack = false;
|
|
304
|
+
db;
|
|
305
|
+
savepointName;
|
|
306
|
+
constructor(db, transactionDepth = 0, savepointName){
|
|
307
|
+
this.db = db;
|
|
308
|
+
this.orm = new ORM(db, transactionDepth);
|
|
309
|
+
this.savepointName = savepointName;
|
|
310
|
+
}
|
|
311
|
+
select(fields) {
|
|
312
|
+
this.checkNotFinalized();
|
|
313
|
+
return this.orm.select(fields);
|
|
314
|
+
}
|
|
315
|
+
insert(tableName) {
|
|
316
|
+
this.checkNotFinalized();
|
|
317
|
+
return this.orm.insert(tableName);
|
|
318
|
+
}
|
|
319
|
+
update(tableName) {
|
|
320
|
+
this.checkNotFinalized();
|
|
321
|
+
return this.orm.update(tableName);
|
|
322
|
+
}
|
|
323
|
+
delete(tableName) {
|
|
324
|
+
this.checkNotFinalized();
|
|
325
|
+
return this.orm.delete(tableName);
|
|
326
|
+
}
|
|
327
|
+
execute(sql, params) {
|
|
328
|
+
this.checkNotFinalized();
|
|
329
|
+
return this.orm.execute(sql, params);
|
|
330
|
+
}
|
|
331
|
+
async transaction(fn) {
|
|
332
|
+
this.checkNotFinalized();
|
|
333
|
+
if (fn) return await this.orm.transaction(fn);
|
|
334
|
+
return await this.orm.transaction();
|
|
335
|
+
}
|
|
336
|
+
async commit() {
|
|
337
|
+
if (this.isCommitted) throw new Error('Transaction already committed');
|
|
338
|
+
if (this.isRolledBack) throw new Error('Transaction already rolled back');
|
|
339
|
+
if (this.savepointName) await this.db.execute(`RELEASE SAVEPOINT ${this.savepointName}`, []);
|
|
340
|
+
else await this.db.execute('COMMIT', []);
|
|
341
|
+
this.isCommitted = true;
|
|
342
|
+
}
|
|
343
|
+
async rollback() {
|
|
344
|
+
if (this.isCommitted) throw new Error('Transaction already committed');
|
|
345
|
+
if (this.isRolledBack) throw new Error('Transaction already rolled back');
|
|
346
|
+
if (this.savepointName) await this.db.execute(`ROLLBACK TO SAVEPOINT ${this.savepointName}`, []);
|
|
347
|
+
else await this.db.execute('ROLLBACK', []);
|
|
348
|
+
this.isRolledBack = true;
|
|
349
|
+
}
|
|
350
|
+
checkNotFinalized() {
|
|
351
|
+
if (this.isCommitted) throw new Error('Cannot perform operations on committed transaction');
|
|
352
|
+
if (this.isRolledBack) throw new Error('Cannot perform operations on rolled back transaction');
|
|
353
|
+
}
|
|
354
|
+
}
|
|
299
355
|
class ORM {
|
|
300
356
|
db;
|
|
301
|
-
|
|
357
|
+
transactionDepth = 0;
|
|
358
|
+
constructor(db, transactionDepth = 0){
|
|
302
359
|
this.db = db;
|
|
360
|
+
this.transactionDepth = transactionDepth;
|
|
303
361
|
}
|
|
304
362
|
table(tableName) {
|
|
305
363
|
return new TableQueryBuilder(this.db, tableName);
|
|
@@ -325,6 +383,33 @@ var __webpack_modules__ = {
|
|
|
325
383
|
execute(sql, params) {
|
|
326
384
|
return this.db.execute(sql, params);
|
|
327
385
|
}
|
|
386
|
+
async transaction(fn) {
|
|
387
|
+
if (!fn) if (this.transactionDepth > 0) {
|
|
388
|
+
const savepointName = `sp_${this.transactionDepth}_${Date.now()}`;
|
|
389
|
+
await this.db.execute(`SAVEPOINT ${savepointName}`, []);
|
|
390
|
+
return new Transaction(this.db, this.transactionDepth + 1, savepointName);
|
|
391
|
+
} else {
|
|
392
|
+
await this.db.execute('BEGIN TRANSACTION', []);
|
|
393
|
+
return new Transaction(this.db, 1);
|
|
394
|
+
}
|
|
395
|
+
if (!(this.transactionDepth > 0)) return await this.db.transaction(async (txConnection)=>{
|
|
396
|
+
const txOrm = new ORM(txConnection, 1);
|
|
397
|
+
return await fn(txOrm);
|
|
398
|
+
});
|
|
399
|
+
{
|
|
400
|
+
const savepointName = `sp_${this.transactionDepth}_${Date.now()}`;
|
|
401
|
+
try {
|
|
402
|
+
await this.db.execute(`SAVEPOINT ${savepointName}`, []);
|
|
403
|
+
const nestedOrm = new ORM(this.db, this.transactionDepth + 1);
|
|
404
|
+
const result = await fn(nestedOrm);
|
|
405
|
+
await this.db.execute(`RELEASE SAVEPOINT ${savepointName}`, []);
|
|
406
|
+
return result;
|
|
407
|
+
} catch (error) {
|
|
408
|
+
await this.db.execute(`ROLLBACK TO SAVEPOINT ${savepointName}`, []);
|
|
409
|
+
throw error;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
328
413
|
}
|
|
329
414
|
function createORM(db) {
|
|
330
415
|
return new ORM(db);
|
|
@@ -1204,6 +1289,26 @@ function sql_template_where(conditions) {
|
|
|
1204
1289
|
args: values
|
|
1205
1290
|
};
|
|
1206
1291
|
}
|
|
1292
|
+
function parseJsonColumns(rows, jsonColumns) {
|
|
1293
|
+
if (!jsonColumns || 0 === jsonColumns.length) return rows;
|
|
1294
|
+
return rows.map((row)=>{
|
|
1295
|
+
const parsed = {
|
|
1296
|
+
...row
|
|
1297
|
+
};
|
|
1298
|
+
for (const col of jsonColumns)if (col in parsed && 'string' == typeof parsed[col]) try {
|
|
1299
|
+
parsed[col] = JSON.parse(parsed[col]);
|
|
1300
|
+
} catch {}
|
|
1301
|
+
return parsed;
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
function stringifyJsonParams(params, stringifyParams) {
|
|
1305
|
+
if (!stringifyParams || 0 === Object.keys(stringifyParams).length) return params;
|
|
1306
|
+
const result = [
|
|
1307
|
+
...params
|
|
1308
|
+
];
|
|
1309
|
+
for (const [_columnName, index] of Object.entries(stringifyParams))if (index < result.length && null != result[index] && 'object' == typeof result[index]) result[index] = JSON.stringify(result[index]);
|
|
1310
|
+
return result;
|
|
1311
|
+
}
|
|
1207
1312
|
class BunSQLiteAdapter {
|
|
1208
1313
|
type = 'bun-sqlite';
|
|
1209
1314
|
config;
|
|
@@ -1261,10 +1366,10 @@ class BunSQLiteConnection {
|
|
|
1261
1366
|
this.sql.set = set;
|
|
1262
1367
|
this.sql.where = sql_template_where;
|
|
1263
1368
|
}
|
|
1264
|
-
async query(sql, params = []) {
|
|
1265
|
-
return this.execute(sql, params);
|
|
1369
|
+
async query(sql, params = [], options) {
|
|
1370
|
+
return this.execute(sql, params, options);
|
|
1266
1371
|
}
|
|
1267
|
-
async execute(sql, params = []) {
|
|
1372
|
+
async execute(sql, params = [], options) {
|
|
1268
1373
|
try {
|
|
1269
1374
|
let sqlStr;
|
|
1270
1375
|
let sqlParams;
|
|
@@ -1283,12 +1388,14 @@ class BunSQLiteConnection {
|
|
|
1283
1388
|
sqlStr = sql;
|
|
1284
1389
|
sqlParams = params;
|
|
1285
1390
|
}
|
|
1391
|
+
if (options?.stringifyParams) sqlParams = stringifyJsonParams(sqlParams, options.stringifyParams);
|
|
1286
1392
|
const stmt = this.db.query(sqlStr);
|
|
1287
1393
|
const isSelect = sqlStr.trim().toUpperCase().startsWith('SELECT') || sqlStr.trim().toUpperCase().includes('RETURNING');
|
|
1288
1394
|
if (isSelect) {
|
|
1289
|
-
|
|
1395
|
+
let rows = stmt.all(...sqlParams);
|
|
1396
|
+
if (options?.jsonColumns) rows = parseJsonColumns(rows, options.jsonColumns);
|
|
1290
1397
|
return {
|
|
1291
|
-
rows
|
|
1398
|
+
rows,
|
|
1292
1399
|
rowsAffected: 0
|
|
1293
1400
|
};
|
|
1294
1401
|
}
|
|
@@ -1355,6 +1462,26 @@ class BunSQLiteConnection {
|
|
|
1355
1462
|
return createORM(this);
|
|
1356
1463
|
}
|
|
1357
1464
|
}
|
|
1465
|
+
function libsql_parseJsonColumns(rows, jsonColumns) {
|
|
1466
|
+
if (!jsonColumns || 0 === jsonColumns.length) return rows;
|
|
1467
|
+
return rows.map((row)=>{
|
|
1468
|
+
const parsed = {
|
|
1469
|
+
...row
|
|
1470
|
+
};
|
|
1471
|
+
for (const col of jsonColumns)if (col in parsed && 'string' == typeof parsed[col]) try {
|
|
1472
|
+
parsed[col] = JSON.parse(parsed[col]);
|
|
1473
|
+
} catch {}
|
|
1474
|
+
return parsed;
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
function libsql_stringifyJsonParams(params, stringifyParams) {
|
|
1478
|
+
if (!stringifyParams || 0 === Object.keys(stringifyParams).length) return params;
|
|
1479
|
+
const result = [
|
|
1480
|
+
...params
|
|
1481
|
+
];
|
|
1482
|
+
for (const [_columnName, index] of Object.entries(stringifyParams))if (index < result.length && null != result[index] && 'object' == typeof result[index]) result[index] = JSON.stringify(result[index]);
|
|
1483
|
+
return result;
|
|
1484
|
+
}
|
|
1358
1485
|
class LibSQLAdapter {
|
|
1359
1486
|
type = 'libsql';
|
|
1360
1487
|
config;
|
|
@@ -1412,10 +1539,10 @@ class LibSQLConnection {
|
|
|
1412
1539
|
this.sql.set = set;
|
|
1413
1540
|
this.sql.where = sql_template_where;
|
|
1414
1541
|
}
|
|
1415
|
-
async query(sql, params = []) {
|
|
1416
|
-
return this.execute(sql, params);
|
|
1542
|
+
async query(sql, params = [], options) {
|
|
1543
|
+
return this.execute(sql, params, options);
|
|
1417
1544
|
}
|
|
1418
|
-
async execute(sql, params = []) {
|
|
1545
|
+
async execute(sql, params = [], options) {
|
|
1419
1546
|
try {
|
|
1420
1547
|
const target = this.txClient || this.client;
|
|
1421
1548
|
let query;
|
|
@@ -1424,23 +1551,29 @@ class LibSQLConnection {
|
|
|
1424
1551
|
console.log('[LibSQL] Executing SQL:', sql);
|
|
1425
1552
|
console.log('[LibSQL] With params:', params);
|
|
1426
1553
|
}
|
|
1554
|
+
let args = params;
|
|
1555
|
+
if (options?.stringifyParams) args = libsql_stringifyJsonParams(args, options.stringifyParams);
|
|
1427
1556
|
query = {
|
|
1428
1557
|
sql,
|
|
1429
|
-
args
|
|
1558
|
+
args
|
|
1430
1559
|
};
|
|
1431
1560
|
} else {
|
|
1432
1561
|
if (process.env.DEBUG_SQL) {
|
|
1433
1562
|
console.log('[LibSQL] Executing SQL:', sql.sql);
|
|
1434
1563
|
console.log('[LibSQL] With args:', sql.args);
|
|
1435
1564
|
}
|
|
1565
|
+
let args = sql.args || [];
|
|
1566
|
+
if (options?.stringifyParams) args = libsql_stringifyJsonParams(args, options.stringifyParams);
|
|
1436
1567
|
query = {
|
|
1437
1568
|
sql: sql.sql,
|
|
1438
|
-
args
|
|
1569
|
+
args
|
|
1439
1570
|
};
|
|
1440
1571
|
}
|
|
1441
1572
|
const result = await target.execute(query);
|
|
1573
|
+
let rows = result.rows;
|
|
1574
|
+
if (options?.jsonColumns) rows = libsql_parseJsonColumns(rows, options.jsonColumns);
|
|
1442
1575
|
return {
|
|
1443
|
-
rows
|
|
1576
|
+
rows,
|
|
1444
1577
|
rowsAffected: Number(result.rowsAffected),
|
|
1445
1578
|
lastInsertRowid: result.lastInsertRowid ? BigInt(result.lastInsertRowid.toString()) : void 0
|
|
1446
1579
|
};
|
|
@@ -1482,6 +1615,26 @@ class LibSQLConnection {
|
|
|
1482
1615
|
return createORM(this);
|
|
1483
1616
|
}
|
|
1484
1617
|
}
|
|
1618
|
+
function odblite_parseJsonColumns(rows, jsonColumns) {
|
|
1619
|
+
if (!jsonColumns || 0 === jsonColumns.length) return rows;
|
|
1620
|
+
return rows.map((row)=>{
|
|
1621
|
+
const parsed = {
|
|
1622
|
+
...row
|
|
1623
|
+
};
|
|
1624
|
+
for (const col of jsonColumns)if (col in parsed && 'string' == typeof parsed[col]) try {
|
|
1625
|
+
parsed[col] = JSON.parse(parsed[col]);
|
|
1626
|
+
} catch {}
|
|
1627
|
+
return parsed;
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
function odblite_stringifyJsonParams(params, stringifyParams) {
|
|
1631
|
+
if (!stringifyParams || 0 === Object.keys(stringifyParams).length) return params;
|
|
1632
|
+
const result = [
|
|
1633
|
+
...params
|
|
1634
|
+
];
|
|
1635
|
+
for (const [_columnName, index] of Object.entries(stringifyParams))if (index < result.length && null != result[index] && 'object' == typeof result[index]) result[index] = JSON.stringify(result[index]);
|
|
1636
|
+
return result;
|
|
1637
|
+
}
|
|
1485
1638
|
class ODBLiteAdapter {
|
|
1486
1639
|
type = 'odblite';
|
|
1487
1640
|
config;
|
|
@@ -1568,32 +1721,42 @@ class ODBLiteConnection {
|
|
|
1568
1721
|
this.sql.set = set;
|
|
1569
1722
|
this.sql.where = sql_template_where;
|
|
1570
1723
|
}
|
|
1571
|
-
async query(sql, params = []) {
|
|
1572
|
-
return this.execute(sql, params);
|
|
1724
|
+
async query(sql, params = [], options) {
|
|
1725
|
+
return this.execute(sql, params, options);
|
|
1573
1726
|
}
|
|
1574
|
-
async execute(sql, params = []) {
|
|
1727
|
+
async execute(sql, params = [], options) {
|
|
1575
1728
|
try {
|
|
1729
|
+
let rows;
|
|
1730
|
+
let rowsAffected;
|
|
1731
|
+
let lastInsertRowid;
|
|
1576
1732
|
if ('object' == typeof sql) {
|
|
1577
1733
|
if (process.env.DEBUG_SQL) {
|
|
1578
1734
|
console.log('[ODBLite] Executing SQL:', sql.sql);
|
|
1579
1735
|
console.log('[ODBLite] With args:', sql.args);
|
|
1580
1736
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1737
|
+
let args = sql.args || [];
|
|
1738
|
+
if (options?.stringifyParams) args = odblite_stringifyJsonParams(args, options.stringifyParams);
|
|
1739
|
+
const result = await this.client.sql.execute(sql.sql, args);
|
|
1740
|
+
rows = result.rows;
|
|
1741
|
+
rowsAffected = result.rowsAffected || 0;
|
|
1742
|
+
lastInsertRowid = result.lastInsertRowid;
|
|
1743
|
+
} else {
|
|
1744
|
+
if (process.env.DEBUG_SQL) {
|
|
1745
|
+
console.log('[ODBLite] Executing SQL:', sql);
|
|
1746
|
+
console.log('[ODBLite] With params:', params);
|
|
1747
|
+
}
|
|
1748
|
+
let args = params;
|
|
1749
|
+
if (options?.stringifyParams) args = odblite_stringifyJsonParams(args, options.stringifyParams);
|
|
1750
|
+
const result = await this.client.sql.execute(sql, args);
|
|
1751
|
+
rows = result.rows;
|
|
1752
|
+
rowsAffected = result.rowsAffected || 0;
|
|
1753
|
+
lastInsertRowid = result.lastInsertRowid;
|
|
1591
1754
|
}
|
|
1592
|
-
|
|
1755
|
+
if (options?.jsonColumns) rows = odblite_parseJsonColumns(rows, options.jsonColumns);
|
|
1593
1756
|
return {
|
|
1594
|
-
rows
|
|
1595
|
-
rowsAffected
|
|
1596
|
-
lastInsertRowid
|
|
1757
|
+
rows,
|
|
1758
|
+
rowsAffected,
|
|
1759
|
+
lastInsertRowid
|
|
1597
1760
|
};
|
|
1598
1761
|
} catch (error) {
|
|
1599
1762
|
throw error;
|
|
@@ -1875,6 +2038,7 @@ class DatabaseManager {
|
|
|
1875
2038
|
var orm = __webpack_require__("./src/orm/index.ts");
|
|
1876
2039
|
const { raw: src_raw, identifier: src_identifier, where: src_where, insertValues: src_insertValues, updateSet: src_updateSet, join: src_join } = ODBLiteClient;
|
|
1877
2040
|
var __webpack_exports__ORM = orm.ORM;
|
|
2041
|
+
var __webpack_exports__ORMTransaction = orm.Transaction;
|
|
1878
2042
|
var __webpack_exports__and = orm.and;
|
|
1879
2043
|
var __webpack_exports__createORM = orm.createORM;
|
|
1880
2044
|
var __webpack_exports__eq = orm.eq;
|
|
@@ -1888,4 +2052,4 @@ var __webpack_exports__lt = orm.lt;
|
|
|
1888
2052
|
var __webpack_exports__lte = orm.lte;
|
|
1889
2053
|
var __webpack_exports__ne = orm.ne;
|
|
1890
2054
|
var __webpack_exports__or = orm.or;
|
|
1891
|
-
export { BunSQLiteAdapter, ConnectionError, DatabaseManager, HTTPClient, LibSQLAdapter, ODBLiteAdapter, ODBLiteClient, ODBLiteError, ODBLiteTransaction, types_QueryError as QueryError, sql_parser_SQLParser as SQLParser, ServiceClient, SimpleTransaction, convertTemplateToQuery, odblite as default, empty, fragment, src_identifier as identifier, src_insertValues as insertValues, src_join as join, odblite, parseSQL, src_raw as raw, sql_template_raw as rawSQL, set, splitSQLStatements, sql_parser_sql as sql, sql_template_fragment as sqlFragment, sql_template_join as sqlJoin, sql_template_sql as sqlTemplate, sql_template_where as sqlWhere, src_updateSet as updateSet, src_where as where, __webpack_exports__ORM as ORM, __webpack_exports__and as and, __webpack_exports__createORM as createORM, __webpack_exports__eq as eq, __webpack_exports__gt as gt, __webpack_exports__gte as gte, __webpack_exports__inArray as inArray, __webpack_exports__isNotNull as isNotNull, __webpack_exports__isNull as isNull, __webpack_exports__like as like, __webpack_exports__lt as lt, __webpack_exports__lte as lte, __webpack_exports__ne as ne, __webpack_exports__or as or };
|
|
2055
|
+
export { BunSQLiteAdapter, ConnectionError, DatabaseManager, HTTPClient, LibSQLAdapter, ODBLiteAdapter, ODBLiteClient, ODBLiteError, ODBLiteTransaction, types_QueryError as QueryError, sql_parser_SQLParser as SQLParser, ServiceClient, SimpleTransaction, convertTemplateToQuery, odblite as default, empty, fragment, src_identifier as identifier, src_insertValues as insertValues, src_join as join, odblite, parseSQL, src_raw as raw, sql_template_raw as rawSQL, set, splitSQLStatements, sql_parser_sql as sql, sql_template_fragment as sqlFragment, sql_template_join as sqlJoin, sql_template_sql as sqlTemplate, sql_template_where as sqlWhere, src_updateSet as updateSet, src_where as where, __webpack_exports__ORM as ORM, __webpack_exports__ORMTransaction as ORMTransaction, __webpack_exports__and as and, __webpack_exports__createORM as createORM, __webpack_exports__eq as eq, __webpack_exports__gt as gt, __webpack_exports__gte as gte, __webpack_exports__inArray as inArray, __webpack_exports__isNotNull as isNotNull, __webpack_exports__isNull as isNull, __webpack_exports__like as like, __webpack_exports__lt as lt, __webpack_exports__lte as lte, __webpack_exports__ne as ne, __webpack_exports__or as or };
|
package/dist/orm/index.d.ts
CHANGED
|
@@ -186,13 +186,53 @@ declare class TableQueryBuilder {
|
|
|
186
186
|
*/
|
|
187
187
|
delete(): DeleteBuilder;
|
|
188
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Manual Transaction Control
|
|
191
|
+
* Allows explicit commit/rollback control
|
|
192
|
+
*/
|
|
193
|
+
export declare class Transaction {
|
|
194
|
+
private orm;
|
|
195
|
+
private isCommitted;
|
|
196
|
+
private isRolledBack;
|
|
197
|
+
private db;
|
|
198
|
+
private savepointName?;
|
|
199
|
+
constructor(db: Connection, transactionDepth?: number, savepointName?: string);
|
|
200
|
+
/**
|
|
201
|
+
* Access ORM methods (select, insert, update, delete)
|
|
202
|
+
*/
|
|
203
|
+
select(fields?: Record<string, any>): {
|
|
204
|
+
from: (tableName: string) => SelectBuilder<any>;
|
|
205
|
+
};
|
|
206
|
+
insert(tableName: string): InsertBuilder<any>;
|
|
207
|
+
update(tableName: string): UpdateBuilder<any>;
|
|
208
|
+
delete(tableName: string): DeleteBuilder;
|
|
209
|
+
execute(sql: string, params?: any[]): Promise<import("../index.ts").DatabaseQueryResult<any>>;
|
|
210
|
+
/**
|
|
211
|
+
* Create nested transaction (savepoint)
|
|
212
|
+
*/
|
|
213
|
+
transaction(): Promise<Transaction>;
|
|
214
|
+
transaction<T>(fn: (tx: ORM) => Promise<T>): Promise<T>;
|
|
215
|
+
/**
|
|
216
|
+
* Commit the transaction
|
|
217
|
+
*/
|
|
218
|
+
commit(): Promise<void>;
|
|
219
|
+
/**
|
|
220
|
+
* Rollback the transaction
|
|
221
|
+
*/
|
|
222
|
+
rollback(): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Check if transaction is finalized
|
|
225
|
+
*/
|
|
226
|
+
private checkNotFinalized;
|
|
227
|
+
}
|
|
189
228
|
/**
|
|
190
229
|
* ORM Wrapper for Connection
|
|
191
230
|
* Provides Drizzle-like syntax for database operations
|
|
192
231
|
*/
|
|
193
232
|
export declare class ORM {
|
|
194
233
|
private db;
|
|
195
|
-
|
|
234
|
+
private transactionDepth;
|
|
235
|
+
constructor(db: Connection, transactionDepth?: number);
|
|
196
236
|
/**
|
|
197
237
|
* Access a table for querying
|
|
198
238
|
*/
|
|
@@ -219,6 +259,44 @@ export declare class ORM {
|
|
|
219
259
|
* Raw query access
|
|
220
260
|
*/
|
|
221
261
|
execute(sql: string, params?: any[]): Promise<import("../index.ts").DatabaseQueryResult<any>>;
|
|
262
|
+
/**
|
|
263
|
+
* Execute a transaction with support for nested transactions (savepoints)
|
|
264
|
+
* @example
|
|
265
|
+
* // Callback-style transaction
|
|
266
|
+
* const result = await orm.transaction(async (tx) => {
|
|
267
|
+
* const user = await tx.insert('users').values({ name: 'Alice' }).returning()
|
|
268
|
+
* const profile = await tx.insert('profiles').values({
|
|
269
|
+
* userId: user[0].id,
|
|
270
|
+
* bio: 'Hello world',
|
|
271
|
+
* }).returning()
|
|
272
|
+
* return { user, profile }
|
|
273
|
+
* })
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* // Manual transaction control
|
|
277
|
+
* const tx = await orm.transaction()
|
|
278
|
+
* try {
|
|
279
|
+
* await tx.insert('users').values({ name: 'Bob' }).execute()
|
|
280
|
+
* await tx.insert('profiles').values({ userId: 1, bio: 'Something' }).execute()
|
|
281
|
+
* await tx.commit()
|
|
282
|
+
* } catch (err) {
|
|
283
|
+
* await tx.rollback()
|
|
284
|
+
* throw err
|
|
285
|
+
* }
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* // Nested transaction (savepoint)
|
|
289
|
+
* await orm.transaction(async (outer) => {
|
|
290
|
+
* await outer.insert('users').values({ name: 'Outer' })
|
|
291
|
+
*
|
|
292
|
+
* await outer.transaction(async (inner) => {
|
|
293
|
+
* await inner.insert('users').values({ name: 'Inner' })
|
|
294
|
+
* // If this inner block throws, only the inner part rolls back
|
|
295
|
+
* })
|
|
296
|
+
* })
|
|
297
|
+
*/
|
|
298
|
+
transaction(): Promise<Transaction>;
|
|
299
|
+
transaction<T>(fn: (tx: ORM) => Promise<T>): Promise<T>;
|
|
222
300
|
}
|
|
223
301
|
/**
|
|
224
302
|
* Create ORM instance from Connection
|
package/dist/orm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orm/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orm/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pineliner/odb-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Isomorphic client for ODB-Lite with postgres.js-like template string SQL support",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -42,4 +42,4 @@
|
|
|
42
42
|
"template-strings",
|
|
43
43
|
"postgres-like"
|
|
44
44
|
]
|
|
45
|
-
}
|
|
45
|
+
}
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
QueryResult,
|
|
6
6
|
PreparedStatement,
|
|
7
7
|
BunSQLiteConfig,
|
|
8
|
+
QueryOptions,
|
|
8
9
|
} from '../types'
|
|
9
10
|
import {
|
|
10
11
|
convertTemplateToQuery,
|
|
@@ -17,6 +18,48 @@ import {
|
|
|
17
18
|
where
|
|
18
19
|
} from '../sql-template'
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Parse JSON columns in query results
|
|
23
|
+
* Only parses if the value is a string (to avoid double-parsing)
|
|
24
|
+
*/
|
|
25
|
+
function parseJsonColumns<T = any>(rows: any[], jsonColumns?: string[]): T[] {
|
|
26
|
+
if (!jsonColumns || jsonColumns.length === 0) {
|
|
27
|
+
return rows
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return rows.map(row => {
|
|
31
|
+
const parsed = { ...row }
|
|
32
|
+
for (const col of jsonColumns) {
|
|
33
|
+
if (col in parsed && typeof parsed[col] === 'string') {
|
|
34
|
+
try {
|
|
35
|
+
parsed[col] = JSON.parse(parsed[col])
|
|
36
|
+
} catch {
|
|
37
|
+
// Keep original value if parsing fails
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return parsed
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Stringify JSON parameters for INSERT/UPDATE queries
|
|
47
|
+
* Only stringifies if the value is an object/array (not already a string)
|
|
48
|
+
*/
|
|
49
|
+
function stringifyJsonParams(params: any[], stringifyParams?: Record<string, number>): any[] {
|
|
50
|
+
if (!stringifyParams || Object.keys(stringifyParams).length === 0) {
|
|
51
|
+
return params
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const result = [...params]
|
|
55
|
+
for (const [_columnName, index] of Object.entries(stringifyParams)) {
|
|
56
|
+
if (index < result.length && result[index] != null && typeof result[index] === 'object') {
|
|
57
|
+
result[index] = JSON.stringify(result[index])
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result
|
|
61
|
+
}
|
|
62
|
+
|
|
20
63
|
/**
|
|
21
64
|
* Bun SQLite adapter for DatabaseManager
|
|
22
65
|
* Wraps bun:sqlite with Connection interface
|
|
@@ -117,14 +160,14 @@ class BunSQLiteConnection implements Connection {
|
|
|
117
160
|
/**
|
|
118
161
|
* Query with SQL string and parameters (alias for execute)
|
|
119
162
|
*/
|
|
120
|
-
async query<T = any>(sql: string, params: any[] = []): Promise<QueryResult<T>> {
|
|
121
|
-
return this.execute(sql, params) as Promise<QueryResult<T>>
|
|
163
|
+
async query<T = any>(sql: string, params: any[] = [], options?: QueryOptions): Promise<QueryResult<T>> {
|
|
164
|
+
return this.execute(sql, params, options) as Promise<QueryResult<T>>
|
|
122
165
|
}
|
|
123
166
|
|
|
124
167
|
/**
|
|
125
168
|
* Execute SQL with parameters
|
|
126
169
|
*/
|
|
127
|
-
async execute(sql: string | { sql: string; args?: any[] }, params: any[] = []): Promise<QueryResult> {
|
|
170
|
+
async execute(sql: string | { sql: string; args?: any[] }, params: any[] = [], options?: QueryOptions): Promise<QueryResult> {
|
|
128
171
|
try {
|
|
129
172
|
// Handle object format { sql, args }
|
|
130
173
|
let sqlStr: string
|
|
@@ -147,14 +190,25 @@ class BunSQLiteConnection implements Connection {
|
|
|
147
190
|
sqlParams = params
|
|
148
191
|
}
|
|
149
192
|
|
|
193
|
+
// Stringify JSON parameters if specified
|
|
194
|
+
if (options?.stringifyParams) {
|
|
195
|
+
sqlParams = stringifyJsonParams(sqlParams, options.stringifyParams)
|
|
196
|
+
}
|
|
197
|
+
|
|
150
198
|
const stmt = this.db.query(sqlStr)
|
|
151
199
|
const isSelect = sqlStr.trim().toUpperCase().startsWith('SELECT') ||
|
|
152
200
|
sqlStr.trim().toUpperCase().includes('RETURNING')
|
|
153
201
|
|
|
154
202
|
if (isSelect) {
|
|
155
|
-
|
|
203
|
+
let rows = stmt.all(...sqlParams) as any[]
|
|
204
|
+
|
|
205
|
+
// Parse JSON columns if specified
|
|
206
|
+
if (options?.jsonColumns) {
|
|
207
|
+
rows = parseJsonColumns(rows, options.jsonColumns)
|
|
208
|
+
}
|
|
209
|
+
|
|
156
210
|
return {
|
|
157
|
-
rows
|
|
211
|
+
rows,
|
|
158
212
|
rowsAffected: 0,
|
|
159
213
|
}
|
|
160
214
|
} else {
|