### Navigation

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

# 7. Query Servers

## 7.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()` | any, except Reduce and rereduce functions
`send()` | List functions
`start()` | List functions
`sum()` | any
`toJSON()` | any

### 7.1.1. Design functions context

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

`emit`(key, value)

  Emits a key-value pair for further processing by CouchDB after the map function is done.

  Arguments: | key – The view key value – The key‘s associated value

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

`getRow`()

  Extracts the next row from a 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)

  A helper function to check if the provided value is an Array.

  Arguments: | obj – Any Javascript value
  Returns: | `true` if obj is Array-typed, `false` otherwise
  Return type: | boolean

`log`(message)

  Log a message to the CouchDB log (at the INFO level).

  Arguments: | message – Message to be logged

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

  After the map function has run, the following line can be found in CouchDB logs (e.g. at /var/log/couchdb/couch.log):

      [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 a specified path. The path should not start with a slash.

  Arguments: | path – A 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, a custom response object may be sent at this point. For list-functions only!

  Note

  list functions may set the HTTP response code and headers by calling this function. This function must be called before `send()`, `getRow()` or a return statement; otherwise, the query server will implicitly call this function with the empty object (`{}`).

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

`sum`(arr)

  Sum arr‘s items.

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

`toJSON`(obj)

  Encodes obj to JSON string. This is an alias for the `JSON.stringify` method.

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

### 7.1.2. CommonJS Modules

Support for CommonJS Modules (introduced in CouchDB 0.11.0) allows you to create modular design functions without the need for duplication of functionality.

Here’s a CommonJS module that checks user permissions:

    function user_context(userctx, secobj) {
      var is_admin = function() {
        return userctx.indexOf('_admin') != -1;
      }
      return {'is_admin': is_admin}
    }

    exports['user'] = user_context

Each module has access to additional global variables:

- module (object): Contains information about the stored module
  - id (string): The module id; a JSON path in ddoc context
  - current (code): Compiled module code object
  - parent (object): Parent frame
  - exports (object): Export statements
- exports (object): Shortcut to the `module.exports` object

The CommonJS module can be added to a design document, like so:

    {
       "views": {
          "lib": {
             "security": "function user_context(userctx, secobj) { ... }"
          },
          "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) {
            user = require('lib/security').user(userctx, secobj);
            return user.is_admin();
          }"
       },
       "_id": "_design/test"
    }

Modules paths are relative to the design document’s `views` object, but modules can only be loaded from the object referenced via `lib`. The `lib` structure can still be used for view functions as well, by simply storing view functions at e.g. `views.lib.map`, `views.lib.reduce`, etc.

## 7.2. Erlang

Warning

Unlike the JavaScript query server, the Erlang query server does not run in a sandbox. This means Erlang code has full access to your OS, filesystem and network, which may lead to security issues. While Erlang functions are faster than JavaScript ones, you need to be careful about running them, especially if they were written by someone else.

Note

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

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

Don’t forget to restart CouchDB after updating the configuration, and use the `language: "erlang"` property in your Erlang design documents.

`Emit`(Id, Value)

  Emits key-value pairs 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 a list function.

  Arguments: | Fun – Function object. Acc – The value previously returned 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 the next row from a 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 – Log a message at the 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.

  After the map function has run, the following line can be found in CouchDB logs (e.g. at /var/log/couchdb/couch.log):

      [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.

  The function above produces the following 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, this function redirects to the CouchDB web site:

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

### Navigation

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