Skip to content

Commit 2bb749a

Browse files
author
Lars-Erik Roald
committed
dynamic import
1 parent d2e4460 commit 2bb749a

36 files changed

+980
-51
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ The ultimate Object Relational Mapper for Node.js and Typescript, offering seaml
2323
- **Works in the Browser**: You can securely use Orange in the browser by utilizing the Express.js plugin, which serves to safeguard sensitive database credentials from exposure at the client level and protect against SQL injection. This method mirrors a traditional REST API, augmented with advanced TypeScript tooling for enhanced functionality.
2424

2525
## Supported Databases and Runtimes
26-
| | Node | Deno | Bun |
27-
| ------------- | :-----: | :-----: | :-----: |
28-
| Postgres ||||
29-
| MS SQL || ||
30-
| MySQL ||||
31-
| Oracle ||||
32-
| SAP ASE || | |
33-
| SQLite ||||
34-
| Cloudflare D1 | | | |
26+
| | Node | Deno | Bun |Cloudflare |
27+
| ------------- | :-----: | :-----: | :-----: | :-----: |
28+
| Postgres | ✅ | ✅ | ✅ |
29+
| MS SQL || ||
30+
| MySQL ||||
31+
| Oracle ||||
32+
| SAP ASE || | |
33+
| SQLite ||||
34+
| Cloudflare D1 | | | |
3535

3636

3737
✅ Postgres

