### Navigation

- index
- next |
- previous |
- Apache CouchDB 1.3 Manual »

# 12. Query servers

## 12.1. JavaScript

Note

While every design function has access to all JavaScript objects, the table below describes appropriate usage cases. For example, you may use `emit()` in List functions, but `getRow()` is not permitted during Map functions.

JS Function | Reasonable to use in design doc functions
--- | ---
`emit()` | Map functions
`getRow()` | List functions
`JSON` | any
`isArray()` | any
`log()` | any
`provides()` | Show functions, List functions
`registerType()` | Show functions, List functions
`require()` | every except Reduce and rereduce functions
`send()` | List functions
`start()` | List functions
`sum()` | any
`toJSON()` | any

### 12.1.1. Design functions context

Each design function executes within special context of predefined objects, modules and functions:

`emit`(key, value)

  Puts key-value pair into inner stack for further passing to CouchDB when map function is done.

  Arguments: | key – View’s key. value – Associated value with key.

      function(doc){
        emit(doc._id, doc._rev);
      }

`getRow`()

  Extracts next row from the related view result.

  Returns: | View result row
  Return type: | object

      function(head, req){
        send('[');
        row = getRow();
        if (row){
          send(toJSON(row));
          while(row = getRow()){
            send(',');
            send(toJSON(row));
          }
        }
        return ']';
      }

`JSON`

  JSON2 object.

`isArray`(obj)

  Helper to check is provided value array or not

  Arguments: | obj – Any Javascript value
  Returns: | `true` is obj is array typed, `false` otherwise.
  Return type: | boolean

`log`(message)

  Arguments: | message – Message to log in at CouchDB INFO level.

      function(doc){
        log('Procesing doc ' + doc['_id']);
        emit(doc['_id'], null);
      }

  On map function run in CouchDB logs (e.g. at /var/log/couchdb/couch.log) you may find next record:

      [Sat, 03 Nov 2012 17:38:02 GMT] [info] [<0.7543.0>] OS Process #Port<0.3289> Log :: Processing doc 8d300b86622d67953d102165dbe99467

`provides`(key, func)

  Registers callable handler for specified MIME key.

  Arguments: | key – MIME key previously defined by `registerType()` func – MIME type handler.

`registerType`(key, *mimes)

  Registers list of MIME types by associated key.

  Arguments: | key – MIME types mimes – MIME types enumeration.

  Predefined mappings (key-array):

  - all: `*/*`
  - text: `text/plain; charset=utf-8`, `txt`
  - html: `text/html; charset=utf-8`
  - xhtml: `application/xhtml+xml`, `xhtml`
  - xml: `application/xml`, `text/xml`, `application/x-xml`
  - js: `text/javascript`, `application/javascript`, `application/x-javascript`
  - css: `text/css`
  - ics: `text/calendar`
  - csv: `text/csv`
  - rss: `application/rss+xml`
  - atom: `application/atom+xml`
  - yaml: `application/x-yaml`, `text/yaml`
  - multipart_form: `multipart/form-data`
  - url_encoded_form: `application/x-www-form-urlencoded`
  - json: `application/json`, `text/x-json`

`require`(path)

  Loads CommonJS module by specified path. Path shouldn’t starts with slash.

  Arguments: | path – CommonJS module path started from design document root.
  Returns: | Exported statements.

`send`(chunk)

  Sends a single string chunk in response.

  Arguments: | chunk – Text chunk

      function(head, req){
        send('Hello,');
        send(' ');
        send('Couch');
        return !
      }

`start`(init_resp)

  Initiates chunked response. As an option, custom response object may be sent at this point. For list-functions only!

  Note

  Only at this point list functions may set response HTTP code and headers. Also, you need to run this function before `send()`, `getRow()` or return statement or query server will implicitly call this function with empty object (`{}`).

      function(head, req){
        start({
          "code": 302,
          "headers": {
            "Location": "http://couchdb.apache.org"
          }
        });
        return "Relax!";
      }

`sum`(arr)

  Summarize arr items.

  Arguments: | arr – Array of numbers.
  Return type: | number

`toJSON`(obj)

  Encodes obj to JSON string. Actually is a proxy to `JSON.stringify` method.

  Arguments: | obj – JSON encodable object.
  Returns: | JSON string.

### 12.1.2. CommonJS Modules

CommonJS Modules is the one of major CouchDB feature introduced in 0.11.0 version that allows to create modular design functions without needs to duplicate a lot of same functionality.

