couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject git commit: Docs: work on design doc section and commonJS
Date Mon, 19 Nov 2012 00:21:14 GMT
Updated Branches:
  refs/heads/docs de2b2bbf4 -> de6dc7150


Docs: work on design doc section and commonJS


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/de6dc715
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/de6dc715
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/de6dc715

Branch: refs/heads/docs
Commit: de6dc7150887efa1654275caead1b06cab774341
Parents: de2b2bb
Author: Dave Cottlehuber <dch@apache.org>
Authored: Mon Nov 19 01:08:06 2012 +0100
Committer: Dave Cottlehuber <dch@apache.org>
Committed: Mon Nov 19 01:13:28 2012 +0100

----------------------------------------------------------------------
 share/doc/build/Makefile.am     |    1 +
 share/doc/src/commonjs.rst      |    8 +-
 share/doc/src/ddocs.rst         |  101 ++++----
 share/doc/src/index.rst         |    2 +-
 share/doc/src/query-servers.rst |  480 +++++++++++++++++++++++++++++++++
 share/doc/src/queryservers.rst  |  482 ----------------------------------
 6 files changed, 537 insertions(+), 537 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/build/Makefile.am
----------------------------------------------------------------------
diff --git a/share/doc/build/Makefile.am b/share/doc/build/Makefile.am
index 15b0ed1..6044392 100644
--- a/share/doc/build/Makefile.am
+++ b/share/doc/build/Makefile.am
@@ -160,6 +160,7 @@ src_files = \
     ../src/intro.rst \
     ../src/json-structure.rst \
     ../src/os-daemons.rst \
+    ../query-servers.rst \
     ../src/range.rst \
     ../src/release.rst \
     ../src/replication.rst \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/src/commonjs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/commonjs.rst b/share/doc/src/commonjs.rst
index ff31095..49ccaa6 100644
--- a/share/doc/src/commonjs.rst
+++ b/share/doc/src/commonjs.rst
@@ -15,9 +15,9 @@
 CommonJS support for map functions
 ==================================
 
-CommonJS support allows you to use CommonJS notation inside map and
-reduce functions, but only of libraries that are stored inside the views
-part of the design doc.
+CommonJS support allows you to use `CommonJS notation <http://commonjs.org/specs>`_
+inside map and reduce functions, but only of libraries that are stored
+inside the views part of the design doc.
 
 So you could continue to access CommonJS code in design\_doc.foo, from
 your list functions etc, but we'd add the ability to require CommonJS
@@ -54,5 +54,3 @@ A sample design doc (taken from the test suite in Futon) is below:
 
 The ``require()`` statement is relative to the design document, but
 anything loaded form outside of ``views/lib`` will fail.
-
-.. _CommonJS: http://commonjs.org/specs

http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/src/ddocs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/ddocs.rst b/share/doc/src/ddocs.rst
index 89fa62c..368f49e 100644
--- a/share/doc/src/ddocs.rst
+++ b/share/doc/src/ddocs.rst
@@ -18,12 +18,12 @@
 Design Docs
 ===========
 
-In this section we'll show how to write design document in context of the
+In this section we'll show how to write design documents, using the built-in
 :ref:`JavaScript Query Server <queryserver_js>`.
 
-But before we start to write our first function, take a look at the list of
-common objects that will be used during our code journey - we'll made big deal
-with them for each function:
+But before we start to write our first function, let's take a look at the list
+of common objects that will be used during our code journey - we'll be using
+them extensively within each function:
 
 - :ref:`Database information object <dbinfo_object>`
 - :ref:`Request object <request_object>`
@@ -48,9 +48,9 @@ Map functions
 
    :param doc: Processed document object.
 
-Map functions should take a single argument as document object and emits pair
-values also known as `key` and `value`. Since JavaScript doesn't support
-generators and ``yield`` statement it got emulated via :func:`emit`:
+Map functions should take a single argument as document object and optionally
+emits paired values also known as `key` and `value`. Since JavaScript
+doesn't support generators and ``yield`` statement it is emulated via :func:`emit`:
 
 .. code-block:: javascript
 
