multi-db-orm 1.3.1 → 2.0.1

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.
@@ -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
@@ -17,6 +17,15 @@ npm install multi-db-orm
17
17
  `
18
18
 
19
19
  ### Initialize
20
+ Install the target optional database dependencies based on your usage
21
+ ```
22
+ npm install --save mongodb
23
+ npm install --save firebase-admin
24
+ npm install --save sqlite3
25
+ npm install --save oracledb oracle-instantclient
26
+ ```
27
+
28
+ Configure the database
20
29
  ```
21
30
  const { MultiDbORM, FireStoreDB, MongoDB, SQLiteDB, Sync } = require("multi-db-orm");
22
31
 
@@ -24,7 +33,7 @@ const { MultiDbORM, FireStoreDB, MongoDB, SQLiteDB, Sync } = require("multi-db-o
24
33
 
25
34
  // Firestore
26
35
  var firebasedb = new FireStoreDB(require("/path/to/serviceAccountFile.json"));
27
- Note: If you use firebase DB then keys with undefined values will be removed while insert or update
36
+ Note: If you use firebase DB then keys with undefined values will be set to null while insert or update as firebase dosent support undefined values
28
37
 
29
38
  // Sqlite
30
39
  var sqlitedb = new SQLiteDB("/path/to/mydatabase.db"); // if no path is passed , an in-memory db is used
@@ -32,6 +41,17 @@ var sqlitedb = new SQLiteDB("/path/to/mydatabase.db"); // if no path is passed ,
32
41
  // MongoDB
33
42
  var mongodb = new MongoDB("mongodb+srv://username:PassW0rd@host.server.net/my_db_name","my_db_name");
34
43
 
44
+ // OracleDB
45
+ // Download client credentials (Wallet) and extract to /path/to/your/extracted/wallet-dir
46
+ // Oracle field names are case insensetive, Always name your fields in snake case
47
+ var oracledb = new OracleDB({
48
+ username: 'your-username',
49
+ password: 'your-password',
50
+ wallet_dir: '/path/to/your/extracted/wallet-dir',
51
+ net_service_name: 'connstring-high', //get any one from tnsnames.ora
52
+ connection_pool_name:'your-conn-pool-name' //optional
53
+ });
54
+
35
55
  var db = firebasedb;
36
56
  ```
37
57
 
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
  }
@@ -1,16 +1,19 @@
1
1
  const { MultiDbORM } = require("./multidb");
2
2
 
3
- function removeUndefined(obj) {
3
+ function replaceUndefinedWithNull(obj) {
4
4
  try {
5
5
 
6
- Object.keys(obj).forEach(function (key) {
7
- if (typeof obj[key] === 'undefined') {
8
- delete obj[key];
6
+ for (let key in obj) {
7
+ if (obj.hasOwnProperty(key)) {
8
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
9
+ replaceUndefinedWithNull(obj[key]);
10
+ } else if (typeof obj[key] === 'undefined') {
11
+ obj[key] = null;
12
+ }
9
13
  }
10
- });
11
- return obj
14
+ }
12
15
  } catch (e) {
13
- console.log('Error in sanitizing update of object ! ', e.message)
16
+ console.log('Error in sanitizing object before insert/update ! ', e.message)
14
17
  }
15
18
  }
16
19
 
@@ -142,7 +145,7 @@ class FireStoreDB extends MultiDbORM {
142
145
  }
143
146
 
144
147
  async insert(modelname, object, id) {
145
- removeUndefined(object)
148
+ replaceUndefinedWithNull(object)
146
149
  this.sync.insert(modelname, object, id)
147
150
  this.metrics.insert(modelname, object, id)
148
151
 
@@ -150,7 +153,7 @@ class FireStoreDB extends MultiDbORM {
150
153
  var idx = id || object.id || Date.now()
151
154
  const docref = db.collection(modelname).doc("" + idx);
152
155
  try {
153
- removeUndefined(object)
156
+ replaceUndefinedWithNull(object)
154
157
  return await docref.set(object);
155
158
  } catch (e) {
156
159
 
@@ -172,7 +175,7 @@ class FireStoreDB extends MultiDbORM {
172
175
 
173
176
 
174
177
  try {
175
- removeUndefined(object)
178
+ replaceUndefinedWithNull(object)
176
179
  if (idx) {
177
180
  this.metrics.update(modelname, filter, object, id)
178
181
  await this.getdb().collection(modelname).doc(idx).update(object);
@@ -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": "1.3.1",
3
+ "version": "2.0.1",
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
- "node-firestore-import-export": "^1.1.0",
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
- testSqlite();
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()