Git Product home page Git Product logo

couch-client's Introduction

Couch Client

Couch Client is a simple wrapper around CouchDB's http interface.

"CouchDB is a document-oriented, Non-Relational Database Management Server (NRDBMS)."

This wrapper/driver implements some nice things like request batching and automatic revision and key generation. Usage should be simple and straight-forward. For anything advanced, a simple http client is exposed that already connected to the couch server.

CouchClient(url) - A client factory

This module exports a single factory function called CouchClient. Usage is simple, it takes a single url for the connection to the database.

var CouchClient = require('couch-client');
var Users = CouchClient("http://username:password@yourhost:5984/users");

Since this assumes many defaults, for local testing on a stock CouchDB build, you can connect with simply CouchCLient("/users").

This object will internally keep track of revisions it's seen before and batches http requests that happen in the same "tick" to go out at the same time using CouchDB's batch processing APIs.

The resulting object has the following four functions (save, get, remove, request);

The default port is 5984.

CouchClient.save(doc, callback) - Save a document

Pass in a document and it will save it to the database. If the document happens to have a _id property that that will be used as the key. Also if the document has a _rev property, that will be passed to the server. If they are missing, CouchClient will provide an automatic UUID using CouchDB's services and look up the latest revision. Revisions are remembered.

Users.save({_id: "creationix", name: "Tim Caswell", age: 28}, function ( err, doc) {
  // You know know if there was an error and have an updated version
  // of the document (with `_id` and `_rev`).
});

CouchClient.get(key, callback) - Load a document

Once you put data in the database, it's nice to be able to load it back out. The .get() function takes a key as a string and returns the document in a callback.

Users.get("creationix", function (err, doc) {
  // Now you have the document or error if there was trouble
});

CouchClient.view(path, obj, callback) - Call a view

view takes a path to a view, an object containing GET parameters, and a callback

Users.view('/users/_design/design_name/_view/usernames', {key: "creationix"}, function(err, doc) {
    // Now you have the document(s) or error if there was trouble
});

If obj is missing then it returns all the items in the view.

CouchClient.remove(key/doc, callback) - Remove a document

Sometimes you want to remove documents from the database. This function takes either a key as a string or a document with an _id property. It will tell couch to delete it and give you back the modified document with the _deleted property.

Users.remove("creationix", function (err, doc) {
  // If there was no error, it's gone
});

CouchClient.request(method, path, body, callback) - Arbitrary HTTP request.

This is the helper used internally to execute HTTP requests against the CouchDB database. It's exposed here because CouchDB provides a very rich interface, and it can't all be easily wrapped. The body parameter is optional and should be passed in as a raw JavaScript object.

Users.request("GET", "/some_database/_design/company/_view/all", function (err, result) {
  // result is a javascript object of CouchDB's response JSON
});

// Manually insert a single document
Users.request("PUT", "/foo/bar", {Foo:"Bar"}, function (err, result) {
  // result is a javascript object of CouchDB's response JSON
});

Also if you omit the callback an EventEmitter object that emits "data", "end", and "error" events. Note that the data events are not parsed. They are raw utf8 strings.

CouchClient.changes(since, callback) - Watch for changes to the database.

CouchDB provides a neat feature known as the _changes feed. This allows you do watch a database and be notified when it's changed. The changes() function is a wrapper. You give it the since parameter and a callback. The callback is called once per JSON document in the response stream.

Testing

The basicTests file currently tests a;

Adding Tests

Add tests to the basicTests.js file. Test function names need to start with 'test'.

testSomething:function() {
	// testing something
},

Contributing

  • please include tests with your pull requests.

Changes from 0.0.3 -> 0.0.4

  • view improvements / fixes
  • basic auth support

Contributors

flashingpumpkin dready92 devioustree hij1nx steelThread candland

couch-client's People

Contributors

candland avatar creationix avatar devioustree avatar dready92 avatar flashingpumpkin avatar nick avatar sgentle avatar steelthread avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

couch-client's Issues

_bulk_docs response undefined

Every once in awhile when using save() my program crashes with this error:

node.js:183
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
TypeError: Cannot read property 'error' of undefined
    at /root/bro-bot/node_modules/couch-client/lib/couch-client.js:134:20
    at ClientRequest.errorHandler (/root/bro-bot/node_modules/couch-client/lib/couch-client.js:47:23)
    at ClientRequest.emit (events.js:64:17)
    at Socket.<anonymous> (http.js:1216:11)
    at Socket.emit (events.js:64:17)
    at Array.<anonymous> (net.js:833:27)
    at EventEmitter._tickCallback (node.js:175:26)

realGet actually Posts?

I don't understand why you guys chose to use POST in your get() method to pull documents. Could someone explain this? It doesn't make sense to me.

Thanks.