@@ -65,19 +65,19 @@ generators and ``yield`` statement it got emulated via :func:`emit`:
 
 In this example the map function produces documents view by tag if they
 has `tags` attribute as array and `type` attribute with "post" value. Note that
-:func:`emit` function could be called for multiple times, so same document
+:func:`emit` function could be called  multiple times, so the same document
 will be available by several `keys`.
 
 Also keep in mind that each document is *sealed* to prevent situation when one
-map function changes document state and the other one received his modified
+map function changes document state and the other one received a modified
 version.
 
-Yes, as was mentioned above, map function doesn't executes alone. Instead of
-that each document is processed by group of map functions from all views of
+For efficiency reasons, documents are passed to a group of map functions -
+each document is processed by group of map functions from all views of
 related design document. This means that if you trigger index update for one
-view in ddoc, all others will get up-to-dated too.
+view in ddoc, all others will get updated too.
 
-Since `1.1.0` release `map` function gains support for
+Since `1.1.0` release `map` function supports 
 :ref:`CommonJS <commonjs>` modules and access to :func:`require` function.
 
 .. _reducefun:
@@ -95,13 +95,13 @@ Reduce and rereduce functions
    :return: Reduces `values`
 
 Reduce functions takes two required arguments of keys and values lists - the
-result of the related map function - and optional third one which signs if
+result of the related map function - and optional third one which indicates if
 `rereduce` mode is active or not. `Rereduce` is using for additional reduce
 values list, so when it is ``true`` there is no information about related `keys`
 (first argument is ``null``).
 
 Note, that if produced result by `reduce` function is longer than initial
-values list then an Query Server error will be raised. However, this behavior
+values list then a Query Server error will be raised. However, this behavior
 could be disabled by setting ``reduce_limit`` config option to ``false``:
 
 .. code-block:: ini
@@ -111,7 +111,8 @@ could be disabled by setting ``reduce_limit`` config option to ``false``:
 
 While disabling ``reduce_limit`` might be useful for debug proposes, remember,
 that main task of reduce functions is to *reduce* mapped result, not to make it
-even bigger.
+even bigger. Generally, your reduce function should converge rapidly to a single
+value - which could be an array or similar object.
 
 Also CouchDB has three built-in reduce functions. These are implemented in
 Erlang and run right inside CouchDB, so they are much faster than the equivalent
@@ -151,21 +152,22 @@ JavaScript below:
       }
     }
 
-.. note:: **Why reduce functions has no support of CommonJS modules?**
+.. note:: **Why don't reduce functions support CommonJS modules?**
 
-   While `map` functions has limited access to stored modules through
+   While `map` functions have limited access to stored modules through
    :func:`require` function there is no such feature for `reduce` functions.
    The reason lies deep inside in mechanism how `map` and `reduce` functions
    are processed by Query Server. Let's take a look on `map` functions first:
 
    #. CouchDB sends all `map` functions for processed design document to
       Query Server.
-   #. Query Server handles them one by one, compiles and puts into inner stack.
-   #. After all `map` functions had been proceeded, CouchDB starts to send
-      reamain documents to index one by one.
-   #. Query Server handles document object and apply to him every function from
-      inner stack. Their emitted result joins into single array and pulls back
-      to CouchDB.
+   #. Query Server handles them one by one, compiles and puts them onto an
+      internal stack.
+   #. After all `map` functions had been processed, CouchDB will send the
+      remaining documents to index one by one.
+   #. The Query Server receives the document object and applies it to every function
+      from the stack. The emitted results are then joined into a single array and sent
+      back to CouchDB.
 
    Now let's see how `reduce` functions are handled:
 
@@ -176,10 +178,10 @@ JavaScript below:
       lists. Reduced result sends back to CouchDB.
 
    As you may note, `reduce` functions been applied in single shot while
