diff --git a/README.md b/README.md index 0702314..58fbce9 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,18 @@ From Node: }); -From the CLI: - - TBD +From the CLI (-l start repl in fork): + ./bin/multicouch -p 5984 -d data -l + + couch.start() // to initiate dbs + + couch.db.xxx.allDocs() + couch.db.xxx.get("id") + couch.db.xxx.post({test:"test"}) + couch.db.xxx.put("id", "rev",{test:"test"}) + couch.db.xxx.head() + couch.db.xxx.del("id", "rev") ## Configuration diff --git a/bin/multicouch b/bin/multicouch index 8812b2a..8e59f80 100755 --- a/bin/multicouch +++ b/bin/multicouch @@ -1,28 +1,44 @@ #!/usr/bin/env node var mc = require("../lib/multicouch"), - cmdline = require('commander'); + cmdline = require('commander'), + repl = require("repl"), + couchr = require('../lib/couchrwrap'); var opts = cmdline .usage('[options] []') .option("-p, --port [number]", "bind server to port", parseInt) .option("-d, --db_dir [path]", "database directory") .option("-c, --couchdb_path [path]", "executable path") + .option("-l, --repl", "repl couch") .parse(process.argv); if (opts.args.length) opts.prefix = opts.args[0]; - var couch_process = new mc(opts); couch_process.start(); -// HACK: keep process alive until a quit-ly signal is received -setInterval(function (){}, 60000); -function quit() { - couch_process.on('stop', function() { process.exit(0); }); - couch_process.stop(); +if (opts.repl) { + var exp = repl.start({ + prompt: "repl couch> ", + input: couch_process.stdin, + output: couch_process.stdout + }).on('exit', function() { + couch_process.on('stop', function() { process.exit(0); }); + couch_process.stop(); + }); + exp.context.couch = couchr; +} else { + //HACK: keep process alive until a quit-ly signal is received + setInterval(function (){}, 60000); + + function quit() { + couch_process.on('stop', function() { process.exit(0); }); + couch_process.stop(); + } + // HT: node-supervisor + ['SIGTERM', 'SIGINT', 'SIGHUP', 'SIGQUIT'].forEach(function (s) { + process.on(s, quit); + }); } -// HT: node-supervisor -['SIGTERM', 'SIGINT', 'SIGHUP', 'SIGQUIT'].forEach(function (s) { - process.on(s, quit); -}); + diff --git a/lib/couchrwrap.js b/lib/couchrwrap.js new file mode 100644 index 0000000..b9c369e --- /dev/null +++ b/lib/couchrwrap.js @@ -0,0 +1,101 @@ +var couchr = require('couchr'); +var json_tb = require('json-table'); +var _ = require('lodash'); + +function treatErr(err) { + if (err) { + console.log(err); + process.exit(1); + } +} + +function showData(data) { + + //console.log(_.pluck(data, 'doc')); + + + var json_tb_out = new json_tb(_.pluck(data, 'doc'), { + chars: { 'top': '═' , 'top-mid': '╤' , 'top-left': '╔' , 'top-right': '╗' + , 'bottom': '═' , 'bottom-mid': '╧' , 'bottom-left': '╚' , 'bottom-right': '╝' + , 'left': '║' , 'left-mid': '╟' , 'mid': '─' , 'mid-mid': '┼' + , 'right': '║' , 'right-mid': '╢' , 'middle': '│' } + }, function(table) { + table.show() // **have to call show() function to print out the table** + }) +} + +function api(host, db) { + return { + allDocs: function() { + couchr.get(host + '/' + db + '/_all_docs', { include_docs: true }, function (err, _data, resp) { + treatErr(err); + showData(_data.rows); + }) + }, + get: function(id) { + couchr.get(host + '/' + db + '/' + id, { include_docs: true }, function (err, data, resp) { + treatErr(err); + showData([{doc: data}]); + }) + }, + post: function(data) { + couchr.post(host + '/' + db, data, function (err, _data, resp) { + treatErr(err); + showData([{doc: _data}]) + }) + }, + head: function(data) { + couchr.post(host + '/' + db, data, function (err, _data, resp) { + treatErr(err); + showData([{doc: _data}]) + }) + }, + put: function(id, rev, data) { + data._id = id; + data._rev = rev; + couchr.put(host + '/' + db + '/' + id, data, function (err, _data, resp) { + treatErr(err); + showData([{doc: _data}]) + }) + }, + del: function(id, rev) { + var data = { + rev: rev + } + couchr.del(host + '/' + db + '/' + id , data, function (err, _data, resp) { + treatErr(err); + showData([{doc: _data}]) + }) + } + } +} + +function wrap_couchr() { + var wrap = { + host: process.env.COUCH_URL || 'http://localhost:5984', + db: {}, + start: function () { + var self = this; + couchr.get(this.host + '/_all_dbs', function (err, list) { + treatErr(err); + list.forEach(function (key, value) { + console.log(key, value) + self.db[key] = api(self.host, key); + }) + }) + }, + use: function () { + + Object.keys(couchr).forEach(function (propertyValue, propertyName) { + wrap[propertyName] = function () { + return couchr[propertyName].apply(couchr, arguments) + } + }); + } + }; + + + return wrap; +}; + +module.exports = wrap_couchr(); \ No newline at end of file diff --git a/lib/multicouch.js b/lib/multicouch.js index 0dda74c..a9e0092 100644 --- a/lib/multicouch.js +++ b/lib/multicouch.js @@ -11,6 +11,7 @@ var exec = require("child_process").exec; function MultiCouch(args) { events.EventEmitter.call(this); + var self = this; var prefix = args.prefix || (process.platform === "win32" ? process.env["TEMP"] : "/tmp"); var win_ini, win_bin; if (process.platform === "win32") { @@ -26,7 +27,8 @@ function MultiCouch(args) { default_sys_ini: args.default_sys_ini || system_couch.default_ini || "/usr/local/etc/couchdb/default.ini", pid_file: args.pid_file || prefix + "/couch.pid", couchdb_path: args.couchdb_path || win_bin || system_couch.bin, - respawn: args.respawn === undefined ? 5: args.respawn + respawn: args.respawn === undefined ? 5: args.respawn, + repl: args.repl }; var iniContent = { @@ -46,9 +48,13 @@ function MultiCouch(args) { } }; + this.stdin = process.stdin; + this.stdout = process.stdout; + this.start = function() { // do the start - var out = fs.openSync(options.stdout_file, "a"); + var iin = (options.repl) ? self.stdin : "ignore"; + var out = (options.repl) ? self.stdout : fs.openSync(options.stdout_file, "a"); var err = fs.openSync(options.stderr_file, "a"); if(fs.existsSync(options.ini_file)) { @@ -81,29 +87,32 @@ function MultiCouch(args) { "-detached" ]; couch = spawn(path.join(path.dirname(options.couchdb_path), "erl.exe"),args,{ - stdio:["ignore", out, err], + stdio:[iin, out, err], env: process.env, detached: true, cwd: path.dirname(options.couchdb_path) }); couch.unref(); } else { - args = [ - "-b", - "-o " + options.stdout_file, - "-e " + options.stderr_file, + args = []; + if (!options.repl) args.push("-b"); + if (!options.repl) args.push("-o " + options.stdout_file); + if (!options.repl) args.push("-e " + options.stderr_file); + args.push( "-p " + options.pid_file, "-n", // reset config file chain "-a " + options.default_sys_ini, // re add system default "-a " + options.ini_file - ]; + ); if (options.respawn) { args.unshift("-r " + options.respawn); } couch = spawn(options.couchdb_path, args, { - stdio: ["ignore", out, err], + stdio: [iin, out, err], env: process.env }); + if (options.repl) + options.pid_file = couch.pid } this.emit("start"); }; @@ -113,15 +122,20 @@ function MultiCouch(args) { if (process.platform === "win32") { process.kill(fs.readFileSync(options.pid_file,{encoding:"utf8"})); } else { - var out = fs.openSync(options.stdout_file, "a"); + var iin = (options.repl) ? self.stdin : "ignore"; + var out = (options.repl) ? self.stdout : fs.openSync(options.stdout_file, "a"); var err = fs.openSync(options.stderr_file, "a"); - var couch = spawn(options.couchdb_path, [ - "-d", - "-p " + options.pid_file + "" - ], { - stdio: ["ignore", out, err], - env: process.env - }); + if (options.repl) { + process.kill(options.pid_file); + } else { + var couch = spawn(options.couchdb_path, [ + "-d", + "-p " + options.pid_file + "" + ], { + stdio: [iin, out, err], + env: process.env + }); + } } this.emit("stop"); }; diff --git a/package.json b/package.json index 6b4760c..d4b6784 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "multicouch", - "version": "0.8.2", + "version": "0.8.3", "description": "Launch multiple CouchDBs from the same installation.", "main": "lib/multicouch.js", "scripts": { @@ -11,10 +11,14 @@ "license": "Apache 2", "readmeFilename": "README.md", "dependencies": { + "cli-table": "^0.3.1", "commander": "^1.3.2", - "which": "^1.0.5", + "couchr": "0.0.15", "ini": "^1.2.1", - "shelljs": "^0.2.6" + "json-table": "^0.1.3", + "lodash": "^2.4.1", + "shelljs": "^0.2.6", + "which": "^1.0.5" }, "devDependencies": { "grunt": "^0.4.5",