Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

PJsonCouch

landeiro edited this page · 6 revisions
Clone this wiki locally

PJsonCouch

(PJs-on-Couch) is a node.js client lib for CouchDB.

PJsonCouch it means Pure-Json-on-Couch but it should be read PJs-on-Couch :)

Why.

The main idea is to use as most as possible JSON for data transport.

For example the CouchDB URL invocation:

/developers/_design/basic_info/_view/by_name?reduce=false&key="Jane"

translates to:

{db:"developers",design:"basic_info",view:"by_name",args:{reduce:false,key:"Jane"}}

With this method we can send all data necessary to query views in the same structure:

{db:"developers",design:"basic_info",view:"by_name",args:{reduce:false},request:{keys:["Jane"]}}

Requirements

Tested on node.js v0.4.7 and CouchDB 1.1.1

PJsonCouch requires knowing the CouchDB API and does not intend to overcome the logic behind the original API.

How is PJsonCouch organized?

PJsonCouch is inspired on the CouchDB HTTP API structure, so is divide in 4 main blocks

  • Database Methods.
  • Document Methods / Local (non-replicating) Document Methods
  • Design Document Methods
  • Miscellaneous Methods

Examples

How to connect to CouchDB without db definition and request a complex query to _all_docs

    // Constructor without db definition
    var test = PJsonCouch({
        host : "127.0.0.1",
        port : 5984
    });

    // set a DB, this does not have callbackfuntion
    test.setDB({
        db : "thisisatempdb"
    });

    // Login if your DB is protected
    test.login({
        user : "landeiro",
        password : "123"
    }, function(r) {
        // Get all docs from DB, supports all args and request data from original couchdb API
        test.queryDB({
            action : "_all_docs",
            args : {
                descending : true,
                startkey : "objmyid6",
                endkey : "objmyid2"
            }
        }, function(r) {
            log("*queryDB start/endkey*", r);
        });
        test.queryDB({
            action : "_all_docs",
            request : {
                keys : ["objmyid1", "objmyid7"]
            }
        }, function(r) {
            log("*queryDB keys*", r);
        });
    });

How to connect to CouchDB with db definition and execute some docs operations

    var test = PJsonCouch({
        host : "127.0.0.1",
        port : 5984,
        db : "mydatabase"
    });

    // Docs for test
    var docs = [{
        _id : "objmyid0",
        a : 0
    }, {
        _id : "objmyid1",
        a : 1
    }, {
        _id : "objmyid2",
        a : 3
    }];

    // Save bulk, supports all request data from original couchdb API
    test.saveBulkDocs({
        docs : docs
    }, function(r) {
        log("insert bulk", r);
        // Get Doc, supports all arguments from original couchdb API
        test.getDoc({
            id : "objmyid0"
        }, function(gdoc) {
            log("*get doc*", gdoc)
            if(!gdoc.error) {
                // Delete a Doc, supports all arguments from original couchdb API
                test.deleteDoc({
                    doc : gdoc
                }, function(r) {
                    log("*deleted " + gdoc._id + "*", r);
                });
            }
        });
    });

Some random server operations

    test.server({}, function(r) {
        log("*welcome msg*", r);
    });

    // Show active tasks
    test.server({
        action : "_active_tasks"
    }, function(r) {
        log("*active tasks*", r);
    });

Start continuos replication database. Replication supports all configuration from original couchdb API

    test.server({
        action : "_replicate",
        source : "thisisatempdb",
        target : "http://somedomain.com/land",
        continuous : true
    }, function(r) {
        log("*replicate*", r);
        // Cancel continuos replication database, supports all configuration from original couchdb API
        test.server({
            action : "_replicate",
            source : "thisisatempdb",
            target : "http://somedomain.com/land",
            continuous : true,
            cancel : true
        }, function(r) {
            log("*cancel    replication*", r);
        })
    });