-   `map` ones are applies in iterative way per each document. This means that
-   it's possible for `map` functions to precompile CommonJS library and use it
-   during whole view processing, but for `reduce` functions it will be
-   compiled again and again for each view result reducing which may leads to
+   `map` ones are applied in an iterative way per each document. This means that
+   it's possible for `map` functions to precompile CommonJS libraries and use them
+   during the entire view processing, but for `reduce` functions it will be
+   compiled again and again for each view result reduction, which will lead to
    performance degradation (`reduce` function are already does hard work to make
    large result smaller).
 
@@ -198,7 +200,8 @@ Show functions
    :rtype: object or string
 
 Show functions are used to represent documents in various formats, commonly as
-HTML page with nicer formatting.
+HTML page with nicer formatting. They can also be used to run server-side functions
+without requiring a pre-existing document.
 
 Basic example of show function could be:
 
@@ -248,7 +251,7 @@ and even files (this one is CouchDB logo):
       }
     }
 
-But what if you need to represent data in different formats by single function?
+But what if you need to represent data in different formats via a single function?
 Functions :func:`registerType` and :func:`provides` are your the best friends in
 that question:
 
@@ -299,8 +302,8 @@ that question:
 
 This function may return `html`, `json` , `xml` or our custom `text json` format
 representation of same document object with same processing rules. Probably,
-the `xml` provider in our function needs in more care to handle nested objects
-and keys with invalid characters, but you've got the idea!
+the `xml` provider in our function needs more care to handle nested objects
+correctly, and keys with invalid characters, but you've got the idea!
 
 .. seealso::
 
@@ -325,9 +328,9 @@ List functions
    :rtype: string
 
 While :ref:`showfun` are used to customize document presentation, :ref:`listfun`
-are used for same propose, but against :ref:`viewfun` result.
+are used for same purpose, but against :ref:`viewfun` results.
 
-Next list function formats view and represent in as very simple HTML page:
+The next list function formats view and represents it as a very simple HTML page:
 
 .. code-block:: javascript
 
@@ -351,9 +354,9 @@ Next list function formats view and represent in as very simple HTML page:
       send('</table></body></html>');
     }
 
-Probably, you'd better to think about templates, styles and more other things to
-show data in more nicer way, but this is good point to start from. Note, that
-you may use there :func:`registerType` and :func:`provides` functions in same
+Templates and styles could obviously be used to present data in a nicer
+fashion, but this is an excellent starting point. Note that you may also
+use :func:`registerType` and :func:`provides` functions in the same
 way as for :ref:`showfun`!
 
 .. seealso::
@@ -436,13 +439,13 @@ formats, but more correctly to say, they *filters* :ref:`changes feed<changes>`.
 Classic filters
 ---------------
 
-By default changes feed emits all database documents changes. But if you're
-waiting for some special changes this is not optimal to process each record.
+By default the changes feed emits all database documents changes. But if you're
+waiting for some special changes, processing all documents is inefficient.
 
 Filters are special design document functions that allows changes feed to emit
-only specific documents that passed filter rules.
+only specific documents that pass filter rules.
 
-Lets assume that our database is mailbox and we need to to handle only new mails
+Lets assume that our database is a mailbox and we need to to handle only new mails
 (documents with status `new`) events. Assuming that, our filter function
 will looks like next one:
 
@@ -534,7 +537,7 @@ systems.
 View filters
 ------------
 
-View filters are the same as classic one with one small difference: they uses
+View filters are the same as above, with one small difference: they use
 views `map` function instead to `filter` one to process the changes feed. Each
 time when a key-value pair could be emitted, a change is returned. This allows
 to avoid creating filter functions that are mostly does same works as views.
@@ -546,8 +549,8 @@ To use them just specify `_view` value for ``filter`` parameter and
 
 .. note::
 
-   Since view filters are uses `map` functions as filter they couldn't
-   have dynamic behavior since :ref:`request object<request_object>` is not
+   Since view filters uses `map` functions as filters, they can't show any
+   dynamic behavior since :ref:`request object<request_object>` is not
    available.
 
 .. seealso::
@@ -573,11 +576,11 @@ Validate document update functions
 
    :throws: ``forbidden`` error to gracefully prevent document storing.
 
