orange-orm 4.9.1 → 4.10.0-beta.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.
- package/README.md +120 -0
- package/deno.lock +76 -0
- package/dist/index.browser.mjs +187 -53
- package/dist/index.mjs +287 -176
- package/other.db +0 -0
- package/package.json +1 -1
- package/src/bunPg/newDatabase.js +3 -14
- package/src/bunPg/newTransaction.js +1 -0
- package/src/bunSqlite/newDatabase.js +22 -13
- package/src/bunSqlite/newTransaction.js +1 -0
- package/src/client/index.js +8 -1
- package/src/client/netAdapter.js +13 -2
- package/src/d1/newDatabase.js +3 -13
- package/src/d1/newTransaction.js +1 -0
- package/src/getTSDefinition.js +14 -1
- package/src/hostExpress.js +8 -3
- package/src/hostLocal.js +66 -6
- package/src/map2.d.ts +18 -1
- package/src/mssql/newDatabase.js +3 -13
- package/src/mssql/newTransaction.js +1 -0
- package/src/mySql/newDatabase.js +3 -13
- package/src/mySql/newTransaction.js +1 -0
- package/src/nodeSqlite/newDatabase.js +29 -18
- package/src/nodeSqlite/newTransaction.js +1 -0
- package/src/oracle/newDatabase.js +3 -13
- package/src/oracle/newTransaction.js +1 -0
- package/src/pg/newDatabase.js +4 -16
- package/src/pg/newTransaction.js +1 -0
- package/src/pglite/newDatabase.js +3 -14
- package/src/pglite/newTransaction.js +1 -0
- package/src/sap/newDatabase.js +3 -13
- package/src/sap/newTransaction.js +1 -0
- package/src/sqlite3/newDatabase.js +22 -13
- package/src/sqlite3/newTransaction.js +1 -0
- package/src/sqliteFunction.js +20 -0
- package/src/table/begin.js +0 -1
- package/src/table/commit.js +21 -1
- package/src/table/rollback.js +22 -2
- package/src/tedious/newDatabase.js +3 -13
- package/src/tedious/newTransaction.js +1 -0
package/README.md
CHANGED
|
@@ -309,6 +309,31 @@ await pool.close(); // closes all pooled connections
|
|
|
309
309
|
__Why close ?__
|
|
310
310
|
In serverless environments (e.g. AWS Lambda, Vercel, Cloudflare Workers) execution contexts are frequently frozen and resumed. Explicitly closing the client or pool ensures that file handles are released promptly and prevents “database locked” errors between invocations.
|
|
311
311
|
|
|
312
|
+
__SQLite user-defined functions__
|
|
313
|
+
You can register custom SQLite functions on the connection using `db.function(name, fn)`.
|
|
314
|
+
|
|
315
|
+
```javascript
|
|
316
|
+
import map from './map';
|
|
317
|
+
const db = map.sqlite('demo.db');
|
|
318
|
+
|
|
319
|
+
db.function('add_prefix', (text, prefix) => `${prefix}${text}`);
|
|
320
|
+
|
|
321
|
+
const rows = await db.query(
|
|
322
|
+
"select id, name, add_prefix(name, '[VIP] ') as prefixedName from customer"
|
|
323
|
+
);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
If you need the function inside a transaction, register it within the transaction callback to ensure it is available on that connection.
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
await db.transaction(async (db) => {
|
|
330
|
+
db.function('add_prefix', (text, prefix) => `${prefix}${text}`);
|
|
331
|
+
return db.query(
|
|
332
|
+
"select id, name, add_prefix(name, '[VIP] ') as prefixedName from customer"
|
|
333
|
+
);
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
312
337
|
__From the browser__
|
|
313
338
|
You can securely use Orange from the browser by utilizing the Express plugin, which serves to safeguard sensitive database credentials from exposure at the client level. This technique bypasses the need to transmit raw SQL queries directly from the client to the server. Instead, it logs method calls initiated by the client, which are later replayed and authenticated on the server. This not only reinforces security by preventing the disclosure of raw SQL queries on the client side but also facilitates a smoother operation. Essentially, this method mirrors a traditional REST API, augmented with advanced TypeScript tooling for enhanced functionality. You can read more about it in the section called [In the browser](#user-content-in-the-browser)
|
|
314
339
|
<sub>📄 server.ts</sub>
|
|
@@ -1273,6 +1298,101 @@ async function updateRows() {
|
|
|
1273
1298
|
|
|
1274
1299
|
}
|
|
1275
1300
|
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1303
|
+
__Row Level Security (Postgres)__
|
|
1304
|
+
You can enforce tenant isolation at the database level by combining Postgres RLS with Express hooks. The example below mirrors the “Interceptors and base filter” style by putting the tenant id in a (fake) token on the client, then extracting it on the server and setting it inside the transaction. This is convenient for a demo because we can seed data and prove rows are filtered. In a real application you must validate signatures and derive tenant id from a trusted identity source, not from arbitrary client input.
|
|
1305
|
+
|
|
1306
|
+
<sub>📄 setup.sql</sub>
|
|
1307
|
+
|
|
1308
|
+
```sql
|
|
1309
|
+
create role rls_app_user nologin;
|
|
1310
|
+
|
|
1311
|
+
create table tenant_data (
|
|
1312
|
+
id serial primary key,
|
|
1313
|
+
tenant_id int not null,
|
|
1314
|
+
value text not null
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1317
|
+
alter table tenant_data enable row level security;
|
|
1318
|
+
create policy tenant_data_tenant on tenant_data
|
|
1319
|
+
using (tenant_id = current_setting('app.tenant_id', true)::int);
|
|
1320
|
+
|
|
1321
|
+
grant select, insert, update, delete on tenant_data to rls_app_user;
|
|
1322
|
+
|
|
1323
|
+
insert into tenant_data (tenant_id, value) values
|
|
1324
|
+
(1, 'alpha'),
|
|
1325
|
+
(1, 'beta'),
|
|
1326
|
+
(2, 'gamma');
|
|
1327
|
+
```
|
|
1328
|
+
|
|
1329
|
+
<sub>📄 server.ts</sub>
|
|
1330
|
+
|
|
1331
|
+
```javascript
|
|
1332
|
+
import map from './map';
|
|
1333
|
+
import { json } from 'body-parser';
|
|
1334
|
+
import express from 'express';
|
|
1335
|
+
import cors from 'cors';
|
|
1336
|
+
|
|
1337
|
+
const db = map.postgres('postgres://postgres:postgres@localhost/postgres');
|
|
1338
|
+
|
|
1339
|
+
express().disable('x-powered-by')
|
|
1340
|
+
.use(json({ limit: '100mb' }))
|
|
1341
|
+
.use(cors())
|
|
1342
|
+
.use('/orange', validateToken)
|
|
1343
|
+
.use('/orange', db.express({
|
|
1344
|
+
hooks: {
|
|
1345
|
+
transaction: {
|
|
1346
|
+
afterBegin: async (db, req) => {
|
|
1347
|
+
const tenantId = Number.parseInt(String(req.user?.tenantId ?? ''), 10);
|
|
1348
|
+
if (!Number.isFinite(tenantId)) throw new Error('Missing tenant id');
|
|
1349
|
+
await db.query('set local role rls_app_user');
|
|
1350
|
+
await db.query({
|
|
1351
|
+
sql: 'select set_config(\'app.tenant_id\', ?, true)',
|
|
1352
|
+
parameters: [String(tenantId)]
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}))
|
|
1358
|
+
.listen(3000, () => console.log('Example app listening on port 3000!'));
|
|
1359
|
+
|
|
1360
|
+
function validateToken(req, res, next) {
|
|
1361
|
+
const authHeader = req.headers.authorization;
|
|
1362
|
+
if (!authHeader) return res.status(401).json({ error: 'Authorization header missing' });
|
|
1363
|
+
try {
|
|
1364
|
+
const token = authHeader.replace(/^Bearer\s+/i, '');
|
|
1365
|
+
const payload = decodeFakeJwt(token); // demo-only, do not use in production
|
|
1366
|
+
req.user = { tenantId: String(payload.tenantId) };
|
|
1367
|
+
return next();
|
|
1368
|
+
} catch (error) {
|
|
1369
|
+
return res.status(401).json({ error: 'Invalid token' });
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
function decodeFakeJwt(token) {
|
|
1374
|
+
// Demo-only format: "tenant:<id>"
|
|
1375
|
+
const match = /^tenant:(\d+)$/.exec(token);
|
|
1376
|
+
if (!match) throw new Error('Invalid demo token');
|
|
1377
|
+
return { tenantId: Number(match[1]) };
|
|
1378
|
+
}
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
<sub>📄 browser.ts</sub>
|
|
1382
|
+
|
|
1383
|
+
```javascript
|
|
1384
|
+
import map from './map';
|
|
1385
|
+
|
|
1386
|
+
const db = map.http('http://localhost:3000/orange');
|
|
1387
|
+
|
|
1388
|
+
db.interceptors.request.use((config) => {
|
|
1389
|
+
// Demo-only token: payload carries the tenant id so we can verify filtering
|
|
1390
|
+
config.headers.Authorization = 'Bearer tenant:1';
|
|
1391
|
+
return config;
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
const rows = await db.tenant_data.getMany();
|
|
1395
|
+
// rows => [{ id: 1, tenant_id: 1, value: 'alpha' }, { id: 2, tenant_id: 1, value: 'beta' }]
|
|
1276
1396
|
```
|
|
1277
1397
|
</details>
|
|
1278
1398
|
|
package/deno.lock
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "5",
|
|
3
|
+
"specifiers": {
|
|
4
|
+
"jsr:@std/assert@*": "1.0.17",
|
|
5
|
+
"jsr:@std/assert@^1.0.17": "1.0.17",
|
|
6
|
+
"jsr:@std/internal@^1.0.12": "1.0.12",
|
|
7
|
+
"jsr:@std/path@*": "1.1.4",
|
|
8
|
+
"jsr:@std/testing@*": "1.0.17"
|
|
9
|
+
},
|
|
10
|
+
"jsr": {
|
|
11
|
+
"@std/assert@1.0.17": {
|
|
12
|
+
"integrity": "df5ebfffe77c03b3fa1401e11c762cc8f603d51021c56c4d15a8c7ab45e90dbe",
|
|
13
|
+
"dependencies": [
|
|
14
|
+
"jsr:@std/internal"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"@std/internal@1.0.12": {
|
|
18
|
+
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
|
19
|
+
},
|
|
20
|
+
"@std/path@1.1.4": {
|
|
21
|
+
"integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5",
|
|
22
|
+
"dependencies": [
|
|
23
|
+
"jsr:@std/internal"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"@std/testing@1.0.17": {
|
|
27
|
+
"integrity": "87bdc2700fa98249d48a17cd72413352d3d3680dcfbdb64947fd0982d6bbf681",
|
|
28
|
+
"dependencies": [
|
|
29
|
+
"jsr:@std/assert@^1.0.17",
|
|
30
|
+
"jsr:@std/internal"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"workspace": {
|
|
35
|
+
"packageJson": {
|
|
36
|
+
"dependencies": [
|
|
37
|
+
"npm:@cloudflare/workers-types@^4.20241106.0",
|
|
38
|
+
"npm:@electric-sql/pglite@0.3",
|
|
39
|
+
"npm:@lroal/on-change@^4.0.2",
|
|
40
|
+
"npm:@rollup/plugin-commonjs@^28.0.2",
|
|
41
|
+
"npm:@rollup/plugin-json@^6.1.0",
|
|
42
|
+
"npm:@rollup/plugin-node-resolve@13",
|
|
43
|
+
"npm:@tediousjs/connection-string@~0.4.1",
|
|
44
|
+
"npm:@types/express@^4.17.13",
|
|
45
|
+
"npm:@types/oracledb@^6.0.4",
|
|
46
|
+
"npm:@types/tedious@^4.0.14",
|
|
47
|
+
"npm:@typescript-eslint/eslint-plugin@6",
|
|
48
|
+
"npm:@typescript-eslint/parser@6",
|
|
49
|
+
"npm:@vitest/coverage-v8@^3.2.4",
|
|
50
|
+
"npm:ajv@^8.17.1",
|
|
51
|
+
"npm:axios@^1.6.2",
|
|
52
|
+
"npm:better-sqlite3@^11.8.1",
|
|
53
|
+
"npm:cors@^2.8.5",
|
|
54
|
+
"npm:eslint-plugin-jest@^27.1.7",
|
|
55
|
+
"npm:eslint@^8.57.0",
|
|
56
|
+
"npm:express@^4.18.2",
|
|
57
|
+
"npm:fast-json-patch@^3.1.1",
|
|
58
|
+
"npm:findup-sync@5",
|
|
59
|
+
"npm:glob@^10.3.4 || ^11.0.2",
|
|
60
|
+
"npm:module-definition@4 || 5 || * || 6",
|
|
61
|
+
"npm:msnodesqlv8@^4.1.0",
|
|
62
|
+
"npm:mysql2@^3.9.4",
|
|
63
|
+
"npm:oracledb@^6.3.0",
|
|
64
|
+
"npm:owasp-dependency-check@^0.0.21",
|
|
65
|
+
"npm:pg-query-stream@^3.3.2",
|
|
66
|
+
"npm:pg@^8.5.1",
|
|
67
|
+
"npm:rfdc@^1.2.0",
|
|
68
|
+
"npm:rollup@^2.52.7",
|
|
69
|
+
"npm:tedious@19",
|
|
70
|
+
"npm:typescript@^5.4.5",
|
|
71
|
+
"npm:uuid@^8.3.2 || 9 || 10 || ^11.1.0",
|
|
72
|
+
"npm:vitest@^3.2.4"
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -465,6 +465,7 @@ export interface ExpressConfig {
|
|
|
465
465
|
concurrency?: Concurrency;
|
|
466
466
|
readonly?: boolean;
|
|
467
467
|
disableBulkDeletes?: boolean;
|
|
468
|
+
hooks?: ExpressHooks;
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
export interface ExpressContext {
|
|
@@ -473,6 +474,18 @@ export interface ExpressContext {
|
|
|
473
474
|
client: RdbClient;
|
|
474
475
|
}
|
|
475
476
|
|
|
477
|
+
export interface ExpressTransactionHooks {
|
|
478
|
+
beforeBegin?: (db: Pool, request: import('express').Request, response: import('express').Response) => void | Promise<void>;
|
|
479
|
+
afterBegin?: (db: Pool, request: import('express').Request, response: import('express').Response) => void | Promise<void>;
|
|
480
|
+
beforeCommit?: (db: Pool, request: import('express').Request, response: import('express').Response) => void | Promise<void>;
|
|
481
|
+
afterCommit?: (db: Pool, request: import('express').Request, response: import('express').Response) => void | Promise<void>;
|
|
482
|
+
afterRollback?: (db: Pool, request: import('express').Request, response: import('express').Response, error?: unknown) => void | Promise<void>;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export interface ExpressHooks extends ExpressTransactionHooks {
|
|
486
|
+
transaction?: ExpressTransactionHooks;
|
|
487
|
+
}
|
|
488
|
+
|
|
476
489
|
export interface ExpressTables {${getExpressTables()}
|
|
477
490
|
}
|
|
478
491
|
`;
|
|
@@ -610,13 +623,18 @@ function requireHostExpress () {
|
|
|
610
623
|
const dbOptions = { db: options.db || client.db };
|
|
611
624
|
let c = {};
|
|
612
625
|
const readonly = { readonly: options.readonly};
|
|
626
|
+
const sharedHooks = options.hooks;
|
|
613
627
|
for (let tableName in client.tables) {
|
|
628
|
+
const tableOptions = options[tableName] || {};
|
|
629
|
+
const hooks = tableOptions.hooks || sharedHooks;
|
|
614
630
|
c[tableName] = hostLocal({
|
|
615
631
|
...dbOptions,
|
|
616
632
|
...readonly,
|
|
617
|
-
...
|
|
633
|
+
...tableOptions,
|
|
618
634
|
table: client.tables[tableName],
|
|
619
|
-
isHttp: true,
|
|
635
|
+
isHttp: true,
|
|
636
|
+
client,
|
|
637
|
+
hooks
|
|
620
638
|
|
|
621
639
|
});
|
|
622
640
|
}
|
|
@@ -2200,6 +2218,35 @@ function requireQuery () {
|
|
|
2200
2218
|
return query;
|
|
2201
2219
|
}
|
|
2202
2220
|
|
|
2221
|
+
var sqliteFunction;
|
|
2222
|
+
var hasRequiredSqliteFunction;
|
|
2223
|
+
|
|
2224
|
+
function requireSqliteFunction () {
|
|
2225
|
+
if (hasRequiredSqliteFunction) return sqliteFunction;
|
|
2226
|
+
hasRequiredSqliteFunction = 1;
|
|
2227
|
+
const executeChanges = requireExecuteChanges();
|
|
2228
|
+
const popChanges = requirePopChanges();
|
|
2229
|
+
const getSessionSingleton = requireGetSessionSingleton();
|
|
2230
|
+
|
|
2231
|
+
function executeQueries(context, ...rest) {
|
|
2232
|
+
var changes = popChanges(context);
|
|
2233
|
+
|
|
2234
|
+
return executeChanges(context, changes).then(onDoneChanges);
|
|
2235
|
+
|
|
2236
|
+
function onDoneChanges() {
|
|
2237
|
+
var client = getSessionSingleton(context, 'dbClient');
|
|
2238
|
+
if (client && typeof client.function === 'function')
|
|
2239
|
+
return client.function.apply(client, rest);
|
|
2240
|
+
if (client && typeof client.createFunction === 'function')
|
|
2241
|
+
return client.createFunction.apply(client, rest);
|
|
2242
|
+
throw new Error('SQLite client does not support user-defined functions');
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
sqliteFunction = executeQueries;
|
|
2247
|
+
return sqliteFunction;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2203
2250
|
var hostLocal_1;
|
|
2204
2251
|
var hasRequiredHostLocal;
|
|
2205
2252
|
|
|
@@ -2210,6 +2257,7 @@ function requireHostLocal () {
|
|
|
2210
2257
|
let getMeta = requireGetMeta();
|
|
2211
2258
|
let setSessionSingleton = requireSetSessionSingleton();
|
|
2212
2259
|
let executeQuery = requireQuery();
|
|
2260
|
+
let executeSqliteFunction = requireSqliteFunction();
|
|
2213
2261
|
let hostExpress = requireHostExpress();
|
|
2214
2262
|
const readonlyOps = ['getManyDto', 'getMany', 'aggregate', 'count'];
|
|
2215
2263
|
// { db, table, defaultConcurrency,
|
|
@@ -2220,9 +2268,12 @@ function requireHostLocal () {
|
|
|
2220
2268
|
// disableBulkDeletes, isBrowser }
|
|
2221
2269
|
function hostLocal() {
|
|
2222
2270
|
const _options = arguments[0];
|
|
2223
|
-
let { table, transaction, db, isHttp } = _options;
|
|
2271
|
+
let { table, transaction, db, isHttp, hooks, client } = _options;
|
|
2272
|
+
const transactionHooks = hooks && hooks.transaction;
|
|
2273
|
+
const getTransactionHook = (name) =>
|
|
2274
|
+
(transactionHooks && transactionHooks[name]) || (hooks && hooks[name]);
|
|
2224
2275
|
|
|
2225
|
-
let c = { get, post, patch, query, express };
|
|
2276
|
+
let c = { get, post, patch, query, sqliteFunction, express };
|
|
2226
2277
|
|
|
2227
2278
|
function get() {
|
|
2228
2279
|
return getMeta(table);
|
|
@@ -2273,10 +2324,41 @@ function requireHostLocal () {
|
|
|
2273
2324
|
else
|
|
2274
2325
|
db = dbPromise;
|
|
2275
2326
|
}
|
|
2276
|
-
|
|
2327
|
+
const beforeBegin = getTransactionHook('beforeBegin');
|
|
2328
|
+
const afterBegin = getTransactionHook('afterBegin');
|
|
2329
|
+
const beforeCommit = getTransactionHook('beforeCommit');
|
|
2330
|
+
const afterCommit = getTransactionHook('afterCommit');
|
|
2331
|
+
const afterRollback = getTransactionHook('afterRollback');
|
|
2332
|
+
const hasTransactionHooks = !!(beforeBegin
|
|
2333
|
+
|| afterBegin
|
|
2334
|
+
|| beforeCommit
|
|
2335
|
+
|| afterCommit
|
|
2336
|
+
|| afterRollback);
|
|
2337
|
+
if (!hasTransactionHooks && readonlyOps.includes(body.path))
|
|
2277
2338
|
await db.transaction({ readonly: true }, fn);
|
|
2278
|
-
else
|
|
2279
|
-
await db.transaction(
|
|
2339
|
+
else {
|
|
2340
|
+
await db.transaction(async (context) => {
|
|
2341
|
+
const hookDb = typeof client === 'function'
|
|
2342
|
+
? client({ transaction: (fn) => fn(context) })
|
|
2343
|
+
: (client || db);
|
|
2344
|
+
if (afterCommit)
|
|
2345
|
+
setSessionSingleton(context, 'afterCommitHook', () =>
|
|
2346
|
+
afterCommit(hookDb, request, response)
|
|
2347
|
+
);
|
|
2348
|
+
if (afterRollback)
|
|
2349
|
+
setSessionSingleton(context, 'afterRollbackHook', (error) =>
|
|
2350
|
+
afterRollback(hookDb, request, response, error)
|
|
2351
|
+
);
|
|
2352
|
+
if (beforeBegin)
|
|
2353
|
+
await beforeBegin(hookDb, request, response);
|
|
2354
|
+
if (afterBegin)
|
|
2355
|
+
await afterBegin(hookDb, request, response);
|
|
2356
|
+
await fn(context);
|
|
2357
|
+
if (beforeCommit)
|
|
2358
|
+
await beforeCommit(hookDb, request, response);
|
|
2359
|
+
});
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2280
2362
|
}
|
|
2281
2363
|
return result;
|
|
2282
2364
|
|
|
@@ -2311,6 +2393,31 @@ function requireHostLocal () {
|
|
|
2311
2393
|
|
|
2312
2394
|
}
|
|
2313
2395
|
|
|
2396
|
+
async function sqliteFunction() {
|
|
2397
|
+
let args = arguments;
|
|
2398
|
+
let result;
|
|
2399
|
+
|
|
2400
|
+
if (transaction)
|
|
2401
|
+
await transaction(fn);
|
|
2402
|
+
else {
|
|
2403
|
+
if (typeof db === 'function') {
|
|
2404
|
+
let dbPromise = db();
|
|
2405
|
+
if (dbPromise.then)
|
|
2406
|
+
db = await dbPromise;
|
|
2407
|
+
else
|
|
2408
|
+
db = dbPromise;
|
|
2409
|
+
}
|
|
2410
|
+
result = await db.sqliteFunction.apply(null, arguments);
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
return result;
|
|
2414
|
+
|
|
2415
|
+
async function fn(...args1) {
|
|
2416
|
+
result = await executeSqliteFunction.apply(null, [...args1, ...args]);
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2314
2421
|
function express(client, options) {
|
|
2315
2422
|
return hostExpress(hostLocal, client, options);
|
|
2316
2423
|
}
|
|
@@ -2401,6 +2508,7 @@ function requireNetAdapter () {
|
|
|
2401
2508
|
post,
|
|
2402
2509
|
patch,
|
|
2403
2510
|
query,
|
|
2511
|
+
sqliteFunction,
|
|
2404
2512
|
express
|
|
2405
2513
|
};
|
|
2406
2514
|
|
|
@@ -2456,6 +2564,10 @@ function requireNetAdapter () {
|
|
|
2456
2564
|
throw new Error('Queries are not supported through http');
|
|
2457
2565
|
}
|
|
2458
2566
|
|
|
2567
|
+
function sqliteFunction() {
|
|
2568
|
+
throw new Error('Sqlite Function is not supported through http');
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2459
2571
|
function express() {
|
|
2460
2572
|
throw new Error('Hosting in express is not supported on the client side');
|
|
2461
2573
|
}
|
|
@@ -2469,7 +2581,8 @@ function requireNetAdapter () {
|
|
|
2469
2581
|
get,
|
|
2470
2582
|
post,
|
|
2471
2583
|
patch,
|
|
2472
|
-
query
|
|
2584
|
+
query,
|
|
2585
|
+
sqliteFunction
|
|
2473
2586
|
};
|
|
2474
2587
|
|
|
2475
2588
|
return c;
|
|
@@ -2494,6 +2607,11 @@ function requireNetAdapter () {
|
|
|
2494
2607
|
return adapter.query.apply(null, arguments);
|
|
2495
2608
|
}
|
|
2496
2609
|
|
|
2610
|
+
async function sqliteFunction() {
|
|
2611
|
+
const adapter = await getInnerAdapter();
|
|
2612
|
+
return adapter.sqliteFunction.apply(null, arguments);
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2497
2615
|
async function getInnerAdapter() {
|
|
2498
2616
|
const db = await getDb();
|
|
2499
2617
|
if (typeof db === 'string') {
|
|
@@ -2782,6 +2900,7 @@ function requireClient () {
|
|
|
2782
2900
|
}
|
|
2783
2901
|
};
|
|
2784
2902
|
client.query = query;
|
|
2903
|
+
client.function = sqliteFunction;
|
|
2785
2904
|
client.transaction = runInTransaction;
|
|
2786
2905
|
client.db = baseUrl;
|
|
2787
2906
|
client.mssql = onProvider.bind(null, 'mssql');
|
|
@@ -2870,6 +2989,11 @@ function requireClient () {
|
|
|
2870
2989
|
return adapter.query.apply(null, arguments);
|
|
2871
2990
|
}
|
|
2872
2991
|
|
|
2992
|
+
async function sqliteFunction() {
|
|
2993
|
+
const adapter = netAdapter(baseUrl, undefined, { tableOptions: { db: baseUrl, transaction } });
|
|
2994
|
+
return adapter.sqliteFunction.apply(null, arguments);
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2873
2997
|
function express(arg) {
|
|
2874
2998
|
if (providers.express) {
|
|
2875
2999
|
return providers.express(client, { ...options, ...arg });
|
|
@@ -3553,6 +3677,7 @@ function requireClient () {
|
|
|
3553
3677
|
return;
|
|
3554
3678
|
|
|
3555
3679
|
let body = stringify({ patch, options: { ...tableOptions, ...concurrencyOptions, strategy, deduceStrategy } });
|
|
3680
|
+
|
|
3556
3681
|
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
3557
3682
|
let { changed, strategy: newStrategy } = await adapter.patch(body);
|
|
3558
3683
|
copyInto(changed, [row]);
|
|
@@ -12938,14 +13063,34 @@ function requireCommit () {
|
|
|
12938
13063
|
const getSessionSingleton = requireGetSessionSingleton();
|
|
12939
13064
|
|
|
12940
13065
|
function _commit(context, result) {
|
|
13066
|
+
let hookError;
|
|
12941
13067
|
return popAndPushChanges()
|
|
13068
|
+
.then(callAfterCommit)
|
|
12942
13069
|
.then(releaseDbClient.bind(null, context))
|
|
12943
|
-
.then(onReleased)
|
|
13070
|
+
.then(onReleased)
|
|
13071
|
+
.then(throwHookErrorIfAny);
|
|
12944
13072
|
|
|
12945
13073
|
function onReleased() {
|
|
12946
13074
|
return result;
|
|
12947
13075
|
}
|
|
12948
13076
|
|
|
13077
|
+
function throwHookErrorIfAny(res) {
|
|
13078
|
+
if (hookError)
|
|
13079
|
+
throw hookError;
|
|
13080
|
+
return res;
|
|
13081
|
+
}
|
|
13082
|
+
|
|
13083
|
+
function callAfterCommit() {
|
|
13084
|
+
const hook = getSessionSingleton(context, 'afterCommitHook');
|
|
13085
|
+
if (!hook)
|
|
13086
|
+
return Promise.resolve();
|
|
13087
|
+
return Promise.resolve()
|
|
13088
|
+
.then(() => hook())
|
|
13089
|
+
.catch((e) => {
|
|
13090
|
+
hookError = e;
|
|
13091
|
+
});
|
|
13092
|
+
}
|
|
13093
|
+
|
|
12949
13094
|
async function popAndPushChanges() {
|
|
12950
13095
|
let changes = popChanges(context);
|
|
12951
13096
|
while (changes.length > 0) {
|
|
@@ -13046,10 +13191,13 @@ function requireRollback () {
|
|
|
13046
13191
|
const getSessionSingleton = requireGetSessionSingleton();
|
|
13047
13192
|
|
|
13048
13193
|
function _rollback(context, e) {
|
|
13194
|
+
let hookError;
|
|
13049
13195
|
var chain = resultToPromise()
|
|
13050
13196
|
.then(() => popChanges(context))
|
|
13051
13197
|
.then(executeRollback)
|
|
13052
|
-
.then(
|
|
13198
|
+
.then(callAfterRollback)
|
|
13199
|
+
.then(() => releaseDbClient(context))
|
|
13200
|
+
.then(throwHookErrorIfAny);
|
|
13053
13201
|
|
|
13054
13202
|
|
|
13055
13203
|
function executeRollback() {
|
|
@@ -13059,6 +13207,23 @@ function requireRollback () {
|
|
|
13059
13207
|
return executeQuery(context, rollbackCommand);
|
|
13060
13208
|
}
|
|
13061
13209
|
|
|
13210
|
+
function callAfterRollback() {
|
|
13211
|
+
const hook = getSessionSingleton(context, 'afterRollbackHook');
|
|
13212
|
+
if (!hook)
|
|
13213
|
+
return Promise.resolve();
|
|
13214
|
+
return Promise.resolve()
|
|
13215
|
+
.then(() => hook(e))
|
|
13216
|
+
.catch((err) => {
|
|
13217
|
+
hookError = err;
|
|
13218
|
+
});
|
|
13219
|
+
}
|
|
13220
|
+
|
|
13221
|
+
function throwHookErrorIfAny(res) {
|
|
13222
|
+
if (hookError)
|
|
13223
|
+
throw hookError;
|
|
13224
|
+
return res;
|
|
13225
|
+
}
|
|
13226
|
+
|
|
13062
13227
|
if (e) {
|
|
13063
13228
|
if (e.message?.indexOf('ORA-01476: divisor is equal to zero') > -1)
|
|
13064
13229
|
return newThrow(context, new Error('Conflict when updating a column'), chain);
|
|
@@ -13940,6 +14105,7 @@ function requireNewTransaction$2 () {
|
|
|
13940
14105
|
rdb.aggregateCount = 0;
|
|
13941
14106
|
rdb.quote = (name) => `"${name}"`;
|
|
13942
14107
|
rdb.cache = {};
|
|
14108
|
+
rdb.changes = [];
|
|
13943
14109
|
|
|
13944
14110
|
if (readonly) {
|
|
13945
14111
|
rdb.dbClient = {
|
|
@@ -14043,7 +14209,6 @@ function requireBegin () {
|
|
|
14043
14209
|
let setSessionSingleton = requireSetSessionSingleton();
|
|
14044
14210
|
|
|
14045
14211
|
function begin(context, transactionLess) {
|
|
14046
|
-
setSessionSingleton(context, 'changes', []);
|
|
14047
14212
|
if (transactionLess) {
|
|
14048
14213
|
setSessionSingleton(context, 'transactionLess', true);
|
|
14049
14214
|
return Promise.resolve();
|
|
@@ -14840,7 +15005,6 @@ function requireNewDatabase$2 () {
|
|
|
14840
15005
|
let hostLocal = requireHostLocal();
|
|
14841
15006
|
let doQuery = requireQuery();
|
|
14842
15007
|
let releaseDbClient = requireReleaseDbClient();
|
|
14843
|
-
let setSessionSingleton = requireSetSessionSingleton();
|
|
14844
15008
|
|
|
14845
15009
|
function newDatabase(d1Database, poolOptions) {
|
|
14846
15010
|
if (!d1Database)
|
|
@@ -14857,10 +15021,9 @@ function requireNewDatabase$2 () {
|
|
|
14857
15021
|
}
|
|
14858
15022
|
let domain = createDomain();
|
|
14859
15023
|
|
|
14860
|
-
if (fn)
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
return domain.run(run);
|
|
15024
|
+
if (!fn)
|
|
15025
|
+
throw new Error('transaction requires a function');
|
|
15026
|
+
return domain.run(runInTransaction);
|
|
14864
15027
|
|
|
14865
15028
|
async function runInTransaction() {
|
|
14866
15029
|
let result;
|
|
@@ -14879,13 +15042,6 @@ function requireNewDatabase$2 () {
|
|
|
14879
15042
|
return _begin(domain, transactionLess);
|
|
14880
15043
|
}
|
|
14881
15044
|
|
|
14882
|
-
function run() {
|
|
14883
|
-
let p;
|
|
14884
|
-
let transaction = newTransaction(domain, pool, options);
|
|
14885
|
-
p = new Promise(transaction);
|
|
14886
|
-
|
|
14887
|
-
return p.then(begin);
|
|
14888
|
-
}
|
|
14889
15045
|
|
|
14890
15046
|
};
|
|
14891
15047
|
|
|
@@ -14913,7 +15069,6 @@ function requireNewDatabase$2 () {
|
|
|
14913
15069
|
let domain = createDomain();
|
|
14914
15070
|
let transaction = newTransaction(domain, pool);
|
|
14915
15071
|
let p = domain.run(() => new Promise(transaction)
|
|
14916
|
-
.then(() => setSessionSingleton(domain, 'changes', []))
|
|
14917
15072
|
.then(() => doQuery(domain, query).then(onResult, onError)));
|
|
14918
15073
|
return p;
|
|
14919
15074
|
|
|
@@ -15358,6 +15513,7 @@ function requireNewTransaction$1 () {
|
|
|
15358
15513
|
rdb.aggregateCount = 0;
|
|
15359
15514
|
rdb.quote = quote;
|
|
15360
15515
|
rdb.cache = {};
|
|
15516
|
+
rdb.changes = [];
|
|
15361
15517
|
|
|
15362
15518
|
if (readonly) {
|
|
15363
15519
|
rdb.dbClient = {
|
|
@@ -15600,7 +15756,6 @@ function requireNewDatabase$1 () {
|
|
|
15600
15756
|
let hostLocal = requireHostLocal();
|
|
15601
15757
|
let doQuery = requireQuery();
|
|
15602
15758
|
let releaseDbClient = requireReleaseDbClient();
|
|
15603
|
-
let setSessionSingleton = requireSetSessionSingleton();
|
|
15604
15759
|
|
|
15605
15760
|
function newDatabase(connectionString, poolOptions) {
|
|
15606
15761
|
poolOptions = poolOptions || { min: 1 };
|
|
@@ -15615,10 +15770,9 @@ function requireNewDatabase$1 () {
|
|
|
15615
15770
|
}
|
|
15616
15771
|
let domain = createDomain();
|
|
15617
15772
|
|
|
15618
|
-
if (fn)
|
|
15619
|
-
|
|
15620
|
-
|
|
15621
|
-
return domain.run(run);
|
|
15773
|
+
if (!fn)
|
|
15774
|
+
throw new Error('transaction requires a function');
|
|
15775
|
+
return domain.run(runInTransaction);
|
|
15622
15776
|
|
|
15623
15777
|
async function runInTransaction() {
|
|
15624
15778
|
let result;
|
|
@@ -15637,14 +15791,6 @@ function requireNewDatabase$1 () {
|
|
|
15637
15791
|
return _begin(domain, options);
|
|
15638
15792
|
}
|
|
15639
15793
|
|
|
15640
|
-
function run() {
|
|
15641
|
-
let p;
|
|
15642
|
-
let transaction = newTransaction(domain, pool, options);
|
|
15643
|
-
p = new Promise(transaction);
|
|
15644
|
-
|
|
15645
|
-
return p.then(begin)
|
|
15646
|
-
.then(negotiateSchema);
|
|
15647
|
-
}
|
|
15648
15794
|
|
|
15649
15795
|
function negotiateSchema(previous) {
|
|
15650
15796
|
let schema = options && options.schema;
|
|
@@ -15685,7 +15831,6 @@ function requireNewDatabase$1 () {
|
|
|
15685
15831
|
let domain = createDomain();
|
|
15686
15832
|
let transaction = newTransaction(domain, pool);
|
|
15687
15833
|
let p = domain.run(() => new Promise(transaction)
|
|
15688
|
-
.then(() => setSessionSingleton(domain, 'changes', []))
|
|
15689
15834
|
.then(() => doQuery(domain, query).then(onResult, onError)));
|
|
15690
15835
|
return p;
|
|
15691
15836
|
|
|
@@ -15887,6 +16032,7 @@ function requireNewTransaction () {
|
|
|
15887
16032
|
rdb.aggregateCount = 0;
|
|
15888
16033
|
rdb.quote = quote;
|
|
15889
16034
|
rdb.cache = {};
|
|
16035
|
+
rdb.changes = [];
|
|
15890
16036
|
|
|
15891
16037
|
if (readonly) {
|
|
15892
16038
|
rdb.dbClient = {
|
|
@@ -16152,7 +16298,6 @@ function requireNewDatabase () {
|
|
|
16152
16298
|
let hostLocal = requireHostLocal();
|
|
16153
16299
|
let doQuery = requireQuery();
|
|
16154
16300
|
let releaseDbClient = requireReleaseDbClient();
|
|
16155
|
-
let setSessionSingleton = requireSetSessionSingleton();
|
|
16156
16301
|
|
|
16157
16302
|
function newDatabase(connectionString, poolOptions) {
|
|
16158
16303
|
if (!connectionString)
|
|
@@ -16169,10 +16314,9 @@ function requireNewDatabase () {
|
|
|
16169
16314
|
}
|
|
16170
16315
|
let domain = createDomain();
|
|
16171
16316
|
|
|
16172
|
-
if (fn)
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
return domain.run(run);
|
|
16317
|
+
if (!fn)
|
|
16318
|
+
throw new Error('transaction requires a function');
|
|
16319
|
+
return domain.run(runInTransaction);
|
|
16176
16320
|
|
|
16177
16321
|
async function runInTransaction() {
|
|
16178
16322
|
let result;
|
|
@@ -16191,15 +16335,6 @@ function requireNewDatabase () {
|
|
|
16191
16335
|
return _begin(domain, options);
|
|
16192
16336
|
}
|
|
16193
16337
|
|
|
16194
|
-
function run() {
|
|
16195
|
-
let p;
|
|
16196
|
-
let transaction = newTransaction(domain, pool, options);
|
|
16197
|
-
p = new Promise(transaction);
|
|
16198
|
-
|
|
16199
|
-
return p.then(begin)
|
|
16200
|
-
.then(negotiateSchema);
|
|
16201
|
-
}
|
|
16202
|
-
|
|
16203
16338
|
function negotiateSchema(previous) {
|
|
16204
16339
|
let schema = options && options.schema;
|
|
16205
16340
|
if (!schema)
|
|
@@ -16239,7 +16374,6 @@ function requireNewDatabase () {
|
|
|
16239
16374
|
let domain = createDomain();
|
|
16240
16375
|
let transaction = newTransaction(domain, pool);
|
|
16241
16376
|
let p = domain.run(() => new Promise(transaction)
|
|
16242
|
-
.then(() => setSessionSingleton(domain, 'changes', []))
|
|
16243
16377
|
.then(() => doQuery(domain, query).then(onResult, onError)));
|
|
16244
16378
|
return p;
|
|
16245
16379
|
|