Some random design doc operations

    // List customers using view by_name from "Jane" to "Pedro"
    test.queryDesign({
        design : "design_doc",
        list : "customers",
        view : "by_name",
        args : {
            startkey : "Jane",
            endkey : "Pedro"
        }
    }, function(r) {
        log("*get list with view with args*", r);
    });
    // Display a Doc using Show costumer, supports all arguments from original couchdb API
    test.queryDesign({
        design : "design_doc",
        show : "customer",
        id : "3535e007bd9c765de0554c0a4900385b"
    }, function(r) {
        log("*get show*", r);
    });
    // Getting docs using view by_name with request keys ["Jane"] and argument limit=1
    test.queryDesign({
        design : "design_doc",
        view : "by_name",
        args : {
            limit : 1
        },
        request : {
            keys : ["Jane", "joey"]
        }
    }, function(r) {
        log("*get view with request and args*", r);
    });

Errors can be configured to return a lot of debug, like request content and headers.

Cannot connect do CouchDB

    { error: 'request_to_couchdb',
      detail: 
       { stack: 'Error: ECONNREFUSED, Connection refused\n    at Socket._onConnect (net.js:576:18)\n    at IOWatcher.onWritable [as callback] (net.js:165:12)',
         message: 'ECONNREFUSED, Connection refused',
         errno: 61,
         code: 'ECONNREFUSED',
         syscall: 'connect' },
      debug: 
       { content: '""',
         request: 
          { protocol: 'http',
            host: '127.0.0.1',
            port: 5984,
            path: '/_log?bytes=2000',
            method: 'GET',
            headers: [Object],
            agent: [Object] } } }

Unauthorized

    { error: 'unauthorized',
      reason: 'You are not a server admin.',
      debug: 
       { content: '""',
         request: 
          { protocol: 'http',
            host: '127.0.0.1',
            port: 5984,
            path: '/_active_tasks',
            method: 'GET',
            headers: [Object],
            agent: [Object],
            content_type: 'text/plain;charset=utf-8',
            content_length: '64' },
         resultHeaders: 
          { server: 'CouchDB/1.1.1 (Erlang OTP/R14B)',
            location: 'http://127.0.0.1/_utils/session.html?return=%2F_active_tasks&reason=You%20are%20not%20a%20server%20admin.',
            date: 'Tue, 26 Apr 2011 11:47:53 GMT',
            'content-type': 'text/plain;charset=utf-8',
            'content-length': '64',
            'cache-control': 'must-revalidate' } } }

How to send data to couch using JSON?

Data is sent with some pre-defined properties:

  • db: string - defines the database to use.
  • args: {} - defines the group of arguments (url parameters).
  • request: {} - defines the group of elements to send in the request
  • design: string - defines the design doc to be used
  • view: string - defines the view to be used
  • list: string - defines the list to be used
  • show: string - defines the show to be used
  • local: boolean - specifies if the referred doc is local
  • doc: {} - identifies a doc
  • id - string - refers to a doc id
  • rev - string - refers to a doc revision
  • action - string - defines an action
  • source - string - defines the source for replication
  • destination - string - defines the destination for replication
  • attachment: {} - defines an attachment
  • content: string - defines the content of an attachment
  • content_type - string - defines the content type of an attachment
  • content_length - number - defines the length of an attachment
  • content_encoding - string - defines the encoding of an attachment
  • if_match:string - defines the rev of an attachment

The properties defined in the objects "args" and "request" could have anything you want to send in the URL variables and/or in the request.

What does it do.

Here is the list of CouchDB API supported with examples

Constructor

With DB definition:

var couch = PJsonCouch({protocol:"http",host:"127.0.0.1",port:5984,db:"test"});

Without BD:

var couch = PJsonCouch({protocol:"http",host:"127.0.0.1",port:5984});

This only builds a instance of the object and does not connect to CouchDB yet.

Special Methods (without callbackfunction)

Get login session hash

getSession()

Set database to use

setDB({db:"mydatabase"})

Get database in use

getDB()

Set debug confguration (all properties are optional)

setDebugConfig({debug:false, debugWithHeaders:true, debugOnError:true, throwExceptionsOnError:false});

Database Methods

The {db:"mydatabase"} is optional (exception of createDB and deleteDB) if have you setDB before or defined in the constructor.

Existing methods:

  • createDB
  • deleteDB
  • queryDB

Create a new database

createDB({db:"mydatabase"})

Delete an existing database

deleteDB({db:"mydatabase"})

Returns database information

queryDB({db:"mydatabase"})

Returns a built-in view of all documents/ certain rows in this database (supports all arguments defined in CouchDB API)