Example of CommonJS module that checks user permissions:

    function user_context(userctx, secobj){
      var is_admin = function(){
        return userctx.indexOf('_admin') != -1;
      }
      var is_db_admin = function(){
        if (is_admin() || !secobj){
          return true;
        }
        if (secobj.admins.names.indexOf(userctx.name) != -1){
          return true;
        }
        for (var idx in userctx.roles){
          if (secobj.admins.roles.indexOf(userctx.roles[idx]) != -1){
            return true;
          }
        }
        return false;
      }
      var is_db_member = function(){
        if (is_admin() || is_db_admin() || !secobj){
          return true;
        }
        if (secobj.members.names.indexOf(userctx.name) != -1){
          return true;
        }
        for (var idx in userctx.roles){
          if (secobj.members.roles.indexOf(userctx.roles[idx]) != -1){
            return true;
          }
        }
        return false;
      }
      var has_all_roles = function(roles){
        for (var idx in roles){
          if (userctx.roles.indexOf(roles[idx]) == -1){
            return false;
          }
        }
        return true;
      }
      var has_any_role = function(roles){
        for (var idx in roles){
          if (userctx.roles.indexOf(roles[idx]) != -1){
            return true;
          }
        }
        return false;
      }
      return {
        'is_admin': is_admin,
        'is_db_admin': is_db_admin,
        'is_db_member': is_db_member,
        'has_all_roles': has_all_roles,
        'has_any_role': has_any_role
      }
    }

    exports['user'] = user_context

Each module has access to additional global variables:

- module (object): Contains information about stored module.
  - id (string): Module id that is actually JSON path in ddoc context.
  - current (code): Compiled module code object.
  - parent (object): Parent frame.
  - exports (object): Export statements.
- exports (object): Shortcut to `module.exports` object.

Lets place module above within design document under lib/validate path. Now we could use it in our design functions:

    function(newdoc, olddoc, userctx, secobj){
      user = require('lib/validate').user(userctx, secobj);
      if (user.is_admin()){
        return true;
      }
      if (newdoc.author != olddoc.author){
        throw({'forbidden': 'unable to update `author` field'});
      }
    }

## 12.2. Erlang

Warning

Erlang query server runs out of sandbox feature like JavaScript has to! This means, that Erlang code has full access to your OS, file system and network which may leads to security issues. While Erlang functions are faster than JavaScript ones, you need to be careful with running them, especially if they wasn’t written by your own hands.

Keep in mind: don’t trust every code - review it first before running.

Note

Due to security restriction, Erlang query server is disabled by default. To enable it you’ll need to edit your local.ini to include a `native_query_servers` section:

    [native_query_servers]
    erlang = {couch_native_process, start_link, []}

And don’t forget to restart CouchDB after that and use `language: "erlang"` property in your Erlang design documents.

`Emit`(Id, Value)

  Emits key-value pair to view indexer process.

      fun({Doc}) ->
        <<K,_/binary>> = proplists:get_value(<<"_rev">>, Doc, null),
        V = proplists:get_value(<<"_id">>, Doc, null),
        Emit(<<K>>, V)
      end.

`FoldRows`(Fun, Acc)

  Helper to iterate over all rows in list function.

  Arguments: | Fun – Function object. Acc – Previous returned value by Fun.

      fun(Head, {Req}) ->
        Fun = fun({Row}, Acc) ->
          Id = couch_util:get_value(<<"id">>, Row),
          Send(list_to_binary(io_lib:format("Previous doc id: ~p~n", [Acc]))),
          Send(list_to_binary(io_lib:format("Current  doc id: ~p~n", [Id]))),
          {ok, Id}
        end,
        FoldRows(Fun, nil),
        ""
      end.

`GetRow`()

  Retrieves next row from related view result.

      %% FoldRows background implementation.
      %% https://git-wip-us.apache.org/repos/asf?p=couchdb.git;a=blob;f=src/couchdb/couch_native_process.erl;hb=HEAD#l368
      %%
      foldrows(GetRow, ProcRow, Acc) ->
        case GetRow() of
          nil ->
            {ok, Acc};
          Row ->
            case (catch ProcRow(Row, Acc)) of
              {ok, Acc2} ->
                foldrows(GetRow, ProcRow, Acc2);
              {stop, Acc2} ->
                {ok, Acc2}
            end
      end.

`Log`(Msg)

  Arguments: | Msg – Message to log in at CouchDB INFO level.

      fun({Doc}) ->
        <<K,_/binary>> = proplists:get_value(<<"_rev">>, Doc, null),
        V = proplists:get_value(<<"_id">>, Doc, null),
        Log(lists:flatten(io_lib:format("Hello from ~s doc!", [V]))),
        Emit(<<K>>, V)
      end.

  On map function run in CouchDB logs (e.g. at /var/log/couchdb/couch.log) you may find next record:

      [Sun, 04 Nov 2012 11:33:58 GMT] [info] [<0.9144.2>] Hello from 8d300b86622d67953d102165dbe99467 doc!

`Send`(Chunk)

  Sends a single string Chunk in response.

      fun(Head, {Req}) ->
        Send("Hello,"),
        Send(" "),
        Send("Couch"),
        "!"
      end.

  Function above produces next response:

      Hello, Couch!

`Start`(Headers)

  Arguments: | Headers – Proplist of response object.

  Initialize List functions response. At this point response code and headers may be defined. For example, next function redirect to CouchDB web site:

      fun(Head, {Req}) ->
        Start({[{<<"code">>, 302},
                {<<"headers">>, {[
                  {<<"Location">>, <<"http://couchdb.apache.org">>}]
                }}
              ]}),
        "Relax!"
      end.

### Navigation

- index
- next |
- previous |
- Apache CouchDB 1.3 Manual »