-To perform validate operations on document saving there is special design
+To perform validate operations on document saving there is a special design
 function type called `validate_doc_update`.
 
-Instead of thousands words take a look on next good example of validate
-function - this function is uses in ``_design/_auth`` ddoc from `_users`
+Instead of thousands words take a look at the next example of validate
+function - this function is used in ``_design/_auth`` ddoc from `_users`
 database to control users documents required field set and modification
 permissions:
 
@@ -709,8 +712,8 @@ permissions:
 
 .. note::
 
-   The ``return`` statement used only for function exiting and it doesn't
-   controls validation process.
+   The ``return`` statement used only for function, it has no impact on 
+   the validation process.
 
 .. seealso::
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/src/index.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/index.rst b/share/doc/src/index.rst
index 5712d7c..b7591d3 100644
--- a/share/doc/src/index.rst
+++ b/share/doc/src/index.rst
@@ -33,7 +33,7 @@ Contents:
     config_reference
     replication
     ddocs
-    queryservers
+    query-servers
     commonjs
     errors
     changes

http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/src/query-servers.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/query-servers.rst b/share/doc/src/query-servers.rst
new file mode 100644
index 0000000..c6f3a74
--- /dev/null
+++ b/share/doc/src/query-servers.rst
@@ -0,0 +1,480 @@
+.. 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 servers
+=============
+
+.. _queryserver_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:`listfun`, 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`                | every except :ref:`reducefun`               |
++--------------------------------+---------------------------------------------+
+| :func:`send`                   | :ref:`listfun`                              |
++--------------------------------+---------------------------------------------+
+| :func:`start`                  | :ref:`listfun`                              |
++--------------------------------+---------------------------------------------+
+| :func:`sum`                    | any                                         |
++--------------------------------+---------------------------------------------+
+| :func:`toJSON`                 | any                                         |
++--------------------------------+---------------------------------------------+
+
+Design functions context
+------------------------
+
+Each design function executes within special context of predefined objects,
+modules and functions:
+
+
+.. function:: emit(key, value)
+
+   Puts `key`-`value` pair into inner stack for further passing to CouchDB
+   when map function is done.
+
+   :param key: View's key.
+   :param value: Associated value with `key`.
+
+   .. code-block:: javascript
+
+      function(doc){
+        emit(doc._id, doc._rev);
+      }
+
+
+.. function:: getRow()
+
+   Extracts next row from the 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://git-wip-us.apache.org/repos/asf?p=couchdb.git;a=blob;f=share/server/json2.js>`_
+   object.
+
+
+.. function:: isArray(obj)
+
+   Helper to check is provided value `array` or not
+
+   :param obj: Any Javascript value
+   :return: ``true`` is `obj` is `array` typed, ``false`` otherwise.
+   :rtype: boolean
+
+
+.. function:: log(message)
+
+   :param message: Message to log in at CouchDB `INFO` level.
+
+   .. code-block:: javascript
+
+      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:
+
+   .. 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 specified `path`. Path shouldn't starts with slash.
+
+   :param path: 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, custom
+   :ref:`response <response_object>` 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 :func:`send`,
+      :func:`getRow` or `return` statement or query server will implicitly call
+      this function with empty object (``{}``).
+
+   .. code-block:: javascript
+
+      function(head, req){
+        start({
+          "code": 302,
+          "headers": {
+            "Location": "http://couchdb.apache.org"
+          }
+        });
+        return "Relax!";
+      }
+
+
+.. function:: sum(arr)
+
+   Summarize `arr` items.
+
+   :param arr: Array of numbers.
+   :rtype: number
+
+
+.. function:: toJSON(obj)
+
+   Encodes `obj` to JSON string. Actually is a proxy to ``JSON.stringify``
+   method.
+
+   :param obj: JSON encodable object.
+   :return: JSON string.
+
+
+
+CommonJS Modules
+----------------
+
+`CommonJS Modules <http://wiki.commonjs.org/wiki/Modules/1.1.1>`_ 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:
+
+.. code-block:: javascript
+
+    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:
+
+.. code-block:: javascript
+
+    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'});
+      }
+    }
+
+
+.. _queryserver_erlang:
+
+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:
+
+   .. code-block:: ini
+
+      [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.
+
+
+.. function:: Emit(Id, Value)
+
+   Emits `key`-`value` pair to view indexer process.
+
+   .. code-block:: erlang
+
+      fun({Doc}) ->
+        <<K,_/binary>> = proplists:get_value(<<"_rev">>, Doc, null),
+        V = proplists:get_value(<<"_id">>, Doc, null),
+        Emit(<<K>>, V)
+      end.
+
+
+.. function:: FoldRows(Fun, Acc)
+
+   Helper to iterate over all rows in list function.
+
+   :param Fun: Function object.
+   :param Acc: Previous returned value by `Fun`.
+
+   .. code-block:: erlang
+
+      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.
+
+
+.. function:: GetRow()
+
+   Retrieves next row from related view result.
+
+   .. code-block:: erlang
+
+      %% 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.
+
+.. function:: Log(Msg)
+
+   :param Msg: Message to log in at CouchDB `INFO` level.
+
+   .. code-block:: erlang
+
+      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:
+
+   .. code-block:: text
+
+      [Sun, 04 Nov 2012 11:33:58 GMT] [info] [<0.9144.2>] Hello from 8d300b86622d67953d102165dbe99467
doc!
+
+
+.. function:: Send(Chunk)
+
+   Sends a single string `Chunk` in response.
+
+   .. code-block:: erlang
+
+      fun(Head, {Req}) ->
+        Send("Hello,"),
+        Send(" "),
+        Send("Couch"),
+        "!"
+      end.
+
+   Function above produces next response:
+
+   .. code-block:: text
+
+      Hello, Couch!
+
+
+.. function:: Start(Headers)
+
+   :param Headers: Proplist of :ref:`response object<response_object>`.
+
+   Initialize :ref:`listfun` response. At this point response code and headers
+   may be defined. For example, next function redirect to CouchDB web site:
+
+   .. code-block:: erlang
+
+      fun(Head, {Req}) ->
+        Start({[{<<"code">>, 302},
+                {<<"headers">>, {[
+                  {<<"Location">>, <<"http://couchdb.apache.org">>}]
+                }}
+              ]}),
+        "Relax!"
+      end.
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/de6dc715/share/doc/src/queryservers.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/queryservers.rst b/share/doc/src/queryservers.rst
deleted file mode 100644
index cfeee75..0000000
--- a/share/doc/src/queryservers.rst
+++ /dev/null
@@ -1,482 +0,0 @@
-.. 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 servers
-=============
-
-.. _queryserver_js:
-
-JavaScript
-==========
-
-.. note::
-   While every design function has access to all described there objects
-   the table below describes reasonable usage cases. For example, you may
-   use :func:`emit` in :ref:`listfun`, but this is useless while using
-   :func:`getRow` in :ref:`mapfun` will made it broken.
-
-+--------------------------------+---------------------------------------------+
-| 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`                | every except :ref:`reducefun`               |
-+--------------------------------+---------------------------------------------+
-| :func:`send`                   | :ref:`listfun`                              |
-+--------------------------------+---------------------------------------------+
-| :func:`start`                  | :ref:`listfun`                              |
-+--------------------------------+---------------------------------------------+
-| :func:`sum`                    | any                                         |
-+--------------------------------+---------------------------------------------+
-| :func:`toJSON`                 | any                                         |
-+--------------------------------+---------------------------------------------+
-
-Design functions context
-------------------------
-
-Each design function executes within special context of predefined objects,
-modules and functions:
-
-
-.. function:: emit(key, value)
-
-   Puts `key`-`value` pair into inner stack for further passing to CouchDB
-   when map function is done.
-
-   :param key: View's key.
-   :param value: Associated value with `key`.
-
-   .. code-block:: javascript
-
-      function(doc){
-        emit(doc._id, doc._rev);
-      }
-
-
-.. function:: getRow()
-
-   Extracts next row from the 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://git-wip-us.apache.org/repos/asf?p=couchdb.git;a=blob;f=share/server/json2.js>`_
-   object.
-
-
-.. function:: isArray(obj)
-
-   Helper to check is provided value `array` or not
-
-   :param obj: Any Javascript value
-   :return: ``true`` is `obj` is `array` typed, ``false`` otherwise.
-   :rtype: boolean
-
-
-.. function:: log(message)
-
-   :param message: Message to log in at CouchDB `INFO` level.
-
-   .. code-block:: javascript
-
-      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:
-
-   .. 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 specified `path`. Path shouldn't starts with slash.
-
-   :param path: 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, custom
-   :ref:`response <response_object>` 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 :func:`send`,
-      :func:`getRow` or `return` statement or query server will implicitly call
-      this function with empty object (``{}``).
-
-   .. code-block:: javascript
-
-      function(head, req){
-        start({
-          "code": 302,
-          "headers": {
-            "Location": "http://couchdb.apache.org"
-          }
-        });
-        return "Relax!";
-      }
-
-
-.. function:: sum(arr)
-
-   Summarize `arr` items.
-
-   :param arr: Array of numbers.
-   :rtype: number
-
-
-.. function:: toJSON(obj)
-
-   Encodes `obj` to JSON string. Actually is a proxy to ``JSON.stringify``
-   method.
-
-   :param obj: JSON encodable object.
-   :return: JSON string.
-
-
-
-CommonJS Modules
-----------------
-
-`CommonJS Modules <http://wiki.commonjs.org/wiki/Modules/1.1.1>`_ 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:
-
-.. code-block:: javascript
-
-    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:
-
-.. code-block:: javascript
-
-    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'});
-      }
-    }
-
-
-.. _queryserver_erlang:
-
-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:
-
-   .. code-block:: ini
-
-      [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.
-
-
-.. function:: Emit(Id, Value)
-
-   Emits `key`-`value` pair to view indexer process.
-
-   .. code-block:: erlang
-
-      fun({Doc}) ->
-        <<K,_/binary>> = proplists:get_value(<<"_rev">>, Doc, null),
-        V = proplists:get_value(<<"_id">>, Doc, null),
-        Emit(<<K>>, V)
-      end.
-
-
-.. function:: FoldRows(Fun, Acc)
-
-   Helper to iterate over all rows in list function.
-
-   :param Fun: Function object.
-   :param Acc: Previous returned value by `Fun`.
-
-   .. code-block:: erlang
-
-      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.
-
-
-.. function:: GetRow()
-
-   Retrieves next row from related view result.
-
-   .. code-block:: erlang
-
-      %% 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.
-
-.. function:: Log(Msg)
-
-   :param Msg: Message to log in at CouchDB `INFO` level.
-
-   .. code-block:: erlang
-
-      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:
-
-   .. code-block:: text
-
-      [Sun, 04 Nov 2012 11:33:58 GMT] [info] [<0.9144.2>] Hello from 8d300b86622d67953d102165dbe99467
doc!
-
-
-.. function:: Send(Chunk)
-
-   Sends a single string `Chunk` in response.
-
-   .. code-block:: erlang
-
-      fun(Head, {Req}) ->
-        Send("Hello,"),
-        Send(" "),
-        Send("Couch"),
-        "!"
-      end.
-
-   Function above produces next response:
-
-   .. code-block:: text
-
-      Hello, Couch!
-
-
-.. function:: Start(Headers)
-
-   :param Headers: Proplist of :ref:`response object<response_object>`.
-
-   Initialize :ref:`listfun` response. At this point response code and headers
-   may be defined. For example, next function redirect to CouchDB web site:
-
-   .. code-block:: erlang
-
-      fun(Head, {Req}) ->
-        Start({[{<<"code">>, 302},
-                {<<"headers">>, {[
-                  {<<"Location">>, <<"http://couchdb.apache.org">>}]
-                }}
-              ]}),
-        "Relax!"
-      end.
-
-


Mime
View raw message