orange-orm 4.6.0 → 4.7.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 +24 -15
- package/dist/index.browser.mjs +22 -6
- package/dist/index.mjs +667 -216
- package/package.json +9 -4
- package/src/bunPg/newTransaction.js +0 -2
- package/src/client/clientMap.js +2 -0
- package/src/client/createProviders.js +8 -0
- package/src/client/index.js +1 -0
- package/src/client/map.js +1 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +8 -0
- package/src/map.d.ts +3 -0
- package/src/pglite/newDatabase.js +135 -0
- package/src/pglite/newPool.js +19 -0
- package/src/pglite/newTransaction.js +83 -0
- package/src/pglite/pool/end.js +14 -0
- package/src/pglite/pool/newPgPool.js +96 -0
- package/src/pglite/wrapQuery.js +27 -0
- package/src/pglite.d.ts +64 -0
- package/src/table/column/boolean/newEncode.js +7 -3
- package/src/table/column/json/newEncode.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orange-orm",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0-beta.0",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"browser": "./dist/index.browser.mjs",
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"beta": "npm publish --tag beta"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
+
"@cloudflare/workers-types": "^4.20241106.0",
|
|
65
66
|
"@lroal/on-change": "^4.0.2",
|
|
66
67
|
"@tediousjs/connection-string": "^0.4.1",
|
|
67
68
|
"@types/express": "^4.17.13",
|
|
68
|
-
"@cloudflare/workers-types": "^4.20241106.0",
|
|
69
69
|
"@types/oracledb": "^6.0.4",
|
|
70
70
|
"@types/tedious": "^4.0.14",
|
|
71
71
|
"ajv": "^6.10.2",
|
|
@@ -85,7 +85,8 @@
|
|
|
85
85
|
"pg-native": "^3.0.0",
|
|
86
86
|
"pg-query-stream": "^3.3.2",
|
|
87
87
|
"sqlite3": "^5.0.2",
|
|
88
|
-
"tedious": "^15.1.2 || ^16.0.0 || ^18.1.0"
|
|
88
|
+
"tedious": "^15.1.2 || ^16.0.0 || ^18.1.0",
|
|
89
|
+
"@electric-sql/pglite": "^0.3.0"
|
|
89
90
|
},
|
|
90
91
|
"peerDependenciesMeta": {
|
|
91
92
|
"pg": {
|
|
@@ -111,9 +112,13 @@
|
|
|
111
112
|
},
|
|
112
113
|
"oracledb": {
|
|
113
114
|
"optional": true
|
|
115
|
+
},
|
|
116
|
+
"@electric-sql/pglite": {
|
|
117
|
+
"optional": true
|
|
114
118
|
}
|
|
115
119
|
},
|
|
116
|
-
"devDependencies": {
|
|
120
|
+
"devDependencies": {
|
|
121
|
+
"@electric-sql/pglite": "^0.3.0",
|
|
117
122
|
"@miniflare/d1": "^2.14.4",
|
|
118
123
|
"@rollup/plugin-commonjs": "^28.0.2",
|
|
119
124
|
"@rollup/plugin-json": "^6.1.0",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
var wrapQuery = require('./wrapQuery');
|
|
2
2
|
var encodeDate = require('../pg/encodeDate');
|
|
3
|
-
var encodeBoolean = require('../pg/encodeBoolean');
|
|
4
3
|
const encodeBinary = require('../nodeSqlite/encodeBinary');
|
|
5
4
|
const decodeBinary = require('../nodeSqlite/decodeBinary');
|
|
6
5
|
var deleteFromSql = require('../pg/deleteFromSql');
|
|
@@ -20,7 +19,6 @@ function newResolveTransaction(domain, pool, { readonly = false } = {}) {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
rdb.engine = 'pg';
|
|
23
|
-
rdb.encodeBoolean = encodeBoolean;
|
|
24
22
|
rdb.encodeDate = encodeDate;
|
|
25
23
|
rdb.encodeBinary = encodeBinary;
|
|
26
24
|
rdb.decodeBinary = decodeBinary;
|
package/src/client/clientMap.js
CHANGED
|
@@ -32,6 +32,7 @@ function map(index, _fn) {
|
|
|
32
32
|
|
|
33
33
|
dbMap.http = (url) => url;
|
|
34
34
|
dbMap.pg = throwDb;
|
|
35
|
+
dbMap.pglite = throwDb;
|
|
35
36
|
dbMap.postgres = throwDb;
|
|
36
37
|
dbMap.mssql = throwDb;
|
|
37
38
|
dbMap.mssqlNative = throwDb;
|
|
@@ -59,6 +60,7 @@ function map(index, _fn) {
|
|
|
59
60
|
|
|
60
61
|
onFinal.http = (url) => index({ db: url, providers: dbMap });
|
|
61
62
|
onFinal.pg = () => index({ db: throwDb, providers: dbMap });
|
|
63
|
+
onFinal.pglite = () => index({ db: throwDb, providers: dbMap });
|
|
62
64
|
onFinal.postgres = () => index({ db: throwDb, providers: dbMap });
|
|
63
65
|
onFinal.mssql = () => index({ db: throwDb, providers: dbMap });
|
|
64
66
|
onFinal.mssqlNative = () => index({ db: throwDb, providers: dbMap });
|
|
@@ -13,6 +13,11 @@ function createProviders(index) {
|
|
|
13
13
|
return createPool.bind(null, 'pg');
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
|
+
Object.defineProperty(dbMap, 'pglite', {
|
|
17
|
+
get: function() {
|
|
18
|
+
return createPool.bind(null, 'pglite');
|
|
19
|
+
}
|
|
20
|
+
});
|
|
16
21
|
Object.defineProperty(dbMap, 'postgres', {
|
|
17
22
|
get: function() {
|
|
18
23
|
return createPool.bind(null, 'pg');
|
|
@@ -81,6 +86,9 @@ function negotiateCachedPool(fn, providers) {
|
|
|
81
86
|
get pg() {
|
|
82
87
|
return createPool.bind(null, 'pg');
|
|
83
88
|
},
|
|
89
|
+
get pglite() {
|
|
90
|
+
return createPool.bind(null, 'pglite');
|
|
91
|
+
},
|
|
84
92
|
get postgres() {
|
|
85
93
|
return createPool.bind(null, 'pg');
|
|
86
94
|
},
|
package/src/client/index.js
CHANGED
|
@@ -56,6 +56,7 @@ function rdbClient(options = {}) {
|
|
|
56
56
|
client.mssql = onProvider.bind(null, 'mssql');
|
|
57
57
|
client.mssqlNative = onProvider.bind(null, 'mssqlNative');
|
|
58
58
|
client.pg = onProvider.bind(null, 'pg');
|
|
59
|
+
client.pglite = onProvider.bind(null, 'pglite');
|
|
59
60
|
client.postgres = onProvider.bind(null, 'postgres');
|
|
60
61
|
client.d1 = onProvider.bind(null, 'd1');
|
|
61
62
|
client.sqlite = onProvider.bind(null, 'sqlite');
|
package/src/client/map.js
CHANGED
|
@@ -41,6 +41,7 @@ function map(index, context, providers, fn) {
|
|
|
41
41
|
}
|
|
42
42
|
context.map = map.bind(null, index, context, providers);
|
|
43
43
|
context.pg = connect.bind(null, 'pg');
|
|
44
|
+
context.pglite = connect.bind(null, 'pglite');
|
|
44
45
|
context.postgres = connect.bind(null, 'pg');
|
|
45
46
|
context.mssql = connect.bind(null, 'mssql');
|
|
46
47
|
context.mssqlNative = connect.bind(null, 'mssqlNative');
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Options } from './ajv';
|
|
2
|
+
import type { PGliteOptions } from './pglite.d.ts';
|
|
2
3
|
import type { RequestHandler } from 'express';
|
|
3
4
|
import type { D1Database } from '@cloudflare/workers-types';
|
|
4
5
|
import type { ConnectionConfiguration } from 'tedious';
|
|
@@ -13,6 +14,7 @@ declare namespace r {
|
|
|
13
14
|
function end(): Promise<void>;
|
|
14
15
|
function d1(database: D1Database, options?: PoolOptions): Pool;
|
|
15
16
|
function postgres(connectionString: string, options?: PoolOptions): Pool;
|
|
17
|
+
function pglite(config?: PGliteOptions | string | undefined, options?: PoolOptions): Pool;
|
|
16
18
|
function sqlite(connectionString: string, options?: PoolOptions): Pool;
|
|
17
19
|
function sap(connectionString: string, options?: PoolOptions): Pool;
|
|
18
20
|
function mssql(connectionConfig: ConnectionConfiguration, options?: PoolOptions): Pool;
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const runtimes = require('./runtimes');
|
|
|
6
6
|
|
|
7
7
|
let _mySql;
|
|
8
8
|
let _pg;
|
|
9
|
+
let _pglite;
|
|
9
10
|
let _sqlite;
|
|
10
11
|
let _mssqlNative;
|
|
11
12
|
let _sap;
|
|
@@ -54,6 +55,13 @@ Object.defineProperty(connectViaPool, 'mySql', {
|
|
|
54
55
|
return _mySql;
|
|
55
56
|
}
|
|
56
57
|
});
|
|
58
|
+
Object.defineProperty(connectViaPool, 'pglite', {
|
|
59
|
+
get: function() {
|
|
60
|
+
if (!_pglite)
|
|
61
|
+
_pglite = require('./pglite/newDatabase');
|
|
62
|
+
return _pglite;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
57
65
|
Object.defineProperty(connectViaPool, 'postgres', {
|
|
58
66
|
get: function() {
|
|
59
67
|
if (!_pg)
|
package/src/map.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Options } from './ajv';
|
|
2
|
+
import type { PGliteOptions } from './pglite.d.ts';
|
|
2
3
|
import type { ConnectionConfiguration } from 'tedious';
|
|
3
4
|
import type { D1Database } from '@cloudflare/workers-types';
|
|
4
5
|
import type { PoolAttributes } from 'oracledb';
|
|
@@ -32,6 +33,7 @@ type DbConnectable<T> = {
|
|
|
32
33
|
http(url: string): MappedDbInstance<T>;
|
|
33
34
|
d1(database: D1Database): MappedDbInstance<T>;
|
|
34
35
|
postgres(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
|
|
36
|
+
pglite(config?: PGliteOptions| string | undefined, options?: PoolOptions): MappedDbInstance<T>;
|
|
35
37
|
sqlite(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
|
|
36
38
|
sap(connectionString: string, options?: PoolOptions): MappedDbInstance<T>;
|
|
37
39
|
mssql(connectionConfig: ConnectionConfiguration, options?: PoolOptions): MappedDbInstance<T>;
|
|
@@ -63,6 +65,7 @@ interface Connectors {
|
|
|
63
65
|
http(url: string): Pool;
|
|
64
66
|
d1(database: D1Database): Pool;
|
|
65
67
|
postgres(connectionString: string, options?: PoolOptions): Pool;
|
|
68
|
+
pglite(config?: PGliteOptions| string | undefined, options?: PoolOptions): Pool;
|
|
66
69
|
sqlite(connectionString: string, options?: PoolOptions): Pool;
|
|
67
70
|
sap(connectionString: string, options?: PoolOptions): Pool;
|
|
68
71
|
mssql(connectionConfig: ConnectionConfiguration, options?: PoolOptions): Pool;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
let createDomain = require('../createDomain');
|
|
2
|
+
let newTransaction = require('./newTransaction');
|
|
3
|
+
let _begin = require('../table/begin');
|
|
4
|
+
let commit = require('../table/commit');
|
|
5
|
+
let rollback = require('../table/rollback');
|
|
6
|
+
let newPool = require('./newPool');
|
|
7
|
+
let lock = require('../lock');
|
|
8
|
+
let executeSchema = require('../pg/schema');
|
|
9
|
+
let express = require('../hostExpress');
|
|
10
|
+
let hostLocal = require('../hostLocal');
|
|
11
|
+
let doQuery = require('../query');
|
|
12
|
+
let releaseDbClient = require('../table/releaseDbClient');
|
|
13
|
+
let setSessionSingleton = require('../table/setSessionSingleton');
|
|
14
|
+
|
|
15
|
+
function newDatabase(connectionString, poolOptions) {
|
|
16
|
+
var pool;
|
|
17
|
+
if (!poolOptions)
|
|
18
|
+
pool = newPool.bind(null, connectionString, poolOptions);
|
|
19
|
+
else
|
|
20
|
+
pool = newPool(connectionString, poolOptions);
|
|
21
|
+
|
|
22
|
+
let c = { poolFactory: pool, hostLocal, express };
|
|
23
|
+
|
|
24
|
+
c.transaction = function(options, fn) {
|
|
25
|
+
if ((arguments.length === 1) && (typeof options === 'function')) {
|
|
26
|
+
fn = options;
|
|
27
|
+
options = undefined;
|
|
28
|
+
}
|
|
29
|
+
let domain = createDomain();
|
|
30
|
+
|
|
31
|
+
if (fn)
|
|
32
|
+
return domain.run(runInTransaction);
|
|
33
|
+
else
|
|
34
|
+
return domain.run(run);
|
|
35
|
+
|
|
36
|
+
async function runInTransaction() {
|
|
37
|
+
let result;
|
|
38
|
+
let transaction = newTransaction(domain, pool, options);
|
|
39
|
+
await new Promise(transaction)
|
|
40
|
+
.then(begin)
|
|
41
|
+
.then(negotiateSchema)
|
|
42
|
+
.then(() => fn(domain))
|
|
43
|
+
.then((res) => result = res)
|
|
44
|
+
.then(() => commit(domain))
|
|
45
|
+
.then(null, (e) => rollback(domain,e));
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function begin() {
|
|
50
|
+
return _begin(domain, options);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function run() {
|
|
54
|
+
let p;
|
|
55
|
+
let transaction = newTransaction(domain, pool, options);
|
|
56
|
+
p = new Promise(transaction);
|
|
57
|
+
|
|
58
|
+
return p.then(begin)
|
|
59
|
+
.then(negotiateSchema);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function negotiateSchema(previous) {
|
|
63
|
+
let schema = options && options.schema;
|
|
64
|
+
if (!schema)
|
|
65
|
+
return previous;
|
|
66
|
+
return executeSchema(domain, schema);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
c.createTransaction = function(options) {
|
|
71
|
+
let domain = createDomain();
|
|
72
|
+
let transaction = newTransaction(domain, pool, options);
|
|
73
|
+
let p = domain.run(() => new Promise(transaction)
|
|
74
|
+
.then(begin).then(negotiateSchema));
|
|
75
|
+
|
|
76
|
+
function run(fn) {
|
|
77
|
+
return p.then(domain.run.bind(domain, fn));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function begin() {
|
|
81
|
+
return _begin(domain, options);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function negotiateSchema(previous) {
|
|
85
|
+
let schema = options && options.schema;
|
|
86
|
+
if (!schema)
|
|
87
|
+
return previous;
|
|
88
|
+
return executeSchema(domain,schema);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
run.rollback = rollback.bind(null, domain);
|
|
92
|
+
run.commit = commit.bind(null, domain);
|
|
93
|
+
|
|
94
|
+
return run;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
c.query = function(query) {
|
|
98
|
+
let domain = createDomain();
|
|
99
|
+
let transaction = newTransaction(domain, pool);
|
|
100
|
+
let p = domain.run(() => new Promise(transaction)
|
|
101
|
+
.then(() => setSessionSingleton(domain, 'changes', []))
|
|
102
|
+
.then(() => doQuery(domain, query).then(onResult, onError)));
|
|
103
|
+
return p;
|
|
104
|
+
|
|
105
|
+
function onResult(result) {
|
|
106
|
+
releaseDbClient(domain);
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function onError(e) {
|
|
111
|
+
releaseDbClient(domain);
|
|
112
|
+
throw e;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
c.rollback = rollback;
|
|
117
|
+
c.commit = commit;
|
|
118
|
+
c.lock = lock;
|
|
119
|
+
c.schema = executeSchema;
|
|
120
|
+
|
|
121
|
+
c.end = function() {
|
|
122
|
+
if (poolOptions)
|
|
123
|
+
return pool.end();
|
|
124
|
+
else
|
|
125
|
+
return Promise.resolve();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
c.accept = function(caller) {
|
|
129
|
+
caller.visitPg();
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return c;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = newDatabase;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const promisify = require('../promisify');
|
|
2
|
+
const pools = require('../pools');
|
|
3
|
+
const end = require('./pool/end');
|
|
4
|
+
const newPgPool = require('./pool/newPgPool');
|
|
5
|
+
const newId = require('../newId');
|
|
6
|
+
|
|
7
|
+
function newPool(connectionString, poolOptions) {
|
|
8
|
+
let pool = newPgPool(connectionString, poolOptions);
|
|
9
|
+
let id = newId();
|
|
10
|
+
let boundEnd = end.bind(null, pool, id);
|
|
11
|
+
let c = {};
|
|
12
|
+
|
|
13
|
+
c.connect = pool.connect;
|
|
14
|
+
c.end = promisify(boundEnd);
|
|
15
|
+
pools[id] = c;
|
|
16
|
+
return c;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = newPool;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var wrapQuery = require('./wrapQuery');
|
|
2
|
+
var encodeDate = require('../pg/encodeDate');
|
|
3
|
+
const encodeBinary = require('../nodeSqlite/encodeBinary');
|
|
4
|
+
const decodeBinary = require('../nodeSqlite/decodeBinary');
|
|
5
|
+
var deleteFromSql = require('../pg/deleteFromSql');
|
|
6
|
+
var selectForUpdateSql = require('../pg/selectForUpdateSql');
|
|
7
|
+
var limitAndOffset = require('../pg/limitAndOffset');
|
|
8
|
+
var formatDateOut = require('../pg/formatDateOut');
|
|
9
|
+
var insertSql = require('../pg/insertSql');
|
|
10
|
+
var insert = require('../pg/insert');
|
|
11
|
+
var quote = require('../pg/quote');
|
|
12
|
+
|
|
13
|
+
function newResolveTransaction(domain, pool, { readonly = false } = {}) {
|
|
14
|
+
var rdb = { poolFactory: pool };
|
|
15
|
+
if (!pool.connect) {
|
|
16
|
+
pool = pool();
|
|
17
|
+
rdb.pool = pool;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
rdb.engine = 'pg';
|
|
21
|
+
rdb.encodeDate = encodeDate;
|
|
22
|
+
rdb.encodeBinary = encodeBinary;
|
|
23
|
+
rdb.decodeBinary = decodeBinary;
|
|
24
|
+
rdb.formatDateOut = formatDateOut;
|
|
25
|
+
rdb.deleteFromSql = deleteFromSql;
|
|
26
|
+
rdb.selectForUpdateSql = selectForUpdateSql;
|
|
27
|
+
rdb.lastInsertedIsSeparate = false;
|
|
28
|
+
rdb.insertSql = insertSql;
|
|
29
|
+
rdb.insert = insert;
|
|
30
|
+
rdb.multipleStatements = true;
|
|
31
|
+
rdb.limitAndOffset = limitAndOffset;
|
|
32
|
+
rdb.accept = function(caller) {
|
|
33
|
+
caller.visitPg();
|
|
34
|
+
};
|
|
35
|
+
rdb.aggregateCount = 0;
|
|
36
|
+
rdb.quote = quote;
|
|
37
|
+
rdb.cache = {};
|
|
38
|
+
|
|
39
|
+
if (readonly) {
|
|
40
|
+
rdb.dbClient = {
|
|
41
|
+
executeQuery: function(query, callback) {
|
|
42
|
+
pool.connect((err, client, done) => {
|
|
43
|
+
if (err) {
|
|
44
|
+
return callback(err);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
wrapQuery(domain, client)(query, (err, res) => {
|
|
48
|
+
done();
|
|
49
|
+
callback(err, res);
|
|
50
|
+
});
|
|
51
|
+
} catch (e) {
|
|
52
|
+
done();
|
|
53
|
+
callback(e);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
domain.rdb = rdb;
|
|
59
|
+
return (onSuccess) => onSuccess();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return function(onSuccess, onError) {
|
|
63
|
+
pool.connect(onConnected);
|
|
64
|
+
|
|
65
|
+
function onConnected(err, client, done) {
|
|
66
|
+
try {
|
|
67
|
+
if (err) {
|
|
68
|
+
onError(err);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
client.executeQuery = wrapQuery(domain, client);
|
|
72
|
+
rdb.dbClient = client;
|
|
73
|
+
rdb.dbClientDone = done;
|
|
74
|
+
domain.rdb = rdb;
|
|
75
|
+
onSuccess();
|
|
76
|
+
} catch (e) {
|
|
77
|
+
onError(e);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = newResolveTransaction;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* eslint-disable no-prototype-builtins */
|
|
2
|
+
// Simplified pool creator using URL API and handling search_path param
|
|
3
|
+
|
|
4
|
+
const log = require('../../table/log');
|
|
5
|
+
const defaults = require('../../poolDefaults');
|
|
6
|
+
const genericPool = require('../../generic-pool');
|
|
7
|
+
let PGlite;
|
|
8
|
+
|
|
9
|
+
function newPgPool(connectionString, poolOptions = {}) {
|
|
10
|
+
let { connStr, searchPath } = extractSearchPath(connectionString);
|
|
11
|
+
|
|
12
|
+
//@ts-ignore
|
|
13
|
+
const pool = genericPool.Pool({
|
|
14
|
+
max: poolOptions.size || poolOptions.poolSize || defaults.poolSize,
|
|
15
|
+
idleTimeoutMillis: poolOptions.idleTimeout || defaults.poolIdleTimeout,
|
|
16
|
+
reapIntervalMillis: poolOptions.reapIntervalMillis || defaults.reapIntervalMillis,
|
|
17
|
+
log: poolOptions.log,
|
|
18
|
+
|
|
19
|
+
create: async (cb) => {
|
|
20
|
+
try {
|
|
21
|
+
if (!PGlite) ({ PGlite } = await import('@electric-sql/pglite'));
|
|
22
|
+
const client = connStr === undefined ? new PGlite() : new PGlite(connStr);
|
|
23
|
+
client.poolCount = 0;
|
|
24
|
+
await applySearchPath(client, searchPath);
|
|
25
|
+
cb(null, client);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
cb(err, null);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
destroy: (client) => {
|
|
32
|
+
client._destroying = true;
|
|
33
|
+
client.poolCount = undefined;
|
|
34
|
+
client.close();
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
pool.connect = (cb) => {
|
|
39
|
+
pool.acquire((err, client) => {
|
|
40
|
+
if (err) return cb(err, null, () => { });
|
|
41
|
+
client.poolCount++;
|
|
42
|
+
cb(null, client, (releaseErr) => {
|
|
43
|
+
releaseErr ? pool.destroy(client) : pool.release(client);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return pool;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function applySearchPath(client, searchPath) {
|
|
52
|
+
if (searchPath) {
|
|
53
|
+
const sql = `SET search_path TO ${searchPath}`;
|
|
54
|
+
log.emitQuery({ sql, parameters: [] });
|
|
55
|
+
await client.exec(sql);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function extractSearchPath(connectionString) {
|
|
60
|
+
let connStr = connectionString;
|
|
61
|
+
let searchPath;
|
|
62
|
+
|
|
63
|
+
// Guard: nothing to do
|
|
64
|
+
if (typeof connectionString !== 'string' || connectionString.length === 0) {
|
|
65
|
+
return { connStr, searchPath };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Split on the *first* "?" only
|
|
69
|
+
const qPos = connectionString.indexOf('?');
|
|
70
|
+
if (qPos === -1) {
|
|
71
|
+
// No query-string segment
|
|
72
|
+
return { connStr, searchPath };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const pathPart = connectionString.slice(0, qPos);
|
|
76
|
+
const qsPart = connectionString.slice(qPos + 1);
|
|
77
|
+
|
|
78
|
+
// Robust query-string handling via URLSearchParams
|
|
79
|
+
const params = new URLSearchParams(qsPart);
|
|
80
|
+
|
|
81
|
+
const paramName = 'search_path';
|
|
82
|
+
|
|
83
|
+
if (paramName) {
|
|
84
|
+
searchPath = params.get(paramName);
|
|
85
|
+
params.delete(paramName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Re-assemble the cleaned connection string
|
|
89
|
+
const remainingQs = params.toString();
|
|
90
|
+
connStr = remainingQs ? `${pathPart}?${remainingQs}` : pathPart;
|
|
91
|
+
|
|
92
|
+
return { connStr, searchPath };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
module.exports = newPgPool;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var log = require('../table/log');
|
|
2
|
+
var replaceParamChar = require('../pg/replaceParamChar');
|
|
3
|
+
|
|
4
|
+
function wrapQuery(_context, connection) {
|
|
5
|
+
var runOriginalQuery = connection.query;
|
|
6
|
+
return runQuery;
|
|
7
|
+
|
|
8
|
+
function runQuery(query, onCompleted) {
|
|
9
|
+
var params = query.parameters;
|
|
10
|
+
var sql = replaceParamChar(query, params);
|
|
11
|
+
log.emitQuery({sql, parameters: params});
|
|
12
|
+
runOriginalQuery.call(connection, sql, params).then((result) => onInnerCompleted(null, result), (e) => onInnerCompleted(e));
|
|
13
|
+
|
|
14
|
+
function onInnerCompleted(err, result) {
|
|
15
|
+
if (err)
|
|
16
|
+
onCompleted(err);
|
|
17
|
+
else {
|
|
18
|
+
if (Array.isArray(result))
|
|
19
|
+
result = result[result.length-1];
|
|
20
|
+
onCompleted(null, result.rows);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = wrapQuery;
|
package/src/pglite.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* pglite-options.d.ts */
|
|
2
|
+
|
|
3
|
+
/** Log-level for debug output (0 = silent, 5 = most verbose). */
|
|
4
|
+
export type DebugLevel = 0 | 1 | 2 | 3 | 4 | 5;
|
|
5
|
+
|
|
6
|
+
/** Function that converts a textual Postgres value to a JS value. */
|
|
7
|
+
export type Parser = (value: string, typeId?: number) => unknown;
|
|
8
|
+
/** Function that converts a JS value to its Postgres text form. */
|
|
9
|
+
export type Serializer = (value: unknown) => string;
|
|
10
|
+
|
|
11
|
+
/** Per-OID parser override map. */
|
|
12
|
+
export interface ParserOptions {
|
|
13
|
+
[pgType: number]: Parser;
|
|
14
|
+
}
|
|
15
|
+
/** Per-OID serializer override map. */
|
|
16
|
+
export interface SerializerOptions {
|
|
17
|
+
[pgType: number]: Serializer;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Arbitrary extension registry keyed by namespace. */
|
|
21
|
+
export type Extensions = Record<string, unknown>;
|
|
22
|
+
|
|
23
|
+
/** Virtual-filesystem interface (sans `init`). */
|
|
24
|
+
export interface Filesystem {
|
|
25
|
+
syncToFs(relaxedDurability?: boolean): Promise<void>;
|
|
26
|
+
initialSyncFs(): Promise<void>;
|
|
27
|
+
dumpTar(
|
|
28
|
+
dbname: string,
|
|
29
|
+
compression?: 'none' | 'gzip' | 'auto'
|
|
30
|
+
): Promise<File | Blob>;
|
|
31
|
+
closeFs(): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Construction options for a `PGlite` instance. */
|
|
35
|
+
export interface PGliteOptions<
|
|
36
|
+
TExtensions extends Extensions = Extensions
|
|
37
|
+
> {
|
|
38
|
+
/** Directory for database files (e.g. `"idb://mydb"`, `"memory://"`). */
|
|
39
|
+
dataDir?: string;
|
|
40
|
+
/** PostgreSQL user name (defaults to `"postgres"`). */
|
|
41
|
+
username?: string;
|
|
42
|
+
/** Default database name (defaults to `"postgres"`). */
|
|
43
|
+
database?: string;
|
|
44
|
+
/** Custom virtual filesystem implementation. */
|
|
45
|
+
fs?: Filesystem;
|
|
46
|
+
/** Debug verbosity; `0` disables all logging. */
|
|
47
|
+
debug?: DebugLevel;
|
|
48
|
+
/** If `true`, disables `fsync` for faster but less-durable writes. */
|
|
49
|
+
relaxedDurability?: boolean;
|
|
50
|
+
/** Map of extension namespaces → implementations or URLs. */
|
|
51
|
+
extensions?: TExtensions;
|
|
52
|
+
/** Pre-seed the cluster with an existing data directory. */
|
|
53
|
+
loadDataDir?: Blob | File;
|
|
54
|
+
/** Initial WebAssembly memory size in bytes. */
|
|
55
|
+
initialMemory?: number;
|
|
56
|
+
/** Pre-compiled WASM module to reuse instead of fetching the default. */
|
|
57
|
+
wasmModule?: WebAssembly.Module;
|
|
58
|
+
/** Pre-bundled filesystem layer to mount at startup. */
|
|
59
|
+
fsBundle?: Blob | File;
|
|
60
|
+
/** Override parsers per type-OID. */
|
|
61
|
+
parsers?: ParserOptions;
|
|
62
|
+
/** Override serializers per type-OID. */
|
|
63
|
+
serializers?: SerializerOptions;
|
|
64
|
+
}
|
|
@@ -11,7 +11,7 @@ function _new(column) {
|
|
|
11
11
|
return newParam('null');
|
|
12
12
|
return newParam('\'' + column.dbNull + '\'');
|
|
13
13
|
}
|
|
14
|
-
var encodeCore = getSessionSingleton(context, 'encodeBoolean');
|
|
14
|
+
var encodeCore = getSessionSingleton(context, 'encodeBoolean') || encodeDefault;
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
return newParam('?', [encodeCore(value)]);
|
|
@@ -24,14 +24,14 @@ function _new(column) {
|
|
|
24
24
|
return 'null';
|
|
25
25
|
return '\'' + column.dbNull + '\'';
|
|
26
26
|
}
|
|
27
|
-
var encodeCore = getSessionSingleton(context, 'encodeBoolean');
|
|
27
|
+
var encodeCore = getSessionSingleton(context, 'encodeBoolean') || encodeDefault;
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
return encodeCore(value);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
encode.direct = function(context, value) {
|
|
34
|
-
var encodeCore = getSessionSingleton(context, 'encodeBoolean');
|
|
34
|
+
var encodeCore = getSessionSingleton(context, 'encodeBoolean') || encodeDefault;
|
|
35
35
|
|
|
36
36
|
return encodeCore(value);
|
|
37
37
|
};
|
|
@@ -39,4 +39,8 @@ function _new(column) {
|
|
|
39
39
|
return encode;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function encodeDefault(value) {
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
module.exports = _new;
|
|
@@ -11,7 +11,7 @@ function _new(column) {
|
|
|
11
11
|
return newPara('null');
|
|
12
12
|
return newPara('\'' + column.dbNull + '\'');
|
|
13
13
|
}
|
|
14
|
-
var encodeCore = getSessionSingleton(context, 'encodeJSON');
|
|
14
|
+
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
15
15
|
|
|
16
16
|
if (encodeCore) {
|
|
17
17
|
value = encodeCore(value);
|
|
@@ -27,7 +27,7 @@ function _new(column) {
|
|
|
27
27
|
return 'null';
|
|
28
28
|
return '\'' + column.dbNull + '\'';
|
|
29
29
|
}
|
|
30
|
-
var encodeCore = getSessionSingleton(context, 'encodeJSON');
|
|
30
|
+
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
31
31
|
|
|
32
32
|
if (encodeCore) {
|
|
33
33
|
value = encodeCore(value);
|
|
@@ -36,7 +36,7 @@ function _new(column) {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
encode.direct = function(context, value) {
|
|
39
|
-
var encodeCore = getSessionSingleton(context, 'encodeJSON');
|
|
39
|
+
var encodeCore = getSessionSingleton(context, 'encodeJSON') || ((v) => v);
|
|
40
40
|
|
|
41
41
|
if (encodeCore) {
|
|
42
42
|
value = encodeCore(value);
|