You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.6 KiB
182 lines
4.6 KiB
var Collection = require('./collection')
|
|
var mongodb = require('mongodb')
|
|
var xtend = require('xtend')
|
|
var thunky = require('thunky')
|
|
var parse = require('parse-mongo-url')
|
|
var util = require('util')
|
|
var EventEmitter = require('events').EventEmitter
|
|
|
|
var noop = function () {}
|
|
|
|
var Database = function (connString, cols, options) {
|
|
var self = this
|
|
|
|
EventEmitter.call(this)
|
|
|
|
if (typeof connString === 'string') {
|
|
this._dbname = parse(connString).dbName
|
|
|
|
// Fix short cut connection URLs consisting only of a db name or db + host
|
|
if (connString.indexOf('/') < 0) {
|
|
connString = 'localhost/' + connString
|
|
}
|
|
|
|
if (connString.indexOf('mongodb://') < 0) {
|
|
connString = 'mongodb://' + connString
|
|
}
|
|
|
|
this._getConnection = thunky(function (cb) {
|
|
mongodb.connect(connString, options, function (err, db) {
|
|
if (err) {
|
|
self.emit('error', err) // It's safer to emit an error instead of rely on the cb to handle the error
|
|
return cb(err)
|
|
}
|
|
|
|
self.emit('connect')
|
|
cb(null, db)
|
|
})
|
|
})
|
|
} else if (typeof connString._getConnection === 'function') { // mongojs
|
|
this._dbname = connString._dbname
|
|
this._getConnection = connString._getConnection
|
|
} else { // try mongodb-native
|
|
this._dbname = parse(connString.options.url).dbName
|
|
|
|
this._getConnection = thunky(function (cb) {
|
|
cb(null, connString)
|
|
})
|
|
}
|
|
|
|
this.ObjectId = mongodb.ObjectId
|
|
|
|
cols = cols || []
|
|
cols.forEach(function (colName) {
|
|
self[colName] = self.collection(colName)
|
|
|
|
var parts = colName.split('.')
|
|
|
|
var last = parts.pop()
|
|
var parent = parts.reduce(function (parent, prefix) {
|
|
parent[prefix] = parent[prefix] || {}
|
|
return parent[prefix]
|
|
}, self)
|
|
|
|
parent[last] = self.collection(colName)
|
|
})
|
|
}
|
|
|
|
util.inherits(Database, EventEmitter)
|
|
|
|
Database.prototype.collection = function (colName) {
|
|
return new Collection({name: colName}, this._getConnection)
|
|
}
|
|
|
|
Database.prototype.close = function (force, cb) {
|
|
if (typeof force === 'function') { return this.close(false, force) }
|
|
|
|
var self = this
|
|
|
|
cb = cb || noop
|
|
this._getConnection(function (err, server) {
|
|
if (err) return cb(err)
|
|
|
|
server.close(force)
|
|
|
|
self.emit('close')
|
|
cb()
|
|
})
|
|
}
|
|
|
|
Database.prototype.runCommand = function (opts, cb) {
|
|
cb = cb || noop
|
|
if (typeof opts === 'string') {
|
|
var tmp = opts
|
|
opts = {}
|
|
opts[tmp] = 1
|
|
}
|
|
|
|
this._getConnection(function (err, connection) {
|
|
if (err) return cb(err)
|
|
connection.command(opts, function (err, result) {
|
|
if (err) return cb(err)
|
|
cb(null, result)
|
|
})
|
|
})
|
|
}
|
|
|
|
Database.prototype.listCollections = function (cb) {
|
|
this._getConnection(function (err, connection) {
|
|
if (err) { return cb(err) }
|
|
|
|
connection.listCollections().toArray(function (err, collections) {
|
|
if (err) { return cb(err) }
|
|
cb(null, collections)
|
|
})
|
|
})
|
|
}
|
|
|
|
Database.prototype.getCollectionNames = function (cb) {
|
|
this.listCollections(function (err, collections) {
|
|
if (err) { return cb(err) }
|
|
cb(null, collections.map(function (collection) { return collection.name }))
|
|
})
|
|
}
|
|
|
|
Database.prototype.createCollection = function (name, opts, cb) {
|
|
if (typeof opts === 'function') return this.createCollection(name, {}, opts)
|
|
|
|
var cmd = {create: name}
|
|
Object.keys(opts).forEach(function (opt) {
|
|
cmd[opt] = opts[opt]
|
|
})
|
|
this.runCommand(cmd, cb)
|
|
}
|
|
|
|
Database.prototype.stats = function (scale, cb) {
|
|
if (typeof scale === 'function') return this.stats(1, scale)
|
|
this.runCommand({dbStats: 1, scale: scale}, cb)
|
|
}
|
|
|
|
Database.prototype.dropDatabase = function (cb) {
|
|
this.runCommand('dropDatabase', cb)
|
|
}
|
|
|
|
Database.prototype.createUser = function (usr, cb) {
|
|
var cmd = xtend({createUser: usr.user}, usr)
|
|
delete cmd.user
|
|
this.runCommand(cmd, cb)
|
|
}
|
|
Database.prototype.addUser = Database.prototype.createUser
|
|
|
|
Database.prototype.dropUser = function (username, cb) {
|
|
this.runCommand({dropUser: username}, cb)
|
|
}
|
|
Database.prototype.removeUser = Database.prototype.dropUser
|
|
|
|
Database.prototype.eval = function (fn) {
|
|
var cb = arguments[arguments.length - 1]
|
|
this.runCommand({
|
|
eval: fn.toString(),
|
|
args: Array.prototype.slice.call(arguments, 1, arguments.length - 1)
|
|
}, function (err, res) {
|
|
if (err) return cb(err)
|
|
cb(null, res.retval)
|
|
})
|
|
}
|
|
|
|
Database.prototype.getLastErrorObj = function (cb) {
|
|
this.runCommand('getLastError', cb)
|
|
}
|
|
|
|
Database.prototype.getLastError = function (cb) {
|
|
this.runCommand('getLastError', function (err, res) {
|
|
if (err) return cb(err)
|
|
cb(null, res.err)
|
|
})
|
|
}
|
|
|
|
Database.prototype.toString = function () {
|
|
return this._dbname
|
|
}
|
|
|
|
module.exports = Database
|
|
|