Server crashing when receiving a connection refused error message from Couchdb

When calling the "get" message with (id, callback), and attempting to connect on a closed port or to a server which is down (and refusing connections), looks like the error message is improperly handled causing the app server to crash with the following output:

node.js:116
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: ECONNREFUSED, Connection refused
at Client._onConnect (net.js:576:18)
at IOWatcher.onWritable as callback

This may be a nodejs issue? Currently running with nodejs 4.1.

NPM 0.3.0 install fails

Since NPM now expects a proper JSON in the package.json, couch-client now fails to install/depend on. (it's the last comma before the ending } that causes it)

merge

Hey :)

Would you be interested in having a CouchClient#merge (or #update) method that requires an _id and just updates the attributes provided, while leaving others untouched?

This would make obsolete the task of getting the previous document first in order to merge the changes into the object that's being passed to #save.

Would this make sense?

Error when saving with outdated _rev value

Hi,
I ran into this problem, that might be relevant for other users as well:

  1. Create document with couch-client, receiving _rev 1-X
  2. Change document NOT with couch-client, i.e. by using Futon, resulting in _rev 2-Y
  3. Call save() again from couch-client. => Will NOT cause error in callback, but faulty doc (_rev undefined).

The actual CouchDB response to the bulk_docs POST contains the appropriate error (conflict), which is not handled by couch-client however.

I'm using CouchDB 1.0.2, couch-client 0.0.4 and node.js 0.4.7

Thanks for your help!
Greets

The request method should allow functions in body to be able to save design docs correctly

Example request:
databaseClient.request("PUT", designName, designDoc, function(err, data) {} );

Design doc contains functions and they are cut off internally by JSON.stringify. Please, enhance this line:

body = JSON.stringify(body)

with this snippet:

body = JSON.stringify(body, function(key, val) {
  if (typeof val == 'function') {
    return val.toString();
  }
  return val;
});

Response missing for arbitrary HTTP requests

When using the arbitrary HTTP request function, it would be helpful to have access to the response code. Otherwise, this prevents the simple detection of "Conflict" or "Not Found" responses, because only the response body is accessible.

Default Port of 5984 Breaking Connections to Cloudant over HTTPS

I'm trying to setup an app on Heroku. Heroku provides the URL to the your couch instance through an environment variable. So connecting to the database would be achieved like this:

var CouchClient = require('couch-client');
var client = new CouchClient(process.env.CLOUDANT_URL + "/myDocument")

The resulting URL is over HTTPs, however, because the port 5984 is defaulted, the connection never works.

See: http://support.cloudant.com/kb/faqs/does-cloudant-support-ssl
And: http://devcenter.heroku.com/articles/cloudant

basic auth not working

When trying to create a db with this client, I get
{"error":"unauthorized","reason":"You are not a server admin."}

I scanned the code and didn't see anything resembling setting auth headers, even though some of the examples/tests included user:pass@host:port type url strings.

