multi-db-orm 1.3.2 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/launch.json +13 -0
- package/README.md +21 -0
- package/databases.js +3 -2
- package/engines/multidb.js +5 -1
- package/engines/oracledb.js +232 -0
- package/index.js +2 -1
- package/package.json +8 -4
- package/postinstall.js +9 -0
- package/test/test.js +69 -3
package/.vscode/launch.json
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
5
|
"version": "0.2.0",
|
|
6
6
|
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Launch via NPM",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"runtimeArgs": [
|
|
11
|
+
"run-script",
|
|
12
|
+
"test"
|
|
13
|
+
],
|
|
14
|
+
"runtimeExecutable": "npm",
|
|
15
|
+
"skipFiles": [
|
|
16
|
+
"<node_internals>/**"
|
|
17
|
+
],
|
|
18
|
+
"type": "node"
|
|
19
|
+
},
|
|
7
20
|
{
|
|
8
21
|
"type": "node",
|
|
9
22
|
"request": "launch",
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Supported databases:
|
|
|
9
9
|
1. MongoDB
|
|
10
10
|
2. Google Firestore
|
|
11
11
|
3. SQlite3
|
|
12
|
+
4. Oracle
|
|
12
13
|
|
|
13
14
|
### Install
|
|
14
15
|
The package is available on npm
|
|
@@ -17,6 +18,15 @@ npm install multi-db-orm
|
|
|
17
18
|
`
|
|
18
19
|
|
|
19
20
|
### Initialize
|
|
21
|
+
Install the target optional database dependencies based on your usage
|
|
22
|
+
```
|
|
23
|
+
npm install --save mongodb
|
|
24
|
+
npm install --save firebase-admin
|
|
25
|
+
npm install --save sqlite3
|
|
26
|
+
npm install --save oracledb oracle-instantclient
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Configure the database
|
|
20
30
|
```
|
|
21
31
|
const { MultiDbORM, FireStoreDB, MongoDB, SQLiteDB, Sync } = require("multi-db-orm");
|
|
22
32
|
|
|
@@ -32,6 +42,17 @@ var sqlitedb = new SQLiteDB("/path/to/mydatabase.db"); // if no path is passed ,
|
|
|
32
42
|
// MongoDB
|
|
33
43
|
var mongodb = new MongoDB("mongodb+srv://username:PassW0rd@host.server.net/my_db_name","my_db_name");
|
|
34
44
|
|
|
45
|
+
// OracleDB
|
|
46
|
+
// Download client credentials (Wallet) and extract to /path/to/your/extracted/wallet-dir
|
|
47
|
+
// Oracle field names are case insensetive, Always name your fields in snake case
|
|
48
|
+
var oracledb = new OracleDB({
|
|
49
|
+
username: 'your-username',
|
|
50
|
+
password: 'your-password',
|
|
51
|
+
wallet_dir: '/path/to/your/extracted/wallet-dir',
|
|
52
|
+
net_service_name: 'connstring-high', //get any one from tnsnames.ora
|
|
53
|
+
connection_pool_name:'your-conn-pool-name' //optional
|
|
54
|
+
});
|
|
55
|
+
|
|
35
56
|
var db = firebasedb;
|
|
36
57
|
```
|
|
37
58
|
|
package/databases.js
CHANGED
|
@@ -2,11 +2,12 @@ const { MultiDbORM } = require("./engines/multidb");
|
|
|
2
2
|
const { FireStoreDB } = require("./engines/firestoredb");
|
|
3
3
|
const { MongoDB } = require("./engines/mongodb");
|
|
4
4
|
const { SQLiteDB } = require("./engines/sqlitedb");
|
|
5
|
-
|
|
5
|
+
const { OracleDB } = require('./engines/oracledb')
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
MultiDbORM,
|
|
9
9
|
FireStoreDB,
|
|
10
10
|
MongoDB,
|
|
11
|
-
SQLiteDB
|
|
11
|
+
SQLiteDB,
|
|
12
|
+
OracleDB
|
|
12
13
|
}
|
package/engines/multidb.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {Sync} = require('../sync')
|
|
1
|
+
const { Sync } = require('../sync')
|
|
2
2
|
const { Metrics } = require('./metrics')
|
|
3
3
|
class MultiDbORM {
|
|
4
4
|
|
|
@@ -16,6 +16,10 @@ class MultiDbORM {
|
|
|
16
16
|
this.metrics = new Metrics(this.loglevel)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
async connect() {
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
setdb(db) {
|
|
20
24
|
this.reqMade = 0
|
|
21
25
|
this.db = db;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { MultiDbORM } = require("./multidb");
|
|
3
|
+
var fs = require('fs')
|
|
4
|
+
|
|
5
|
+
class OracleDB extends MultiDbORM {
|
|
6
|
+
|
|
7
|
+
connection_pool_name
|
|
8
|
+
schema
|
|
9
|
+
pool_creation
|
|
10
|
+
dataMap = {
|
|
11
|
+
"id": "VARCHAR(50) NOT NULL PRIMARY KEY",
|
|
12
|
+
"string": "VARCHAR2(4000)",
|
|
13
|
+
"number": "NUMBER",
|
|
14
|
+
"boolean": "VARCHAR(5)",
|
|
15
|
+
"array": "CLOB",
|
|
16
|
+
"object": "CLOB",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
static async initOracleLibraries() {
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
constructor({
|
|
25
|
+
username,
|
|
26
|
+
password,
|
|
27
|
+
net_service_name,
|
|
28
|
+
wallet_dir,
|
|
29
|
+
connection_pool_name }) {
|
|
30
|
+
super()
|
|
31
|
+
const oracledb = require('oracledb')
|
|
32
|
+
const oracleInstantClient = require("oracle-instantclient");
|
|
33
|
+
|
|
34
|
+
process.env.LD_LIBRARY_PATH = oracleInstantClient.path
|
|
35
|
+
process.env.TS_ADMIN = wallet_dir
|
|
36
|
+
oracledb.initOracleClient()
|
|
37
|
+
oracledb.autoCommit = true;
|
|
38
|
+
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT
|
|
39
|
+
oracledb.fetchAsString = [oracledb.CLOB];
|
|
40
|
+
|
|
41
|
+
this.connection_pool_name = connection_pool_name || username
|
|
42
|
+
this.db = oracledb
|
|
43
|
+
this.schema = username
|
|
44
|
+
this.pool_creation = oracledb.createPool({
|
|
45
|
+
user: username,
|
|
46
|
+
password: password,
|
|
47
|
+
configDir: wallet_dir,
|
|
48
|
+
connectString: net_service_name,
|
|
49
|
+
poolAlias: this.connection_pool_name
|
|
50
|
+
}).then(async (pool) => {
|
|
51
|
+
console.log(`OracleDB Initialized`);
|
|
52
|
+
}).catch(e => {
|
|
53
|
+
console.log("Error initializing oracle DB: " + e.message)
|
|
54
|
+
throw e
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
this.dbType = 'oracle'
|
|
58
|
+
this.reqMade = 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async connect() {
|
|
62
|
+
await this.pool_creation
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async run(query) {
|
|
66
|
+
let connection
|
|
67
|
+
var that = this
|
|
68
|
+
this.reqMade++
|
|
69
|
+
return new Promise(async function (resolve, reject) {
|
|
70
|
+
try {
|
|
71
|
+
connection = await that.db.getConnection(that.connection_pool_name);
|
|
72
|
+
let resp = await connection.execute(query)
|
|
73
|
+
resolve(resp);
|
|
74
|
+
if (that.loglevel > 3)
|
|
75
|
+
console.log("Query ", query, ' -> ', resp)
|
|
76
|
+
|
|
77
|
+
} catch (err) {
|
|
78
|
+
reject(err)
|
|
79
|
+
} finally {
|
|
80
|
+
if (connection) {
|
|
81
|
+
try {
|
|
82
|
+
await connection.close();
|
|
83
|
+
} catch (err) {
|
|
84
|
+
throw (err);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async get(modelname, filter, options) {
|
|
94
|
+
this.metrics.get(modelname, filter, options)
|
|
95
|
+
var where = ''
|
|
96
|
+
for (var key in filter) {
|
|
97
|
+
where = where + `"${key}" = '${filter[key]}' AND `
|
|
98
|
+
}
|
|
99
|
+
where = where + " 1 = 1 ";
|
|
100
|
+
var sort = "";
|
|
101
|
+
if (options) {
|
|
102
|
+
if (options.apply) {
|
|
103
|
+
if (options.apply.ineq) {
|
|
104
|
+
where = where + ` AND "${options.apply.field}" ${options.apply.ineq.op} '${options.apply.ineq.value}'`;
|
|
105
|
+
}
|
|
106
|
+
if (options.apply.sort) {
|
|
107
|
+
sort = `ORDER BY "${options.apply.field}" ${options.apply.sort}`
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (options.sort) {
|
|
111
|
+
sort = `ORDER BY`
|
|
112
|
+
for (let i = 0; i < options.sort.length; i++) {
|
|
113
|
+
sort = sort + ` "${options.sort[i].field}" ${options.sort[i].order}`;
|
|
114
|
+
if (i < options.sort.length - 1) {
|
|
115
|
+
sort = sort + ' , ';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
var query = `SELECT * FROM ${modelname} WHERE ${where} ${sort} `
|
|
122
|
+
var row = await this.run(query)
|
|
123
|
+
|
|
124
|
+
return row.rows
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async getOne(modelname, filter) {
|
|
128
|
+
this.metrics.getOne(modelname, filter)
|
|
129
|
+
var where = ''
|
|
130
|
+
for (var key in filter) {
|
|
131
|
+
where = where + `"${key}" = '${filter[key]}' AND `
|
|
132
|
+
}
|
|
133
|
+
where = where + " 1 = 1 ";
|
|
134
|
+
var query = `SELECT * FROM ${modelname} WHERE ${where} AND rownum < 2`
|
|
135
|
+
var row = await this.run(query)
|
|
136
|
+
return row.rows[0];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async create(modelname, sampleObject) {
|
|
140
|
+
this.sync.create(modelname, sampleObject)
|
|
141
|
+
this.metrics.create(modelname, sampleObject)
|
|
142
|
+
|
|
143
|
+
var cols = ''
|
|
144
|
+
for (var key in sampleObject) {
|
|
145
|
+
var type = this.dataMap[typeof (sampleObject[key])] || 'VARCHAR(4000)'
|
|
146
|
+
if (Array.isArray(sampleObject[key])) {
|
|
147
|
+
type = this.dataMap['array']
|
|
148
|
+
}
|
|
149
|
+
if (key == 'id') {
|
|
150
|
+
type = this.dataMap['id']
|
|
151
|
+
}
|
|
152
|
+
cols = cols + `"${key}" ${type}, `
|
|
153
|
+
}
|
|
154
|
+
cols = cols.substring(0, cols.length - 2)
|
|
155
|
+
var query = `CREATE TABLE ${modelname} (${cols})`
|
|
156
|
+
try {
|
|
157
|
+
return await this.run(query)
|
|
158
|
+
} catch (err) {
|
|
159
|
+
if (!err.message.indexOf("name is already used")) {
|
|
160
|
+
console.log(err)
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async insert(modelname, object) {
|
|
167
|
+
this.sync.insert(modelname, object)
|
|
168
|
+
this.metrics.insert(modelname, object)
|
|
169
|
+
var cols = ''
|
|
170
|
+
var vals = ''
|
|
171
|
+
for (var key in object) {
|
|
172
|
+
cols = cols + `"${key}",`
|
|
173
|
+
let value = object[key]
|
|
174
|
+
if (typeof value == 'object')
|
|
175
|
+
value = JSON.stringify(value)
|
|
176
|
+
vals = vals + `'${value}',`
|
|
177
|
+
}
|
|
178
|
+
cols = cols.substring(0, cols.length - 1)
|
|
179
|
+
vals = vals.substring(0, vals.length - 1)
|
|
180
|
+
|
|
181
|
+
var query = `INSERT INTO ${modelname} (${cols}) VALUES(${vals})`
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
return await this.run(query)
|
|
185
|
+
} catch (err) {
|
|
186
|
+
if (err.message && err.message.indexOf('SQLITE_ERROR: no such table: ') > -1) {
|
|
187
|
+
await this.create(modelname, object);
|
|
188
|
+
return await this.run(query)
|
|
189
|
+
}
|
|
190
|
+
else
|
|
191
|
+
throw err;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async update(modelname, filter, object) {
|
|
196
|
+
this.sync.update(modelname, filter, object)
|
|
197
|
+
this.metrics.update(modelname, filter, object)
|
|
198
|
+
|
|
199
|
+
var where = ''
|
|
200
|
+
var vals = ''
|
|
201
|
+
for (var key in filter) {
|
|
202
|
+
where = where + `"${key}" = '${filter[key]}' AND `
|
|
203
|
+
}
|
|
204
|
+
for (var key in object) {
|
|
205
|
+
vals = vals + ` "${key}" = '${object[key]}',`
|
|
206
|
+
}
|
|
207
|
+
where = where + " 1 = 1";
|
|
208
|
+
vals = vals.substring(0, vals.length - 1)
|
|
209
|
+
|
|
210
|
+
var query = `UPDATE ${modelname} SET ${vals} WHERE ${where}`
|
|
211
|
+
return await this.run(query)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async delete(modelname, filter) {
|
|
215
|
+
this.sync.delete(modelname, filter)
|
|
216
|
+
this.metrics.delete(modelname, filter)
|
|
217
|
+
|
|
218
|
+
var where = ''
|
|
219
|
+
for (var key in filter) {
|
|
220
|
+
where = where + `"${key}" = '${filter[key]}' AND `
|
|
221
|
+
}
|
|
222
|
+
where = where + " 1 = 1";
|
|
223
|
+
var query = `DELETE FROM ${modelname} WHERE ${where}`
|
|
224
|
+
return await this.run(query)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
module.exports = {
|
|
231
|
+
OracleDB
|
|
232
|
+
}
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { MultiDBSafe,FireStoreDB,MongoDB,SQLiteDB } = require("./databases");
|
|
1
|
+
const { MultiDBSafe, FireStoreDB, MongoDB, SQLiteDB, OracleDB } = require("./databases");
|
|
2
2
|
const { Sync } = require("./sync");
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
@@ -6,5 +6,6 @@ module.exports = {
|
|
|
6
6
|
FireStoreDB,
|
|
7
7
|
MongoDB,
|
|
8
8
|
SQLiteDB,
|
|
9
|
+
OracleDB,
|
|
9
10
|
Sync
|
|
10
11
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-db-orm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "CRUD , Backup , Restore and Migration library for multiple databases",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"firebase-admin": "^9.3.0",
|
|
8
7
|
"fs": "0.0.1-security",
|
|
8
|
+
"node-firestore-import-export": "^1.1.0"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"firebase-admin": "^9.3.0",
|
|
9
12
|
"mongodb": "^3.6.3",
|
|
10
|
-
"
|
|
13
|
+
"oracle-instantclient": "^1.0.1",
|
|
14
|
+
"oracledb": "^6.1.0",
|
|
11
15
|
"sqlite3": "^5.0.0"
|
|
12
16
|
},
|
|
13
|
-
"devDependencies": {},
|
|
14
17
|
"scripts": {
|
|
18
|
+
"postinstall": "node postinstall.js",
|
|
15
19
|
"test": "node test/test.js"
|
|
16
20
|
},
|
|
17
21
|
"repository": {
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
console.log(`
|
|
2
|
+
!!!!! MULTI DB ORM !!!
|
|
3
|
+
!!!!! Make sure to install one of the target dependencies !!!!
|
|
4
|
+
npm install --save mongodb
|
|
5
|
+
npm install --save firebase-admin
|
|
6
|
+
npm install --save sqlite3
|
|
7
|
+
npm install --save oracledb oracle-instantclient
|
|
8
|
+
!!!!! MULTI DB ORM !!!
|
|
9
|
+
`)
|
package/test/test.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const { Game } = require("./models");
|
|
2
|
-
const { MultiDBSafe, FireStoreDB, MongoDB, SQLiteDB, Sync } = require("../index");
|
|
2
|
+
const { MultiDBSafe, FireStoreDB, MongoDB, SQLiteDB, Sync, OracleDB } = require("../index");
|
|
3
|
+
const path = require('path')
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
var testCount = 3
|
|
@@ -181,6 +183,70 @@ async function testMongo() {
|
|
|
181
183
|
|
|
182
184
|
}
|
|
183
185
|
|
|
184
|
-
|
|
186
|
+
|
|
187
|
+
async function testOracleDb() {
|
|
188
|
+
var oracledb = new OracleDB(require('../creds/oracle/creds.json'));
|
|
189
|
+
console.log(oracledb.metrics.getStatus())
|
|
190
|
+
var gm = new Game('IndVSPak', Date.now(), 'Dhoni', 67.33, 'paid')
|
|
191
|
+
gm.completed = true
|
|
192
|
+
gm.runs = ['a', 'b']
|
|
193
|
+
gm.extras = {
|
|
194
|
+
location: 'India',
|
|
195
|
+
raining: false,
|
|
196
|
+
match: 1
|
|
197
|
+
}
|
|
198
|
+
oracledb.loglevel = 1
|
|
199
|
+
await oracledb.connect()
|
|
200
|
+
var res = await oracledb.create('games', gm);
|
|
201
|
+
gm.id = Date.now()
|
|
202
|
+
res = await oracledb.insert('games', gm);
|
|
203
|
+
gm.id = Date.now()
|
|
204
|
+
|
|
205
|
+
res = await oracledb.insert('games', gm);
|
|
206
|
+
gm.amount = 1
|
|
207
|
+
gm.id = Date.now()
|
|
208
|
+
|
|
209
|
+
res = await oracledb.insert('games', gm);
|
|
210
|
+
res = await oracledb.get('games', { amount: 1 });
|
|
211
|
+
res = await oracledb.getOne('games', { amount: 1 });
|
|
212
|
+
res = await oracledb.update('games', { amount: 1 }, { userid: 'xxxx' });
|
|
213
|
+
res = await oracledb.getOne('games', { userid: 'xxxx' });
|
|
214
|
+
|
|
215
|
+
res = await oracledb.insert('games', new Game('IndVSPak1', Date.now(), 'Dhoni', 100, 'free'));
|
|
216
|
+
|
|
217
|
+
res = await oracledb.insert('games', new Game('IndVSPak2', Date.now(), 'Dhoni', 200, 'free'));
|
|
218
|
+
|
|
219
|
+
res = await oracledb.insert('games', new Game('IndVSPak3', Date.now(), 'Dhoni', 300, 'paid'));
|
|
220
|
+
|
|
221
|
+
res = await oracledb.insert('games', new Game('IndVSPak4', Date.now(), 'Dhoni', 400, 'paid'));
|
|
222
|
+
|
|
223
|
+
res = await oracledb.get('games', undefined, { sort: [{ field: 'timeStamp', order: 'asc' }, { field: 'amount', order: 'asc' }], limit: 5, offset: 1 })
|
|
224
|
+
|
|
225
|
+
res = await oracledb.get('games', { type: 'paid' }, { sort: [{ field: 'amount', order: 'desc' }, { field: 'timeStamp', order: 'desc' }] })
|
|
226
|
+
|
|
227
|
+
res = await oracledb.get('games', { amount: 400 }, {
|
|
228
|
+
apply: {
|
|
229
|
+
field: 'timeStamp',
|
|
230
|
+
sort: 'desc',
|
|
231
|
+
ineq: {
|
|
232
|
+
op: '>=',
|
|
233
|
+
value: 1
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
sort: [{ field: 'amount', order: 'asc' }, { field: 'timeStamp', order: 'desc' }],
|
|
237
|
+
limit: 2, offset: 1
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
res = await oracledb.delete('games', { id: 'IndVSPak1' });
|
|
241
|
+
res = await oracledb.getOne('games', { id: 'IndVSPak1' });
|
|
242
|
+
|
|
243
|
+
console.log('SQLite DB Tests Successfull')
|
|
244
|
+
console.log(oracledb.metrics.getStatus())
|
|
245
|
+
checkTestsCompleted();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
// testSqlite();
|
|
185
250
|
// testFireStore();
|
|
186
|
-
// testMongo();
|
|
251
|
+
// testMongo();
|
|
252
|
+
// testOracleDb()
|