Tag Archives: design document

CouchDB, Validation functions

The last CouchDB post was about Design Documents, and we described how it’s possible to create views directly on it. Now this post is about another part of Design Documents and it’s fundamental on a CouchDB project context.

We already know that CouchDB is a schema free document oriented database, this means that there are no constraints when we create / update documents ! now let’s imagine that every user of the CouchDB application can create any kind of document with what he wants .. we need to deal with data consistency and for that we’ll need Validation Functions !

The Validation Function definition :

It’s important to know that Validation functions are optional, if you don’t define them there will be no check. Also validation functions are stored on the Design Document under the “validate_doc_update” field.

  function(newDoc, oldDoc, userCtx) {}
  • newDoc is for the incoming document.
  • oldDoc is the current saved document.
  • userCtx the user object doing the request.

Now let’s try to add a validation function to a design document, what you need is to open Futon then :

choose a database > view “Design documents” > Choose a design

Now edit the document and add this at the end of document defintion :

"validate_doc_update": "function(newDoc, oldDoc, userCtx) {
  throw({forbidden : 'you are not allowed !'
});}"

You will get something like this (you’ll need to save the document) :

couchDb validation function

Okey now let’s try to create an new document using Curl :

curl -X PUT http://127.0.0.1:5984/contacts/contactValidation -d '{"name" : "contact validation"}'
//return
{"error":"forbidden","reason":"you are not allowed !"}

Et voilà ! the validation function has thrown an exception and no more document creation / update is possible ! now lets tune it a little bit. We are using a contact database so we’ll not permit creation of document without name, and phone fields :

function(newDoc, oldDoc, userCtx) {
   function require(field){
      var message = field + ' is required';
      if(!newDoc[field]){
         throw({'forbidden':message})
      }
   }
   require('name');
   require('phone')}

Okey let’s try again with curl :

curl -X PUT http://127.0.0.1:5984/contacts/contactValidation -d '{"name" : "contact validation"}'
{"error":"forbidden","reason":"phone is required"}

And now we add required fields :

curl -X PUT http://127.0.0.1:5984/contacts/contactValidation -d '{"name" : "contact validation", "phone":"123-1111"}'
{"ok":true,"id":"contactValidation","rev":"1-8330cb19d688702b4c24e3ae468f31f2"}

And it’s working ! as you can see it’s simple to check document consistency with simple javascript tests ! Hope you like this post.

CouchDB, Design Documents

In this post i will try to talk about another concept of CouchDb “Design Documents” ( you can read the last post that i wrote about CouchDB views it will be a reference for the rest of this content)

So what are Design Documents ?? in the last tutorial we created temporary views then we stored them into permanent views. These views are stored on a special document called Design Document ! Let’s see what we have on futon :

You have to go to : contact database  > then choose View “Design Documents” :

Then choose “_design/contacts” :

You will notice that also a design Document is a Document ! Let’s explain what we have here :

language : is the language used for the views, usually it’s Javascript but in the latest Versions of CouchDB you can use Erlang.

views : contains all the views included with the contact document, and for every view you can find the map and reduce functions :

{
   "_id": "_design/contacts",
   "_rev": "1-a8487fd2a8b3698a19a5ae6dd59b178d",
   "language": "javascript",
   "views": {
       "phones": {
           "map": "function(doc) {
              if(doc.phone){
                  temit(doc._id, doc.phone);
              }
           }"
       }
   }
}

Creating permanent Views using Curl

We already know how to execute a view using curl :

curl -X GET http://127.0.0.1:5984/contacts/_design/contacts/_view/phones

Now we will try to create a new view to get “contact names”, so first of all we need to create our new Design Document :

{
  "language" : "javascript",
  "views" : {
    "contact_names" : {
      "map" : "function(doc){
         emit(doc._id, {Name : doc.firstName});
      }"
    }
  }
}

As you can see the json document have the same structure of the first Design Document.
Now let’s tell Couch to add our new json definition :

curl -X PUT http://127.0.0.1:5984/contacts/_design/new_design -d @new_design.json

will return :

{"ok":true,"id":"_design/new_design",
    "rev":"1-485e1a6b2ab85442744a994da51eb9c0"}

Now to call the new view :

curl -X GET http://127.0.0.1:5984/contacts/_design/new_design/_view/contact_names

getting :

{"total_rows":2,"offset":0,"rows":[
  {"id":"joelennon","key":"joelennon","value":{"Name":"Joe"}},
  {"id":"johnsmith","key":"johnsmith","value":{"Name":"John"}}
]}

That’s all ! hope you enjoy using CouchDB :)