| .. Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| .. use this file except in compliance with the License. You may obtain a copy of |
| .. the License at |
| .. |
| .. http://www.apache.org/licenses/LICENSE-2.0 |
| .. |
| .. Unless required by applicable law or agreed to in writing, software |
| .. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| .. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| .. License for the specific language governing permissions and limitations under |
| .. the License. |
| |
| .. default-domain:: js |
| |
| .. _query-server/js: |
| |
| ========== |
| JavaScript |
| ========== |
| |
| .. note:: |
| While every design function has access to all JavaScript objects, the table |
| below describes appropriate usage cases. For example, you may use |
| :func:`emit` in :ref:`mapfun`, but :func:`getRow` is not permitted |
| during :ref:`mapfun`. |
| |
| +--------------------------------+---------------------------------------------+ |
| | JS Function | Reasonable to use in design doc functions | |
| +================================+=============================================+ |
| | :func:`emit` | :ref:`mapfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`getRow` | :ref:`listfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :data:`JSON` | any | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`isArray` | any | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`log` | any | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`provides` | :ref:`showfun`, :ref:`listfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`registerType` | :ref:`showfun`, :ref:`listfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`require` | any, except :ref:`reducefun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`send` | :ref:`listfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`start` | :ref:`listfun` | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`sum` | any | |
| +--------------------------------+---------------------------------------------+ |
| | :func:`toJSON` | any | |
| +--------------------------------+---------------------------------------------+ |
| |
| Design functions context |
| ======================== |
| |
| Each design function executes in a special context of predefined objects, |
| modules and functions: |
| |
| .. function:: emit(key, value) |
| |
| Emits a `key`-`value` pair for further processing by CouchDB after the map |
| function is done. |
| |
| :param key: The view key |
| :param value: The `key`'s associated value |
| |
| .. code-block:: javascript |
| |
| function(doc){ |
| emit(doc._id, doc._rev); |
| } |
| |
| .. function:: getRow() |
| |
| Extracts the next row from a related view result. |
| |
| :return: View result row |
| :rtype: object |
| |
| .. code-block:: javascript |
| |
| function(head, req){ |
| send('['); |
| row = getRow(); |
| if (row){ |
| send(toJSON(row)); |
| while(row = getRow()){ |
| send(','); |
| send(toJSON(row)); |
| } |
| } |
| return ']'; |
| } |
| |
| .. data:: JSON |
| |
| `JSON2 <https://github.com/apache/couchdb/blob/main/share/server/json2.js>`_ |
| object. |
| |
| .. function:: isArray(obj) |
| |
| A helper function to check if the provided value is an `Array`. |
| |
| :param obj: Any JavaScript value |
| :return: ``true`` if `obj` is `Array`-typed, ``false`` otherwise |
| :rtype: boolean |
| |
| .. function:: log(message) |
| |
| Log a message to the CouchDB log (at the `INFO` level). |
| |
| :param message: Message to be logged |
| |
| .. code-block:: javascript |
| |
| 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`): |
| |
| .. code-block:: text |
| |
| [Sat, 03 Nov 2012 17:38:02 GMT] [info] [<0.7543.0>] OS Process #Port<0.3289> Log :: Processing doc 8d300b86622d67953d102165dbe99467 |
| |
| .. function:: provides(key, func) |
| |
| Registers callable handler for specified MIME key. |
| |
| :param key: MIME key previously defined by :func:`registerType` |
| :param func: MIME type handler |
| |
| .. function:: registerType(key, *mimes) |
| |
| Registers list of MIME types by associated `key`. |
| |
| :param key: MIME types |
| :param 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`` |
| |
| .. function:: require(path) |
| |
| Loads CommonJS module by a specified `path`. The path should not start with |
| a slash. |
| |
| :param path: A CommonJS module path started from design document root |
| :return: Exported statements |
| |
| .. function:: send(chunk) |
| |
| Sends a single string `chunk` in response. |
| |
| :param chunk: Text chunk |
| |
| .. code-block:: javascript |
| |
| function(head, req){ |
| send('Hello,'); |
| send(' '); |
| send('Couch'); |
| return ; |
| } |
| |
| .. function:: start(init_resp) |
| |
| Initiates chunked response. As an option, a custom |
| :ref:`response <response_object>` 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 :func:`send`, |
| :func:`getRow` or a `return` statement; otherwise, the query server will |
| implicitly call this function with the empty object (``{}``). |
| |
| .. code-block:: javascript |
| |
| function(head, req){ |
| start({ |
| "code": 302, |
| "headers": { |
| "Location": "http://couchdb.apache.org" |
| } |
| }); |
| return "Relax!"; |
| } |
| |
| .. function:: sum(arr) |
| |
| Sum `arr`'s items. |
| |
| :param arr: Array of numbers |
| :rtype: number |
| |
| .. function:: toJSON(obj) |
| |
| Encodes `obj` to JSON string. This is an alias for the ``JSON.stringify`` |
| method. |
| |
| :param obj: JSON-encodable object |
| :return: JSON string |
| |
| .. _commonjs: |
| |
| CommonJS Modules |
| ================ |
| |
| Support for `CommonJS Modules <http://wiki.commonjs.org/wiki/Modules/1.1.1>`_ |
| (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: |
| |
| .. code-block:: javascript |
| |
| 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: |
| |
| .. code-block:: javascript |
| |
| { |
| "views": { |
| "lib": { |
| "security": "function user_context(userctx, secobj) { ... }" |
| } |
| }, |
| "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) { |
| user = require('views/lib/security').user_context(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. |