Send to Kindle

Thursday, March 25, 2010

Spike node-couchdb

‹prev | My Chain | next›

Last night I began my flirtation with node.js (with a decided bias towards CouchDB). I had based some of my exploration on the node-couch, which I found easy to follow along while trying to figure things out. Several folks suggested checking out node-couchdb, so let's give it a whirl...

I clone the repository into ~/repos like all of my other code repositories:
cstrom@whitefall:~/repos$ git clone git://github.com/felixge/node-couchdb.git
Initialized empty Git repository in /home/cstrom/repos/node-couchdb/.git/
...
The instructions for node-couchdb introduce me to the node.js location for libraries, which, for local users, are stored in :
cstrom@whitefall:~$ mkdir ~/.node_libraries
cstrom@whitefall:~$ cd !$
cd ~/.node_libraries
cstrom@whitefall:~/.node_libraries$ ln -s ../repos/node-couchdb
To use that library in a node.js script, I need to assign a local variable to the result of a require statement:
// ...
couchdb = require('node-couchdb/lib/couchdb'),
//...
The node-couchdb is the repository I just symlinked and lib/couchdb point to a couchdb.js in that directory. I am eager to explore that library to figure out how it returns an object assigned to the couchdb variable, but I will likely leave that for another day. For now, I try to use the couchdb variable to print out a list of all DBs, just as I did manually last night:
var
sys = require('sys'),
couchdb = require('node-couchdb/lib/couchdb'),
client = couchdb.createClient(5984, 'localhost');

sys.puts(client.allDbs());
The allDbs() method definition does not contain a callback in the documentation, so I wonder if it will work like this:
cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.js
undefined
Ah, it does not. It is beginning to dawn on me that everything needs a callback in node.js. I am not sure how many arguments are needed for allDbs(), but I would guess just a callback:
var
sys = require('sys'),
couchdb = require('node-couchdb/lib/couchdb'),
client = couchdb.createClient(5984, 'localhost');

client.allDbs(function (er, data) {
sys.puts(data);
});
The other request methods in node-couch have callbacks with two arguments: an error object (set only if an error occurs) and a data object. Above, I am assuming no errors. Running this script, I find:
cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.js 
eee,test,seed
Cool! That is a lot less code than I had to use last night, so node-couchdb is already a win.

Ooh! There is a replicate() method in node-couchdb! And it accepts options like {create_target:true}? I cannot resist replication, but I was not even aware there was a {create_target:true}—now I have to try this out. So I boot three of my VMs, then I modify my script to output all DBs on my localhost CouchDB instance and on one of my VMs:
var
sys = require('sys'),
couchdb = require('node-couchdb/lib/couchdb'),
client = couchdb.createClient(5984, 'localhost'),
clienta = couchdb.createClient(5984, 'couch-011a.local'),
clientb = couchdb.createClient(5984, 'couch-011b.local'),
clientc = couchdb.createClient(5984, 'couch-011c.local');

client.allDbs(function (er, data) {
sys.puts(data);
});

clientc.allDbs(function (er, data) {
sys.puts(data);
});
Running that script I find that the VM does not have a "seed" DB:
cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.js 
eee,test,seed
test
Now, if {create_target:true} does what I think it does, then I ought to be able to replicate the "seed" DB onto clienta, then replicate it from clienta to clientb, and finally from clientb to clientc. Will this work?
var
sys = require('sys'),
couchdb = require('node-couchdb/lib/couchdb'),
client = couchdb.createClient(5984, 'localhost'),
clienta = couchdb.createClient(5984, 'couch-011a.local'),
clientb = couchdb.createClient(5984, 'couch-011b.local'),
clientc = couchdb.createClient(5984, 'couch-011c.local');


client.allDbs(function (er, data) {
sys.puts(data);
});

clientc.allDbs(function (er, data) {
sys.puts(data);
});

client.replicate("seed", "http://couch-011a.local:5984/seed", {create_target:true});
clienta.replicate("seed", "http://couch-011b.local:5984/seed", {create_target:true});
clientb.replicate("seed", "http://couch-011c.local:5984/seed", {create_target:true});


clientc.allDbs(function (er, data) {
sys.puts(data);
});
If it does work, the last line should include a "seed" DB in the output:
cstrom@whitefall:~$ ./local/bin/node ./tmp/node-couch.js
eee,test,seed
test
test
Dang. Checking the localhost log, I see:
[Fri, 26 Mar 2010 02:43:56 GMT] [debug] [<0.2440.0>] httpd 404 error response:
{"error":"db_not_found","reason":"could not open http://couch-011a.local:5984/seed/"}
I am not positive, but that trailing slash on "seed" seems wrong. I am not sure if the problem is that or just that the {create_target:true} is not being honored.

I'm at a bit of a loss at this point, so I will pick it back up starting here tomorrow.

Day #53

No comments:

Post a Comment