//examples
queryDB({db:"mydatabase",action:"_all_docs", args:{descending:true,startkey:"Jane",endkey:"Peter"}})
queryDB({db:"mydatabase",action:"_all_docs", request:{keys:["Jane"]}}) 

Returns changes for the given database (argument feed only supports normal mode)

queryDB({db:"mydatabase",action:"_changes", args:{limit:10}}) 

Starts a compaction for the database

queryDB({db:"mydatabase",action:"_compact"}) 

Makes sure all uncommitted changes are written and synchronized to the disk

queryDB({db:"mydatabase",action:"_ensure_full_commit"}) 

Purge some historical documents entirely from database history

queryDB({db:"mydatabase",action:"_purge",request:{"myID":["myRev"]}})

Given a list of document revisions, returns differences between the given revisions and ones that are in the database

queryDB({db:"mydatabase",action:"_revs_diff"}) 

Gets the limit of historical revisions to store for a single document in the database

queryDB({db:"mydatabase",action:"_revs_limit"}) 

Returns the special security object for the database

queryDB({db:"mydatabase",action:"_security"}) 

Sets the special security object for the database

queryDB({db:"mydatabase",action:"_security",request:{admins:{roles: [],names: ["mc","slp"]}}})

Execute a given view function for all documents and return the result

queryDB({db:"mydatabase",action:"_temp_view",request:{map : "function(doc) { if (doc.value > 9995) { emit(null, doc.value); } }"}})

Removes view files that are not used by any design document

queryDB({db:"mydatabase",action:"_view_cleanup"}) 

Document Methods / Local (non-replicating) Document Methods

The {db:"mydatabase"} is optional if have you setDB before or defined in the constructor.

Existing methods:

  • getDoc
  • saveDoc
  • deleteDoc
  • infoDoc
  • copyDoc
  • getDocAttachment
  • saveDocAttachment
  • deleteDocAttachment

Create a new document (supports all arguments defined in CouchDB API)

//examples
saveDoc({db:"mydatabase",doc:{name:"pedro",surname:"landeiro"}})  
saveDoc({db:"mydatabase",doc:{_id:"myOwnId",name:"pedro",surname:"landeiro"}})
saveDoc({db:"mydatabase",doc:{_id:"myOwnId",name:"pedro",surname:"landeiro"}})
saveDoc({db:"mydatabase",doc:{_id:"myOwnLocalId",name:"This is a local doc"},local:true})  

Returns the latest revision of the document (supports all arguments defined in CouchDB API)

//examples
getDoc({db:"mydatabase",id:"myOwnId",args:{rev:"revOfTheDocument"}})
getDoc({db:"mydatabase",id:"myOwnId"},local:true)

Returns bare information in the HTTP Headers for the document (supports all arguments defined in CouchDB API)

infoDoc({db:"mydatabase",id:"myOwnId",args:{rev:"revOfTheDocument"}}})

Insert multiple documents in to the database in a single request (This method is originally part of Database methods CouchDB API)

saveBulkDocs({db:"mydatabase",docs:[{_id:"myOwnId",name:"docWithId"},{name:"docWithouId"}]})

Deletes the document (supports all arguments defined in CouchDB API)

//examples
deleteDoc({db:"mydatabase",doc:{_id:"myOwnId"},args:{rev:"mycurrentRev"}})
deleteDoc({db:"mydatabase",doc:{_id:"myOwnId",_rev:"myCurrentRev"}})

Copies the document