(felixge / node-couchdb works for me, but he's not maintaining anymore...)

My snippet of code that fails follows. user and pass are valid admin, and the couchdb is set to require authentication (not in admin party mode). Also, the database does not yet exist

  var url_obj = {'host':user+':'+pass+'@'+host,
               'port':port,
               'pathname':"/"+dbname };
  var url_string = formatUrl(url_obj);
  console.log ('url string is '+ url_string);

  var cdb  = CouchClient(url_string);
  cdb.request('PUT',"/"+dbname, function(e,r){
      if(e) console.log('e is '+JSON.stringify(e)); // does not trigger0
      console.log('r is '+JSON.stringify(r));
     // prints:
     //  {"error":"unauthorized","reason":"You are not a server admin."}
  });

changes should allow arbitrary query params

I need to specify a filter for my changes function. I think the first argument should be an options hash so that that can be done. (Also filters can take arbitrary query params, so those are definitely needed.)

I do agree with the default hearbeat and feed setting you have.

Works on localhost, crashes using Cloudant

Using the same database works find on local, but when replicated to Cloudant the connection crashes Node.js with an exception:

undefined:1

SyntaxError: Unexpected token ILLEGAL
at Object.parse (native)
at IncomingMessage. (/usr/local/Cellar/node/0.2.3/lib/node/.npm/couch-client/0.0.1/package/lib/couch-client.js:86:45)
at IncomingMessage.emit (events:41:20)
at HTTPParser.onMessageComplete (http:107:23)
at Client.onEnd as onend
at IOWatcher.callback (net:472:28)
at node.js:768:9

I can connect to the db using curl and retrieve data, and Node's JSON module can parse the data retrieved by curl just fine, so I'm not sure what's going on.

HEAD requests fail

When I try to perform a HEAD request I get this:

undefined:0

^
SyntaxError: Unexpected end of input
    at Object.parse (native)
    at IncomingMessage.<anonymous> (/usr/local/lib/node/.npm/couch-client/0.0.4/package/lib/cou ch-client.js:80:45)
    at IncomingMessage.emit (events.js:81:20)
    at HTTPParser.onMessageComplete (http.js:132:23)
    at Socket.ondata (http.js:1206:22)
    at Socket._onReadable (net.js:675:27)
    at IOWatcher.onReadable [as callback] (net.js:177:10)

Does couch-client support HEAD requests?

Beyond Basic Auth Bugs

Hey guys,

I too have been trying to work with couchone and here 's what I've found out when using couch-client with node v0.3.x. First using the ftp style credential passing on the url simply doesn't work. What happens is the parsed uri.host includes the credentials which in turn gets added as the 'host' header. Resulting response body is 'Host not found' but this is getting hidden and couch-client simply errors out. I didn't spend a lot of time finding the exact line but I think this is when the client is trying to JSON.parse the body for the callback. Solution is to use 'hostname' field of the parsed uri. Seems pretty redundant to specify this on the http.createClient call too.

The second issue is that in order to pass the credentials along, the authorization header needs to be set. The parsed uri still has an 'auth' field so this should be simple to add. It does seems a little odd and disjoint to me that, from an API perspective, this form of credential passing is supported by url parser but not natively supported by the http client.

Finally, and this is a show stopper, I have made the appropriate changes to the code so i can at least use basic auth with my couchone app. The big problem is that TLS (SSL) is not currently working in node v0.3.x for http clients, at least I can't get it to work. I think the server stuff was recently reworked and the client stuff is coming soon. Of course none of the .3.x versions are marked as stable so keeping up with the bleeding edge right now is somewhat futile and very frustrating.

In any case I just wanted to pass this along in case others are running into similar issues. I'd submit a pull request but seeing how the solution (only) allows you to pass your credentials over an unsecured channel I don't think any one of us would want to promote such usage. I'll watch for node updates and once the client stuff stabilizes I'll work up a patch and submit it then if someone doesn't get to it beforehand.

later

save writes over previous document

The current behavior of save() in couch-client is risky. The couchdb way is to require a _rev property to save over a previous version, to avoid conflicts, but couch-client "automagically" retrieves the current version and simply overwrites it.

This is not what I expected and requires the client to do a separate HEAD/GET lookup just to find out whether a save is safe. Actually, between that get() and the new save(), the doc could have been updated, so save() is never safe to use in couch-client. :-(

I think save() should be changed to never overwrite a previous document, unless a _rev is specified, or some kind of parameter option for this should be provided. Unfortunately this requires me to fork couch-client just to get a safe save(), which is a necessity in most non-toy applications.

I'm willing to help provide a patch for any of these options.

Broken on Node 0.4.7

The latest Node release (at the time of writing, 0.4.7) breaks compatibility with couch-client, with the following error:

TypeError: Object # has no method 'match'
at Object.urlParse as parse
at CouchClient (/home/corey/local/node/lib/node/.npm/couch-client/0.0.4/package/lib/couch-client.js:24:17)
at Object.query (/home/corey/Dropbox/Public/node-mvc/db/couchdb.js:76:18)
at Object. (/home/corey/Dropbox/Public/node-mvc/example/home/views.js:7:13)
at nextMiddleware (/home/corey/local/node/lib/node/.npm/express/2.3.2/package/lib/router/index.js:139:34)
at param (/home/corey/local/node/lib/node/.npm/express/2.3.2/package/lib/router/index.js:147:16)
at pass (/home/corey/local/node/lib/node/.npm/express/2.3.2/package/lib/router/index.js:155:10)
at Object.router as handle
at next (/home/corey/local/node/lib/node/.npm/connect/1.4.0/package/lib/http.js:204:15)
at next (/home/corey/local/node/lib/node/.npm/connect/1.4.0/package/lib/http.js:206:9)

Setting Host header incorrectly

I believe that line 52 where you are setting the Host header is incorrect. You want to be using the host property of the uri instead of hostname because it includes the port:

var headers = {
  "Host": uri.host
};

_all_docs

is that really neccessary to do this that way? just for getting a document out of thousands, this lib downloads every doc? weird, sorry. you can offer more useful things. because its easy todo get("/id") -> .../database/_id

:D sorry, but this implementation i really dislike

revCache never being cleared

Hi,
Prior to using the library I was reading the source code and couldn't help but notice the odd use of revCache for trying to allow saves without revisions. Leaving aside the question of whether this is a little heavy-handed, I can't see anywhere where you are clearing the revCache entries. Am I reading this right to assume that a long lived CouchClient instance will leak memory continuously? Is a client instance only meant to be used for short interactions?

Thanks.

  • stella

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.