var q = require('q'); var HTTP = require('q-io/http'); var URL = require('url'); var _ = require('underscore'); var util = require('util'); var designDocs = require('./couchdb-design-docs'); module.exports = function(couchDbURL) { function stringifyFunctions(value) { if ( value === null ) { return null; } else if ( _.isArray(value) ) { return value; } else if ( _.isFunction(value) ) { return value.toString(); } else if ( _.isObject(value) ) { value = _.clone(value); _.each(value, function(propValue, propName){ value[propName] = stringifyFunctions(propValue); }); return value; } else { return value; } } function request(method,path,content) { var url = couchDbURL+path; var parsedURL = URL.parse(url); var options = { url: url, method: method, headers: { 'content-type': 'application/json; charset=utf-8', 'accept': 'application/json' }, body: { forEach: function(callback) { callback(JSON.stringify(content || {})); } } }; // because q-io doesn't support auth properly, we have to // build the f*ing wheel again. if ( parsedURL.auth ) { var auth = new Buffer(parsedURL.auth).toString("base64"); options.headers.authorization = 'Basic '+auth; } return HTTP.request(options) .then(function(res){ return res.body.read().then(function(content){ return JSON.parse(content.toString() || "{}"); }); },function(res){ return res.body.read().then(function(error){ console.warn(error); // q.all doesn't do errors, so let's show them here return JSON.parse(error.toString() || "{}"); }); }); } console.log("Configuring CouchDB for QED"); console.log("Checking CouchDB version"); return request('GET','') .then(function(res){ if (res.version !== "1.2.0" ) { console.log("Found "+res.version+", only tested with CouchDB 1.2.0"); } else { console.log("CouchDB 1.2.0 found"); } }).then(function(res){ console.log("Checking database 'qed'"); return request('GET','qed') .then(function(res){ console.log("Database 'qed' found."); },function(err){ console.log("Creating database 'qed'"); return request('PUT','qed'); }); }).then(function(){ console.log("Putting documents in database."); designDocs = stringifyFunctions(designDocs); return q.all(_.map(designDocs, function(doc,docUrl){ var configAction = doc.__configAction; delete doc.__configAction; switch (configAction) { case "ignore": console.log(docUrl+" ignored."); break; case "update": console.log(docUrl+" updating."); return request('GET',docUrl) .then(function(oldDoc){ _.extend(oldDoc,doc); return request('PUT',docUrl,oldDoc); },function(){ return request('PUT',docUrl,doc); }); break; case "replace": default: console.log(docUrl+" replacing."); return request('GET',docUrl) .then(function(oldDoc){ _.extend(doc,_.pick(oldDoc,'_id','_rev')); return request('PUT',docUrl,doc); },function(){ return request('PUT',docUrl,doc); }); break; } })); }).then(function(){ console.log("Done!"); },function(err){ console.error("ERROR",err,err.stack); }); };