copyDoc({db:"mydatabase",source:{id:"sourceId",rev:"sourceRev"},destination:{id:"destId",rev:"destRev"})

Gets the attachment of a document

//examples
getDocAttachment({db:"mydatabase",id:"docIdWithTheAttachment",attachment:{file:"isATextFile"}})
getDocAttachment({db:"mydatabase",id:"docIdWithTheAttachment",attachment:{file:"isAImage",content_encoding:"binary"}})        

Adds an attachment of a document

c.saveDocAttachment({db:"mydatabase",id:"docId",rev:"docRevId",attachment:{file:"filename",content:"content of file",content_type:"text/plain", if_match:"docRevId"}});

Deletes an attachment of a document

c.deleteDocAttachment({db:"mydatabase",id:"docIdWithTheAttachment",rev:"docRevIdWithTheAttachment",attachment:{file:"filename"}});

Design Document Methods

Existing methods:

  • queryDesign
  • infoDesign

The {db:"mydatabase"} is optional if have you setDB before or defined in the constructor.

Returns the latest revision of the design document

queryDesign({db:"mydatabase",design:"design_doc"})

Returns information about the design document

infoDesign({db:"mydatabase",design:"design_doc"})

Invokes the list handler to translate the given view results (supports all arguments defined in CouchDB API)

queryDesign({db:"mydatabase",design:"design_doc",list:"customers",view:"by_name"})

Invokes the list handler to translate the given view results for certain documents (supports all arguments and request data defined in CouchDB API)

queryDesign({db:"mydatabase",design:"design_doc",list:"customers",view:"by_name",args:{reduce:false},request:{keys:["Jane"]}})

Invokes the show handler for the given document (supports all arguments defined in CouchDB API)

queryDesign({db:"mydatabase",design:"design_doc",show:"customer",id:"docId})

Returns results of the view (supports all arguments and request data defined in CouchDB API)

//examples
queryDesign({db:"mydatabase",design:"design_doc",view:"by_name",args:{reduce:false,key:"Jane"}})
queryDesign({db:"mydatabase",design:"design_doc",view:"by_name",args:{reduce:false,startkey:["key1",0],endkey:["key4",100]}});

Returns certain rows from the view (supports all arguments and request data defined in CouchDB API)

queryDesign({db:"mydatabase",design:"design_doc",view:"by_name",args:{reduce:false},request:{keys:["Jane"]}})

Miscellaneous Methods

Existing methods:

  • server
  • login
  • logout

Get the welcome message and version information

server({})          

Obtain a list of the tasks running in the server

server({action:"_active_tasks"})

Get a list of all the DBs

server({action:"_all_dbs"})

Return the server log file

//examples
server({action:"_log"})
server({action:"_log",args:{bytes:2000}})

Set or cancel replication

//examples
server({action:"_replicate",source:"sourceDB",target:"targerDB",continuous:true})   
server({action:"_replicate",source:"sourceDB",target:"targerDB",continuous:true,cancel:true})   

Return server statistics

server({action:"_stats"})

Get generated UUIDs from the server

server({action:"_uuids"})
server({action:"_uuids",args:{count:15}})

How to login and logout

Returning results

CouchDB returns in JSON by default. For the other content like results from lists, shows, or attachments, the result comes on the special property not_json, with the indication of content-type and length, heres an example:

{ content_type: 'text/html; charset=utf-8',lenght: undefined, not_json: '<p>Customers</p><ul><li>Jane</li></ul>'}

Errors.

PJsonCouch can be configure to report errors in JSON format or through exceptions.

var config = {
        debug: false, // always returns debug data  if true 
        debugWithHeaders: false, // when debug return also the result headers from CouchDB
        debugOnError:true, // only return debug on error
        throwExceptionsOnError: false // throws exceptions instead of error object if true
    }

Example of unknown database:

{ error: 'not_found',
    reason: 'no_db_file',
    debug: 
        { content: '{"keys":["Jane"]}',
            request: 
            { protocol: 'http',
            host: '127.0.0.1',
            port: 5984,
            db: 'bandfk',
            path: '/bandfk/_design/design_doc/_list/customers/by_name?reduce=false',
            method: 'POST',
            headers: [Object],
            agent: [Object],
            content_type: 'text/plain;charset=utf-8',
            content_length: '44' } } }

Example of CouchDB offline:

{ error: 'request_to_couchdb',
    detail: 
    { stack: 'Error: ECONNREFUSED, Connection refused\n    at Socket._onConnect (net.js:576:18)\n    at IOWatcher.onWritable [as callback] (net.js:165:12)',
    message: 'ECONNREFUSED, Connection refused',
    errno: 61,
    code: 'ECONNREFUSED',
    syscall: 'connect' },
    debug: 
    { content: '{"keys":["Jane"]}',
        request: 
            { protocol: 'http',
            host: '127.0.0.1',
            port: 5984,
            db: 'bank',
            path: '/bank/_design/design_doc/_list/customers/by_name?reduce=false',
            method: 'POST',
            headers: [Object],
            agent: [Object] } } }
Something went wrong with that request. Please try again.