CouchDB-APIA Node.JS wrapper for the CouchDB API | |
| lib/client.js |
Module Dependencies
|
var _ = require("underscore"),
http = require('http'),
url = require('url'),
qs = require("querystring"),
crypto = require("crypto"),
sha1 = crypto.createHash("sha1"),
cookie = require("./cookie"),
Vargs = require("vargs").Constructor;
|
The Client deals with all the HTTP communication with CouchDB.
It will handle content-negotiation and response.
|
function Client() {}
|
Performs an HTTP request
param: object urlObj Object returned from url.parse() param: object [options] HTTP request configuration param: function callback Callback for HTTP response
|
Client.prototype.request = function (urlObj, options, callback) {
var self = this,
opts = _.clone(options);
_.defaults(opts, {
method: "GET",
headers: {}
});
_.defaults(opts.headers, {
"content-type": "application/json",
"accept": ["/plain", "application/json", "application/x-www-form-urlencoded"].join(", ")
});
opts.method = opts.method.toUpperCase();
opts.host = urlObj.hostname;
opts.port = urlObj.port;
opts.path = urlObj.pathname;
if (urlObj.query) {
opts.path += "?" + qs.stringify(urlObj.query);
}
if (this.user) {
opts.headers.authorization = "Basic " + new Buffer(this.user.name + ":" + this.user.password).toString("base64");
}
if (this.debug) {
console.log(opts);
}
var req = http.request(opts, function (res) {
var response = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
response += chunk;
});
res.on('end', function () {
var result = response;
switch (res.headers["content-type"]) {
case "application/json":
result = JSON.parse(result);
break;
case "application/x-www-form-urlencoded":
result = qs.parse(result);
break;
}
if (res.statusCode >= 200 && res.statusCode < 300) {
callback.call(self, null, result, res.headers, res.statusCode);
} else {
callback.call(self, result, null, res.headers, res.statusCode);
}
if (self.debug) {
console.log(result, res.headers, res.statusCode);
}
});
});
if (opts.body) {
var body = opts.body;
switch (opts.headers["content-type"]) {
case "application/json":
body = JSON.stringify(body);
break;
case "application/x-www-form-urlencoded":
body = qs.stringify(body);
break;
}
req.write(body);
}
req.end();
};
|
Performs an HTTP GET request
param: object urlObj Object returned from url.parse() param: object [options] HTTP request configuration param: function callback Callback for HTTP response
|
Client.prototype.get = function () {
var args = new Vargs(arguments),
urlObj = args.first,
options = args.all[1] || {};
options.method = "GET";
this.request(urlObj, options, args.callback);
};
|
Performs an HTTP PUT request
param: object urlObj Object returned from url.parse() param: string | object body Body of request (string, json object, qs object, etc.) param: object [options] HTTP request configuration param: function callback Callback for HTTP response
|
Client.prototype.put = function () {
var args = new Vargs(arguments),
urlObj = args.first,
body = args.all[1] || null,
options = args.all[2] || {};
options.method = "PUT";
if (body) {
options.body = body;
}
this.request(urlObj, options, args.callback);
};
|
Performs an HTTP POST request
param: object urlObj Object returned from url.parse() param: string | object body Body of request (string, json object, qs object, etc.) param: object [options] HTTP request configuration param: function callback Callback for HTTP response
|
Client.prototype.post = function () {
var args = new Vargs(arguments),
urlObj = args.first,
body = args.all[1] || null,
options = args.all[2] || {};
options.method = "POST";
if (body) {
options.body = body;
}
this.request(urlObj, options, args.callback);
};
|
Performs an HTTP DELETE request
param: object urlObj Object returned from url.parse() param: object [options] HTTP request configuration param: function callback Callback for HTTP response
|
Client.prototype.del = function () {
var args = new Vargs(arguments),
urlObj = args.first,
options = args.all[1] || {};
options.method = "DELETE";
this.request(urlObj, options, args.callback);
};
|
Export to CommonJS
|
module.exports = Client;
|
| lib/cookie.js |
HTTP Cookie Toolkit
- requires: underscore
.js
|
|
Module Dependencies
|
var _ = require("underscore");
|
Parses the HTTP Header into a Cookie object
|
module.exports.parse = function (cookieStr) {
if (_.isArray(cookieStr)) {
return _.map(cookieStr, this.parse);
}
var parts = cookieStr.split(";"),
main = parts.shift().split("="),
ret = {
name: main[0],
value: main[1]
};
_.each(parts, function (part, x) {
part = part.split("=");
var name = part[0] ? part[0].trim() : "",
value = part[1] ? part[1].trim() : "";
ret[name] = value;
});
return ret;
};
|
Output an HTTP header based on a parsed Cookie object
|
module.exports.format = function (cookieObj) {
var cookie = _.clone(cookieObj),
ret = [cookie.name + "=" + cookie.value];
delete cookie.name;
delete cookie.value;
_.each(cookie, function (value, key) {
ret.push(value ? key + "=" + value : key);
});
return ret.join("; ");
};
|
| lib/database.js |
Module Dependencies
|
var Document = require("./document"),
DesignDocument = require("./designDocument"),
_ = require("underscore");
|
Handles interaction at the CouchDB database level
|
function Database(server, name) {
this.server = server;
this.name = name;
this.urlObj = _.clone(server.urlObj);
this.urlObj.pathname += name + "/"; // add the db name and trailing slash to the pathname
this.client = this.server.client;
}
|
|
_.extend(Database.prototype, require("./request"));
|
Get basic information about the database
GET /db
|
Database.prototype.info = function (callback) {
this.req("get", callback);
};
|
Create the database
PUT /db
|
Database.prototype.create = function (callback) {
this.req("put", callback);
};
|
Drop the database
DELETE /db
|
Database.prototype.drop = function (callback) {
this.req("del", callback);
};
|
Query the CouchDB _changes API
GET /db/_changes
param: object query Query arguments to be passed param: function callback Callback to be performed (arguments: err, response )
|
Database.prototype.changes = function (query, callback) {
var url = {
pathname: "_changes",
query: query
};
this.req("get", url, callback);
};
|
Perform a database (or design document view index) compation
GET /db/_compact GET /db/_compact/ddoc
param: string [ddoc] If passed, will compact the specified design document's view indexes param: function callback Callback to be performed (arguments: err, response )
|
Database.prototype.compact = function (ddoc, callback) {
if (typeof ddoc === "function") {
callback = ddoc;
ddoc = null;
}
var path = "_compact";
if (ddoc) {
path += "/" + ddoc;
}
this.req("post", path, callback);
};
|
Clear the cached view output
GET /db/_view_cleanup
|
Database.prototype.viewCleanup = function (callback) {
this.req("post", "_view_cleanup", callback);
};
|
Commits recent db changes to disk
GET /db/_ensure_full_commit
|
Database.prototype.ensureFullCommit = function (callback) {
this.req("post", "_ensure_full_commit", callback);
};
|
Returns a new Document object
|
Database.prototype.doc = function (id) {
return new Document(this, id);
};
|
Returns a new DesignDocument object
|
Database.prototype.ddoc = function (name) {
return new DesignDocument(this, name);
};
|
Export to CommonJS
|
module.exports = Database;
|
| lib/designDocument.js |
Module Dependencies
|
var _ = require("underscore"),
Document = require("./document");
|
Handles interaction at the design document level
|
function DesignDocument(db, name) {
this.db = db;
this.server = db.server;
this.id = "_design/" + name;
this.urlObj = _.clone(db.urlObj);
this.body = {
_id: this.id
};
this.urlObj.pathname += this.id;
this.client = this.server.client;
}
|
|
_.extend(DesignDocument.prototype, Document.prototype);
|
Gets the list of views
|
DesignDocument.prototype.views = function () {
this.body.views = this.body.views || {};
return this.body.views;
};
|
Add a new view to this design document
|
DesignDocument.prototype.view = function (name, map, reduce) {
if (map) {
var view = { map: map.toString() };
if (reduce) {
view.reduce = reduce.toString();
}
this.views()[name] = view;
} else {
return this.views()[name];
}
};
|
Get all the show functions
|
DesignDocument.prototype.shows = function () {
this.body.shows = this.body.shows || {};
return this.body.shows;
};
|
Get/set the specified show function
|
DesignDocument.prototype.show = function (name, func) {
if (func) {
this.shows()[name] = func.toString();
} else {
return this.shows()[name];
}
};
|
Get all the list functions
|
DesignDocument.prototype.lists = function () {
this.body.lists = this.body.lists || {};
return this.body.lists;
};
|
Get/set the specified list function
|
DesignDocument.prototype.list = function (name, func) {
if (func) {
this.lists()[name] = func.toString();
} else {
return this.lists()[name];
}
};
|
Get all the update handler
|
DesignDocument.prototype.updates = function () {
this.body.updates = this.body.updates || {};
return this.body.updates;
};
|
Get/set the specified update handler
|
DesignDocument.prototype.update = function (name, func) {
if (func) {
this.updates()[name] = func.toString();
} else {
return this.updates()[name];
}
};
|
Get/set the validation function
|
DesignDocument.prototype.val = function (func) {
if (func) {
this.body.validate_doc_update = func.toString();
} else {
return this.body.validate_doc_update;
}
};
|
Export to CommonJS
|
module.exports = DesignDocument;
|
| lib/document.js |
Module Dependencies
|
var Client = require("./client"),
_ = require("underscore");
|
Handles interaction at the document level
|
function Document(db, id) {
this.db = db;
this.server = db.server;
this.id = id || null;
this.urlObj = _.clone(db.urlObj);
this.body = {};
if (id) {
this.body._id = id;
this.urlObj.pathname += id;
}
this.client = this.server.client;
}
|
|
_.extend(Document.prototype, require("./request"));
|
Retrieve the document from the server
GET /db/doc
|
Document.prototype.get = function (callback) {
var self = this;
this.req("get", null, function (err, response) {
if (!err) {
self.body = response;
}
callback.apply(self, arguments);
});
};
|
Save the document's current state to the server
PUT /db/doc (w/ id)POST /db (w/o id)
|
Document.prototype.save = function (callback) {
var self = this;
this.req(this.id ? "put" : "post", null, this.body, function (err, response) {
if (!err) {
if (!self.id) {
self.id = self.body._id = response.id;
self.urlObj.pathname += response.id;
}
self.body._rev = response.rev;
}
callback.apply(self, arguments);
});
};
|
Delete the document from the server
DELETE /db/doc
|
Document.prototype.del = function (callback) {
var self = this,
options = { headers: { "if-match": this.body._rev } };
this.req("del", null, options, function (err, response) {
if (!err) {
self.body = false;
}
callback.apply(self, arguments);
});
};
|
Export to CommonJS
|
module.exports = Document;
|
| lib/request.js |
Module Dependencies
|
var _ = require("underscore"),
url = require("url");
|
Pass along a request to the underlying Client object, using the current objects urlObj as the base
|
exports.req = function () {
var args = _.toArray(arguments),
method = args.shift().toLowerCase();
if (args.length > 1) {
args[0] = modifyUrl(this.urlObj, args[0]);
} else {
args.unshift(this.urlObj);
}
this.client[method].apply(this.client, args);
};
|
Enable debug mode for the client object (not very useful externally right now)
|
exports.debug = function (status) {
this.client.debug = typeof status === "undefined" ? true : !!status;
};
|
| lib/server.js |
Module Dependencies
|
var Client = require("./client"),
Database = require("./database"),
qs = require("querystring"),
url = require("url"),
_ = require("underscore");
|
Handles interaction at the server level
|
function Server(host, port) {
var urlObj = url.parse("http:
if (host) {
urlObj.host = host;
}
if (port) {
urlObj.port = port;
}
this.urlObj = urlObj;
this.client = new Client();
}
|
|
_.extend(Server.prototype, require("./request"));
|
Get basic information about the server
GET /
|
Server.prototype.info = function (callback) {
this.req("get", callback);
};
|
Get a list of all the databases on the server
GET /_all_dbs
|
Server.prototype.allDbs = function (callback) {
this.req("get", "_all_dbs", callback);
};
|
Get information about all the active tasks currently running on the server
GET /_active_tasks
|
Server.prototype.activeTasks = function (callback) {
this.req("get", "_active_tasks", callback);
};
|
Get the text of the server's log file
GET /_log
param: object query Query arguments to be passed param: function callback Callback to be performed (arguments: err, response )
|
Server.prototype.log = function (query, callback) {
if (typeof query === "function") {
callback = query;
query = null;
}
if (!query) {
this.req("get", "_log", callback);
} else {
this.req("get", {
pathname: "_log",
query: query
}, callback);
}
};
|
Restarts the server process
GET /_restart
|
Server.prototype.restart = function (callback) {
this.req("post", "_restart", callback);
};
|
Restarts the server process
GET /_restart
|
Server.prototype.stats = function (callback) {
this.req("get", "_stats", callback);
};
|
Get a list of generated UUIDs from the server
GET /_uuids
param: number [count] Number of UUIDs to be returned (default: 1) param: function callback Callback to be performed (arguments: err, uuids )
|
Server.prototype.uuids = function (count, callback) {
var self = this;
if (typeof count === "function") {
callback = count;
count = 1;
}
this.req("get", {
pathname: "_uuids",
query: { count: count || 5 }
}, function (err, response) {
callback.call(self, null, response.uuids);
});
};
|
Specify a username/password to send to the server with each request (uses HTTP Basic auth)
|
Server.prototype.setUser = function (user, pass) {
this.client.user = {
name: user,
password: pass
};
};
|
Attempt a login against the server itself
param: string user Username param: string pass Password param: function callback Callback to be performed (arguments: err, response )
|
Server.prototype.login = function (user, pass, callback) {
var self = this, body, options;
body = {
name: user,
password: pass
};
options = {
headers: {
"content-type": "application/x-www-form-urlencoded"
}
};
this.req("post", "_session", body, options, function (err, response) {
if (!err) {
self.client.user = {
ctx: _.clone(response),
name: user,
password: pass
};
}
callback.apply(self, arguments);
});
};
|
Logout (destroy the session)
|
Server.prototype.logout = function (callback) {
this.req("del", "_session", callback);
};
|
Check the status of the current session
|
Server.prototype.session = function (callback) {
this.req("get", "_session", callback);
};
|
Returns a new Database object
|
Server.prototype.db = function (name) {
return new Database(this, name);
};
|
Export to CommonJS
|
module.exports = Server;
|