Skip to content

Commit 9af8ea7

Browse files
author
高鸣飞
committed
[feature] support backend: mongodb #25
1 parent cc3af59 commit 9af8ea7

File tree

8 files changed

+454
-5
lines changed

8 files changed

+454
-5
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
.*
3-
package-lock.json
3+
package-lock.json
4+
yarn.lock

README.md

+32-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- [Usage](#usage)
1616
- [database list](#database-list)
1717
- [feature list](#feature-list)
18+
- [api support](#api-support)
1819
- [interface](#interface)
1920
- [overall](#overall)
2021
- [action whitelist: operator_info.actions](#action-whitelist-operator_infoactions)
@@ -32,13 +33,26 @@ database driver with extended features.
3233

3334
## database list
3435
* mysql
36+
* mongodb
3537
* redis
3638
* define custom function to use any database or service
3739

3840
## feature list
3941
* changelog/oplog
4042
* auto release timeout connection
4143

44+
## api support
45+
46+
| Method | MySQL | MongoDB | Redis |
47+
| :------- |:------:| :------:| :----:|
48+
| select ||||
49+
| selectEx || × | × |
50+
| insert ||||
51+
| update ||||
52+
| delete ||||
53+
| find | × || × |
54+
| aggregate| × || × |
55+
4256
## interface
4357

4458

@@ -179,7 +193,7 @@ const InterfaceTwo = {
179193
### method
180194
```javascript
181195
// callback
182-
conn.selectEx(
196+
conn.selectEx( // mysql only
183197
/* table */ 'table0',
184198
/* custom sql */ 'select ... join ...where field1 = ? and field2 = ?',
185199
/* where */ [1,2]
@@ -219,6 +233,23 @@ conn.delete(
219233
function(err, rows, info) {
220234
})
221235

236+
conn.find( // mongodb only
237+
/* table */ 'table5',
238+
/* opt */ {fields: ['field1'], skip: 10, sort: 'field1'},
239+
/* where */ {field1: 10},
240+
function(err, rows, info) {
241+
})
242+
243+
conn.aggregate( // mongodb only
244+
/* table */ 'table5',
245+
/* opt */ {skip: 10, sort: 'name'},
246+
/* pipe */ [
247+
{$match: {field1: {$regex: /[a-z]*/}}},
248+
{$sort: {field1: -1}},
249+
]
250+
function(err, rows, info) {
251+
})
252+
222253
// Promise/async/await
223254
let result
224255
try {

lib/$/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ ALL_METHODS: [
88
'queryReadonly',
99
'release',
1010
'selectEx',
11+
'find',
12+
'aggregate',
1113
],
1214

1315
util: require('util'),

lib/Connection.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ $.ALL_METHODS.forEach(function(method) {
7272
callback(new Error('connection timeout.'))
7373
}, this._opts.connection_timeout)
7474

75-
const start_time = +new Date()
75+
const start_time = + new Date()
7676
const that = this
7777
const args = arguments
7878
arguments[arguments.length - 1] = function() {

lib/define/mongodb.js

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
module.exports.Context = class {
2+
3+
constructor(config) {
4+
if (!config.config.url) {
5+
throw new Error('url is required for mongodb connection')
6+
}
7+
this._config = config.config
8+
}
9+
10+
getConnection() {
11+
return new MongoDB(this._config)
12+
}
13+
14+
}
15+
16+
class MongoDB {
17+
18+
constructor(config) {
19+
this._config = config
20+
this._readonly = config.readonly
21+
this._released = false
22+
this._conn = monk(config.url)
23+
log.trace('mongodb connection established')
24+
}
25+
26+
__destroy() {
27+
if (this._conn._state === 'closed') {
28+
return
29+
}
30+
this._conn.close()
31+
}
32+
33+
/**
34+
* MongoDB.insert()
35+
*
36+
* @param {string} table
37+
* @param {object|Array} sets
38+
* @param {function} callback
39+
*/
40+
insert(table, sets, callback) {
41+
if (sets.constructor !== Object && sets.constructor !== Array) {
42+
return callback(new Error('invalid sets'))
43+
}
44+
if (this._readonly) {
45+
return errNotAllowd(callback)
46+
}
47+
this._conn.collection(table).insert(sets, (err, result) => {
48+
if (result.constructor === Object) {
49+
result = [result]
50+
}
51+
return callback(err, {
52+
affected_rows: result.length,
53+
docs: result,
54+
}, null)
55+
})
56+
}
57+
58+
update(table, sets, where, callback) {
59+
if (sets.constructor !== Object && sets.constructor !== Array) {
60+
return callback(new Error('invalid sets'))
61+
}
62+
if (this._readonly) {
63+
return errNotAllowd(callback)
64+
}
65+
this._conn.collection(table)
66+
.update(where, {$set: sets}, {multi: true}, (err, result) => {
67+
return callback(err, {
68+
affected_rows: result.n,
69+
changed_rows: result.nModified,
70+
}, null)
71+
})
72+
}
73+
74+
/**
75+
* Mongodb.remove()
76+
*
77+
* @param {string} table
78+
* @param {object} where
79+
* @param {function} callback
80+
*/
81+
delete(table, where, callback) {
82+
if (this._readonly) {
83+
return errNotAllowd(callback)
84+
}
85+
this._conn.collection(table).remove(where, (err, result) => {
86+
return callback(err, {
87+
affected_rows: result.deletedCount,
88+
}, null)
89+
})
90+
}
91+
92+
/**
93+
* Mongodb.find()
94+
*
95+
* @param {string} table
96+
* @param {string|array} options
97+
* @param {string|object_id|object} where
98+
* @param {function} callback
99+
*/
100+
select(table, fields, where, callback) {
101+
let _fields = fields === '*' ? {} : fields
102+
this._conn.collection(table).find(where, _fields, (err, docs) => {
103+
return callback(err, docs, null)
104+
})
105+
}
106+
107+
/**
108+
* Mongodb.find()
109+
* support sort/fileds/limit/skip/rawCursor in options
110+
*
111+
* @param {string} table
112+
* @param {object} options
113+
* @param {string|object_id|object} where
114+
* @param {function} callback
115+
*/
116+
find(table, options, where, callback) {
117+
this._conn.collection(table).find(where, options, (err, docs) => {
118+
return callback(err, docs, null)
119+
})
120+
}
121+
122+
/**
123+
* Mongodb.close()
124+
*/
125+
release() {
126+
this._released = true
127+
if (!this._conn._state === 'open') return
128+
this._conn.close()
129+
this._conn = null
130+
}
131+
132+
/**
133+
* Mongodb.aggregate()
134+
*
135+
* @param {string} table
136+
* @param {object} options
137+
* @param {array} pipeline
138+
* @param {function} callback
139+
*/
140+
aggregate(table, options, pipeline, callback) {
141+
this._conn.collection(table).aggregate(pipeline, options, (err, docs) => {
142+
return callback(err, docs, null)
143+
})
144+
}
145+
146+
}
147+
148+
const util = require('util')
149+
const debug = require('debug')('sqlx')
150+
const monk = require('monk')
151+
function __log() {
152+
debug(util.format.apply(null, arguments))
153+
}
154+
const log = {
155+
trace: __log,
156+
error: __log,
157+
debug: __log,
158+
info : __log,
159+
}
160+
161+
function errNotAllowd(callback) {
162+
return callback(new Error('not allowed'))
163+
}

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sqlx",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"description": "Database driver with extended features like mysql changelog/oplog, connection auto release.",
55
"main": "index.js",
66
"directories": {
@@ -22,7 +22,7 @@
2222
"release"
2323
],
2424
"author": "yinrong",
25-
"license": "ISC",
25+
"license": "MIT",
2626
"bugs": {
2727
"url": "https://github.com/yinrong/node-sqlx/issues"
2828
},
@@ -31,6 +31,7 @@
3131
"async": "^2.0.1",
3232
"debug": "^2.2.0",
3333
"mongo-sql": "^2.7.5",
34+
"monk": "^6.0.5",
3435
"mysql": "^2.11.1",
3536
"redis": "^2.8.0"
3637
},

0 commit comments

Comments
 (0)