src/bunSqlite/newPool.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const promisify = require('../promisify');
2+
const pools = require('../pools');
3+
const end = require('../sqlite/pool/end');
4+
const newGenericPool = require('./pool/newGenericPool');
5+
const newId = require('../newId');
6+
7+
function newPool(connectionString, poolOptions) {
8+
let pool = newGenericPool(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;

src/bunSqlite/newTransaction.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const wrapQuery = require('./wrapQuery');
2+
const encodeBoolean = require('../sqlite/encodeBoolean');
3+
const deleteFromSql = require('../sqlite/deleteFromSql');
4+
const selectForUpdateSql = require('../sqlite/selectForUpdateSql');
5+
const lastInsertedSql = require('../sqlite/lastInsertedSql');
6+
const limitAndOffset = require('../sqlite/limitAndOffset');
7+
const insertSql = require('../sqlite/insertSql');
8+
const insert = require('../sqlite/insert');
9+
const quote = require('../sqlite/quote');
10+
11+
function newResolveTransaction(domain, pool, { readonly = false } = {}) {
12+
var rdb = {poolFactory: pool};
13+
if (!pool.connect) {
14+
pool = pool();
15+
rdb.pool = pool;
16+
}
17+
rdb.engine = 'sqlite';
18+
rdb.encodeBoolean = encodeBoolean;
19+
rdb.decodeJSON = decodeJSON;
20+
rdb.encodeJSON = JSON.stringify;
21+
rdb.deleteFromSql = deleteFromSql;
22+
rdb.selectForUpdateSql = selectForUpdateSql;
23+
rdb.lastInsertedSql = lastInsertedSql;
24+
rdb.insertSql = insertSql;
25+
rdb.insert = insert;
26+
rdb.lastInsertedIsSeparate = true;
27+
rdb.multipleStatements = false;
28+
rdb.limitAndOffset = limitAndOffset;
29+
rdb.accept = function(caller) {
30+
caller.visitSqlite();
31+
};
32+
rdb.aggregateCount = 0;
33+
rdb.quote = quote;
34+
35+
if (readonly) {
36+
rdb.dbClient = {
37+
executeQuery: function(query, callback) {
38+
pool.connect((err, client, done) => {
39+
if (err) {
40+
return callback(err);
41+
}
42+
try {
43+
wrapQuery(client)(query, (err, res) => {
44+
done();
45+
callback(err, res);
46+
});
47+
} catch (e) {
48+
done();
49+
callback(e);
50+
}
51+
});
52+
}
53+
};
54+
domain.rdb = rdb;
55+
return (onSuccess) => onSuccess();
56+
}
57+
58+
return function(onSuccess, onError) {
59+
pool.connect(onConnected);
60+
61+
function onConnected(err, client, done) {
62+
try {
63+
if (err) {
64+
onError(err);
65+
return;
66+
}
67+
client.executeQuery = wrapQuery(client);
68+
rdb.dbClient = client;
69+
rdb.dbClientDone = done;
70+
domain.rdb = rdb;
71+
onSuccess();
72+
} catch (e) {
73+
onError(e);
74+
}
75+
}
76+
};
77+
}
78+
79+
function decodeJSON(value) {
80+
return JSON.parse(value);
81+
}
82+
83+
module.exports = newResolveTransaction;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* eslint-disable no-prototype-builtins */
2+
var defaults = require('../../poolDefaults');
3+
4+
var genericPool = require('../../generic-pool');
5+
var sqlite;
6+
7+
function newGenericPool(connectionString, poolOptions) {
8+
poolOptions = poolOptions || {};
9+
var pool = genericPool.Pool({
10+
max: poolOptions.size || poolOptions.poolSize || defaults.poolSize,
11+
idleTimeoutMillis: poolOptions.idleTimeout || defaults.poolIdleTimeout,
12+
reapIntervalMillis: poolOptions.reapIntervalMillis || defaults.reapIntervalMillis,
13+
log: poolOptions.log || defaults.poolLog,
14+
create: async function(cb) {
15+
try {
16+
try {
17+
if (!sqlite)
18+
sqlite = await import('bun:sqlite');
19+
}
20+
catch (err) {
21+
return cb(err, null);
22+
}
23+
24+
var client = new sqlite.DatabaseSync(connectionString);
25+
client.poolCount = 0;
26+
cb(null, client);
27+
}
28+
catch(err) {
29+
return cb(err, null);
30+
}
31+
},
32+
33+
destroy: function(client) {
34+
client.poolCount = undefined;
35+
client.close();
36+
}
37+
});
38+
//monkey-patch with connect method
39+
pool.connect = function(cb) {
40+
pool.acquire(function(err, client) {
41+
if(err) return cb(err, null, function() {/*NOOP*/});
42+
client.poolCount++;
43+
cb(null, client, function(err) {
44+
if(err) {
45+
pool.destroy(client);
46+
} else {
47+
pool.release(client);
48+
}
49+
});
50+
});
51+
};
52+
return pool;
53+
}
54+
55+
module.exports = newGenericPool;

src/bunSqlite/wrapQuery.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var log = require('../table/log');
2+
3+
function wrapQuery(connection) {
4+
return runQuery;
5+
6+
function runQuery(query, onCompleted) {
7+
try {
8+
var params = query.parameters;
9+
var sql = query.sql();
10+
log.emitQuery({ sql, parameters: params });
11+
12+
var statement = connection.prepare(sql);
13+
const rows = statement.all.apply(statement, params);
14+
onCompleted(null, rows);
15+
}
16+
catch (e) {
17+
onCompleted(e);
18+
}
19+
}
20+
21+
}
22+
23+
module.exports = wrapQuery;

src/index.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const hostExpress = require('./hostExpress');
22
const hostLocal = require('./hostLocal');
33
const client = require('./client/index.js');
44
const map = require('./client/map');
5+
const runtimes = require('./runtimes');
6+
57
let _mySql;
68
let _pg;
79
let _sqlite;
@@ -70,8 +72,16 @@ Object.defineProperty(connectViaPool, 'pg', {
7072

7173
Object.defineProperty(connectViaPool, 'sqlite', {
7274
get: function() {
73-
if (!_sqlite)
74-
_sqlite = require('./sqlite/newDatabase');
75+
if (!_sqlite) {
76+
if (runtimes.deno || (runtimes.node && runtimes.node.major >= 22))
77+
_sqlite = require('./nodeSqlite/newDatabase');
78+
else if (runtimes.deno)
79+
_sqlite = require('./denoSqlite');
80+
else if (runtimes.node)
81+
_sqlite = require('./sqlite3/newDatabase');
82+
else
83+
throw new Error('SQLite is not supported in this environment');
84+
}
7585
return _sqlite;
7686
}
7787
});

src/mssql/pool/newGenericPool.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
var defaults = require('../../poolDefaults');
55
var genericPool = require('../../generic-pool');
6-
var mssql = require('msnodesqlv8');
6+
var mssql;
77

88
function newGenericPool(connectionString, poolOptions) {
99
poolOptions = poolOptions || {};
@@ -12,7 +12,14 @@ function newGenericPool(connectionString, poolOptions) {
1212
idleTimeoutMillis: poolOptions.idleTimeout || defaults.poolIdleTimeout,
1313
reapIntervalMillis: poolOptions.reapIntervalMillis || defaults.reapIntervalMillis,
1414
log: poolOptions.log || defaults.poolLog,
15-
create: function(cb) {
15+
create: async function(cb) {
16+
try {
17+
if (!mssql)
18+
mssql = await import('msnodesqlv8');
19+
}
20+
catch (err) {
21+
return cb(err, null);
22+
}
1623
var client;
1724
mssql.open(connectionString, onConnected);
1825

src/mySql/pool/newGenericPool.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* eslint-disable no-prototype-builtins */
33
var defaults = require('../../poolDefaults');
44
var genericPool = require('../../generic-pool');
5-
var mysql = require('mysql2');
5+
var mysql;
66

77
function newGenericPool(connectionString, poolOptions) {
88
if (typeof connectionString === 'string')
@@ -15,7 +15,16 @@ function newGenericPool(connectionString, poolOptions) {
1515
idleTimeoutMillis: poolOptions.idleTimeout || defaults.poolIdleTimeout,
1616
reapIntervalMillis: poolOptions.reapIntervalMillis || defaults.reapIntervalMillis,
1717
log: poolOptions.log,
18-
create: function(cb) {
18+
create: async function(cb) {
19+
try {
20+
if(!mysql) {
21+
mysql = await import('mysql2');
22+
mysql = mysql.default || mysql;
23+
}
24+
}
25+
catch(err) {
26+
return cb(err, null);
27+
}
1928
var innerPool = mysql.createPool(connectionString);
2029
return cb(null, innerPool);
2130
// innerPool.getConnection(onConnected);

0 commit comments

Comments
 (0)