@yawetse/pkgcloud
Version:
An infrastructure-as-a-service agnostic cloud library for node.js
191 lines (166 loc) • 6.05 kB
JavaScript
/*
* database.js: Database methods for working with databases from MongoLab
*
* (C) 2012 Charlie Robbins, Ken Perkins, Ross Kukulinski & the Contributors.
*
*/
var errs = require('errs'),
url = require('url');
// Function formatResponse
// This function parse the response from the provider and return an object
// with the correct keys and values.
// ### @response {Object} The body response from the provider api
function formatResponse(response) {
var info, user, dbname, auth;
info = url.parse(response.uri);
auth = encodeURIComponent(info.auth);
user = auth.replace(/%3A/i, ':').split(':');
dbname = response.name;
var database = {
id: dbname,
host: info.hostname,
port: Number(info.port),
uri: 'mongodb://' + info.auth + '@' + info.host,
username: decodeURIComponent(user[0]),
password: decodeURIComponent(user[1]),
dbname: dbname
};
return database;
}
// Create Database
// ### @options {Object} Set of options can be
// #### options['name'] {String} Name of database (required)
// #### options['owner'] {String} Name of the user owner the database (required)
// #### options['plan'] {String} Name of plan according to the MongoLab plans (Default: 'free')
// ### @callback {Function} Continuation to respond to when complete.
exports.create = function create(options, callback) {
// Check for options
if (typeof options === 'function') {
return errs.handle(errs.create({
message: 'Options required for create a database.'
}), options);
}
if (!options['name']) {
return errs.handle(errs.create({
message: 'options. Name is a required argument'
}), callback);
}
if (!options['owner']) {
return errs.handle(errs.create({
message: 'options. Owner is a required argument'
}), callback);
}
if (!options['plan']) {
options['plan'] = 'free';
}
// We have to setup the correct prefix for database name
// for the moment we use the 'owner' field because we expect the correct prefix there.
var databaseName = [options['owner'], options['name']].join('_');
// Setup the account name according mongolab API.
// @todo We need a helper function for add the prefix if its necesary
//var account = [this.config.username, options['owner']].join('_');
// at the moment we need provide the username with the prefix (partner name)
var account = options['owner'];
var createOptions = {
method: 'POST',
path: 'accounts/' + account + '/databases',
body: {
name: databaseName,
plan: options['plan'],
username: options['owner'],
// In future we will have to change this for support multiples clouds and user-selected cloud.
cloud: this.config.cloud
}
};
this._request(createOptions, function (err, body) {
return err
? callback(err)
: callback(null, formatResponse(body));
});
};
// Lists all databases by user account
// ### @owner {String} Username for list their databases
// ### @callback {Function} Continuation to respond to when complete.
exports.getDatabases = function getDatabases(owner, callback) {
// Check for options
if (typeof owner === 'function') {
return errs.handle(errs.create({
message: 'Name required for delete an account.'
}), owner);
}
this._request({ path: 'accounts/' + owner + '/databases' }, function (err, body) {
return err
? callback(err)
: callback(null, body);
});
};
// View one database with details
// NOT USE THIS METHOD YET
// The principal idea of this method is for view details like username and
// password and the hostname and port, but for now MongoLab just answer with the name.
// The behavior I describe its according the parters documentation.
// https://objectlabs.jira.com/wiki/display/partners/MongoLab+Partner+Integration+API#MongoLabPartnerIntegrationAPI-Viewdatabase
// ### @options {Object} Set of options can be
// #### options['name'] {String} Name of the database to view (required)
// #### options['owner'] {String} Username of the database owner (required)
// ### @callback {Function} Continuation to respond to when complete.
exports.getDatabase = function getDatabase(options, callback) {
// Check for options
if (typeof options === 'function') {
return errs.handle(errs.create({
message: 'Options required for view a database.'
}), options);
}
// Check for name
if (!options['name']) {
return errs.handle(errs.create({
message: 'options. Name is a required argument.'
}), callback);
}
// Check for owner
if (!options['owner']) {
return errs.handle(errs.create({
message: 'options. Username of owner is a required argument.'
}), callback);
}
var path = ['accounts', options['owner'], 'databases', options['name']].join('/');
this._request({ path: path }, function (err, body) {
return err
? callback(err)
: callback(null, body);
});
};
// Delete a database
// ### @options {Object} Set of options can be
// #### options['name'] {String} Name of the database to view (required)
// #### options['owner'] {String} Username of the database owner (required)
// ### @callback {Function} Continuation to respond to when complete.
exports.remove = function remove(options, callback) {
// Check for options
if (typeof options === 'function') {
return errs.handle(errs.create({
message: 'Options required for delete a database.'
}), options);
}
// Check for name
if (!options['name']) {
return errs.handle(errs.create({
message: 'options. Name is a required argument.'
}), callback);
}
// Check for owner
if (!options['owner']) {
return errs.handle(errs.create({
message: 'options. Username of owner is a required argument.'
}), callback);
}
var deleteOptions = {
method: 'DELETE',
path: ['accounts', options['owner'], 'databases', options['name']].join('/')
};
this._request(deleteOptions, function (err) {
return err
? callback(err)
: callback(null);
});
};