From 3f7f1ec61a29f201766e717cbb370bd14181b026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20C=C3=B4t=C3=A9?= Date: Sun, 10 Sep 2017 17:30:45 -0400 Subject: [PATCH] Migrated the documentation to Sphinx(Using rst mixed with a bit of markdown) --- .gitignore | 4 + INSTALL.md | 127 --- README.md | 129 +-- TESTING.md | 46 - _resetDB.sh => bin/_resetDB.sh | 0 _runLocalUnix.sh => bin/_runLocalUnix.sh | 0 _runLocalWin.sh => bin/_runLocalWin.sh | 0 bin/install-doctools.sh | 2 + changelist.md | 78 -- composer.json | 2 +- doc/Makefile | 20 + doc/_static/css/local_build.css | 2 + doc/_static/css/my_theme.css | 62 ++ doc/api/couch-admin.rst | 973 ++++++++++++++++++ doc/api/couch-document.rst | 439 ++++++++ doc/api/couch-replicator.rst | 245 +++++ doc/api/couch.rst | 175 ++++ doc/api/couchclient/database.rst | 609 +++++++++++ doc/api/couchclient/document.rst | 633 ++++++++++++ doc/api/couchclient/index.rst | 8 + doc/api/couchclient/mango.rst | 226 ++++ doc/api/couchclient/view.rst | 226 ++++ doc/api/index.rst | 15 + doc/conf.py | 204 ++++ doc/couch.md | 153 --- doc/couch_admin.md | 860 ---------------- doc/couch_client-database.md | 495 --------- doc/couch_client-document.md | 521 ---------- doc/couch_client-view.md | 185 ---- doc/couch_client_mango.md | 232 ----- doc/couch_document.md | 347 ------- doc/couch_replicator.md | 223 ---- doc/index.rst | 19 + doc/make.bat | 36 + doc/overview/changelist/2.0.0.md | 13 + doc/overview/changelist/2.0.1.md | 25 + doc/overview/changelist/2.0.2.md | 16 + doc/overview/changelist/2.0.3.md | 13 + doc/overview/changelist/index.rst | 10 + doc/overview/index.rst | 8 + doc/overview/intro.rst | 14 + codestyle.md => doc/quickstart/codestyle.md | 0 doc/{ => quickstart}/composerInstallation.gif | Bin doc/quickstart/contributing.rst | 6 + doc/quickstart/index.rst | 10 + doc/quickstart/installation.rst | 133 +++ doc/{ => quickstart}/manualInstallation.gif | Bin doc/quickstart/testing.rst | 52 + doc/requirements.txt | 22 + examples/01_databases.php | 2 +- src/Couch.php | 448 ++++---- 51 files changed, 4456 insertions(+), 3612 deletions(-) delete mode 100644 INSTALL.md delete mode 100644 TESTING.md rename _resetDB.sh => bin/_resetDB.sh (100%) rename _runLocalUnix.sh => bin/_runLocalUnix.sh (100%) rename _runLocalWin.sh => bin/_runLocalWin.sh (100%) create mode 100644 bin/install-doctools.sh delete mode 100644 changelist.md create mode 100644 doc/Makefile create mode 100644 doc/_static/css/local_build.css create mode 100644 doc/_static/css/my_theme.css create mode 100644 doc/api/couch-admin.rst create mode 100644 doc/api/couch-document.rst create mode 100644 doc/api/couch-replicator.rst create mode 100644 doc/api/couch.rst create mode 100644 doc/api/couchclient/database.rst create mode 100644 doc/api/couchclient/document.rst create mode 100644 doc/api/couchclient/index.rst create mode 100644 doc/api/couchclient/mango.rst create mode 100644 doc/api/couchclient/view.rst create mode 100644 doc/api/index.rst create mode 100644 doc/conf.py delete mode 100644 doc/couch.md delete mode 100644 doc/couch_admin.md delete mode 100644 doc/couch_client-database.md delete mode 100644 doc/couch_client-document.md delete mode 100644 doc/couch_client-view.md delete mode 100644 doc/couch_client_mango.md delete mode 100644 doc/couch_document.md delete mode 100644 doc/couch_replicator.md create mode 100644 doc/index.rst create mode 100644 doc/make.bat create mode 100644 doc/overview/changelist/2.0.0.md create mode 100644 doc/overview/changelist/2.0.1.md create mode 100644 doc/overview/changelist/2.0.2.md create mode 100644 doc/overview/changelist/2.0.3.md create mode 100644 doc/overview/changelist/index.rst create mode 100644 doc/overview/index.rst create mode 100644 doc/overview/intro.rst rename codestyle.md => doc/quickstart/codestyle.md (100%) rename doc/{ => quickstart}/composerInstallation.gif (100%) create mode 100644 doc/quickstart/contributing.rst create mode 100644 doc/quickstart/index.rst create mode 100644 doc/quickstart/installation.rst rename doc/{ => quickstart}/manualInstallation.gif (100%) create mode 100644 doc/quickstart/testing.rst create mode 100644 doc/requirements.txt diff --git a/.gitignore b/.gitignore index e8bab28..be80711 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,7 @@ composer.lock #Misc setup.sh + + +#Doc build files +doc/_build diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 228a617..0000000 --- a/INSTALL.md +++ /dev/null @@ -1,127 +0,0 @@ -## Table of content - -- [**Version**](#version) -- [**Composer installation**](#composer-installation) - + [**Composer demo**](#composer-demo) -- [**Manual installation**](#manual-installation) - + [**Manual demo**](#manual-demo) - -## Installation - -To install the library and actually use it, you've got two choices: - -- **Easy way** : Require the library and autoload it using [Composer](https://getcomposer.org/). This also make the updates way more easier and version. -- **Manual way** : Download the library from github and import the files from `/src` to a `PHPOnCouch` folder in your project. You will need to update manually. - -### Version - -Before we get into the installation, you need to know that multiple versions are available at the moment. Since it's forked project, you have always access to the origin branches. For the future, here are the description of the available versions : - -- dev-master : The lastest tested sources -- 2.0.0 : The PHP-on-Couch 2.0 Release (Will be installed by default) -- 1.6.1.x-dev : The PHP-on-Couch 1.6.1 production branch. This branch contains the latest developments supporting CouchDB 1.6.1. - -From this information, it is up to you to choose the right version. By default, the latest release will be installed. - -### Composer installation - -Once you have composer installed, you are very close to have PHP-on-Couch installed. You simply need to do : - -1. Add the root of your project, in a command shell, execute the following command : `composer require php-on-couch/php-on-couch`. *Note: By default, it will take the latest release* -2. Make sure your composer autoloader is called. If not, simply **require** the `autoload.php` file in `vendor` folder. -3. Start playing with PHPOnCouch! - -#### Composer demo - -![alt text](doc/composerInstallation.gif "Composer installation demo") - -The content pasted into the `index.php` file is : - -```php -databaseExists()){ - $client->createDatabase(); -} - -//We get the database info just for the demo -var_dump($client->getDatabaseInfos()); - -//Note: Every request should be inside a try catch since CouchExceptions could be thrown.For example, let's try to get a unexisting document - -try{ - $client->getDoc('the id'); - echo 'Document found'; -} -catch(Exceptions\CouchNotFoundException $ex){ - if($ex->getCode() == 404) - echo 'Document not found'; -} -``` - - -### Manual installation - -Since you have chose the manual installation, it's a bit more complicated but still simple! As you are probably reading this, you should be on Github. First of all, you need to select the branch that you want to install. -- Once you're on this branch, click the *Click or download* button and *Download ZIP*. -- Within the ZIP, extract the `src` folder into a folder named `PHPOnCouch` somewhere in your project. -- The only remaning step is to require the files. You can either use your own autloader or simply require the files manually. - - -#### Manual demo - -![alt text](doc/manualInstallation.gif "Manual installation demo") - -`index.php` file content : - -```php -databaseExists()){ - $client->createDatabase(); -} - -//We get the database info just for the demo -var_dump($client->getDatabaseInfos()); - -//Note: Every request should be inside a try catch since CouchExceptions could be thrown.For example, let's try to get a unexisting document - -try{ - $client->getDoc('the id'); - echo 'Document found'; -} -catch(Exceptions\CouchNotFoundException $ex){ - if($ex->getCode() == 404) - echo 'Document not found'; -} -``` - ----- - -And there you go! You can use the library from there following our [documentation](README.md). Have fun! \ No newline at end of file diff --git a/README.md b/README.md index d7da9bd..ed83707 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,15 @@ -[![Latest Stable Version](https://poser.pugx.org/php-on-couch/php-on-couch/version)](https://packagist.org/packages/php-on-couch/php-on-couch)[![Latest Unstable Version](https://poser.pugx.org/php-on-couch/php-on-couch/v/unstable)](//packagist.org/packages/php-on-couch/php-on-couch)[![Build Status](https://travis-ci.org/PHP-on-Couch/PHP-on-Couch.svg?branch=master)](https://travis-ci.org/PHP-on-Couch/PHP-on-Couch)[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/PHP-on-Couch/PHP-on-Couch/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/PHP-on-Couch/PHP-on-Couch/?branch=master)[![codecov](https://codecov.io/gh/PHP-on-Couch/PHP-on-Couch/branch/master/graph/badge.svg)](https://codecov.io/gh/PHP-on-Couch/PHP-on-Couch)[![License](https://poser.pugx.org/php-on-couch/php-on-couch/license)](https://packagist.org/packages/php-on-couch/php-on-couch) +[![Latest Stable Version](https://poser.pugx.org/php-on-couch/php-on-couch/version)](https://packagist.org/packages/php-on-couch/php-on-couch)[![Latest Unstable Version](https://poser.pugx.org/php-on-couch/php-on-couch/v/unstable)](//packagist.org/packages/php-on-couch/php-on-couch)[![Build Status](https://travis-ci.org/PHP-on-Couch/PHP-on-Couch.svg?branch=master)](https://travis-ci.org/PHP-on-Couch/PHP-on-Couch)[![Documentation Status](https://readthedocs.org/projects/php-on-couch/badge/?version=latest)](http://php-on-couch.readthedocs.io/en/latest/?badge=latest)[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/PHP-on-Couch/PHP-on-Couch/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/PHP-on-Couch/PHP-on-Couch/?branch=master)[![codecov](https://codecov.io/gh/PHP-on-Couch/PHP-on-Couch/branch/master/graph/badge.svg)](https://codecov.io/gh/PHP-on-Couch/PHP-on-Couch)[![License](https://poser.pugx.org/php-on-couch/php-on-couch/license)](https://packagist.org/packages/php-on-couch/php-on-couch) + +:fire:For the complete documentation, visit http://php-on-couch.readthedocs.io :fire: + -[![Stories in Ready](https://badge.waffle.io/PHP-on-Couch/PHP-on-Couch.png?label=ready&title=Ready)](https://waffle.io/PHP-on-Couch/PHP-on-Couch) ## Table of content - [Introduction](#introduction) - [What's new](#whats-new) - [Changes](#changes) - [Installation and testing](#installation-and-testing) - [Components and documentation](#components-and-documentation) - + [Couch class](#couch-class) - + [CouchClient class](#couchclient-class) - * [Database functionnalities](#database-functionnalities) - * [Documents functionnalities](#documents-functionnalities) - * [Views functionnalities](#views-functionnalities) - * [Mango Query](#mango-query) - + [CouchDocument class](#couchdocument-class) - + [CouchReplicator class](#couchreplicator-class) - + [CouchAdmin class](#couchadmin-class) - [Quick-start guide](#quick-start-guide) - [Example](#example) - [Community](#community) @@ -27,120 +20,20 @@ [PHP On Couch](http://github.com/PHP-on-Couch/PHP-on-Couch/) tries to provide an easy way to work with your [CouchDB](http://couchdb.apache.org) [documents](http://docs.couchdb.org/) with [PHP](http://php.net). -## What's new - -Due to the lack of support on the last repository, I forked it and I will make sure it's kept active. Feel free to post any issue or feature request. I'm open for further developments but I don't have a lot of time. - -With the new release of 2.0, the master branch will support only this version and the next one. - -To access PHP-on-Couch for CouchDB 1.6.1, please visit [this link](https://github.com/PHP-on-Couch/PHP-on-Couch/tree/1.6.1). - - ## Recent changes -For the complete change list, head over [here](changelist.md) +For the complete change list, head over [here](http://php-on-couch.readthedocs.io/en/stable/overview/changelist/index.html) ## Installation and testing Install the library using composer : `composer require php-on-couch/php-on-couch`. -You can find more detailed informations about installation [here](INSTALL.md). +You can find more detailed informations about installation [here](http://php-on-couch.readthedocs.io/en/stable/quickstart/installation.html). -To test the the application, see [this topic](TESTING.md). +To test the the application, see [this topic](http://php-on-couch.readthedocs.io/en/stable/quickstart/testing.html). ## Components and documentation -This library has four main classes and a custom [Exception](http://php.net/manual/en/language.exceptions.php) class. - -### Couch class -This is the most basic of the three classes, and is responsible for the low level dialog between PHP and the CouchDB server. There should be no need of using it directly. - -From version **2.0.2**, you are able to change the HTTP adapter used by the Couch class. For more details, click [here](doc/couch.md). - - -### CouchClient class - -This class maps all the actions the application can do on the CouchDB server. Documentation is split in three main topics : - -#### [Database functionnalities](doc/couch_client-database.md) - - - List databases - - Create and delete a database - - Retrieve database informations - - Test whether a database exists - - Get uuids - - Get databases changes - -#### [Documents functionnalities](doc/couch_client-document.md) - -- Fetching documents -- Storing documents -- Copy a document -- Store attachments -- Delete document attachments -- Get all documents - -#### [Views functionnalities](doc/couch_client-view.md) - -- Calling a view with query options : key, startkey, endkey, limit, stale, ... - -#### [Mango Query](doc/couch_client_mango.md) - -- Create and manage indexes -- Make complex query with Mango Query - -### CouchDocument class - -Easing the manipulation of documents, the CouchDocument class uses PHP magic getters and setters. Documentation available [here](doc/couch_document.md). - -### CouchReplicator class - -A dedicated class to manage replications over different instances of CouchDB databases. Documentation available [here](doc/couch_replicator.md). - -### CouchAdmin class - -A class to manage users and database/users associations. Documentation available [here](doc/couch_admin.md). - -## Quick-start guide - -1. PHP-on-Couch package is available under the PHPOnCouch namespace. -2. To start using PHP-on-Couch, you need to import the classes. - -**Available high level classes** - -| Class name | Description | -| ---------- | ----------- | -| PHPOnCouch\CouchClient | The client to access a CouchDB database | -| PHPOnCouch\CouchAdmin | The class to handle CouchDB admins,user and permissions. | -| PHPOnCouch\CouchReplicator | A class to handle replication with databases. | -| PHPOnCouch\CouchDocument | A class that enhance document handling. Allow to auto-commit changes, replication and more. | - -**Example** -```php -use PHPOnCouch\CouchClient; -use PHPOnCouch\CouchDocument; -``` - -3. Create a client object. You have to tell it the _Data source name_ (dsn) of your CouchDB server, as well as the name of the database you want to work on. The DSN is the URL of your CouchDB server, for example _http://localhost:5984_. - -```php -$client = new CouchClient($couchdb_server_dsn, $couchdb_database_name); -``` - -4. Use it ! - -```php -try { - $client->createDatabase(); -} catch (\PHPOnCouch\Exceptions\CouchException $e) { - echo "Unable to create database : ".$e->getMessage(); -} - -$doc = new CouchDocument($client); -$doc->set( array('_id'=>'some_doc_id', 'type'=>'story','title'=>"First story") ); - -$view = $client->limit(10)->descending(true)->getView('some_design_doc','viewname'); -``` - +For the full API document, please visite [this link](http://php-on-couch.readthedocs.io/en/stable/api/index.html) ## Example @@ -193,14 +86,12 @@ echo $doc->name; // should echo "Smith" $doc->name = "Brown"; // set document property "name" to "Brown" and store the updated document in the database ``` - - ## Community ### Contributions -Feel free to make any contributions. All contributions must follow the [code style](codestyle.md) and must also comes with valid and complete tests. +Feel free to make any contributions. All contributions must follow the [code style](http://php-on-couch.readthedocs.io/en/stable/quickstart/codestyle.html) and must also comes with valid and complete tests. Help is really appreciated to complete add more tests. @@ -208,6 +99,6 @@ Help is really appreciated to complete add more tests. [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/PHP-on-Couch/PHP-on-Couch) -Don't hesitate to submit feedback, bugs and feature requests ! My contact address is [alexiscote19@hotmail.com](mailto:alexiscote19@hotmail.com?subject=Feedback) +Don't hesitate to submit feedback, bugs and feature requests ! Our contact address is [phponcouch@gmail.com](mailto:phponcouch@gmail.com?subject=Feedback) diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index 7033b55..0000000 --- a/TESTING.md +++ /dev/null @@ -1,46 +0,0 @@ -# Testing - -To test the library, you needs two things: - -- PHPUnit installed -- A CouchDB running. - -By default, the library is binded to "http://localhost:5984". You can change the host and the port by exporting ENV variables before running the tests. - -**Variables** - -| Name | Type | Default | Description | -| ---- | ---- | ------- | ----------- | -| DB_HOST | String | localhost | The host of the database(ip or dns) | -| DB_PORT | Integer | 5984 | The port of the database. Note: for the moment, you can't change the port if you're using the docker image. | - -# Install PHPUnit - -The easy way to install PHPUnit is to use composer. In the project root, execute this : - -```bash -composer install --dev -``` - -# Run tests - -## Recommended way - -PHP-on-Couch provides bash scripts that setup a CouchDB instance via docker and let you test the library. If you're on Windows, you have to install Git Bash which comes with Git when you install it. - -**WARNING** : Before running the scripts, make sure the port 5984 is free. Otherwise, the docker image won't be able to run and the tests will fail. Also, if you already have a local CouchDB, it's not recommended to use it for test. Tests will interact with the database and change it's current state. - -For Windows users : - -```bash -sh _runLocalWin.sh -``` - -For Unix/OSX users : - -```bash -sh _runLocalUnix.sh -``` - - - diff --git a/_resetDB.sh b/bin/_resetDB.sh similarity index 100% rename from _resetDB.sh rename to bin/_resetDB.sh diff --git a/_runLocalUnix.sh b/bin/_runLocalUnix.sh similarity index 100% rename from _runLocalUnix.sh rename to bin/_runLocalUnix.sh diff --git a/_runLocalWin.sh b/bin/_runLocalWin.sh similarity index 100% rename from _runLocalWin.sh rename to bin/_runLocalWin.sh diff --git a/bin/install-doctools.sh b/bin/install-doctools.sh new file mode 100644 index 0000000..6b949d6 --- /dev/null +++ b/bin/install-doctools.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +sudo pip install sphinx sphinx-autobuild sphinx_rtd_theme sphinxcontrib-phpdomain recommonmark \ No newline at end of file diff --git a/changelist.md b/changelist.md deleted file mode 100644 index 31a7778..0000000 --- a/changelist.md +++ /dev/null @@ -1,78 +0,0 @@ -# Changelist - ---- -#### [2.0.3] -##### Added -- CouchClient - + Added query parameters documentation for IDE -- CouchAdmin - + setRolesToUser($user,$roles) -- Added missing tests for the library(code covered at 92%) -- Added detailed documentation for installation - -##### Updated -- Fixed continuous stream (changes, continuous replication) -- Update code examples - - ---- -#### [2.0.2] -##### Added -- Couch - + getAdapter() - + setAdapter(CouchHttpAdapterInterface $adapter) - + initAdapter($opts) -- Adapters - + CouchHttpAdaterCurl - + CouchHttpAdapterSocket -- doc/couch.md -- changelist.md - -##### Fixed -- Removed echoes that were causing unexpected output -- Fixed some classes import -- Fixed Cookie parsing - ---- -#### [2.0.1] -##### Added - -- CouchClient - + getIndexes() - + createIndex(array $fields, $name = null, $ddoc = null, $type = 'json') - + find($selector, array $fields = null, $sort = null, $index = null) - + explain($selector, array $fields = null, $sort = null, $index = null) -- CouchClientTest - + getIndexesTest() - + createIndexTest() - + findTest() - + explainTest() -- changelist.md -- codestyle.md - -##### Updated - -- Refactored all the code to follow our code style -- Travis config to run CheckStyle -- Code example to correct syntax - -##### Fixed - -- Allow to use \_users and \_replicator databases directly - ---- -#### [2.0] -##### Added - -- CouchClient - + getMemberShip() - + getConfig($nodeName[,$section,$key]) - + setConfig($nodeName,$section,$key,$value) - + deleteConfig($nodeName,$section,$key) -- Composer installation now available - -#### Updated -- CouchAdmin($client,$options) -- Updated few tests cases - ---- \ No newline at end of file diff --git a/composer.json b/composer.json index 46b0311..64d41b0 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ } }, "require": { - "php": ">=5.2.0" + "php": ">=5.6.0" }, "require-dev": { "phpunit/phpunit": "5.5.*", diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..bedbf85 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -msphinx +SPHINXPROJ = PHPOnCouch +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/_static/css/local_build.css b/doc/_static/css/local_build.css new file mode 100644 index 0000000..98f1dc5 --- /dev/null +++ b/doc/_static/css/local_build.css @@ -0,0 +1,2 @@ +@import url('theme.css'); +@import url('my_theme.css'); \ No newline at end of file diff --git a/doc/_static/css/my_theme.css b/doc/_static/css/my_theme.css new file mode 100644 index 0000000..84043c2 --- /dev/null +++ b/doc/_static/css/my_theme.css @@ -0,0 +1,62 @@ +/** -- PHPDOMAIN OPTIMIZATIONS -- **/ + +.rst-content dl dd { + margin: 24px 24px 24px 24px; +} + +.rst-content dl > dt { + width: 100%; +} + +.rst-content dl:not(.docutils) { + margin-top: 36px; +} + +.rst-content .hidden { + display: none !important; +} + +nav .hidden, div.section#maintoc .hidden { + display: unset !important; + visibility: visible !important; +} + +div.section#maintoc h2 { + display: none !important; +} + +.wy-table-bordered-all, .rst-content table.docutils { + border: 1px solid #e1e4e5; +} + +.wy-table td p, .rst-content table.docutils td p, .rst-content table.field-list td p { + line-height: unset; +} + +.rst-content table.field-list td { + border: none; + padding-top: 8px; +} + +tr.field-odd.field { + background-color: whitesmoke; +} + +tr.field-odd.field:hover, tr.field-even.field:hover { + background-color: lightyellow; +} + +.wy-table-bordered-all tbody > tr:last-child td, .rst-content table.docutils tbody > tr:last-child td { + padding-bottom: 0; +} + +.rst-content table.field-list td { + padding-bottom: 0; +} + +.wy-table td, .rst-content table.docutils td, .rst-content table.field-list td { + background-color: transparent; + vertical-align: baseline; +} + +/** -- END PHPDOMAIN OPTIMIZATIONS -- **/ \ No newline at end of file diff --git a/doc/api/couch-admin.rst b/doc/api/couch-admin.rst new file mode 100644 index 0000000..2f1bd5e --- /dev/null +++ b/doc/api/couch-admin.rst @@ -0,0 +1,973 @@ +CouchAdmin class +**************** + +Please read this first !! +========================= + +The CouchAdmin class is only needed to **manage** users of a CouchDB server : add users, add admins, ... + +You don't need the CouchAdmin class to connect to CouchDB with a login / password. You only need to add your login and password to the DSN argument when creating your CouchDB client : + +.. code-block:: php + + $client = new CouchClient ("http://theuser:secretpass@couch.server.com:5984","mydatabase"); + + +Managing CouchDB users +====================== + +CouchDB rights management is really complex. `This page `_ can really help to understand how security is implemented in couchDB. + +The **CouchAdmin** class contains helpful methods to create admins, users, and associate users to databases. + +Synopsys +======== + +.. code-block:: php + + createAdmin("superAdmin","secretpass"); + } catch ( Exception $e ) { + die("unable to create admin user: ".$e->getMessage()); + } + + // + // now my database is not in "admin party" anymore. + // To continue Administration I need to setup an authenticated connector + // + $admclient = new CouchClient ("http://superAdmin:secretpass@localhost:5984/", "mydb" ); + $adm = new CouchAdmin($admclient); + + // create a regular (no superadmin) user) + try { + $adm->createUser("joe","secret"); + } catch ( Exception $e ) { + die("unable to create regular user: ".$e->getMessage()); + } + + // set "joe" as admin of the database "mydb" + try { + $adm->addDatabaseAdminUser("joe"); + } catch ( Exception $e ) { + die("unable to add joe to the admins list of mydb: ".$e->getMessage()); + } + + // Oh no I missed up remove "joe" from database "mydb" admins + try { + $adm->removeDatabaseAdminUser("joe"); + } catch ( Exception $e ) { + die("unable to remove joe from the admins list of mydb: ".$e->getMessage()); + } + + // and add it to the members group of database "mydb" + try { + $adm->addDatabaseMemberUser("joe"); + } catch ( Exception $e ) { + die("unable to add joe to the members list of mydb: ".$e->getMessage()); + } + + // well... get the list of users belonging to the "members" group of "mydb" + $users = $adm->getDatabaseMemberUsers(); // array ( "joe" ) + + +Getting started +=============== + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchAdmin + + The class that helps managing permissions, users and admins. + +:hidden:`__construct` +""""""""""""""""""""" + + .. php:method:: __construct(CouchClient $client,$options = array()) + + The CouchAdmin class constructor takes 2 parameters : a couchClient object and an array of configuration options. + + :params CouchClient $client: The CouchClient instance created with enough permissions to perform the administrative tasks. + :params array $options: The options that can be passed to the CouchInstance and CouchAdmin. Here are the specific options for CouchAdmin : + + - users_database : The user database to use (overwrite the default _users) + - node : The node to use for the configuration. **If it's not defined**, the first node of the *cluster_nodes* will be taken. + + Example : + + .. code-block:: php + + // create a CouchClient instance + $client = new CouchClient("http://localhost:5984/","mydb"); + // now create the CouchAdmin instance + $adm = new CouchAdmin($client); + // here $adm will connect to CouchDB without any credentials : that will only work if there is no administrator created yet on the server. + +Admin party +=========== + +On a fresh install, CouchDB is in **admin party** mode : that means any operation (create / delete databases, store documents and design documents) can be performed without any authentication. + +Below is an example to configure the first server administrator, that we will name **couchAdmin** with the password **secretpass** : + +.. code-block:: php + + // create an anonymous couchClient connection (no user/pass) + $client = new CouchClient("http://localhost:5984/","mydb"); + // now create the couchAdmin instance + $adm = new CouchAdmin($client); + //create the server administrator + try { + $adm->createAdmin("couchAdmin","secretpass"); + } catch ( Exception $e ) { + die ("Can't create server administrator : ".$e->getMessage()); + } + +Now that the couch server got a server administrator, it's not in "admin party" mode anymore : we can't create a second server administrator using the same, anonymous couchClient instance. +We need to create a couchClient instance with the credentials of **couchAdmin**. + +.. code-block:: php + + // create a server administrator couchClient connection + $client = new CouchClient("http://couchAdmin:secretpass@localhost:5984/","mydb"); + // now create the CouchAdmin instance + $adm = new CouchAdmin($client); + +Create users and admins +======================= + + +:hidden:`createAdmin` +""""""""""""""""""""" + + .. php:method:: createAdmin($login, $password, $roles = array()) + + Creates a CouchDB *server* administrator. A server administrator can do everything on a CouchDB server. + + :params string $login: The login of the new admin + :params string $password: The raw password for the new admin. + :params array $roles: The roles that will have this admin. + + Example : + + .. code-block:: php + + createAdmin("superAdmin","ommfgwtf"); + } catch ( Exception $e ) { + die("unable to create admin user: ".$e->getMessage()); + } + +:hidden:`createUser` +"""""""""""""""""""" + + .. php:method:: createUser($login, $password, $roles = array()) + + Creates a CouchDB user and returns it. + + :params string $login: The login of the new user + :params string $password: The raw password for the new user. + :params array $roles: The roles that will have this user. + + Example : + + .. code-block:: php + + createUser("joe","dalton"); + } catch ( Exception $e ) { + die("unable to create user: ".$e->getMessage()); + } + + Example with roles + + .. code-block:: php + + createUser("jack","dalton",$roles); + } catch ( Exception $e ) { + die("unable to create user: ".$e->getMessage()); + } + +:hidden:`getUser` +""""""""""""""""" + + .. php:method:: getUser($login) + + The method returns the user document stored in the users database of the CouchDB server. + + :params string $login: The username of the user to find. + :returns: The user if found. Otherwise, a CouchNotFoundException will be thrown. + + Example : + + .. code-block:: php + + getUser("joe"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "User joe does not exist."; + } else { + die("unable to get user: ".$e->getMessage()); + } + } + +:hidden:`getAllUsers` +""""""""""""""""""""" + + .. php:method:: getAllUsers() + + The method returns the list of all users registered in the users database of the CouchDB server. + + .. note:: This method calls a view, so you can use the view query options ! + + :returns: An array of users found in the database. + + Example : + + .. code-block:: php + + getAllUsers(); + } catch ( Exception $e ) { + die("unable to get users: ".$e->getMessage()); + } + print_r($all); + + /** will print something like + Array ( + stdClass ( + "id" => "_design/_auth", + "key" => "_design/_auth", + "value" => stdClass ( + "rev" => "1-54a591939c91922a35efee07eb2c3a72" + ) + ), + stdClass ( + "id" => "org.couchdb.user:jack", + "key" => "org.couchdb.user:jack", + "value" => stdClass ( + "rev" => "1-3e4dd4a7c5a9d422f8379f059fcfce98" + ) + ), + stdClass ( + "id" => "org.couchdb.user:joe", + "key" => "org.couchdb.user:joe", + "value" => stdClass ( + "rev" => "1-9456a56f060799567ec4560fccf34534" + ) + ) + ) + **/ + + Example - including user documents and not showing the design documents + + .. code-block:: php + + include_docs(true)->startkey("org.couchdb.user:")->getAllUsers(); + } catch ( Exception $e ) { + die("unable to get users: ".$e->getMessage()); + } + print_r($all); + + /** will print something like + Array ( + stdClass ( + "id" => "org.couchdb.user:jack", + "key" => "org.couchdb.user:jack", + "value" => stdClass ( + "rev" => "1-3e4dd4a7c5a9d422f8379f059fcfce98" + ), + "doc" => stdClass ( "_id" => "org.couchdb.user:jack", ... ) + ), + stdClass ( + "id" => "org.couchdb.user:joe", + "key" => "org.couchdb.user:joe", + "value" => stdClass ( + "rev" => "1-9456a56f060799567ec4560fccf34534" + ), + "doc" => stdClass ( "_id" => "org.couchdb.user:joe", ... ) + ) + ) + **/ + +Removing users +============== + +.. warning:: This only works with CouchDB starting at version 1.0.1 + +:hidden:`deleteAdmin` +""""""""""""""""""""" + + .. php:method:: deleteAdmin($login) + + This permanently removes the admin $login. + + :params string $login: The username of the admin to delete. + :returns string: + + Returns the hash of the password before it got removed. + + Example : -hashed-0c796d26c439bec7445663c2c2a18933858a8fbb,f3ada55b560c7ca77e5a5cdf61d40e1a + + Example : creating and immediately removing a server administrator + + .. code-block:: php + + createAdmin($adminLogin, $adminPass); + } catch (Exception $e) { + die("unable to create admin user: ".$e->getMessage()); + } + // here "butterfly" admin exists and can login to couchDB to manage the server + + // now we remove it + try { + $ok = $adm->deleteAdmin($adminLogin); + } catch (Exception $e) { + die("unable to delete admin user: ".$e->getMessage()); + } + // here "butterfly" admin does not exist anymore + +:hidden:`deleteUser` +"""""""""""""""""""" + + .. php:method:: deleteUser($login) + + This method permanently removes the user $login. + + :params string $login: The login of the user to delete. + + Example : removing a server user + + .. code-block:: php + + deleteUser("joe"); + } catch (Exception $e) { + die("unable to delete user: ".$e->getMessage()); + } + print_r($ok); + + /** will print something like : + stdClass Object + ( + [ok] => 1 + [id] => org.couchdb.user:joe + [rev] => 6-415784680cff486e2d0144ed39da2431 + ) + */ + +Roles assignation +================= + +:hidden:`addRoleToUser` +""""""""""""""""""""""" + + .. php:method:: addRoleToUser($user, $role) + + This method adds the role *$role* to the list of roles user *$user* belongs to. **$user** can be a PHP stdClass representing a CouchDB user object (as returned by getUser() method), or a user login. + + :params string|stdClass $user: The username of the user to edit or the User object returned by :meth:`CouchAdmin::getUser()` for example. + :params string $role: The role to add to the specified user. + + Example : adding the role *cowboy* to user *joe* + + .. code-block:: php + + addRoleToUser("joe","cowboy"); + } catch ( Exception $e ) { + die("unable to add a role to user: ".$e->getMessage()); + } + echo "Joe now got role cowboy"; + +:hidden:`removeRoleFromUser` +"""""""""""""""""""""""""""" + + .. php:method:: removeRoleFromUser($user, $role) + + This method removes the role *$role* from the list of roles user *$user* belongs to. **$user** can be a PHP stdClass representing a CouchDB user object (as returned by getUser() method), or a user login. + + :params string|stdClass $user: The username of the user to edit or the User object returned by :meth:`CouchAdmin::getUser()` for example. + :params string $role: The role to remove to the specified user. + + Example : removing the role *cowboy* of user *joe* + + .. code-block:: php + + removeRoleFromUser("joe","cowboy"); + } catch ( Exception $e ) { + die("unable to remove a role of a user: ".$e->getMessage()); + } + echo "Joe don't belongs to the cowboy role anymore"; + +:hidden:`setRolesToUser` +"""""""""""""""""""""""" + + .. php:method:: setRolesToUser($user, array $roles = []) + + This method let you set the roles for the selected user. A $user can either be the username of the user or a user object containing an **_id** and a **roles** property. + + Example of usage : + + .. code-block:: php + + setRolesForUser("joe",['tester','developer']); + echo "Joe has now the tester and developer roles."; + } catch ( Exception $e ) { + die("unable to remove a role of a user: ".$e->getMessage()); + } + +Database user security +====================== + +CouchDB databases got two types of privileged users : the *members*, that can read all documents, and only write normal (non-design) documents. +The *admins* got all privileges of the *members*, and they also can write design documents, use temporary views, add and remove *members* and *admins* of the database. +`The CouchDB wiki gives all details regarding rights management. `_ + + +:hidden:`addDatabaseMemberUser` +""""""""""""""""""""""""""""""" + + .. php:method:: addDatabaseMemberUser($login) + + This method adds a user in the members list of the database. + + :params string $login: The user to add to the member list of the current database + + Example - adding joe to the members of the database mydb + + .. code-block:: php + + addDatabaseMemberUser("joe"); + } catch ( Exception $e ) { + die("unable to add user: ".$e->getMessage()); + } + +:hidden:`addDatabaseAdminUser` +"""""""""""""""""""""""""""""" + + .. php:method:: addDatabaseAdminUser($login) + + Adds a user in the admins list of the database. + + :params string $login: The user to add to the admin list of the current database + + Example - adding joe to the admins of the database mydb + + .. code-block:: php + + addDatabaseAdminUser("joe"); + } catch ( Exception $e ) { + die("unable to add user: ".$e->getMessage()); + } + +:hidden:`getDatabaseMemberUsers` +"""""""""""""""""""""""""""""""" + + .. php:method:: getDatabaseMemberUsers() + + Returns the list of users belonging to the *members* of the database. + + :returns: An array of usernames that belong to the member list of this database. + + Example - getting all users beeing *members* of the database mydb + + .. code-block:: php + + getDatabaseMemberUsers(); + } catch ( Exception $e ) { + die("unable to list users: ".$e->getMessage()); + } + print_r($users); + // will echo something like: Array ( "joe" , "jack" ) + +:hidden:`getDatabaseAdminUsers` +""""""""""""""""""""""""""""""" + + .. php:method:: getDatabaseAdminUsers() + + Returns the list of users belonging to the *admins* of the database. + + :returns: An array of usernames that belong to the admin list of this database. + + Example - getting all users beeing *admins* of the database mydb + + .. code-block:: php + + getDatabaseAdminUsers(); + } catch ( Exception $e ) { + die("unable to list users: ".$e->getMessage()); + } + print_r($users); + // will echo something like: Array ( "william" ) + +:hidden:`removeDatabaseMemberUser` +"""""""""""""""""""""""""""""""""" + + .. php:method:: removeDatabaseMemberUser($login) + + Removes a user from the members list of the database. + + :params string $login: Remove the database username from the database member list. + + Example - removing joe from the members of the database mydb + + .. code-block:: php + + removeDatabaseMemberUser("joe"); + } catch ( Exception $e ) { + die("unable to remove user: ".$e->getMessage()); + } + +:hidden:`removeDatabaseAdminUser` +""""""""""""""""""""""""""""""""" + + .. php:method:: removeDatabaseAdminUser($login) + + Removes a user from the admins list of the database. + + :params string $login: Remove the database username from the database admin list. + + Example - removing joe from the admins of the database mydb + + .. code-block:: php + + removeDatabaseAdminUser("joe"); + } catch ( Exception $e ) { + die("unable to remove user: ".$e->getMessage()); + } + +Database roles security +======================= + +Just like users, roles can be assigned as admins or members in a CouchDB database. +`The CouchDB wiki gives all details regarding rights management. `_ + + +:hidden:`addDatabaseMemberRole` +""""""""""""""""""""""""""""""" + + .. php:method:: addDatabaseMemberRole($role) + + Adds a role in the members list of the database. + + :params string $role: The role to add to the member role list of the current database. + + Example - adding cowboy to the members of the database mydb + + .. code-block:: php + + addDatabaseMemberRole("cowboy"); + } catch ( Exception $e ) { + die("unable to add role: ".$e->getMessage()); + } + +:hidden:`addDatabaseAdminRole` +"""""""""""""""""""""""""""""" + + .. php:method:: addDatabaseAdminRole($role) + + Adds a role in the admins list of the database. + + :params string $role: The role to add to the admin role list of the current database. + + Example - adding *cowboy* role to the *admins* of the database mydb + + .. code-block:: php + + addDatabaseAdminrole("cowboy"); + } catch ( Exception $e ) { + die("unable to add role: ".$e->getMessage()); + } + +:hidden:`getDatabaseMemberRoles` +"""""""""""""""""""""""""""""""" + + .. php:method:: getDatabaseMemberRoles() + + Returns the list of roles belonging to the *members* of the database. + + :returns: An array of roles belonging to the member section of the current database. + + Example - getting all roles beeing *members* of the database mydb + + .. code-block:: php + + getDatabaseMemberRoles(); + } catch ( Exception $e ) { + die("unable to list roles: ".$e->getMessage()); + } + print_r($roles); + // will echo something like: Array ( "cowboy" , "indians" ) + +:hidden:`getDatabaseAdminRoles` +""""""""""""""""""""""""""""""" + + .. php:method:: getDatabaseAdminRoles() + + Returns the list of roles belonging to the *admins* of the database. + + :returns: An array of roles belonging to the admin section of the current database. + + Example - getting all roles beeing *admins* of the database mydb + + .. code-block:: php + + getDatabaseAdminRoles(); + } catch ( Exception $e ) { + die("unable to list roles: ".$e->getMessage()); + } + print_r($roles); + // will echo something like: Array ( "martians" ) + +:hidden:`removeDatabaseMemberRole` +"""""""""""""""""""""""""""""""""" + + .. php:method:: removeDatabaseMemberRole($role) + + Removes a role from the members list of the database. + + :params string $role: The role to remove from the database member role list. + + Example - removing *cowboy* from the *members* of the database mydb + + .. code-block:: php + + removeDatabaseMemberRole("cowboy"); + } catch ( Exception $e ) { + die("unable to remove role: ".$e->getMessage()); + } + +:hidden:`removeDatabaseAdminRole` +""""""""""""""""""""""""""""""""" + + .. php:method:: removeDatabaseAdminRole($role) + + Removes a role from the admins list of the database. + + :params string $role: The role to remove from the database admin role list. + + Example - removing *martians* from the admins of the database mydb + + .. code-block:: php + + removeDatabaseAdminRole("martians"); + } catch ( Exception $e ) { + die("unable to remove role: ".$e->getMessage()); + } + +Accessing Database security object +================================== + +Each Couch database got a security object. The security object is made like : + +.. code-block:: json + + { + "admins" : { + "names" : ["joe", "phil"], + "roles" : ["boss"] + }, + "members" : { + "names" : ["dave"], + "roles" : ["producer", "consumer"] + } + } + + +PHP on Couch provides methods to directly get and set the security object. + +:hidden:`getSecurity` +""""""""""""""""""""" + + .. php:method:: getSecurity() + + :returns: Returns the security object of a CouchDB database. + + Example - getting the security object of the database mydb + + .. code-block:: php + + getSecurity(); + } catch ( Exception $e ) { + die("unable to get security object: ".$e->getMessage()); + } + +:hidden:`setSecurity` +""""""""""""""""""""" + + .. php:method:: setSecurity($security) + + Set the security object of a Couch database + + :params stdClass $security: The security object to set to the current database. + + Example - setting the security object of the database mydb + + .. code-block:: php + + setSecurity($security); + } catch ( Exception $e ) { + die("unable to set security object: ".$e->getMessage()); + } + +:hidden:`setUserDatabase` +""""""""""""""""""""""""" + + .. php:method:: setUserDatabase($name) + + Set an alternate name for the users database on an already created couchAdmin instance. + + :params string $name: The name of the custom database to us to store users. + +:hidden:`getUserDatabase` +""""""""""""""""""""""""" + + .. php:method:: getUserDatabase($name) + + :returns: Return the name that is used actually to connect to the users database. + +Database options +================ + +CouchDB got a special database used to store users. By default this database is called **_users**, but this can be changed. + + +CouchAdmin users_database +""""""""""""""""""""""""" + +To create a CouchAdmin instance and specify the name of the users database, use the constructor second parameter $options, setting the option **users_database**: + +Example - setting the couchdb users database name on couchAdmin object creation + +.. code-block:: php + + "theUsers") ); + + +You can also manipulate directly the CouchAdmin with the following methods : :meth:`CouchAdmin::setUserDatabase` and :meth:`CouchAdmin::getUserDatabase`. + + + + + + diff --git a/doc/api/couch-document.rst b/doc/api/couch-document.rst new file mode 100644 index 0000000..e09b81c --- /dev/null +++ b/doc/api/couch-document.rst @@ -0,0 +1,439 @@ + +.. toctree:: + :numbered: + :maxdepth: 3 + :caption: CouchDocument + +CouchDocument class +******************* + +This section give details on using CouchDocument data mapper. + +CouchDocuments to simplify the code +=================================== + +CouchDB embed a simple JSON/REST HTTP API. You can simplify even more your PHP code using couch documents. +Couch Documents take care of revision numbers, and automatically propagate updates on database. + + +Creating a new document +======================= + + +To create an empty CouchDocument, simply instanciate the **CouchDocument** class, passing the CouchClient object as the constructor argument. + +Example : + +.. code-block:: php + + $client = new CouchClient('http://localhost:5984/','myDB'); + $doc = new CouchDocument($client); + +If I set a property on $doc, it'll be registered in the database. If the property is not _id, the unique identifier will be automatically created by CouchDB, and available in the CouchDocument object. + +Example : + +.. code-block:: php + + $doc->type="contact"; + echo $doc->id(); + // 1961f10823408cc9e1cccc145d35d10d + +However if you specify _id, that one will of course be used. + +Example : + +.. code-block:: php + + $doc = new CouchDocument($client); + $doc->_id = "some_doc"; + echo $doc->id(); + // some_doc + +API Reference +============= + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchDocument + + A CouchDocument is a class that maps a document object. + + +:hidden:`set($key,$value)` +"""""""""""""""""""""""""" + + .. php:method:: set($key, $value = null) + + As we just saw, just set the property on the $doc object and it'll be recorded in the database. There are 2 ways to do it. + You can either use the **set($key, $value)** method or simply use the setter **$obj->key = $value**. + + :params string $key: The key to set + :params string $value: The value to set to the key. + + Example : + + .. code-block:: php + + $doc = new CouchDocument($client); + $doc->_id = "some_doc"; + $doc->type = "page"; + $doc->title = "Introduction"; + +:hidden:`set(array $params)` +"""""""""""""""""""""""""""" + + .. php:method:: set(array $params) + + It's always possible to set several properties in one query using the **set($params)** method + + :params array $params: An associative array of parameters that will be set. + + Example using an array : + + .. code-block:: php + + $doc = new CouchDocument($client); + $doc->set ( + array( + '_id' => 'some_doc', + 'type' => "page", + 'title' => "Introduction" + ) + ); + + Example using an object + + .. code-block:: php + + $prop = new stdClass(); + $prop->_id = "some_doc"; + $prop->type = "page"; + $prop->title = "Introduction"; + + $doc = new CouchDocument($client); + $doc->set ( $prop ); + +:hidden:`setAutocommit` +""""""""""""""""""""""" + + .. php:method:: setAutocommit(boolean $autoCommit) + + If, for some reason, you need to disable the auto-commit feature, use the **setAutocommit()** method. + In this case, you'll have to explicitely call the **record()** method to store your changes on the database. + + :params boolean $autoCommit: Determine if the autocommit option should be enabled or not. + + Example : + + .. code-block:: php + + $doc = new CouchDocument($client); + $doc->setAutocommit(false); + $doc->_id = "some_doc"; + $doc->type = "page"; + $doc->title = "Introduction"; + $doc->record(); + +:hidden:`record` +"""""""""""""""" + + .. php:method:: record() + + When the auto-commit feature is off, you need to apply changes manually. Calling the method **record()** apply the changes. + + Example : + + .. code-block:: php + + $doc = new CouchDocument($client); + $doc->setAutocommit(false); + $doc->_id = "some_doc"; + $doc->type = "page"; + $doc->title = "Introduction"; + $doc->record(); + +:hidden:`getAutocommit` +""""""""""""""""""""""" + + .. php:method:: getAutocommit() + + :returns: True if autocommit is enabled. Otherwise false. + + +:hidden:`remove` +"""""""""""""""" + + .. php:method:: remove($key) + + To unset a property, just use the **unset** PHP function, as you'll do for a PHP object. + You can also use the **remove($key)** function which is normally called when you du a **unset**. + + :params string $key: The key of property to unset. + + Example : + + .. code-block:: php + + $prop = new stdClass(); + $prop->_id = "some_doc"; + $prop->type = "page"; + $prop->title = "Introduction"; + + $doc = new CouchDocument($client); + $doc->set ( $prop ); + unset($doc->title); + echo $doc->title ; // won't echo anything + + +:hidden:`getInstance` +""""""""""""""""""""" + + .. php:method:: getInstance( CouchClient $client, $docId ) + + The static method **getInstance( CouchClient $client, $docId )** returns a CouchDocument when the specified id exists : + + :params CouchClient $client: The CouchClient instance initialized. + :params string $docId: The _id of the document to use. + + Example : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + echo $doc->_rev."\n"; + echo $doc->type; + +:hidden:`getUri` +"""""""""""""""" + + .. php:method:: getUri() + + The method **getUri()** sends back a string giving the current document URI. + + :returns: The document URI. + + Example : + + .. code-block:: php + + echo $doc->getUri(); + /* + db.example.com:5984/testdb/dome_doc_id + */ + +:hidden:`getFields` +""""""""""""""""""" + + .. php:method:: getFields() + + To get the Couch document fields from a CouchDocument object, use the **getFields()** method + + :returns: Returns an object with the fields of the document. + + Example : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + print_r($doc->getFields()); + /* + stdClass object { + "_id" => "some_doc", + "_rev" => "3-234234255677684536", + "type" => "page", + "title"=> "Introduction" + } + */ + +:hidden:`storeAttachment` +""""""""""""""""""""""""" + + .. php:method:: storeAttachment($file, $content_type = 'application/octet-stream', $filename = null) + + .. note:: When the attachment is a file on-disk + + Adds a new attachment or update the attachment if it already exists. The attachment contents is located on a file. + + :params string $file: The absolute path of the file. + :params string $content_type: The Content-Type of the file. + :params string $filename: The desired name of the stored attachment. + + Example - Store the file /path/to/some/file.txt as an attachment of document id "some_doc" : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + try { + $doc->storeAttachment("/path/to/some/file.txt","text/plain"); + } catch (Exception $e) { + echo "Error: attachment storage failed : ".$e->getMessage().' ('.$e->getCode().')'; + } + +:hidden:`storeAsAttachment` +""""""""""""""""""""""""""" + + .. php:method:: storeAsAttachment($data, $filename, $content_type = 'application/octet-stream') + + Adds a new attachment, or update the attachment if it already exists. The attachment contents is contained in a PHP variable. + + :params string $data: The data to store as an attachment. + :params string $filename: The desired name of the stored attachment. + :params string $content_type: The Content-Type of the file. + + Example - Store "Hello world !\nAnother Line" as an attachment named "file.txt" on document "some_doc" : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + try { + $doc->storeAsAttachment("Hello world !\nAnother Line", "file.txt" , "text/plain"); + } catch (Exception $e) { + echo "Error: attachment storage failed : ".$e->getMessage().' ('.$e->getCode().')'; + } + +:hidden:`deleteAttachment` +"""""""""""""""""""""""""" + + .. php:method:: deleteAttachment($name) + + Permanently removes an attachment from a document. + + :params string $name: The name of the attachment to delete. + + Example - Deletes the attachment "file.txt" of document "some_doc" : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + try { + $doc->deleteAttachment("file.txt"); + } catch (Exception $e) { + echo "Error: attachment removal failed : ".$e->getMessage().' ('.$e->getCode().')'; + } + +:hidden:`getAttachmentUri` +"""""""""""""""""""""""""" + + .. php:method:: getAttachmentUri($name) + + :params string $name: The name of the attachment to get the URI. + + :returns: Returns the URI of an attachment. + + Example : + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,'some_doc'); + if ( $doc->_attachments ) { + foreach ( $doc->_attachments as $name => $infos ) { + echo $name.' '.$doc->getAttachmentURI($name); + // should say something like "file.txt http://localhost:5984/dbname/some_doc/file.txt" + } + } + try { + $doc->deleteAttachment("file.txt"); + } catch (Exception $e) { + echo "Error: attachment removal failed : ".$e->getMessage().' ('.$e->getCode().')'; + } + +:hidden:`replicateTo` +""""""""""""""""""""" + + .. php:method:: replicateTo($url, $create_target = false) + + Replicate a CouchDocument to another CouchDB database. The create_target parameter let you create the remote database if it's not existing. + The CouchDocuments instance provides an easy way to replicate a document to, or from, another database. + Think about replication like a copy-paste operation of the document to CouchDB databases. + + For those methods to work, you should have included the CouchReplicator class file src/CouchReplicator.php . + + :params string $url: The url of the remote database to replicate to. + :params boolean $create_target: If true, create the target database if it doesn't exists. + + Example : + + .. code-block:: php + + $client = new CouchClient("http://couch.server.com:5984/","mydb"); + // load an existing document + $doc = CouchDocument::getInstance($client,"some_doc_id"); + // replicate document to another database + $doc->replicateTo("http://another.server.com:5984/mydb/"); + + +:hidden:`replicateFrom` +""""""""""""""""""""""" + + .. php:method:: replicateFrom($id, $url, $create_target = false) + + Replicate a CouchDocument from another CouchDB database, and then load it into the CouchDocument instance. + + :params string $id: Replicate from this target document id. + :params string $url: The url of the remote database to replicate to. + :params boolean $create_target: If true, create the target database if it doesn't exists. + + Example : + + .. code-block:: php + + $client = new CouchClient("http://couch.server.com:5984/","mydb"); + // load an existing document + $doc = new CouchDocument($client); + + // replicate document from another database, and then load it into $doc + $doc->replicateFrom("some_doc_id","http://another.server.com:5984/mydb/"); + echo $doc->_id ; (should return "some_doc_id") + $doc->type="foo"; // doc is recorded on "http://couch.server.com:5984/mydb" + + // then replicate $doc back to http://another.server.com:5984/mydb/ + $doc->replicateTo("http://another.server.com:5984/mydb/"); + + +:hidden:`show` +"""""""""""""" + + .. php:method:: show($id, $name, $additionnal_parameters = array()) + + Parses the current document through a CouchDB show function. + + .. note:: The show method is a proxy method to the **getShow()** method of **CouchClient**. + + :params string $id: The name of the _design document. + :params string $name: The name of the show function + :params array $additionnal_parameters: Additional parameters + + Example : the database contains the following design document : + + .. code-block:: json + + { + "_id": "_design/clean", + "shows": { + "html": "function (doc, req) { + send('

ID: '+doc._id+', rev: '+doc._rev+'

'); + }" + } + } + + and another document that got the id "some_doc". We load the "some_doc" document as a CouchDocument object: + + .. code-block:: php + + $doc = CouchDocument::getInstance($client,"some_doc"); + + We can then request CouchDB to parse this document through a show function : + + .. code-block:: php + + $html = $doc->show("clean","html"); + // html should contain "

ID: some_doc, rev: 3-2342342346

" + +:hidden:`update` +"""""""""""""""" + + .. php:method:: update($id, $name, $additionnal_params = array()) + + Allows to use the CouchDB `update handlers `_ feature to update an existing document. + The CouchDocument object shouldd have an id for this to work ! Please see :meth:`CouchClient::updateDoc` method for more infos. diff --git a/doc/api/couch-replicator.rst b/doc/api/couch-replicator.rst new file mode 100644 index 0000000..e2e5cf2 --- /dev/null +++ b/doc/api/couch-replicator.rst @@ -0,0 +1,245 @@ +CouchReplicator class +********************* + +This section give details on using the CouchReplicator object. + + + +Getting started +=============== + +CouchDB supports replicating a database on other CouchDB databases. Think of replication as a copy-paste operation on databases. + +The CouchReplicator object is a simple abstraction of the CouchDB replication model. Those replication features are available in CouchDB 0.11 . At the time of this coding, canceling a continuous replication doesn't seem to always work. + +To create a new CouchReplicator object, you first have to include necessary files, and then instanciate the object, passing in argument a CouchClient instance. + +.. code-block:: php + + to("http://another.server.com:5984/mydb"); + // database http://localhost:5984/mydb will be replicated to http://another.server.com:5984/mydb + + You can also replicato to a local database + + .. code-block:: php + + $response = $replicator->to("mydb_backup"); + // database http://localhost:5984/mydb will be replicated to http://localhost:5984/mydb_backup + +:hidden:`from` +"""""""""""""" + + .. php:method:: from() + + To replicate from a database to an existing database, use the **from()** method. + + Example: + + .. code-block:: php + + $response = $replicator->from("http://another.server.com:5984/mydb"); + // database http://another.server.com:5984/mydb will be replicated to http://localhost:5984/mydb + + .. note:: Please note that CouchDB developpers hardly suggest to use the Pull replication mode : that means to prefer the "from()" method. + +Chainable methods +================= + +:hidden:`create_target` +""""""""""""""""""""""" + + .. php:method:: create_target() + + The **create_target()** chainable method enables CouchDB to automatically create the target database, in case it doesn't exist. + + Example : + + .. code-block:: php + + $response = $replicator->create_target()->from("http://another.server.com:5984/mydb"); + + Which is equivalent to : + + .. code-block:: php + + $replicator->create_target(); + $response = $replicator->from("http://another.server.com:5984/mydb"); + + If the target database already exist, the create_target() method has no use. + +:hidden:`doc_ids` +""""""""""""""""" + + .. php:method:: doc_ids() + + To replicate only some documents, pass their ids to the **doc_ids()** chainable method. + + Example : + + .. code-block:: php + + $replicator->doc_ids( array ("some_doc", "some_other_doc") )->from("http://another.server.com:5984/mydb"); + + This code will replicate documents "some_doc" and "some_other_doc" of database "http://another.server.com:5984/mydb" to database "http://localhost:5984/mydb" + +:hidden:`continous` +""""""""""""""""""" + + .. php:method:: continuous() + + A continuous replication is a replication that is permanent : once set, any change to the source database will be automatically propagated to the destination database. + To setup a continuous replication, use the **continuous()** chainable method. + + Example : + + .. code-block:: php + + // setup a continuous replication + $replicator->continuous()->from("http://another.server.com:5984/mydb"); + // create a CouchClient instance on the source database + $client2 = new CouchClient("http://another.server.com:5984/","mydb"); + // create and record a document on the source database + $doc = new stdClass(); + $doc->_id = "some_doc_on_another_server"; + $doc->type = "foo"; + $client2->storeDoc( $doc ); + // let some time for CouchDB to replicate + sleep(10); + // read the document from the destination database + $doc = $client->getDoc("some_doc_on_another_server"); + echo $doc->type; + +:hidden:`cancel` +"""""""""""""""" + + .. php:method:: cancel() + + To cancel a previously setup continuous replication, use the **cancel()** chainable method. + + Example : + + .. code-block:: php + + // setup a continuous replication + $replicator->continuous()->from("http://another.server.com:5984/mydb"); + (...) //code code code + // remove the continuous replication + $replicator->cancel()->from("http://another.server.com:5984/mydb"); + + +:hidden:`filter` +"""""""""""""""" + + .. php:method:: filter() + + To have a full control over which document should be replicated, setup a filter definition on the source database. Then use the **filter()** chainable method to filter replicated documents. + + .. code-block:: php + + // create a CouchClient instance pointing to the source database + $source_client = new CouchClient("http://localhost:5984","mydb"); + // create a CouchClient instance pointing to the target database + $target_client = new CouchClient("http://another.server.com:5984","mydb") + + // create a design doc + $doc = new stdClass(); + $doc->_id = "_design/replication_rules"; + $doc->language = "javascript"; + // create a "no_design_doc" filter : only documents without the string "_design" will be replicated + $doc->filters = array ( + "no_design_doc" => "function (doc, req) { + if ( doc._id.match('_design') ) { + return false; + } else { + return true; + } + }" + ); + // store the design doc in the SOURCE database + $target_client->storeDoc($doc); + + //create a CouchReplicator instance on the destination database + $replicator = new CouchReplicator($target_client); + + // replicate source database to target database, using the "no_design_doc" filter + $replicator->filter('replication_rules/no_design_doc')->from($source_client->getDatabaseUri()); + +:hidden:`query_params` +"""""""""""""""""""""" + + .. php:method:: query_params() + + Filters can have a query parameters. This allows more generic filter codes. + Let's modify the filter code above to pass the string to compare the document id to via query parameters : + + .. code-block:: php + + // create a CouchClient instance pointing to the source database + $source_client = new CouchClient("http://localhost:5984","mydb"); + // create a CouchClient instance pointing to the target database + $target_client = new CouchClient("http://another.server.com:5984","mydb") + + // create a design doc + $doc = new stdClass(); + $doc->_id = "_design/replication_rules"; + $doc->language = "javascript"; + // create a "no_design_doc" filter : only documents without the string "_design" will be replicated + $doc->filters = array ( + "no_str_in_doc" => "function (doc, req) { + if ( doc._id.match( req.query.needle ) ) { + return false; + } else { + return true; + } + }" + ); + // store the design doc in the SOURCE database + $target_client->storeDoc($doc); + + //create a CouchReplicator instance on the destination database + $replicator = new CouchReplicator($target_client); + + // replicate source database to target database, using the "no_str_in_doc" filter, and setting needle to "_design" + $params = array ("needle"=>"_design"); + $replicator->query_params($params)->filter('replication_rules/no_str_in_doc')->from($source_client->getDatabaseUri()); + + +Replication of individual CouchDocuments +"""""""""""""""""""""""""""""""""""""""" + +Please read the CouchDocument documentation to learn how to simply replicate a document to or from a database to another + + diff --git a/doc/api/couch.rst b/doc/api/couch.rst new file mode 100644 index 0000000..58e2d97 --- /dev/null +++ b/doc/api/couch.rst @@ -0,0 +1,175 @@ + +.. toctree:: + :numbered: + :maxdepth: 3 + +Couch class +*********** + + +Summary +####### + +The Couch.php class is the one of the low level class that is used to handle the communication between the high level classes and CouchDB. Before version **2.0.2**, the default Http adapter was curl and all the possible adapters where declared into the Couch.php class. With **2.0.2**, the library code has been refactored so that the Http adapters are declared into separate classes. The Couch class nowaday use a HttpAdapterInterface to communicate with CouchDB. + +**Note**: The following methods are public methods of the Couch class. Therefore, you will mostly use the high level classes which usually inherit the Couch class. For example, all the following methods will be directly available from the CouchClient class. + +API Reference +############# + +.. php:namespace:: PHPOnCouch + +.. php:class:: Couch + + This is the low level class that handles communications with CouchDB. + +:hidden:`dsn` +""""""""""""" + + .. php:method:: dsn() + + :returns: The dsn of the current Couch instance + +:hidden:`options` +""""""""""""""""" + + .. php:method:: options() + + :returns: The options passed to the Couch instance. + +:hidden:`getSessionCookie` +"""""""""""""""""""""""""" + + .. php:method:: getSessionCookie() + + :returns: The current session cookie. Returns null if not set. + +:hidden:`setSessionCookie` +"""""""""""""""""""""""""" + + .. php:method:: setSessionCookie($cookie) + + Set the current session cookie. + + :params string $cookie: The cookie to set + +:hidden:`query` +""""""""""""""" + + .. php:method:: query($method, $url, $parameters = array(), $data = null, $contentType = null) + + Send a query to the CouchDB server. + + :params string $method: The HTTP method to use (GET,PUT,POST,...) + :params string $url: The URL to fetch + :params array $parameters: The query parameters to pass to the query + :params mixed $data: The request body(null by default) + :params string $contentType: The content type of the data. + :returns: The server response or false if an error occured. + +:hidden:`continuousQuery` +""""""""""""""""""""""""" + + .. php:method:: continuousQuery($callable, $method, $url, $parameters = array(), $data = null) + + Send a query to CouchDB. For each line returned by the server, the $callable will be called. If the callable returns false, the **continuousQuery** will stop. + + :params Function $callable: The function called for every document returned. + :params string $method: The HTTP method to use (GET,PUT,POST,...) + :params string $url: The URL to fetch + :params array $parameters: The query parameters to pass to the query + :params mixed $data: The request body(null by default) + :params string $contentType: The content type of the data. + :returns: The server response or false if an error occured. + +:hidden:`storeFile` +""""""""""""""""""" + + .. php:method:: storeFile($url, $file, $contentType) + + Make a request with the $file content passed into the request body. The $file must be on the disk. + + :params function $callable: The function called for every document returned + :params string $method: The HTTP method to use (GET,PUT,POST,...) + :params string $url: The URL to fetch + :params array $parameters: The query parameters to pass to the query + :params mixed $data: The request body(null by default) + :params string $contentType: The content type of the data. + :returns: The server response or false if an error occured. + +:hidden:`storeAsFile` +""""""""""""""""""""" + + .. php:method:: storeAsFile($url, $data, $contentType) + + Make a request with the $data passed into the request body. + + :params function $callable: The function called for every document returned + :params string $method: The HTTP method to use (GET,PUT,POST,...) + :params string $url: The URL to fetch + :params array $parameters: The query parameters to pass to the query + :params mixed $data: The request body(null by default) + :params string $contentType: The content type of the data. + :returns: The server response or false if an error occured. + +:hidden:`initAdapter` +""""""""""""""""""""" + + .. php:method:: initAdapter($options) + + This function is called to initialized the adapter. By default, it will load the cURL adapter. The options passed are the same options passed to the Couch class. It's must be an array of options. **You don't have to call this method.** It will be automatically call when using the Couch class. + + :params array $options: The options passed to the Couch instance + + Example : + + .. code-block:: php + + $couch = new Couch("http://localhost:5984"); + $couch->initAdapter([]) //Set the curl by default + + +:hidden:`getAdapter` +"""""""""""""""""""" + + .. php:method:: getAdapter() + + This function return the current adapter. If it's not set, the :meth:`Couch::initAdapter` will be called. + + :returns: The Adapter currently used. + + Example : + + .. code-block:: php + + $couch = new PHPOnCouch\Couch("http://localhost:5984"); + $adapter = $couch->getAdapter(); + $doc = $adapte->query('GET','db/_all_docs'); + +:hidden:`setAdapter` +"""""""""""""""""""" + + .. php:method:: setAdapter(CouchHttpAdapterInterface $adapter) + + This function set the current adapter of the Couch class. You must specify a class that implements the CouchHttpAdapterInterface. + + :params CouchHttpAdapterInterface $adapter: The adapter to set. + + You can implemented the following adapters : + + - CouchHttpAdapterSocket + - CouchHttpAdapterCurl (default) + + .. note :: + + Even if the CouchHttpAdapter used is Curl, the Socket adapter is still used for the continuous_query function since it is not implemented with cURL. + + Example: + + .. code-block:: php + + use PHPOnCouch\Adapter\CouchHttpAdapterCurl; + + $couch = new PHPOnCouch\Couch("http://localhost:5984"); + $adapter = new CouchHttpAdapterSocket([]); + $couch->setAdapter($adapter); diff --git a/doc/api/couchclient/database.rst b/doc/api/couchclient/database.rst new file mode 100644 index 0000000..34601c4 --- /dev/null +++ b/doc/api/couchclient/database.rst @@ -0,0 +1,609 @@ +Database +******** + +This section give details on actions on the CouchDB server through PHP on Couch. + +Getting started +=============== + + +To use PHP on Couch client, you have to create a couchClient instance, setting the URL to your couchDB server, and the database name. + +Example : connect to the couchDB server at http://my.server.com on port 5984 and on database mydb : + +.. code-block:: php + + $client = new CouchClient("http://my.server.com:5984/","mydb"); + +If you want to authenticate to the server using a username & password, just set it in the URL. + +Example : connect to the couchDB server at http://my.server.com on port 5984 using the username "couchAdmin", the password "secret" and on database mydb : + +.. code-block:: php + + $client = new CouchClient("http://couchAdmin:secret@my.server.com:5984/","mydb"); + +You can also tell couchClient to use cookie based authentification, by passing an additional flag "cookie_auth" set to true in the options array, as the third parameter of the couchClient constructor. + +Example : as the previous one, but using cookie based authentification + +.. code-block:: php + + $client = new CouchClient("http://couchAdmin:secret@my.server.com:5984/","mydb", array("cookie_auth"=>true) ); + +You can also manually set the session cookie. + +Example : manually setting the session cookie : + +.. code-block:: php + + $client = new CouchClient("http://my.server.com:5984/","mydb"); + $client->setSessionCookie("AuthSession=Y291Y2g6NENGNDgzNzY6Gk0NjM-UKxhpX_IyiH-C-9yXY44"); + +General functions +================= + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchClient + + +:hidden:`dsn` +"""""""""""""" + + .. php:method:: dsn() + + :returns string: The DSN of the server. Database name is not included. + + Example : + + .. code-block:: php + + $client = new CouchClient("http://couch.server.com:5984/","hello"); + echo $client->dsn(); // will echo : http://couch.server.com:5984 + +:hidden:`getSessionCookie` +"""""""""""""""""""""""""" + + .. php:method:: getSessionCookie() + + :returns string: Returns the current session cookie if set. + + Example : + + .. code-block:: php + + $cookie = $client->getSessionCookie(); + +:hidden:`setSessionCookie` +"""""""""""""""""""""""""" + + .. php:method:: setSessionCookie($cookie) + + This method set the cookie and is chainable. + + :params string $cookie: The cookie to set. + :returns CouchClient: Return the current instance. + + Example : + + .. code-block:: php + + $cookie = $client->setSessionCookie("AuthSession=Y291Y2g6NENGNDgzNz")->getSessionCookie(); + + +:hidden:`isValidaDatabaseName` +"""""""""""""""""""""""""""""" + + .. php:method:: isValidDatabaseName($name) + + Database names on CouchDB have restrictions. Here are the allowed characters: + + - lowercase characters (a-z) + - digits (0-9) + - any of the following characters _, $, (, ), +, -, and / are allowed + + The name has to start with a lowercase letter (a-z) or an underscore (_). + + To test if a given database name is valid, use the static **isValidDatabaseName()** CouchClient method. + + :params string $name: The name to validate. + :returns boolean: True if valid. Otherwise false. + + Example : + + .. code-block:: php + + $my_database = "user311(public)"; + if ( CouchClient::isValidDatabaseName($my_database) ) { + $client = new CouchClient("http://couch.server.com:5984/",$my_database); + } else { + die("Invalid database name"); + } + +:hidden:`listDatabases` +""""""""""""""""""""""" + + .. php:method:: listDatabases() + + The method **listDatabases()** lists the available databases on the CouchDB server. + + :returns array: An array of database names. + + Example : + + .. code-block:: php + + $dbs = $client->listDatabases(); + print_r($dbs); // array ('first_database','another_database') + +:hidden:`createDatabase` +"""""""""""""""""""""""" + + .. php:method:: createDatabase() + + Create the database according to the name you set when creating couch_client object $client. + + .. note:: If the database already exist, this method will throw an exception. + + Example : + + .. code-block:: php + + $client->createDatabase(); + + +:hidden:`deleteDatabase` +"""""""""""""""""""""""" + + .. php:method:: deleteDatabase() + + Permanently remove from the server the database according to the name you set when creating couch_client object $client. + + .. note:: If the database does not exist, the method will throw an exception. + + Example : + + .. code-block:: php + + $client->deleteDatabase(); + +:hidden:`databaseExists` +"""""""""""""""""""""""" + + .. php:method:: databaseExists() + + Test if the database already exist on the server. + + :returns boolean: True if it exists. Otherwise false. + + Example : + + .. code-block:: php + + if ( !$client->databaseExists() ) { + $client->createDatabase(); + } + +:hidden:`getDatabaseInfos` +"""""""""""""""""""""""""" + + .. php:method:: getDatabaseInfos() + + Sends back informations about the database. Informations contains the number of documents in the database, the space of the database on disk, the update sequence number, ... + + :returns array: Returns an arrayf with the database informations. + + Example : + + .. code-block:: php + + print_r($client->getDatabaseInfos()); + /* + array("db_name" => "testdb", + "doc_count" => 2, + "doc_del_count" => 0, + "update_seq" => 6, + "purge_seq" => 0, + "compact_running" => false, + "disk_size" => 277707, + "instance_start_time" => "1246277543362647" + ) + */ + +:hidden:`getDatabaseUri` +"""""""""""""""""""""""" + + .. php:method:: getDatabaseUri() + + The method **getDatabaseUri()** sends back a string giving the HTTP connection URL to the database server. + + Example : + + .. code-block:: php + + echo $client->getDatabaseUri(); + /* + http://db.example.com:5984/testdb + */ + +:hidden:`getUuids` +"""""""""""""""""" + + .. php:method:: getUuids($count = 1) + + Sends back an array of universally unique identifiers (that is, big strings that can be used as document ids) + + :params int $count: The number of id to returns. + :returns array: An array of identifiers + + Example : + + .. code-block:: php + + print_r($client->getUuids(5)); + /* + array ( 0 => "65a8f6d272b3e5e62ee9de8eacc083a5", + 1 => "e43b04e44233d72b353c1cd8915b886d", + 2 => "7498fb296f19ebc2554a4812f3d9ae12", + 3 => "f3f855a15eb90e9fcdbda5e017b9f2cd", + 4 => "9d9a8214762d06cdf0158d7f6697cac9" ) + */ + +:hidden:`useDatabase` +""""""""""""""""""""" + + .. php:method:: useDatabase($dbName) + + The method **useDatabase($dbname)** changes the working database on the CouchDB server. + + :params string $dbName: The name of the database to use. + + Example : + + .. code-block:: php + + $client = new CouchClient("http://localhost:5984", "db1"); + $all_docs_db1 = $client->getAllDocs(); //retrieve all docs of database db1 + $client->useDatabase("db2"); //switch to "db2" database + $all_docs_db2 = $client->getAllDocs(); //retrieve all docs of database db2 + +:hidden:`getMembership` +""""""""""""""""""""""" + + .. php:method:: getMembership() + + With the new Cluster infrastructure in CouchDB 2.0, you now have to configure each nodes. To do so, you need to get + the information about them. The *\_membership* endpoint allow you to get all the nodes that the current nodes knows and all + the nodes that are in the same cluster. The method **getMembership()** returns an object like this : + + .. code-block:: json + + { + "all_nodes": [], + "cluster_nodes": [] + } + +:hidden:`getConfig` +""""""""""""""""""" + + .. php:method:: getConfig($nodeName [, $section [, $key ]]) + + .. warning:: The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only. + + To configure, you need to use **getConfig($nodeName [, $section [, $key ]])**. If you don't know the nodeName, you can use the **getMembership()** method. + + :params string $nodeName: The name of the node to use. + :params string $section: The section value to return. + :params string $key: The section key-value to return. + + Examples : + + *getConfig("couchdb@localhost")** + + Returns a JSON object with the whole configuration + + .. code-block:: json + + { + "attachments":{ + + }, + "couchdb":{ + + } + } + + *getConfig("couchdb@localhost","httpd")* + + .. note :: It will return a CouchNotFoundException is the section is not present. + + Returns a JSON object that represent the desired section + + .. code-block:: json + + { + "allow_jsonp": "false", + "authentication_handlers": "{couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}", + "bind_address": "127.0.0.1", + "default_handler": "{couch_httpd_db, handle_request}", + "enable_cors": "false", + "log_max_chunk_size": "1000000", + "port": "5984", + "secure_rewrites": "true", + "vhost_global_handlers": "_utils, _uuids, _session, _oauth, _users" + } + + *getConfig("couchdb@localhost","log","level")* + + Returns either text-plain of JSON value of the section/key. + + .. note:: It will return a CouchNotFoundException is the section or key are not present*. + + .. code-block:: json + + "debug" + +:hidden:`setConfig` +""""""""""""""""""" + + .. php:method:: setConfig($nodeName, $section, $key, $value) + + .. warning:: The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only* + + The method **setConfig($nodeName, $section, $key, $value)** let you configure your installation. It can throws CouchNotAuthorizedException or CouchNotFoundException depending on the parameters supplied. + + Example : + + .. code-block:: php + + $val = $client->setConfig("couchdb@localhost","log","level","info"); + echo $val; + /* + "debug" + */ + +:hidden:`deleteConfig` +"""""""""""""""""""""" + + .. php:method:: deleteConfig($nodeName, $section, $key) + + .. warning:: The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only + + The method **deleteConfig($nodeName, $section, $key)** let you delete a configuration key from your node. + It will returns the JSON value of the parameter before its deletion. Not that the method can throw a CouchNotFoundException or a CouchUnauthorizedException regarding of the section/key and permissions. + + Example: + + .. code-block:: php + + $oldValue = $client->deleteConfig("couchdb@localhost","log","level"); + echo $oldValue; + /* + "info" + */ + + +Changes +======= + +CouchDB implements database changes feedback and polling. You'll find `more infos here `_ . +For any event in the database, CouchDB increments a sequence counter. + +:hidden:`getChanges` +"""""""""""""""""""" + + .. php:method:: getChanges() + + The method **getChanges()** sends back a CouchDB changes object. + + Example : + + .. code-block:: php + + print_r($client->getChanges()); + /* + stdClass Object + ( + [results] => Array + ( + [0] => stdClass Object + ( + [seq] => 'example-last-update-sequence' + [id] => 482fa0bed0473fd651239597d1080f03 + [changes] => Array + ( + [0] => stdClass Object + ( + [rev] => 3-58cae2758cea3e82105e1090d81a9e02 + ) + + ) + + [deleted] => 1 + ) + + [1] => stdClass Object + ( + [seq] => 'example-last-update-sequence' + [id] => 2f3f913f34d60e473fad4334c13a24ed + [changes] => Array + ( + [0] => stdClass Object + ( + [rev] => 1-4c6114c65e295552ab1019e2b046b10e + ) + + ) + + ) + + ) + + [last_seq] => 4 + ) + */ + +Chainable methods to use before getChanges() +============================================ + +The following methods allow a fine grained control on the **changes** request to issue. + +:hidden:`since` +""""""""""""""" + + .. php:method:: since(string $value) + + Retrieve changes that happened after sequence number $value + + :params string $value: The minimal sequence number + +:hidden:`heartbeat` +""""""""""""""""""" + + .. php:method:: heartbeat(integer $value) + + :params integer $value: Number of milliseconds between each heartbeat line (an ampty line) one logpoll and continuous feeds + +:hidden:`feed` +"""""""""""""" + + .. php:method:: feed(string $value, $callback) + + Feed type to use. In case of "continuous" feed type, $callback should be set and should be a PHP callable object (so *is_callable($callback)* should be true) + + The callable function or method will receive two arguments : the JSON object decoded as a PHP object, and a couchClient instance, allowing developers to issue CouchDB queries from inside the callback. + + :params string $value: The feed value. + :params callable $callback: The callback function to execute for each document received. + + +:hidden:`filter` +"""""""""""""""" + + .. php:method:: filter(string $value, array $additional_query_options) + + Apply the changes filter $value. Add additional headers if any + + :params string $value: The filter to use. + :params array $additional_query_options: The additional query options to pass to the filter. + +:hidden:`style` +""""""""""""""" + + .. php:method:: style(string $value) + + Changes display style, use "all_docs" to switch to verbose + + :params string $value: The style to value to apply + + Example : + + .. code-block:: php + + // fetching changes since sequence 'example-last-update-sequence' using filter "messages/incoming" + $changes = $client->since('example-last-update-sequence')->filter("messages/incoming")->getChanges(); + + Example - Continuous changes with a callback function + + .. code-block:: php + + function index_doc($change,$couch) { + if( $change->deleted == true ) { + // won't index a deleted file + return ; + } + echo "indexing ".$change->id."\n"; + $doc = $couch->getDoc($change->id); + unset($doc->_rev); + $id = $doc->_id; + unset($doc->_id); + my_super_fulltext_search_appliance::index($id, $doc); + } + + $client->feed('continuous','index_doc')->getChanges(); + // will return when index_doc returns false or on socket error + +:hidden:`ensureFullCommit` +"""""""""""""""""""""""""" + + .. php:method:: ensureFullCommit() + + The method **ensureFullCommit()** tells couchDB to commit any recent changes to the database file on disk. + + Example : + + .. code-block:: php + + $response = $client->ensureFullCommit(); + print_r($response); + /* should print something like : + stdClass Object + ( + [ok] => 1, + [instance_start_time] => "1288186189373361" + ) + */ + +Maintenance +=========== + +Three main maintenance tasks can be performed on a CouchDB database : compaction, view compaction, and view cleanup. + +:hidden:`compactDatabase` +""""""""""""""""""""""""" + + .. php:method:: compactDatabase() + + CouchDB database file is an append only : during any modification on database documents (add, remove, or update), the modification is recorded at the end of the database file. The compact operation removes old versions of database documents, thus reducing database file size and improving performances. To initiate a compact operation, use the **compactDatabase()** method. + + Example : + + .. code-block:: php + + // asking the server to start a database compact operation + $response = $client->compactDatabase(); // should return stdClass ( "ok" => true ) + +:hidden:`compactAllViews` +""""""""""""""""""""""""" + + .. php:method:: compactAllViews() + + Just as documents files, view files are also append-only files. To compact all view files of all design documents, use the **compactAllViews()** method. + + Example : + + .. code-block:: php + + // asking the server to start a view compact operation on all design documents + $response = $client->compactAllViews(); // return nothing + +:hidden:`compactViews` +"""""""""""""""""""""" + + .. php:method:: compactViews($id) + + To compact only views from a specific design document, use the **compactViews( $id )** method. + + :params string $id: The id of the design document to compact. + + Example : + + .. code-block:: php + + // asking the server to start a database compact operation on the design document _design/example + $response = $client->compactViews( "example" ); // should return stdClass ( "ok" => true ) + +:hidden:`cleanupDatabaseViews` +"""""""""""""""""""""""""""""" + + .. php:method:: cleanupDatabaseViews() + + This operation will delete all unused view files. Use the **cleanupDatabaseViews()** method to initiate a cleanup operation on old view files + + Example : + + .. code-block:: php + + // asking the server to start a database view files cleanup operation + $response = $client->cleanupDatabaseViews(); // should return stdClass ( "ok" => true ) \ No newline at end of file diff --git a/doc/api/couchclient/document.rst b/doc/api/couchclient/document.rst new file mode 100644 index 0000000..518466c --- /dev/null +++ b/doc/api/couchclient/document.rst @@ -0,0 +1,633 @@ +Document +******** + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchClient + + +:hidden:`getAllDocs` +"""""""""""""""""""" + + .. php:method:: getAllDocs() + + Retrieve all documents from the database. In fact it only retrieve document IDs, unless you specify the server to include the documents using the View query parameters syntax. + + :returns: An object with the total_rows number, the rows returned and other informations. + + Example : + + .. code-block:: php + + $all_docs = $client->getAllDocs(); + echo "Database got ".$all_docs->total_rows." documents.
\n"; + foreach ( $all_docs->rows as $row ) { + echo "Document ".$row->id."
\n"; + } + +:hidden:`getDoc` +"""""""""""""""" + + .. php:method:: getDoc($id) + + Gives back the document that got ID $id, if it exists. Note that if the document does not exist, the method will throw an error. + + :params string $id: The id of the document to fetch + :returns: The document if found. Otherwise, a CouchNotFoundException is throw. + + The document is sent back as an HTTP object of class `stdClass `_. + + Example : + + .. code-block:: php + + try { + $doc = $client->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + echo $doc->_id.' revision '.$doc->_rev; + +Chainable methods to use with getDoc() +====================================== + +:hidden:`rev` +""""""""""""" + + .. php:method:: rev($value) + + The chainable **rev($value)** method specify the document revision to fetch. + + :params mixed $value: The specific revision to fetch of a document. + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->rev("1-849aff6ad4a38b1225c80a2119dc31cb")->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id or revision 1-849aff6ad4a38b1225c80a2119dc31cb does not exist !"; + } + exit(1); + } + echo $doc->_rev ; // should echo 1-849aff6ad4a38b1225c80a2119dc31cb + +:hidden:`asCouchDocuments` +"""""""""""""""""""""""""" + + .. php:method:: asCouchDocuments() + + When the getDoc function will be called, it will return a :meth:`CouchDocument`. You can however get back the document as a CouchDocument object by calling the **asCouchDocuments()** method before the **getDoc($id)** method. + + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->asCouchDocuments()->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + echo get_class($doc); // should echo "CouchDocument" + +:hidden:`conflicts` +""""""""""""""""""" + + .. php:method:: conflicts() + + The chainable method **conflicts()** asks CouchDB to add to the document a property *_conflicts* containing conflicting revisions on an object. + + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->conflicts()->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + if ( $doc->_conflicts ) { + print_r($doc->_conflicts); + } + +:hidden:`revs` +"""""""""""""" + + .. php:method:: revs() + + The chainable method **revs()** asks CouchDB to add to the document a property *_revisions* containing the list of revisions for an object. + + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->revs()->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + print_r($doc->_revisions); + +:hidden:`revs_info` +""""""""""""""""""" + + .. php:method:: revs_info() + + The chainable method **revs_info()** asks CouchDB to add to the document a property *_revs_info* containing the avaibility of revisions for an object. + + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->revs_info()->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + print_r($doc->_revs_info); + +:hidden:`open_revs` +""""""""""""""""""" + + .. php:method:: open_revs($value) + + Using the **open_revs($value)** method, CouchDB returns an array of objects. + + :params array|string $value: Should be an array of revision ids or the special keyword all (to fetch all revisions of a document) + :returns: The CouchClient instance. + + Example : + + .. code-block:: php + + try { + $doc = $client->open_revs( array("1-fbd8a6da4d669ae4b909fcdb42bb2bfd", "2-5bc3c6319edf62d4c624277fdd0ae191") )->getDoc("some_doc_id"); + } catch ( Exception $e ) { + if ( $e->getCode() == 404 ) { + echo "Document some_doc_id does not exist !"; + } + exit(1); + } + print_r($doc->_revs_info); + + Which should return something similar to : + + .. code-block:: php + + array ( + stdClass( + "missing" => "1-fbd8a6da4d669ae4b909fcdb42bb2bfd" + ), + stdClass( + "ok" => stdClass( + "_id" => "some_doc_id", + "_rev" => "2-5bc3c6319edf62d4c624277fdd0ae191", + "hello"=> "foo" + ) + ) + ) + +:hidden:`storeDoc` +"""""""""""""""""" + + .. php:method:: storeDoc($doc) + + Store a document on the CouchDB server. + + :params stdClass $doc: $doc should be an object. If the property $doc->_rev is set, the method understand that it's + an update, and as so requires the property $doc->\_id to be set. If the property $doc->\_rev is not set, the method checks for the existance of property $doc->\_id and initiate the appropriate request. + :returns: The response of this method is the CouchDB server response. In other words if the request ends successfully the returned object should be : + + .. code-block:: php + + stdClass ( "ok" => true, "id" => "some_doc_id" , "rev" => "3-23423423476" ) + + Example : creating a document without specifying id + + .. code-block:: php + + $new_doc = new stdClass(); + $new_doc->title = "Some content"; + try { + $response = $client->storeDoc($new_doc); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; + // Doc recorded. id = 0162ff06747761f6d868c05b7aa8500f and revision = 1-249007504 + + Example : creating a document specifying the id + + .. code-block:: php + + $new_doc = new stdClass(); + $new_doc->title = "Some content"; + $new_doc->_id = "BlogPost6576"; + try { + $response = $client->storeDoc($new_doc); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; + // Doc recorded. id = BlogPost6576 and revision = 1-249004576 + + + Example : updating an existing document : + + .. code-block:: php + + // get the document + try { + $doc = $client->getDoc('BlogPost6576'); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + + // make changes + $doc->title = 'Some smart content'; + $doc->tags = array('twitter','facebook','msn'); + + // update the document on CouchDB server + try { + $response = $client->storeDoc($doc); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; + // Doc recorded. id = BlogPost6576 and revision = 2-456769086 + + +Updating a document +=================== + +Using CouchDB `Update handlers `_ , you can easily update any document part without having to send back the whole document. + +:hidden:`updateDoc` +""""""""""""""""""" + + .. php:method:: updateDoc($ddoc_id, $handler_name, $params, $doc_id = null) + + Update document according to the code defined in the update handler. + + :params string $ddoc_id: The desing document id (suffix of _design/) + :params string $handler_name: The update handler name + :params array $params: to complete... + :params string $doc_id: The document id to udpate + + Example : incrementing a document counter + + Let's say we have a design document _design/myapp containing : + + .. code-block:: json + + { + "updates": { + "bump-counter" : "function(doc, req) { + if ( !doc ) return [null, {\"code\": 404, \"body\": \"Document not found / not specified\"}] + if (!doc.counter) doc.counter = 0; + doc.counter += 1; + var message = \"

bumped it!

\"; + return [doc, message]; + }" + } + } + + To bump the counter of the document "some_doc" , use : + + .. code-block:: php + + $client->updateDoc("myapp","bump-counter",array(),"some_doc"); + + +:hidden:`updateDocFullAPI` +"""""""""""""""""""""""""" + + .. php:method:: updateDocFullAPI($ddoc_id, $handler_name, $options) + + Update document according to the code defined in the update handler. + + :params string $ddoc_id: The id of the design document (suffix of _design/) + :params string $handler_name: Update handler name + :params array $options: + + An array of optionnal query modifiers : + + - params : array|object of variable to pass in the URL ( /?foo=bar ) + - data : string|array|object data to set in the body of the request. If data is an array or an object it will be urlencoded using PHP http_build_query function and the request Content-Type header will be set to "application/x-www-form-urlencoded". + - Content-Type: string the Content-Type HTTP header to send to the couch server + + Example : + + .. code-block:: php + + $client->updateDocFullAPI("myapp","bump-counter",array( "data" => array("Something"=>"is set") ) ); + +:hidden:`deleteDoc` +""""""""""""""""""" + + .. php:method:: deleteDoc($doc) + + Permanently removes $doc from the CouchDB server. + + :params stdClass $doc: An object containing at least \_id and \_rev properties. + + Example : + + .. code-block:: php + + // get the document + try { + $doc = $client->getDoc('BlogPost6576'); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + // permanently remove the document + try { + $client->deleteDoc($doc); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + + +:hidden:`copyDoc` +""""""""""""""""" + + .. php:method:: copyDoc($id, $new_id) + + Provides an handy way to copy a document. + + :params string $id: The id of the document to copy. + :params string $new_id: The id of the new document. + + :returns: + + The CouchDB server response, which has the main form than a document storage : + + .. code-block:: php + + stdClass ( "ok" => true, "id" => "new_id" , "rev" => "1-23423423476" ) + + Example : + + .. code-block:: php + + try { + $response = $client->copyDoc('BlogPost6576','CopyOfBlogPost6576'); + } catch (Exception $e) { + echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; + } + + +Attachments +=========== + +There is two methods handling attachments, it depends whether the file to send as attachment is on the harddrive, or if +it's contained in a PHP variable. The first one should be more reliable for large attachments. + +:hidden:`storeAttachment` +""""""""""""""""""""""""" + + .. php:method:: storeAttachment($doc, $file, $content_type = 'application/octet-stream', $filename = null) + + Handles the process of storing an attachment on a CouchDB document. + + :params stdClass $doc: A PHP object containing at least the properties \_id and \_rev + :params string $file: The complete path to the file on disk + :params string $content_type: The file's `content-type `_ + :params string $filename: The name of the attachment on CouchDB document, if the name is not the name of the file in $file + :returns stdClass: + An HTTP response object like this : + + .. code-block:: php + + stdClass ( "ok" => true, "id" => "BlogPost5676" , "rev" => "5-2342345476" ) + + Example : + + .. code-block:: php + + $doc = $client->getDoc('BlogPost5676'); + $ok = $client->storeAttachment($doc,'/etc/resolv.conf','text/plain', 'my-resolv.conf'); + print_r($ok); + // stdClass ( "ok" => true, "id" => "BlogPost5676" , "rev" => "5-2342345476" ) + +:hidden:`storeAsAttachment` +""""""""""""""""""""""""""" + + .. php:method:: storeAsAttachment($doc,$data,$filename,$content_type = 'application/octet-stream') + + Records as a CouchDB document's attachment the content of a PHP variable. + + :params stdClass $doc: A PHP object containing at least the properties \_id and \_rev + :params mixed $data: The data (the content of the attachment + :params string $filename: The name of the attachment on CouchDB document + :params string $content_type: The file's `content-type `_ + :returns: The HTTP response object. + + Example : + + .. code-block:: php + + $doc = $client->getDoc('BlogPost5676'); + $google_home=file_get_contents('http://www.google.com/'); + $ok = $client->storeAsAttachment($doc,$google_home,'GoogleHomepage.html','text/html'); + print_r($ok); + // stdClass ( "ok" => true, "id" => "BlogPost5676" , "rev" => "5-2342345476" ) + + +:hidden:`deleteAttachment` +"""""""""""""""""""""""""" + + .. php:method:: deleteAttachment($doc,$attachment_name) + + Delete an attachment from a CouchDB document. + + :params stdClass $doc: An object with, at least, \_id and \_rev properties, + :params $attachment_name: the name of the attachment to delete. + :returns: An stdClass representing the HTTP response. + + Example : + + .. code-block:: php + + $doc = $client->getDoc('BlogPost5676'); + $ok = $client->deleteAttachment($doc,'GoogleHomepage.html'); + +:hidden:`getShow` +""""""""""""""""" + + .. php:method:: getShow($design_id, $name, $doc_id = null, $additionnal_parameters = array()) + + Request a show formatting of document *$doc_id* with show method *$name* stored in design document *design_id*. + + Example : + + .. code-block:: php + + $output = $client->getShow('blogs','html','BlogPost5676'); + + + More infos on CouchDB show formatting `here `_ . + +Bulk operations +=============== + +A bulk operation is a unique query performing actions on several documents. CouchDB Bulk operations API are described in `this wiki page `_ . + +:hidden:`keys` +"""""""""""""""""""" + + .. php:method:: keys($ids)->getAllDocs() + + To retrieve several documents in one go, knowing their IDs, select documents using the **keys($ids)** coupled with the method **getAllDocs()**. $ids is an array of documents IDs. This function acts like a view, so the output is the view output of CouchDB, and you should use "include_docs(true)" to have documents contents. + + Example : + + .. code-block:: php + + $view = $client->include_docs(true)->keys( array('BlogPost5676','BlogComments5676') )->getAllDocs(); + foreach ( $view->rows as $row ) { + echo "doc id :".$row->doc->_id."\n"; + } + + +:hidden:`storeDocs` +"""""""""""""""""""" + + .. php:method:: storeDocs($docs, $new_edits) + + To store several documents in one go, use the method **storeDocs($docs, $new_edits)**. $docs is an array containing the documents to store (as CouchDocuments, PHP `stdClass `_ or PHP arrays). $new_edits is related to the updates of the revision. If set to true (which is the default), assign new revision id for each update. When set to false, it prevents the database from assigning them new reivision IDS. + + Example : + + .. code-block:: php + + $docs = array ( + array('type'=>'blogpost','title'=>'post'), + array('type'=>'blogcomment','blogpost'=>'post','depth'=>1), + array('type'=>'blogcomment','blogpost'=>'post','depth'=>2) + ); + $response = $client->storeDocs( $docs ); + print_r($response); + + which should give you something like : + + .. code-block:: php + + Array + ( + [0] => stdClass Object + ( + [id] => 8d7bebddc9828ed2edd052773968826b + [rev] => 1-3988163576 + ) + + [1] => stdClass Object + ( + [id] => 37bcfd7d9e94c67617982527c67efe44 + [rev] => 1-1750264873 + ) + + [2] => stdClass Object + ( + [id] => 704a51a0b6448326152f8ffb8c3ea6be + [rev] => 1-2477909627 + ) + + ) + + + This method also works to update documents. + + +:hidden:`deleteDocs` +"""""""""""""""""""" + + .. php:method:: deleteDocs($docs, $new_edits) + + To delete several documents in a single HTTP request, use the method **deleteDocs($docs, $new_edits)**. $docs is an array containing the documents to store (as couchDocuments, PHP `stdClass `_ or PHP arrays). $new_edits is related to the updates of the revision. If set to true (which is the default), assign new revision id for each update. When set to false, it prevents the database from assigning them new reivision IDS. + + +:hidden:`asArray` +""""""""""""""""" + + .. php:method:: asArray() + + When converting a JSON object to PHP, we can choose the type of the value returned from a CouchClient query. + + Take for example the following JSON object : + { 'blog' : true, 'comments' : { 'title' : 'cool' } } + + This can be converted into a PHP object : + + .. code-block:: php + + stdClass Object + ( + [blog] => true + [comments] => stdClass Object + ( + [title] => "cool" + ) + ) + + + OR into a PHP array : + + .. code-block:: php + + Array + ( + [blog] => true + [comments] => Array + ( + [title] => "cool" + ) + ) + + + Using the defaults, JSON objects are mapped to PHP objects. The **asArray()** method can be used to map JSON objects to PHP arrays. + + Example: + + .. code-block:: php + + $doc = $client->asArray()->getDoc('BlogPost5676'); + print_r($doc); + + + should print : + + .. code-block:: php + + Array ( + [id] => "BlogPost5676" + ) + + diff --git a/doc/api/couchclient/index.rst b/doc/api/couchclient/index.rst new file mode 100644 index 0000000..1e0cb27 --- /dev/null +++ b/doc/api/couchclient/index.rst @@ -0,0 +1,8 @@ +CouchClient class +***************** + +.. toctree:: + :maxdepth: 2 + :glob: + + * diff --git a/doc/api/couchclient/mango.rst b/doc/api/couchclient/mango.rst new file mode 100644 index 0000000..2863ac0 --- /dev/null +++ b/doc/api/couchclient/mango.rst @@ -0,0 +1,226 @@ +Mango Query +*********** + +Summary +======= + + +With the new release of CouchDB 2.0, Apache brought us the Mango Query. It's an adapted version of Cloudant Query for CouchDB. It's very similar to MongoDB Query syntax. + +It lets you create indexes and perform queries with more ease that map/reduce. For more details, you may take a look at this : + +- `New feature: Mango Query `_ +- `Cloudant Query `_ +- `Mango source code `_ + +PHPOnCouch and Mango +==================== + +With the recently added new available function to let you use the new Mango Query. This is very minimalist at the moment but feel free to suggest any ameliorations. + +The Mango Query functionalities have been implemented directly in the CouchClient. + + + +Functions +========= + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchClient + + +:hidden:`getIndexes` +"""""""""""""""""""" + + .. php:method:: getIndexes() + + This function returns you an array of indexes. Each index will have those properties : + + - ddoc: The design document id of the index + - name: The name of the index + - type: The type of the index (special,text,json) + - def: The fields indexes + + By default, you always have one index:  \_all_docs + + Example : + + .. code-block:: php + + $indexes = $client->getIndexes(); + + /* + [ + { + "ddoc": null, + "name": "_all_docs", + "type": "special", + "def": { + "fields": [ + { + "_id": "asc" + } + ] + } + } + ] + */ + } + +:hidden:`createIndex` +""""""""""""""""""""" + + .. php:method:: createIndex(array $fields, $name = null, $ddoc = null, $type = 'json') + + This function creates an index. + + :params array $fields: The fields that will be indexed + :params string $name: The name of the index. If null, one will be generated by Couch. + :params string $ddoc: The design document id to store the index. If null, CouchDB will create one. + :params string $type: The type of the index. Only JSON is supported for the moment. + + :returns stdClass: An object. The object contains the following properties: + + - result : Message that normally returns "created" or "exists" + - id : The id of the undex. + - name : The name of the index. + + Example : + + .. code-block:: php + + $index = client->createIndex(['firstName', 'birthDate', 'lastName'], 'personIdx', 'person'); + + /* + $index should give : + { + "result":"created", + "id":"_design/person", + "name":"personIdx" + } + */ + +:hidden:`find` +"""""""""""""" + + .. php:method:: find($selector, $index = null) + + The new **find()** function let you query the database by using the new Mango Query. You can provide a selector query multiple fields and use conditional queries. + You can sort your query and also determine which fields you want to retrieve. CouchDB will automatically select the most efficient index for your query but + it's preferred to specify the index for faster results. Also, the **limit(number)** and **skip(number)** can be applied to the client before the query. + + **Supported query parameters** + + You can use the following query parameters : + + - limit(number) : Limit the number of documents that will be returned. + - skip(n) : Skip n documents and return the documents following. + - sort(sortSyntax) : Array or values that follow the `sort syntax `_ + - fields(fieldsArray) : An array of fields that you want to return from the documents. If null, all the fields will be returned. + + :params stdClass|array $selector: A selector object or array that follows the `Mango query documentation `_ + :params string $index: The name of the index to use("" or ["", ""]). Otherwise automatically choosen. + :returns array: Returns an array of documents + + Example : + + .. code-block:: php + + $selector = [ + '$and' => + [ + ['age' => ['$gt' => 16]], + ['gender' => ['$eq' => 'Female']] + ] + ]; + $docs = $client->skip(10)->limit(30)->sort(["age"])->fields(['firstName'])->find($selector); + +:hidden:`explain` +""""""""""""""""" + + .. php:method:: explain($selector, $index = null) + + Let you perform a query like if you were using the :meth:`CouchClient::find` function. Therefore, the explain will not returns any documents. Instead, it will give you all the details about the query. For example, it could tell you which index has been automatically selected. + + For the parameter, please refer to the :meth:`CouchClient::find` parameters. + + :returns: It returns a object with a lot of detailed properties. Here are main properties : + + - dbname : The name of the database + - index : Index object used to fullfil the query + - selector : The selector used for the query + - opts : The query options used for the query + - limit : The limit used + - skip : The skip parameter used + - fields : The fields returned by the query + - range : Range parameters passed to the underlying view + + Example : + + .. code-block:: php + + $selector = [ + 'year'=>['$gt'=>2010] + ]; + $details = $client->skip(0)->limit(2)->fields(['_id','_rev','year','title'])->sort(['year'=>'asc'])->find($selector); + + The $details values would be the equivalent in JSON : + + .. code-block:: json + + { + "dbname": "movies", + "index": { + "ddoc": "_design/0d61d9177426b1e2aa8d0fe732ec6e506f5d443c", + "name": "0d61d9177426b1e2aa8d0fe732ec6e506f5d443c", + "type": "json", + "def": { + "fields": [ + { + "year": "asc" + } + ] + } + }, + "selector": { + "year": { + "$gt": 2010 + } + }, + "opts": { + "use_index": [], + "bookmark": "nil", + "limit": 2, + "skip": 0, + "sort": {}, + "fields": [ + "_id", + "_rev", + "year", + "title" + ], + "r": [ + 49 + ], + "conflicts": false + }, + "limit": 2, + "skip": 0, + "fields": [ + "_id", + "_rev", + "year", + "title" + ], + "range": { + "start_key": [ + 2010 + ], + "end_key": [ + {} + ] + } + } + + diff --git a/doc/api/couchclient/view.rst b/doc/api/couchclient/view.rst new file mode 100644 index 0000000..0b246b4 --- /dev/null +++ b/doc/api/couchclient/view.rst @@ -0,0 +1,226 @@ +Views +***** + +This section describes how to use PHP on Couch to retrieve views results from a CouchDB server. + +Creating views +============== + +As said in the `documentation `_ , views are stored in CouchDB documents called *design documents*. So to create a view, you have to create a design document. + +Example + +.. code-block:: php + + $view_fn="function(doc) { emit(doc.timestamp,null); }"; + $design_doc = new stdClass(); + $design_doc->_id = '_design/all'; + $design_doc->language = 'javascript'; + $design_doc->views = array ( 'by_date'=> array ('map' => $view_fn ) ); + $client->storeDoc($design_doc); + +.. php:namespace:: PHPOnCouch + +.. php:class:: CouchClient + +:hidden:`getView` +""""""""""""""""" + + .. php:method:: getView($id, $name) + + The method **getView($id, $name)** sends back the CouchDB response of a view. + + :params string $id: is the design document id without '_design/' + :params string $name: is the view name + :returns: The view response object. + + Example : + + .. code-block:: php + + $result = $client->getView('all','by_date'); + +View response +============= + +The CouchDB response of a view is an object containing : + +* **total_rows** , an integer of all documents available in the view, regardless of the query options +* **offset** , an integer givving the offset between the first row of the view and the first row contained in the resultset +* **rows** an array of objects. + +Each object in **rows** contains the properties : + +* **id** : the id of the emited document +* **key** : the emited key +* **value** : the emited value +* **doc** : the document object, if query parameter include_docs is set (read on for that). + +Query parameters +================ + +The CoucClient implements chainable methods to add query parameters. The method names are mapped on their CouchDB counterparts : + +* key +* keys +* startkey +* startkey_docid +* endkey +* endkey_docid +* limit +* stale +* descending +* skip +* group +* group_level +* reduce +* include_docs +* inclusive_end +* attachments + +Example querying a view with a startkey, a limit and include_docs + +.. code-block:: php + + $response = $client->startkey(100000000)->limit(100)->include_docs(true)->getView('all','by_date'); + +Which is the same as : + +.. code-block:: php + + $client->startkey(100000000); + $client->limit(100); + $client->include_docs(true); + $response = $client->getView('all','by_date'); + +:hidden:`setQueryParameters` +"""""""""""""""""""""""""""" + + .. php:method:: setQueryParameters($params) + + You also can set query parameters with a PHP array, using the **setQueryParameters** method : + + :params array $params: A associative array of parameters to set. + + Example: + + .. code-block:: php + + $opts = array ( "include_docs" => true, "limit" => 10, "descending" => true ); + $response = $client->setQueryParameters(opts)->getView("all","by_date"); + +:hidden:`asArray` +""""""""""""""""" + + .. php:method:: asArray() + + When converting a JSON object to PHP, we can choose the type of the value returned from a CouchClient query. + + Take for example the following JSON object : + + .. code-block:: json + + { "blog" : true, "comments" : { "title" : "cool" } } + + This can be converted into a PHP object : + + .. code-block:: php + + stdClass Object + ( + [blog] => true + [comments] => stdClass Object + ( + [title] => "cool" + ) + ) + + OR into a PHP array : + + .. code-block:: php + + Array + ( + [blog] => true + [comments] => Array + ( + [title] => "cool" + ) + ) + + Using the defaults, JSON objects are mapped to PHP objects. The **asArray()** method can be used to map JSON objects to PHP arrays. + + Example : + + .. code-block:: php + + $response = $client->startkey(100000000)->limit(100)->include_docs(true)->asArray()->getView('all','by_date'); + +Format a view with CouchDB list formatting feature +================================================== + +More infos on `CouchDB lists `_ . + +:hidden:`getList` +""""""""""""""""" + + .. php:method:: getList($design_id, $name, $view_name, $additionnal_parameters = array()) + + This method retrieve a view and then format it using the algorithm of the $name list. + + :params string $design_id: The id of the design document(without the _design part) + :params string $name: The name of the formatting algorithm. + :params string $view_name: The name of the view to use. + :params array $additionnal_parameters: The additionnal parameters. + + Example : + + .. code-block:: php + + $response = $client->limit(100)->include_docs(true)->getList('all','html','by_date'); + // will run the view declared in _design/all and named *by_date*, and then + // pass it through the list declared in _design/all and named *html*. + +:hidden:`getForeignList` +"""""""""""""""""""""""" + + .. php:method:: getForeignList($list_design_id, $name, $view_design_id, $view_name, $additionnal_parameters = array()) + + Retrieve a view defined in the document *_design/$view_design_id* and then format it using the algorithm of the list defined in the design document *_design/$list_design_id*. + + :params string $list_design_id: The list design id + :params string $view_design_id: The view design id + :params array $additionnal_parameters: The additionnal parameters that can be passed. + + Example : + + .. code-block:: php + + $response = $client->limit(100)->getForeignList('display','html','posts','by_date'); + // will run the view declared in _design/posts and named *by_date*, and then + // pass it through the list declared in _design/display and named *html*. + + +:hidden:`getViewInfos` +"""""""""""""""""""""" + + .. php:method:: getViewInfos($design_id) + + More info on view informations `here `_ + + The method **getViewInfos($design_id)** sends back some useful informations about a particular design document. + + :params string $design_id: The id of the design document to use + :returns stdClass: + Returns an object with the following properties: + + - name: The design document name + - view_index: `View index informations `_ + + + + Example : + + .. code-block:: php + + $response = $client->getViewInfos("mydesigndoc"); diff --git a/doc/api/index.rst b/doc/api/index.rst new file mode 100644 index 0000000..65ec764 --- /dev/null +++ b/doc/api/index.rst @@ -0,0 +1,15 @@ +.. _api_ref: + +API +=== + + + +.. toctree:: + :maxdepth: 2 + + couch.rst + couchclient/index.rst + couch-admin.rst + couch-replicator.rst + couch-document.rst diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..d2e1d3b --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# +# PHPOnCouch documentation build configuration file, created by +# sphinx-quickstart on Fri Sep 08 21:31:37 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../src/')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ["sphinxcontrib.phpdomain",'sphinx.ext.autosummary'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_suffix = ['.rst', '.md'] + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'PHPOnCouch' +copyright = u'2017, Alexis Côté' +author = u'Alexis Côté' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'2.0.3' +# The full version, including alpha/beta/rc tags. +release = u'2.0.3' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + +html_show_sourcelink= False + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PHPOnCouchdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'PHPOnCouch.tex', u'PHPOnCouch Documentation', + u'Alexis Côté', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'phponcouch', u'PHPOnCouch Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'PHPOnCouch', u'PHPOnCouch Documentation', + author, 'PHPOnCouch', 'One line description of project.', + 'Miscellaneous'), +] + +# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +# Override default css to get a larger width for local build +html_style = "css/local_build.css" + +if on_rtd: + # Override default css to get a larger width for ReadTheDoc build + html_context = { + 'css_files': [ + 'https://media.readthedocs.org/css/sphinx_rtd_theme.css', + 'https://media.readthedocs.org/css/readthedocs-doc-embed.css', + '_static/css/my_theme.css', + ], + } + +# Set up PHP syntax highlights +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer +lexers["php"] = PhpLexer(startinline=True, linenos=1) +lexers["php-annotations"] = PhpLexer(startinline=True, linenos=1) +primary_domain = "php" +highlight_language= "php" + + +rst_prolog = """ +.. role:: hidden + :class: hidden +""" + +source_parsers = { + '.md': 'recommonmark.parser.CommonMarkParser', +} + diff --git a/doc/couch.md b/doc/couch.md deleted file mode 100644 index 3e7e90f..0000000 --- a/doc/couch.md +++ /dev/null @@ -1,153 +0,0 @@ -# Couch - -## Table of content - -- [**Summary**](#summary) -- [**General functions**](#general-functions) - + [**dsn()**](#dsn) - + [**options()**](#options) - + [**getSessionCookie()**](#getsessioncookie) - + [**setSessionCookie($cookie)**](#setsessioncookiecookie) - + [**query($method, $url, $parameters = [], $data = null, $contentType = null)**](#querymethod-url-parameters---data--null-contenttype--null) - + [**continuousQuery($callable, $method, $url, $parameters = [], $data = null)**](#continuousquerycallable-method-url-parameters---data--null) - + [**storeFile($url, $file, $contentType)**](#storefileurl-file-contenttype) - + [**storeAsFile($url, $data, $contentType)**](#storeasfileurl-data-contenttype) - -- [**Adapters**](#adapters) - + [**initAdapter($options())**](#initadapteroptions) - + [**getAdapter()**](#getadapter) - + [**setAdapter(CouchHttpAdapterInterface $adapter)**](#setadaptercouchhttpadapterinterface-adapter) - -## Summary - -The Couch.php class is the one of the low level class that is used to handle the communication between the high level classes and CouchDB. Before version **2.0.2**, the default Http adapter was curl and all the possible adapters where declared into the Couch.php class. With **2.0.2**, the library code has been refactored so that the Http adapters are declared into separate classes. The Couch class nowaday use a HttpAdapterInterface to communicate with CouchDB. - -**Note**: The following methods are public methods of the Couch class. Therefore, you will mostly use the high level classes which usually inherit the Couch class. For example, all the following methods will be directly available from the CouchClient class. - -## General functions - -### dsn() - -Getter the return the dsn set to the current Couch class. - -### options() - -Getter the return the options passed to the Couch class. - -### getSessionCookie() - -Return the current session cookie. - -### setSessionCookie($cookie) - -Set the current session cookie. - -### query($method, $url, $parameters = [], $data = null, $contentType = null) - -Send a query to the CouchDB server. - -**Parameters** - -| Name | Type | Default | Desc | -|---|---|---|---| -| $method | string | | The HTTP method (GET,PUT,POST) | -| $url | string | | Tue URL to fetch | -| $parameters | array | [] | The query parameters to passe to the query | -| $data | mixed | null | The request body | -| $contentType | stirng | | The content type of the data | - -**Returns** the server response or false if an error occured. - -### continuousQuery($callable, $method, $url, $parameters = [], $data = null) - -Send a query to CouchDB. For each line returned by the server, the $callable will be called. If the callable returns false, the **continuousQuery** will stop. - -**Parameters** - -| Name | Type | Default | Desc | -|---|---|---|---| -| $callable | function | | The function called for every document returned | -| $method | string | | The HTTP method (GET,PUT,POST) | -| $url | string | | Tue URL to fetch | -| $parameters | array | [] | The query parameters to passe to the query | -| $data | mixed | null | The request body | - -**Returns** the server response or false if an error occured. - -### storeFile($url, $file, $contentType) - -Make a request with the $file content passed into the request body. The $file must be on the disk. - -**Parameters** - -| Name | Type | Default | Desc | -|---|---|---|---| -| $callable | function | | The function called for every document returned | -| $method | string | | The HTTP method (GET,PUT,POST) | -| $url | string | | Tue URL to fetch | -| $parameters | array | [] | The query parameters to passe to the query | -| $data | mixed | null | The request body | - -**Returns** the server response or false if an error occured. - -### storeAsFile($url, $data, $contentType) - -Make a request with the $data passed into the request body. - -**Parameters** - -| Name | Type | Default | Desc | -|---|---|---|---| -| $callable | function | | The function called for every document returned | -| $method | string | | The HTTP method (GET,PUT,POST) | -| $url | string | | Tue URL to fetch | -| $parameters | array | [] | The query parameters to passe to the query | -| $data | mixed | null | The request body | - -**Returns** the server response or false if an error occured. - -## Adapters - - - -### initAdapter($options) - -This function is called to initialized the adapter. By default, it will load the cURL adapter. The options passed are the same options passed to the Couch class. It's must be an array of options. **You don't have to call this method.** It will be automatically call when using the Couch class. - -Example : - -```php - -$couch = new Couch("http://localhost:5984"); -$couch->initAdapter([]) //Set the curl by default -``` - - -### getAdapter() - -This function return the current adapter. If it's not set, the [initAdapter](#initadapter-options) will be called. - -```php -$couch = new Couch("http://localhost:5984"); -$adapter = $couch->getAdapter(); -$doc = $adapte->query('GET','db/_all_docs'); -``` - -### setAdapter(CouchHttpAdapterInterface $adapter) - -This function set the current adapter of the Couch class. You must specify a class that implements the CouchHttpAdapterInterface. - -You can implemented the following adapters : - - - CouchHttpAdapterSocket - - CouchHttpAdapterCurl (default) - -*Note*: Even if the CouchHttpAdapter used is Curl, the Socket adapter is still used for the continuous_query function since it is not implemented with cURL. - -```php -use PHPOnCouch\Adapter\CouchHttpAdapterCurl; - -$couch = new Couch("http://localhost:5984"); -$adapter = new CouchHttpAdapterSocket([]); -$couch->setAdapter($adapter); -``` diff --git a/doc/couch_admin.md b/doc/couch_admin.md deleted file mode 100644 index a5cadf2..0000000 --- a/doc/couch_admin.md +++ /dev/null @@ -1,860 +0,0 @@ -This section give details about the CouchAdmin object. - -## Table of content - -- [Please read this first](#please-read-this-first-) -- [Managing CouchDB users](#managing-couchdb-users) -- [Synopsys](#synopsys) -- [Getting started](#getting-started) -- [Admin party](#admin-party) -- [Create users and admins](#create-users-and-admins) - + [createAdmin($login, $password, $roles = array())](#createadminlogin-password-roles--array) - + [createUser($login, $password, $roles = array())](#createuserlogin-password-roles--array) - + [getUser($login)](#getuserlogin) - + [getAllUsers()](#getallusers) -- [Removing users](#removing-users) - + [deleteAdmin ($login)](#deleteadminlogin) - + [deleteUser($login)](#deleteuserlogin) -- [Roles assignation](#roles-assignation) - + [addRoleToUser($user, $role)](#addroletouseruser-role) - + [removeRoleFromUser($user, $role)](#removerolefromuseruser-role) - + [setRolesToUser($user,array $roles = [])](#setrolestouseruser-array-roles--) -- [Database user security](#database-user-security) - + [addDatabaseMemberUser($login)](#adddatabasememberuserlogin) - + [addDatabaseAdminUser($login)](#adddatabaseadminuserlogin) - + [getDatabaseMemberUsers()](#getdatabasememberusers) - + [getDatabaseAdminUsers()](#getdatabaseadminusers) - + [removeDatabaseMemberUser($login)](#removedatabasememberuserlogin) - + [removeDatabaseAdminUser($login)](#removedatabaseadminuserlogin) -- [Database roles security](#database-roles-security) - + [addDatabaseMemberRole($role)](#adddatabasememberrolerole) - + [addDatabaseAdminRole($role)](#adddatabaseadminrolerole) - + [getDatabaseMemberRoles()](#getdatabasememberroles) - + [getDatabaseAdminRoles()](#getdatabaseadminroles) - + [removeDatabaseMemberRole($role)](#removedatabasememberrolerole) - + [removeDatabaseAdminRole($role)](#removedatabaseadminrole-role) -- [Accessing Database security object](#accessing-database-security-object) - + [getSecurity()](#getsecurity) - + [setSecurity($security)](#setsecuritysecurity) -- [Database options](#database-options) - + [CouchAdmin users_database](#couchadmin-users_database) - + [setUserDatabase($name)](#setuserdatabasename) - + [getUserDatabase($name)](#getuserdatabasename) - -## Please read this first !! - - -The CouchAdmin class is only needed to **manage** users of a CouchDB server : add users, add admins, ... - -You don't need the couchAdmin class to connect to CouchDB with a login / password. You only need to add your login and password to the DSN argument when creating your CouchDB client : - -```php -$client = new CouchClient ("http://theuser:secretpass@couch.server.com:5984","mydatabase"); -``` - -##Managing CouchDB users - -CouchDB rights management is really complex. [This page](http://wiki.apache.org/couchdb/Security_Features_Overview) can really help to understand how security is implemented in couchDB. - -The **CouchAdmin** class contains helpful methods to create admins, users, and associate users to databases. - -## Synopsys - -```php -createAdmin("superAdmin","secretpass"); -} catch ( Exception $e ) { - die("unable to create admin user: ".$e->getMessage()); -} - -// -// now my database is not in "admin party" anymore : to continue Administration I need to setup an authenticated connector -// -$admclient = new CouchClient ("http://superAdmin:secretpass@localhost:5984/", "mydb" ); -$adm = new CouchAdmin($admclient); - -// create a regular (no superadmin) user) -try { - $adm->createUser("joe","secret"); -} catch ( Exception $e ) { - die("unable to create regular user: ".$e->getMessage()); -} - -// set "joe" as admin of the database "mydb" -try { - $adm->addDatabaseAdminUser("joe"); -} catch ( Exception $e ) { - die("unable to add joe to the admins list of mydb: ".$e->getMessage()); -} - -// Oh no I missed up remove "joe" from database "mydb" admins -try { - $adm->removeDatabaseAdminUser("joe"); -} catch ( Exception $e ) { - die("unable to remove joe from the admins list of mydb: ".$e->getMessage()); -} - -// and add it to the members group of database "mydb" -try { - $adm->addDatabaseMemberUser("joe"); -} catch ( Exception $e ) { - die("unable to add joe to the members list of mydb: ".$e->getMessage()); -} - -// well... get the list of users belonging to the "members" group of "mydb" -$users = $adm->getDatabaseMemberUsers(); // array ( "joe" ) -``` - -## Getting started - -**__construct(CouchClient $client,$options = array())** -The couchAdmin class constructor takes 2 parameters : a couchClient object and an array of configuration options. - -*$client* : You have to be careful, the couchClient object should have enough credentials to perform the administrative tasks. - -*$options*: This array has 2 possibles keys for the moments. -- users_database : The user database to use (overwrite the default _users) -- node : The node to use for the configuration. **If it's not defined**, the first node of the *cluster_nodes* will be taken. - - - -Example : - -```php -// create a CouchClient instance -$client = new CouchClient("http://localhost:5984/","mydb"); -// now create the CouchAdmin instance -$adm = new CouchAdmin($client); -// here $adm will connect to CouchDB without any credentials : that will only work if there is no administrator created yet on the server. -``` - -## Admin party - -On a fresh install, CouchDB is in **admin party** mode : that means any operation (create / delete databases, store documents and design documents) can be performed without any authentication. - -Below is an example to configure the first server administrator, that we will name **couchAdmin** with the password **secretpass** : - -```php -// create an anonymous couchClient connection (no user/pass) -$client = new CouchClient("http://localhost:5984/","mydb"); -// now create the couchAdmin instance -$adm = new CouchAdmin($client); -//create the server administrator -try { - $adm->createAdmin("couchAdmin","secretpass"); -} catch ( Exception $e ) { - die ("Can't create server administrator : ".$e->getMessage()); -} -``` - -Now that the couch server got a server administrator, it's not in "admin party" mode anymore : we can't create a second server administrator using the same, anonymous couchClient instance. -We need to create a couchClient instance with the credentials of **couchAdmin**. - -```php -// create a server administrator couchClient connection -$client = new CouchClient("http://couchAdmin:secretpass@localhost:5984/","mydb"); -// now create the CouchAdmin instance -$adm = new CouchAdmin($client); -``` - -## Create users and admins - -### createAdmin($login, $password, $roles = array()) - -The method **createAdmin ($login, $password, $roles = array())** creates a CouchDB *server* administrator. A server administrator can do everything on a CouchDB server. - -Example : - -```php -createAdmin("superAdmin","ommfgwtf"); -} catch ( Exception $e ) { - die("unable to create admin user: ".$e->getMessage()); -} -``` - -### createUser($login, $password, $roles = array()) - - -The method **createUser($login, $password, $roles = array())** creates a CouchDB user and returns it. - -Example : - -```php -createUser("joe","dalton"); -} catch ( Exception $e ) { - die("unable to create user: ".$e->getMessage()); -} -``` - -Example - creating a user and adding it to some roles - -```php -createUser("jack","dalton",$roles); -} catch ( Exception $e ) { - die("unable to create user: ".$e->getMessage()); -} -``` - -### getUser($login) - -The method **getUser($login)** returns the user document stored in the users database of the CouchDB server. - -Example : - -```php -getUser("joe"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "User joe does not exist."; - } else { - die("unable to get user: ".$e->getMessage()); - } -} -``` - -### getAllUsers() - -The method **getAllUsers()** returns the list of all users registered in the users database of the CouchDB server. This method calls a view, so you can use the view query options ! - -Example : - -```php -getAllUsers(); -} catch ( Exception $e ) { - die("unable to get users: ".$e->getMessage()); -} -print_r($all); - -/** will print something like -Array ( - stdClass ( - "id" => "_design/_auth", - "key" => "_design/_auth", - "value" => stdClass ( - "rev" => "1-54a591939c91922a35efee07eb2c3a72" - ) - ), - stdClass ( - "id" => "org.couchdb.user:jack", - "key" => "org.couchdb.user:jack", - "value" => stdClass ( - "rev" => "1-3e4dd4a7c5a9d422f8379f059fcfce98" - ) - ), - stdClass ( - "id" => "org.couchdb.user:joe", - "key" => "org.couchdb.user:joe", - "value" => stdClass ( - "rev" => "1-9456a56f060799567ec4560fccf34534" - ) - ) -) -**/ -``` - -Example - including user documents and not showing the design documents - -```php -include_docs(true)->startkey("org.couchdb.user:")->getAllUsers(); -} catch ( Exception $e ) { - die("unable to get users: ".$e->getMessage()); -} -print_r($all); - -/** will print something like -Array ( - stdClass ( - "id" => "org.couchdb.user:jack", - "key" => "org.couchdb.user:jack", - "value" => stdClass ( - "rev" => "1-3e4dd4a7c5a9d422f8379f059fcfce98" - ), - "doc" => stdClass ( "_id" => "org.couchdb.user:jack", ... ) - ), - stdClass ( - "id" => "org.couchdb.user:joe", - "key" => "org.couchdb.user:joe", - "value" => stdClass ( - "rev" => "1-9456a56f060799567ec4560fccf34534" - ), - "doc" => stdClass ( "_id" => "org.couchdb.user:joe", ... ) - ) -) -**/ -``` - -## Removing users - -Warning : this only works with CouchDB starting at version 1.0.1 - -### deleteAdmin($login) - -The method **deleteAdmin($login)** permanently removes the admin $login. - -Example : creating and immediately removing a server administrator - -```php -createAdmin($adminLogin, $adminPass); -} catch (Exception $e) { - die("unable to create admin user: ".$e->getMessage()); -} -// here "butterfly" admin exists and can login to couchDB to manage the server - -// now we remove it -try { - $ok = $adm->deleteAdmin($adminLogin); -} catch (Exception $e) { - die("unable to delete admin user: ".$e->getMessage()); -} -// here "butterfly" admin does not exist anymore -``` - -Note : the response of deleteAdmin() method is a string : it's the hash of the password this admin had before been removed. Example : -hashed-0c796d26c439bec7445663c2c2a18933858a8fbb,f3ada55b560c7ca77e5a5cdf61d40e1a - -### deleteUser($login) - -The method **deleteUser($login)** permanently removes the user $login. - -Example : removing a server user - -```php -deleteUser("joe"); -} catch (Exception $e) { - die("unable to delete user: ".$e->getMessage()); -} -print_r($ok); - -/** will print something like : -stdClass Object -( - [ok] => 1 - [id] => org.couchdb.user:joe - [rev] => 6-415784680cff486e2d0144ed39da2431 -) -*/ -``` - - -## Roles assignation - -### addRoleToUser($user, $role) - -The method **addRoleToUser($user, $role)** adds the role *$role* to the list of roles user *$user* belongs to. **$user** can be a PHP stdClass representing a CouchDB user object (as returned by getUser() method), or a user login. - -Example : adding the role *cowboy* to user *joe* - -```php -addRoleToUser("joe","cowboy"); -} catch ( Exception $e ) { - die("unable to add a role to user: ".$e->getMessage()); -} -echo "Joe now got role cowboy"; -``` - -### removeRoleFromUser($user, $role) - -The method **removeRoleFromUser($user, $role)** removes the role *$role* from the list of roles user *$user* belongs to. **$user** can be a PHP stdClass representing a CouchDB user object (as returned by getUser() method), or a user login. - -Example : removing the role *cowboy* of user *joe* - -```php -removeRoleFromUser("joe","cowboy"); -} catch ( Exception $e ) { - die("unable to remove a role of a user: ".$e->getMessage()); -} -echo "Joe don't belongs to the cowboy role anymore"; -``` - -### setRolesToUser($user, array $roles = []) - -This method let you set the roles for the selected user. A $user can either be the username of the user or a user object containing an **_id** and a **roles** property. - -Example of usage : - -```php -setRolesForUser("joe",['tester','developer']); - echo "Joe has now the tester and developer roles."; -} catch ( Exception $e ) { - die("unable to remove a role of a user: ".$e->getMessage()); -} -``` - - -## Database user security - -CouchDB databases got two types of privileged users : the *members*, that can read all documents, and only write normal (non-design) documents. -The *admins* got all privileges of the *members*, and they also can write design documents, use temporary views, add and remove *members* and *admins* of the database. -[The CouchDB wiki gives all details regarding rights management.](http://wiki.apache.org/couchdb/Security_Features_Overview) - - -### addDatabaseMemberUser($login) - -The method **addDatabaseMemberUser($login)** adds a user in the members list of the database. - -Example - adding joe to the members of the database mydb - -```php -addDatabaseMemberUser("joe"); -} catch ( Exception $e ) { - die("unable to add user: ".$e->getMessage()); -} -``` - -### addDatabaseAdminUser($login) - -The method **addDatabaseAdminUser($login)** adds a user in the admins list of the database. - -Example - adding joe to the admins of the database mydb - -```php -addDatabaseAdminUser("joe"); -} catch ( Exception $e ) { - die("unable to add user: ".$e->getMessage()); -} -``` - -### getDatabaseMemberUsers() - -The method **getDatabaseMemberUsers()** returns the list of users belonging to the *members* of the database. - -Example - getting all users beeing *members* of the database mydb - -```php -getDatabaseMemberUsers(); -} catch ( Exception $e ) { - die("unable to list users: ".$e->getMessage()); -} -print_r($users); -// will echo something like: Array ( "joe" , "jack" ) -``` - -### getDatabaseAdminUsers() - -The method **getDatabaseAdminUsers()** returns the list of users belonging to the *admins* of the database. - -Example - getting all users beeing *admins* of the database mydb - -```php -getDatabaseAdminUsers(); -} catch ( Exception $e ) { - die("unable to list users: ".$e->getMessage()); -} -print_r($users); -// will echo something like: Array ( "william" ) -``` - -### removeDatabaseMemberUser($login) - -The method **removeDatabaseMemberUser($login)** removes a user from the members list of the database. - -Example - removing joe from the members of the database mydb - -```php -removeDatabaseMemberUser("joe"); -} catch ( Exception $e ) { - die("unable to remove user: ".$e->getMessage()); -} -``` - -### removeDatabaseAdminUser($login) - -The method **removeDatabaseAdminUser($login)** removes a user from the admins list of the database. - -Example - removing joe from the admins of the database mydb - -```php -removeDatabaseAdminUser("joe"); -} catch ( Exception $e ) { - die("unable to remove user: ".$e->getMessage()); -} -``` - - -## Database roles security - -Just like users, roles can be assigned as admins or members in a CouchDB database. -[The CouchDB wiki gives all details regarding rights management.](http://wiki.apache.org/couchdb/Security_Features_Overview) - - -### addDatabaseMemberRole($role) - -The method **addDatabaseMemberrole($role)** adds a role in the members list of the database. - -Example - adding cowboy to the members of the database mydb - -```php -addDatabaseMemberRole("cowboy"); -} catch ( Exception $e ) { - die("unable to add role: ".$e->getMessage()); -} -``` - -### addDatabaseAdminRole($role) - -The method **addDatabaseAdminRole($role)** adds a role in the admins list of the database. - -Example - adding *cowboy* role to the *admins* of the database mydb - -```php -addDatabaseAdminrole("cowboy"); -} catch ( Exception $e ) { - die("unable to add role: ".$e->getMessage()); -} -``` - -### getDatabaseMemberRoles() - -The method **getDatabaseMemberRoles()** returns the list of roles belonging to the *members* of the database. - -Example - getting all roles beeing *members* of the database mydb - -```php -getDatabaseMemberRoles(); -} catch ( Exception $e ) { - die("unable to list roles: ".$e->getMessage()); -} -print_r($roles); -// will echo something like: Array ( "cowboy" , "indians" ) -``` - -### getDatabaseAdminRoles() - -The method **getDatabaseAdminRoles()** returns the list of roles belonging to the *admins* of the database. - -Example - getting all roles beeing *admins* of the database mydb - -```php -getDatabaseAdminRoles(); -} catch ( Exception $e ) { - die("unable to list roles: ".$e->getMessage()); -} -print_r($roles); -// will echo something like: Array ( "martians" ) -``` - -### removeDatabaseMemberRole($role) - -The method **removeDatabaseMemberRole($role)** removes a role from the members list of the database. - -Example - removing *cowboy* from the *members* of the database mydb - -```php -removeDatabaseMemberRole("cowboy"); -} catch ( Exception $e ) { - die("unable to remove role: ".$e->getMessage()); -} -``` - -### removeDatabaseAdminRole($role) - -The method **removeDatabaseAdminRole($role)** removes a role from the admins list of the database. - -Example - removing *martians* from the admins of the database mydb - -```php -removeDatabaseAdminRole("martians"); -} catch ( Exception $e ) { - die("unable to remove role: ".$e->getMessage()); -} -``` - - - -## Accessing Database security object - -Each Couch database got a security object. The security object is made like : - -```json -{ - "admins" : { - "names" : ["joe", "phil"], - "roles" : ["boss"] - }, - "members" : { - "names" : ["dave"], - "roles" : ["producer", "consumer"] - } -} -``` - -PHP on Couch provides methods to directly get and set the security object. - - -### getSecurity() - -The method **getSecurity()** returns the security object of a CouchDB database. - -Example - getting the security object of the database mydb - -```php -getSecurity(); -} catch ( Exception $e ) { - die("unable to get security object: ".$e->getMessage()); -} -``` - -### setSecurity($security) - -The method **setSecurity($security)** set the security object of a Couch database - -Example - setting the security object of the database mydb - -```php -setSecurity($security); -} catch ( Exception $e ) { - die("unable to set security object: ".$e->getMessage()); -} -``` - -## Database options - -CouchDB got a special database used to store users. By default this database is called **_users**, but this can be changed. - - -### CouchAdmin users_database - -To create a couchAdmin instance and specify the name of the users database, use the constructor second parameter $options, setting the option **users_database**: - -Example - setting the couchdb users database name on couchAdmin object creation - -```php - "theUsers") ); -``` - -### setUserDatabase($name) - -The **setUsersDatabase($name)** method allows to specify an alternate name for the users database on an already created couchAdmin instance. - - -### getUserDatabase($name) - -The **getUsersDatabase($name)** method return the name that is used actually to connect to the users database. - - - - diff --git a/doc/couch_client-database.md b/doc/couch_client-database.md deleted file mode 100644 index b03dc9b..0000000 --- a/doc/couch_client-database.md +++ /dev/null @@ -1,495 +0,0 @@ -This section give details on actions on the CouchDB server through PHP on Couch. - -## Table of content - -- [Getting started](#getting-started) -- [General](#general) - + [dsn()](#dsn) - + [getSessionCookie()](#getsessioncookie) - + [setSessionCookie($cookie)](#setsessioncookiecookie) - + [isValidDatabaseName($name)](#isvaliddatabasename) - + [listDatabases()](#listdatabases) - + [createDatabase()](#createdatabase) - + [deleteDatabase()](#deletedatabase) - + [databaseExists()](#databaseexists) - + [getDatabaseInfos()](#getdatabaseinfos) - + [getDatabaseUri()](#getdatabaseuri) - + [getUuids($count = 1)](#getuuidscount--1) - + [useDatabase($dbName)](#usedatabasedbname) - + [getMembership()](#getmembership) - + [getConfig($nodeName[, $section [, $key ]])](#getconfignodename--section--key-) - + [setConfig($nodeName, $section, $key)](#setconfignodename-section-key-value) - + [deleteConfig($nodeName , $section , $key)](#deleteconfignodename-section-key) -- [Changes](#changes) - + [getChanges()](#getchanges) - + [Chainable methods to use before getChanges()](#chainable-methods-to-use-before-getchanges) - * [since(string $value)](#sincestring-value) - * [heartbeat(integer $value)](#heartbeatinteger-value) - * [feed(string $value, $callback)](#feedstring-value-callback) - * [filter(string $value, array $additional_query_options)](#filterstring-value-array-additional_query_options) - * [style(string $value)](#stylestring-value) -- [Maintenance]() - + [ensureFullCommit()](#ensurefullcommit) - + [compactDatabase()](#compactdatabase) - + [compactAllViews()](#compactallviews) - + [compactViews($id)](#compactviewsid) - + [cleanupDatabaseViews()](#cleanupdatabaseviews) - ------ - - -## Getting started - -To use PHP on Couch client, you have to create a couchClient instance, setting the URL to your couchDB server, and the database name. - -Example : connect to the couchDB server at http://my.server.com on port 5984 and on database mydb : - -```php -$client = new CouchClient("http://my.server.com:5984/","mydb"); -``` - -If you want to authenticate to the server using a username & password, just set it in the URL. - -Example : connect to the couchDB server at http://my.server.com on port 5984 using the username "couchAdmin", the password "secret" and on database mydb : - -```php -$client = new CouchClient("http://couchAdmin:secret@my.server.com:5984/","mydb"); -``` - -You can also tell couchClient to use cookie based authentification, by passing an additional flag "cookie_auth" set to true in the options array, as the third parameter of the couchClient constructor. - -Example : as the previous one, but using cookie based authentification - -```php -$client = new CouchClient("http://couchAdmin:secret@my.server.com:5984/","mydb", array("cookie_auth"=>true) ); -``` - -You can also manually set the session cookie. - -Example : manually setting the session cookie : - -```php -$client = new CouchClient("http://my.server.com:5984/","mydb"); -$client->setSessionCookie("AuthSession=Y291Y2g6NENGNDgzNzY6Gk0NjM-UKxhpX_IyiH-C-9yXY44"); -``` - -## General - -### dsn() - -The method **dsn()** returns the DSN of the server. Database is not included in the DSN. - -Example : - -```php -$client = new CouchClient("http://couch.server.com:5984/","hello"); -echo $client->dsn(); // will echo : http://couch.server.com:5984 -``` - -### getSessionCookie() - -This method returns the current session cookie if set. - -Example : - -```php -$cookie = $client->getSessionCookie(); -``` - -### setSessionCookie($cookie) - -This method set the cookie and is chainable. - -Example : - -```php -$cookie = $client->setSessionCookie("AuthSession=Y291Y2g6NENGNDgzNz")->getSessionCookie(); -``` - -### isValidDatabaseName() - -Database names on CouchDB have restrictions : only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. The name has to start with a lowercase letter (a-z) or an underscore (_). To test if a given database name is valid, use the static **isValidDatabaseName()** couchClient method. - -Note: to allow access to system databases (_users, _replicator), those names added to special list and will return `true`. - -Example : - -```php -$my_database = "user311(public)"; -if ( CouchClient::isValidDatabaseName($my_database) ) { - $client = new CouchClient("http://couch.server.com:5984/",$my_database); -} else { - die("Invalid database name"); -} -``` - -### listDatabases() - -The method **listDatabases()** lists the available databases on the CouchDB server. - -Example : - -```php -$dbs = $client->listDatabases(); -print_r($dbs); // array ('first_database','another_database') -``` - -### createDatabase() - -The method **createDatabase()** will try to create the database according to the name you set when creating couch_client object $client. Note that, is the database already exist, this method will throw an exception. - -Example : - -```php -$client->createDatabase(); -``` - -### deleteDatabase() - -The method **deleteDatabase()** permanently remove from the server the database according to the name you set when creating couch_client object $client. Note that, if the database does not exist, the method will throw an exception. - -Example : - -```php -$client->deleteDatabase(); -``` - -### databaseExists() - -The method **databaseExists()** test if the database already exist on the server. - -Example : - -```php -if ( !$client->databaseExists() ) { - $client->createDatabase(); -} -``` - -### getDatabaseInfos() - -The method **getDatabaseInfos()** sends back informations about the database. Informations contains the number of documents in the database, the space of the database on disk, the update sequence number, ... - -Example : - -```php -print_r($client->getDatabaseInfos()); -/* -array("db_name" => "testdb", - "doc_count" => 2, - "doc_del_count" => 0, - "update_seq" => 6, - "purge_seq" => 0, - "compact_running" => false, - "disk_size" => 277707, - "instance_start_time" => "1246277543362647" - ) - */ -``` - -### getDatabaseUri() - -The method **getDatabaseUri()** sends back a string giving the HTTP connection URL to the database server. - -Example : - -```php -echo $client->getDatabaseUri(); -/* -http://db.example.com:5984/testdb -*/ -``` - -### getUuids($count = 1) - -The method **getUuids($count = 1)** sends back an array of universally unique identifiers (that is, big strings that can be used as document ids) - -Example : - -```php -print_r($client->getUuids(5)); -/* - array ( 0 => "65a8f6d272b3e5e62ee9de8eacc083a5", - 1 => "e43b04e44233d72b353c1cd8915b886d", - 2 => "7498fb296f19ebc2554a4812f3d9ae12", - 3 => "f3f855a15eb90e9fcdbda5e017b9f2cd", - 4 => "9d9a8214762d06cdf0158d7f6697cac9" ) -*/ -``` - -### useDatabase($dbName) - -The method **useDatabase($dbname)** changes the working database on the CouchDB server. - -Example : - -```php -$client = new CouchClient("http://localhost:5984", "db1"); -$all_docs_db1 = $client->getAllDocs(); //retrieve all docs of database db1 -$client->useDatabase("db2"); //switch to "db2" database -$all_docs_db2 = $client->getAllDocs(); //retrieve all docs of database db2 -``` - -### getMembership() - - -With the new Cluster infrastructure in CouchDB 2.0, you now have to configure each nodes. To do so, you need to get the information about them. The `_membership`endpoint allow you to get all the nodes that the current nodes knows and all the nodes that are in the same cluster. The method **getMembership()** returns an object like this : - - -```json -{ - "all_nodes": [], - "cluster_nodes": [] -} -``` - - -### getConfig($nodeName [, $section [, $key ]]) - -*The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only* - -To configure, you need to use **getConfig($nodeName [, $section [, $key ]])**. If you don't know the nodeName, you can use the **getMembership()** method. - -Examples : - -**getConfig("couchdb@localhost")** - -Returns a JSON object with the whole configuration -```json -{ - "attachments":{ - - }, - "couchdb":{ - - } -} -``` - -**getConfig("couchdb@localhost","httpd")** -*Note : It will return a CouchNotFoundException is the section is not present*. -Returns a JSON object that represent the desired section - -```json -{ - "allow_jsonp": "false", - "authentication_handlers": "{couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}", - "bind_address": "127.0.0.1", - "default_handler": "{couch_httpd_db, handle_request}", - "enable_cors": "false", - "log_max_chunk_size": "1000000", - "port": "5984", - "secure_rewrites": "true", - "vhost_global_handlers": "_utils, _uuids, _session, _oauth, _users" -} - -``` - -**getConfig("couchdb@localhost","log","level")** - -Returns either text-plain of JSON value of the section/key. -*Note : It will return a CouchNotFoundException is the section or key are not present*. - -``` -"debug" -``` - - -### setConfig($nodeName, $section, $key, $value) - -*The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only* - -The method **setConfig($nodeName, $section, $key, $value)** let you configure your installation. It can returns CouchNotAuthorizedException or CouchNotFoundException depending on the parameters supplied. - -Example : - -**setConfig("couchdb@localhost","log","level","info")** - -Returns the old value in text-plain or JSON format. -``` -"debug" -``` - -### deleteConfig($nodeName, $section, $key) - -*The configurations methods are implemented for PHP-on-Couch 2.0 only. Note that the configuration is per-node only* - -The method **deleteConfig($nodeName, $section, $key)** let you delete a configuration key from your node. - -Example: - -**deleteConfig("couchdb@localhost","log","level")** -It will returns the JSON value of the parameter before its deletion. Not that the method can throw a CouchNotFoundException or a CouchUnauthorizedException regarding of the section/key and permissions. - -``` -"info" -``` - - -## Changes - -CouchDB implements database changes feedback and polling. [You'll find more infos here](http://books.couchdb.org/relax/reference/change-notifications). -For any event in the database, CouchDB increments a sequence counter. - -### getChanges() - -The method **getChanges()** sends back a CouchDB changes object. - -Example : - -```php -print_r($client->getChanges()); -/* - stdClass Object - ( - [results] => Array - ( - [0] => stdClass Object - ( - [seq] => 'example-last-update-sequence' - [id] => 482fa0bed0473fd651239597d1080f03 - [changes] => Array - ( - [0] => stdClass Object - ( - [rev] => 3-58cae2758cea3e82105e1090d81a9e02 - ) - - ) - - [deleted] => 1 - ) - - [1] => stdClass Object - ( - [seq] => 'example-last-update-sequence' - [id] => 2f3f913f34d60e473fad4334c13a24ed - [changes] => Array - ( - [0] => stdClass Object - ( - [rev] => 1-4c6114c65e295552ab1019e2b046b10e - ) - - ) - - ) - - ) - - [last_seq] => 4 - ) -*/ -``` - -## Chainable methods to use before getChanges() - - -The following methods allow a fine grained control on the _changes_ request to issue. - -### since(string $value) -Retrieve changes that happened after sequence number $value - -### heartbeat(integer $value) -Number of milliseconds between each heartbeat line (an ampty line) one logpoll and continuous feeds - -### feed(string $value, $callback) -Feed type to use. In case of "continuous" feed type, $callback should be set and should be a PHP callable object (so *is_callable($callback)* should be true) - -The callable function or method will receive two arguments : the JSON object decoded as a PHP object, and a couchClient instance, allowing developers to issue CouchDB queries from inside the callback. - -### filter(string $value, array $additional_query_options) -Apply the changes filter $value. Add additional headers if any - -### style(string $value) -Changes display style, use "all_docs" to switch to verbose - -Example : - -```php -// fetching changes since sequence 'example-last-update-sequence' using filter "messages/incoming" -$changes = $client->since('example-last-update-sequence')->filter("messages/incoming")->getChanges(); -``` - -Example - Continuous changes with a callback function - -```php -function index_doc($change,$couch) { - if( $change->deleted == true ) { - // won't index a deleted file - return ; - } - echo "indexing ".$change->id."\n"; - $doc = $couch->getDoc($change->id); - unset($doc->_rev); - $id = $doc->_id; - unset($doc->_id); - my_super_fulltext_search_appliance::index($id, $doc); -} - -$client->feed('continuous','index_doc')->getChanges(); -// will return when index_doc returns false or on socket error -``` - -### ensureFullCommit() - -The method **ensureFullCommit()** tells couchDB to commit any recent changes to the database file on disk. - -Example : - -```php -$response = $client->ensureFullCommit(); -print_r($response); -/* should print something like : - stdClass Object - ( - [ok] => 1, - [instance_start_time] => "1288186189373361" - ) -*/ -``` - -### Maintenance - -Three main maintenance tasks can be performed on a CouchDB database : compaction, view compaction, and view cleanup. - -### compactDatabase() - -CouchDB database file is an append only : during any modification on database documents (add, remove, or update), the modification is recorded at the end of the database file. The compact operation removes old versions of database documents, thus reducing database file size and improving performances. To initiate a compact operation, use the **compactDatabase()** method. - -Example : - -```php -// asking the server to start a database compact operation -$response = $client->compactDatabase(); // should return stdClass ( "ok" => true ) -``` -### compactAllViews() - -Just as documents files, view files are also append-only files. To compact all view files of all design documents, use the **compactAllViews()** method. - -Example : - -```php -// asking the server to start a view compact operation on all design documents -$response = $client->compactAllViews(); // return nothing -``` -### compactViews($id) - -To compact only views from a specific design document, use the **compactViews( $id )** method. - -Example : - -```php -// asking the server to start a database compact operation on the design document _design/example -$response = $client->compactViews( "example" ); // should return stdClass ( "ok" => true ) -``` - -### cleanupDatabaseViews() - -This operation will delete all unused view files. Use the **cleanupDatabaseViews()** method to initiate a cleanup operation on old view files -Example : - -```php -// asking the server to start a database view files cleanup operation -$response = $client->cleanupDatabaseViews(); // should return stdClass ( "ok" => true ) -``` diff --git a/doc/couch_client-document.md b/doc/couch_client-document.md deleted file mode 100644 index 643ad91..0000000 --- a/doc/couch_client-document.md +++ /dev/null @@ -1,521 +0,0 @@ -This section details the available methods to work with documents -## Table of content -- [getAllDocs()](#getalldocs) -- [getDoc($id)](#getdocid) - + [Chainable methods to use with getDoc()](#chainable-methods-to-use-with-getdoc) - + [rev($value)](#revvalue) - + [asCouchDocuments()](#ascouchdocuments) - + [conflicts()](#conflicts) - + [revs()](#revs) - + [revs_info()](#revs_info) - + [open_revs($value)](#open_revsvalue) -- [storeDoc($doc)](#storedocdoc) -- [Updating a document](#updating-a-document) -- [updateDoc($ddoc_id, $handler_name, $params, $doc_id = null)](#updatedocddoc_id-handler_name-params-doc_id--null) -- [updateDocFullAPI($ddoc_id, $handler_name, $options)](#updatedocfullapiddoc_id-handler_name-options) -- [deleteDoc($doc)](#deletedocdoc) -- [copyDoc($id, $new_id)](#copydocid-new_id) -- [Attachments](#attachments) -- [storeAttachment($doc, $file, $content_type = 'application/octet-stream', $filename = null)](#storeattachmentdoc-file-content_type--applicationoctet-stream-filename--null) -- [storeAsAttachment($doc,$data,$filename,$content_type = 'application/octet-stream')](#storeasattachmentdocdatafilenamecontent_type--applicationoctet-stream) -- [deleteAttachment($doc,$attachment_name)](#deleteattachmentdocattachment_name) -- [getShow($design_id, $name, $doc_id = null, $additionnal_parameters = array())](#getshowdesign_id-name-doc_id--null-additionnal_parameters--array) -- [Bulk operations](#bulk-operations) -- [keys($ids)->getAllDocs()](#keysids-getalldocs) -- [storeDocs($docs, $new_edits)](#storedocsdocs-new_edits) -- [deleteDocs($docs, $new_edits)](#deletedocsdocs-new_edits) -- [asArray()](#asarray) - -### getAllDocs() - -The method **getAllDocs()** retrieve all documents from the database. In fact it only retrieve document IDs, unless you specify the server to include the documents using the [View query parameters syntax](couch_client-view.md). - -Example : - -```php -$all_docs = $client->getAllDocs(); -echo "Database got ".$all_docs->total_rows." documents.
\n"; -foreach ( $all_docs->rows as $row ) { - echo "Document ".$row->id."
\n"; -} -``` - -### getDoc($id) - -The method **getDoc($id)** gives back the document that got ID $id, if it exists. Note that if the document does not exist, the method will throw an error. - -The document is sent back as an HTTP object of class [stdClass](http://fr3.php.net/manual/en/reserved.classes.php). - -Example : - -```php -try { - $doc = $client->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -echo $doc->_id.' revision '.$doc->_rev; -``` - -### Chainable methods to use with getDoc() - -#### rev($value) - -The chainable **rev($value)** method specify the document revision to fetch. - -Example : - -```php -try { - $doc = $client->rev("1-849aff6ad4a38b1225c80a2119dc31cb")->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id or revision 1-849aff6ad4a38b1225c80a2119dc31cb does not exist !"; - } - exit(1); -} -echo $doc->_rev ; // should echo 1-849aff6ad4a38b1225c80a2119dc31cb -``` - -#### asCouchDocuments() - -The **getDoc($id)** method returns a PHP stdClass object. You can however get back the document as a CouchDocument object by calling the **asCouchDocuments()** method before the **getDoc($id)** method. - -Example : - -```php -try { - $doc = $client->asCouchDocuments()->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -echo get_class($doc); // should echo "CouchDocument" -``` - -#### conflicts() - -The chainable method **conflicts()** asks CouchDB to add to the document a property *_conflicts* containing conflicting revisions on an object. - -Example : - -```php -try { - $doc = $client->conflicts()->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -if ( $doc->_conflicts ) { - print_r($doc->_conflicts); -} -``` - -#### revs() - -The chainable method **revs()** asks CouchDB to add to the document a property *_revisions* containing the list of revisions for an object. - -Example : - -```php -try { - $doc = $client->revs()->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -print_r($doc->_revisions); -``` - -#### revs_info() - -The chainable method **revs_info()** asks CouchDB to add to the document a property *_revs_info* containing the avaibility of revisions for an object. - -Example : - -```php -try { - $doc = $client->revs_info()->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -print_r($doc->_revs_info); -``` - -#### open_revs($value) - -Using the **open_revs($value)** method, CouchDB returns an array of objects. - -**$value** should be an array of revision ids or the special keyword all (to fetch all revisions of a document) - -Example : - -```php -try { - $doc = $client->open_revs( array("1-fbd8a6da4d669ae4b909fcdb42bb2bfd", "2-5bc3c6319edf62d4c624277fdd0ae191") )->getDoc("some_doc_id"); -} catch ( Exception $e ) { - if ( $e->getCode() == 404 ) { - echo "Document some_doc_id does not exist !"; - } - exit(1); -} -print_r($doc->_revs_info); -``` - -Which should return something similar to : - -```php -array ( - stdClass( - "missing" => "1-fbd8a6da4d669ae4b909fcdb42bb2bfd" - ), - stdClass( - "ok" => stdClass( - "_id" => "some_doc_id", - "_rev" => "2-5bc3c6319edf62d4c624277fdd0ae191", - "hello"=> "foo" - ) - ) -) -``` - -### storeDoc($doc) - -The method **storeDoc($doc)** store a document on the CouchDB server. $doc should be an object. If the property $doc->_rev is set, the method understand that it's an update, and as so requires the property $doc->\_id to be set. If the property $doc->\_rev is not set, the method checks for the existance of property $doc->\_id and initiate the appropriate request. - -The response of this method is the CouchDB server response. In other words if the request ends successfully the returned object should be : - -```php -stdClass ( "ok" => true, "id" => "some_doc_id" , "rev" => "3-23423423476" ) -``` - -Example : creating a document without specifying id - -```php -$new_doc = new stdClass(); -$new_doc->title = "Some content"; -try { - $response = $client->storeDoc($new_doc); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; -// Doc recorded. id = 0162ff06747761f6d868c05b7aa8500f and revision = 1-249007504 -``` - -Example : creating a document specifying the id - -```php -$new_doc = new stdClass(); -$new_doc->title = "Some content"; -$new_doc->_id = "BlogPost6576"; -try { - $response = $client->storeDoc($new_doc); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; -// Doc recorded. id = BlogPost6576 and revision = 1-249004576 -``` - -Example : updating an existing document : - -```php -// get the document -try { - $doc = $client->getDoc('BlogPost6576'); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} - -// make changes -$doc->title = 'Some smart content'; -$doc->tags = array('twitter','facebook','msn'); - -// update the document on CouchDB server -try { - $response = $client->storeDoc($doc); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -echo "Doc recorded. id = ".$response->id." and revision = ".$response->rev."
\n"; -// Doc recorded. id = BlogPost6576 and revision = 2-456769086 -``` - -## Updating a document - -Using CouchDB [Update handlers](http://wiki.apache.org/couchdb/Document_Update_Handlers), you can easily update any document part without having to send back the whole document. - -### updateDoc($ddoc_id, $handler_name, $params, $doc_id = null) - -The method **updateDoc($ddoc_id, $handler_name, $params, $doc_id = null)** will try to update document according to the code defined in the update handler *$handler_name* of th design document *_design/$ddoc_id*. - -Example : incrementing a document counter - -Let's say we have a design document _design/myapp containing : - -``` -"updates": { - "bump-counter" : "function(doc, req) { - if ( !doc ) return [null, {\"code\": 404, \"body\": \"Document not found / not specified\"}] - if (!doc.counter) doc.counter = 0; - doc.counter += 1; - var message = \"

bumped it!

\"; - return [doc, message]; - }", -} -``` - -To bump the counter of the document "some_doc" , use : - -```php -$client->updateDoc("myapp","bump-counter",array(),"some_doc"); -``` - -### updateDocFullAPI($ddoc_id, $handler_name, $options) - -The method **updateDocFullAPI($ddoc_id, $handler_name, $options)** will try to update document according to the code defined in the update handler *$handler_name* of th design document *_design/$ddoc_id*. - -$options is an array of optionnal query modifiers : -"params" : array|object of variable to pass in the URL ( /?foo=bar ) -"data" : string|array|object data to set in the body of the request. If data is an array or an object it will be urlencoded using PHP http_build_query function and the request Content-Type header will be set to "application/x-www-form-urlencoded". -"Content-Type": string the Content-Type HTTP header to send to the couch server - - -Example : - -```php -$client->updateDocFullAPI("myapp","bump-counter",array( "data" => array("Something"=>"is set") ) ); -``` - - -### deleteDoc($doc) - -The method **deleteDoc($doc)** permanently removes $doc from the CouchDB server. $doc should be an object containing at least \_id and \_rev properties. - -Example : - -```php -// get the document -try { - $doc = $client->getDoc('BlogPost6576'); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -// permanently remove the document -try { - $client->deleteDoc($doc); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -``` - -### copyDoc($id, $new_id) - -The **copyDoc($id, $new_id)** method provides an handy way to copy a document. $id is the id of the document to copy. $new_id is the id of the new document. - -Upon success, this method returns the CouchDB server response, which has the main form than a document storage : - -```php -stdClass ( "ok" => true, "id" => "new_id" , "rev" => "1-23423423476" ) -``` - -Example : - -```php -try { - $response = $client->copyDoc('BlogPost6576','CopyOfBlogPost6576'); -} catch (Exception $e) { - echo "ERROR: ".$e->getMessage()." (".$e->getCode().")
\n"; -} -``` - -## Attachments - -There is two methods handling attachments, it depends whether the file to send as attachment is on the harddrive, or if it's contained in a PHP variable. The first one should be more reliable for large attachments. - -### storeAttachment($doc, $file, $content_type = 'application/octet-stream', $filename = null) - -The method **storeAttachment($doc,$file,$content_type = 'application/octet-stream',$filename = null)** handles the process of storing an attachment on a CouchDB document. - -* **$doc** is a PHP object containing at least the properties \_id and \_rev -* **$file** is the complete path to the file on disk -* **$content_type** is the file's [content-type](http://en.wikipedia.org/wiki/MIME) -* **$filename** is the name of the attachment on CouchDB document, if the name is not the name of the file in $file - -Example : - -```php -$doc = $client->getDoc('BlogPost5676'); -$ok = $client->storeAttachment($doc,'/etc/resolv.conf','text/plain', 'my-resolv.conf'); -print_r($ok); -// stdClass ( "ok" => true, "id" => "BlogPost5676" , "rev" => "5-2342345476" ) -``` - -### storeAsAttachment($doc,$data,$filename,$content_type = 'application/octet-stream') - -The method **storeAsAttachment($doc,$data,$filename,$content_type = 'application/octet-stream')** records as a CouchDB document's attachment the content of a PHP variable. - -* **$doc** is a PHP object containing at least the properties \_id and \_rev -* **$data** is the data (the content of the attachment) -* **$filename** is the name of the attachment on CouchDB document -* **$content_type** is the file's [content-type](http://en.wikipedia.org/wiki/MIME) - -Example : - -```php -$doc = $client->getDoc('BlogPost5676'); -$google_home=file_get_contents('http://www.google.com/'); -$ok = $client->storeAsAttachment($doc,$google_home,'GoogleHomepage.html','text/html'); -print_r($ok); -// stdClass ( "ok" => true, "id" => "BlogPost5676" , "rev" => "5-2342345476" ) -``` - -### deleteAttachment($doc,$attachment_name) - -the method **deleteAttachment($doc,$attachment_name)** delete an attachment from a CouchDB document. $doc is an object with, at least, \_id and \_rev properties, and $attachment_name is the name of the attachment to delete. - -Example : - -```php -$doc = $client->getDoc('BlogPost5676'); -$ok = $client->deleteAttachment($doc,'GoogleHomepage.html'); -``` - -### getShow($design_id, $name, $doc_id = null, $additionnal_parameters = array()) - -The method **getShow($design_id, $name, $doc_id = null, $additionnal_parameters = array())** request a show formatting of document *$doc_id* with show method *$name* stored in design document *design_id*. - -Example : - -```php -$output = $client->getShow('blogs','html','BlogPost5676'); -``` - -More infos on CouchDB show formatting [here](http://wiki.apache.org/couchdb/Formatting_with_Show_and_List) - -### Bulk operations - -A bulk operation is a unique query performing actions on several documents. CouchDB Bulk operations API are described in [this wiki page](http://docs.couchdb.org/en/2.0.0/api/database/bulk-api.html). - -### keys($ids)->getAllDocs() - -To retrieve several documents in one go, knowing their IDs, select documents using the **keys($ids)** coupled with the method **getAllDocs()**. $ids is an array of documents IDs. This function acts like a view, so the output is the view output of CouchDB, and you should use "include_docs(true)" to have documents contents. - -Example : - -```php -$view = $client->include_docs(true)->keys( array('BlogPost5676','BlogComments5676') )->getAllDocs(); -foreach ( $view->rows as $row ) { - echo "doc id :".$row->doc->_id."\n"; -} -``` - -### storeDocs($docs, $new_edits) - -To store several documents in one go, use the method **storeDocs($docs, $new_edits)**. $docs is an array containing the documents to store (as CouchDocuments, PHP [stdClass](http://fr3.php.net/manual/en/reserved.classes.php) or PHP arrays). $new_edits is related to the updates of the revision. If set to true (which is the default), assign new revision id for each update. When set to false, it prevents the database from assigning them new reivision IDS. - -Example : - $docs = array ( - array('type'=>'blogpost','title'=>'post'), - array('type'=>'blogcomment','blogpost'=>'post','depth'=>1), - array('type'=>'blogcomment','blogpost'=>'post','depth'=>2) - ); - $response = $client->storeDocs( $docs ); - print_r($response); - -which should give you something like : - -```php -Array -( - [0] => stdClass Object - ( - [id] => 8d7bebddc9828ed2edd052773968826b - [rev] => 1-3988163576 - ) - - [1] => stdClass Object - ( - [id] => 37bcfd7d9e94c67617982527c67efe44 - [rev] => 1-1750264873 - ) - - [2] => stdClass Object - ( - [id] => 704a51a0b6448326152f8ffb8c3ea6be - [rev] => 1-2477909627 - ) - -) -``` - -This method also works to update documents. - -### deleteDocs($docs, $new_edits) - -To delete several documents in a single HTTP request, use the method **deleteDocs($docs, $new_edits)**. $docs is an array containing the documents to store (as couchDocuments, PHP [stdClass](http://fr3.php.net/manual/en/reserved.classes.php) or PHP arrays). $new_edits is related to the updates of the revision. If set to true (which is the default), assign new revision id for each update. When set to false, it prevents the database from assigning them new reivision IDS. - - -### asArray() - -When converting a JSON object to PHP, we can choose the type of the value returned from a CouchClient query. - -Take for example the following JSON object : - { 'blog' : true, 'comments' : { 'title' : 'cool' } } - -This can be converted into a PHP object : - -```php -stdClass Object -( - [blog] => true - [comments] => stdClass Object - ( - [title] => "cool" - ) -) -``` - -OR into a PHP array : - -```php -Array -( - [blog] => true - [comments] => Array - ( - [title] => "cool" - ) -) -``` - -Using the defaults, JSON objects are mapped to PHP objects. The **asArray()** method can be used to map JSON objects to PHP arrays. - -Example: - -```php -$doc = $client->asArray()->getDoc('BlogPost5676'); -print_r($doc); -``` - -should print : - -```php -Array ( - [id] => "BlogPost5676" -) -``` - diff --git a/doc/couch_client-view.md b/doc/couch_client-view.md deleted file mode 100644 index 51aab79..0000000 --- a/doc/couch_client-view.md +++ /dev/null @@ -1,185 +0,0 @@ -This section describes how to use PHP on Couch to retrieve views results from a CouchDB server. - -## Table of content -- [Creating views](#creating-views) -- [getView($id, $name)](#getviewid-name) -- [View response](#view-response) -- [Query parameters](#query-parameters) -- [setQueryParameters($params)](#setqueryparametersparams) -- [asArray()](#asarray) -- [getList($design_id, $name, $view_name, $additionnal_parameters = array())](#getlistdesign_id-name-view_name-additionnal_parameters--array) -- [getForeignList($list_design_id, $name, $view_design_id, $view_name, $additionnal_parameters = array()) ](#getforeignlistlist_design_id-name-view_design_id-view_name-additionnal_parameters--array) -- [getViewInfos($design_id)](#getviewinfosdesign_id) - -### Creating views - - -[As said in the documentation](http://wiki.apache.org/couchdb/HTTP_view_API) , views are stored in CouchDB documents called "design documents". So to create a view, you have to create a design document. - -Example - -```php -$view_fn="function(doc) { emit(doc.timestamp,null); }"; -$design_doc = new stdClass(); -$design_doc->_id = '_design/all'; -$design_doc->language = 'javascript'; -$design_doc->views = array ( 'by_date'=> array ('map' => $view_fn ) ); -$client->storeDoc($design_doc); -``` - -### getView($id, $name) - -The method **getView($id, $name)** sends back the CouchDB response of a view. - -* **$id** is the design document id without '_design/' -* **$name** is the view name - -Example : -```php -$result = $client->getView('all','by_date'); -``` - -## View response - -The CouchDB response of a view is an object containing : - -* **total_rows** , an integer of all documents available in the view, regardless of the query options -* **offset** , an integer givving the offset between the first row of the view and the first row contained in the resultset -* **rows** an array of objects. - -Each object in **rows** contains the properties : - -* **id** : the id of the emited document -* **key** : the emited key -* **value** : the emited value -* **doc** : the document object, if query parameter include_docs is set (read on for that). - -## Query parameters - -PHP on Couch implements chainable methods to add query parameters. The method names are mapped on their CouchDB counterparts : - -* key -* keys -* startkey -* startkey_docid -* endkey -* endkey_docid -* limit -* stale -* descending -* skip -* group -* group_level -* reduce -* include_docs -* inclusive_end -* attachments - -Example querying a view with a startkey, a limit and include_docs - -```php -$response = $client->startkey(100000000)->limit(100)->include_docs(true)->getView('all','by_date'); -``` - -Which is the same as : - -```php -$client->startkey(100000000); -$client->limit(100); -$client->include_docs(true); -$response = $client->getView('all','by_date'); -``` - -### setQueryParameters($params) - -You also can set query parameters with a PHP array, using the **setQueryParameters** method : - -```php -$opts = array ( "include_docs" => true, "limit" => 10, "descending" => true ); -$response = $client->setQueryParameters(opts)->getView("all","by_date"); -``` - -### asArray() - -When converting a JSON object to PHP, we can choose the type of the value returned from a CouchClient query. - -Take for example the following JSON object : - { 'blog' : true, 'comments' : { 'title' : 'cool' } } - -This can be converted into a PHP object : - -```php -stdClass Object -( - [blog] => true - [comments] => stdClass Object - ( - [title] => "cool" - ) -) -``` - -OR into a PHP array : - -```php -Array -( - [blog] => true - [comments] => Array - ( - [title] => "cool" - ) -) -``` - -Using the defaults, JSON objects are mapped to PHP objects. The **asArray()** method can be used to map JSON objects to PHP arrays. - -Example : - -```php -$response = $client->startkey(100000000)->limit(100)->include_docs(true)->asArray()->getView('all','by_date'); -``` - -Format a view with CouchDB list formatting feature -================================================== - -More infos on CouchDB lists [here](http://wiki.apache.org/couchdb/Formatting_with_Show_and_List). - -### getList($design_id, $name, $view_name, $additionnal_parameters = array()) - -The method **getList($design_id, $name, $view_name, $additionnal_parameters = array() )** retrive a view and then format it using the algorithm of the $name list. - -Example : - -```php -$response = $client->limit(100)->include_docs(true)->getList('all','html','by_date'); -// will run the view declared in _design/all and named *by_date*, and then -// pass it through the list declared in _design/all and named *html*. -``` - -### getForeignList($list_design_id, $name, $view_design_id, $view_name, $additionnal_parameters = array()) - -The method **getForeignList($list_design_id, $name, $view_design_id, $view_name, $additionnal_parameters = array() )** retrive a view -defined in the document *_design/$view_design_id* and then format it using the algorithm of the list defined in the design document -*_design/$list_design_id*. - -Example : - -```php -$response = $client->limit(100)->getForeignList('display','html','posts','by_date'); -// will run the view declared in _design/posts and named *by_date*, and then -// pass it through the list declared in _design/display and named *html*. -``` - - -### getViewInfos($design_id) - -More info on view informations [here](http://wiki.apache.org/couchdb/HTTP_view_API# Getting_Information_about_Design_Documents_.28and_their_Views.29) - -The method **getViewInfos($design_id)** sends back some useful informations about a particular design document. - -Example : - -```php -$response = $client->getViewInfos("mydesigndoc"); -``` diff --git a/doc/couch_client_mango.md b/doc/couch_client_mango.md deleted file mode 100644 index 1cf5b81..0000000 --- a/doc/couch_client_mango.md +++ /dev/null @@ -1,232 +0,0 @@ -# Mango Query - -## Table of content - -- [**Summary**](#summary) -- [**PHPonCouch and Mango**](#phponcouch-and-mango) -- [**Functions**](#functions) - + [**getIndexes()**](#getindexes) - + [**createIndex(array $fields, $name = null, $ddoc = null, $type = 'json')**](#createindexarray-fields-name--null-ddoc--null-type--json) - + [**find($selector, $index = null)**](#findselector-index--null) - + [**explain($selector, $index = null)**](#explainselector-index--null) - -## Summary - -With the new release of CouchDB 2.0, Apache brough us the Mango Query. It's an adapted version of Cloudant Query for CouchDB. It's very similar to MongoDB Query syntax. - -It lets you create index and perform query with more ease that map/reduce. For more details, you may take a look at this : - -- [New feature : Mango Query](https://blog.couchdb.org/2016/08/03/feature-mango-query/) -- [Cloudant Query](https://developer.ibm.com/clouddataservices/docs/cloudant/get-started/use-cloudant-query/) -- [Mango source code](https://github.com/cloudant/mango) - -## PHPonCouch and Mango - -With recently added new available function to let you use the new Mango Query. This is very minimalist for the moment but feel free to suggest any ameliorations. - -The Mango Query functionalities have been implemented directly in the CouchClient. - - - - -## Functions - -### getIndexes() - -This function returns you an array of indexes. Each index will have those properties : - -- ddoc : The design document id of the index -- name : The name of the index -- type : The type of the index (special,text,json) -- def : The fields indexes - -By default, you always have one index :  \_all_docs - -Example : - -```php -$indexes = $client->getIndexes(); - -/* -[ - { - "ddoc": null, - "name": "_all_docs", - "type": "special", - "def": { - "fields": [ - { - "_id": "asc" - } - ] - } - } -] - */ -} - -``` - -### createIndex(array $fields, $name = null, $ddoc = null, $type = 'json') - - -This function create a index. - -**@parameters** - -- $fields : Specify the fields that will be indexed -- $name : The name of the index. Otherwise, it will be generated -- $ddoc : The design document id to store de index. Otherwise CouchDB will create one by index. -- $type : The type of index. Could be json or text but only json is supported at the moment. - -**@returns** - -- result : Message that normally returns "created" or "exists" -- id : The id of the undex. -- name : The name of the index. - -Example : - - -```php -$index = client->createIndex(['firstName', 'birthDate', 'lastName'], 'personIdx', 'person'); - -/* -$index should give : -{ - "result":"created", - "id":"_design/person", - "name":"personIdx" -} - */ -``` - - -### find($selector, $index = null) - -The new **find()** function let you query the database by using the new Mango Query. You can provide a selector query multiple fields and use conditional queries. You can sort your query and also determine which fields you want to retreive. CouchDB will automatically select the most efficient index for your query but it's preferred to specify the index for faster results. - -Also, the **limit(number)** and **skip(number)** can be apply to the client before the query. - -**Support query parameters** - -You can use the following query parameters : - -- limit(number) : Limit the number of documents that will be returned. -- skip(n) : Skip n documents and return the documents following. -- sort(sortSyntax) : Array or values that follow the [sort syntax](http://docs.couchdb.org/en/2.0.0/api/database/find.html#find-sort) -- fields(fieldsArray) : An array of fields that you want to return from the documents. If null, all the fields will be returned. - -**@parameters** - -- $selector : A selector object or array that follows the Mango query [documentation](http://docs.couchdb.org/en/2.0.0/api/database/find.html#selector-syntax) -- $index : The name of the index to use("" or ["", ""]). Otherwise automatically choosen. - -**@returns** - -Returns an array of documents - - -Example : - -```php -$selector = [ - '$and' => - [ - ['age' => ['$gt' => 16]], - ['gender' => ['$eq' => 'Female']] - ] -]; -$docs = $client->skip(10)->limit(30)->sort(["age"])->fields(['firstName'])->find($selector); - -``` - - -### explain($selector, $index = null) - -The **explain()** function let you perform a query like if you were using the [**find()**](#findselector-array-fields--null-sort--null-index--null) function. Therefore, the explain will not returns any documents. Instead, it will give you all the details about the query. For example, it could tell you which index has been automatically selected. - -For the parameter, please refer to the [**find()**](#findselector-array-fields--null-sort--null-index--null) parameters. - -**@returns** - -It returns a object with a lot of detailed properties. Here are main properties : - -- dbname : The name of the database -- index : Index object used to fullfil the query -- selector : The selector used for the query -- opts : The query options used for the query -- limit : The limit used -- skip : The skip parameter used -- fields : The fields returned by the query -- range : Range parameters passed to the underlying view - - -Example : - -```php -$selector = [ -'year'=>['$gt'=>2010] -]; -$details = $client->skip(0)->limit(2)->fields(['_id','_rev','year','title'])->sort(['year'=>'asc'])->find($selector); -``` - -The $details values would be the equivalent in JSON : - -```json -{ - "dbname": "movies", - "index": { - "ddoc": "_design/0d61d9177426b1e2aa8d0fe732ec6e506f5d443c", - "name": "0d61d9177426b1e2aa8d0fe732ec6e506f5d443c", - "type": "json", - "def": { - "fields": [ - { - "year": "asc" - } - ] - } - }, - "selector": { - "year": { - "$gt": 2010 - } - }, - "opts": { - "use_index": [], - "bookmark": "nil", - "limit": 2, - "skip": 0, - "sort": {}, - "fields": [ - "_id", - "_rev", - "year", - "title" - ], - "r": [ - 49 - ], - "conflicts": false - }, - "limit": 2, - "skip": 0, - "fields": [ - "_id", - "_rev", - "year", - "title" - ], - "range": { - "start_key": [ - 2010 - ], - "end_key": [ - {} - ] - } -} -``` - - diff --git a/doc/couch_document.md b/doc/couch_document.md deleted file mode 100644 index 51ada86..0000000 --- a/doc/couch_document.md +++ /dev/null @@ -1,347 +0,0 @@ -This section give details on using CouchDocument data mapper - -## CouchDocuments to simplify the code - -CouchDB embed a simple JSON/REST HTTP API. You can simplify even more your PHP code using couch documents. -Couch Documents take care of revision numbers, and automatically propagate updates on database. - -## Table of content - -- [Creating a new document](#creating-a-new-document) -- [set($key, $value = null)](#setkey-value--null) -- [set($params)](#setparams) -- [setAutocommit(boolean $autoCommit)](#setautocommitboolean-autocommit) -- [record()](#record) -- [getAutocommit()](#getautocommit) -- [remove($key)](#removekey) -- [getInstance( CouchClient $client, $docId )](#getinstance-couchclient-client-docid-) -- [getUri()](#geturi) -- [getFields()](#getfields) -- [storeAttachment($file, $content_type = 'application/octet-stream', $filename = null)](#storeattachmentfile-content_type--applicationoctet-stream-filename--null) -- [storeAsAttachment($data, $filename, $content_type = 'application/octet-stream')](#storeasattachmentdata-filename-content_type--applicationoctet-stream) -- [deleteAttachment($name)](#deleteattachmentname) -- [getAttachmentUri($name)](#getattachmenturiname) -- [replicateTo($url, $create_target = false)](#replicatetourl-create_target--false) -- [replicateFrom($id, $url, $create_target = false)](#replicatefromid-url-create_target--false) -- [show($id, $name, $additionnal_parameters = array())](#replicatefromid-url-create_target--false) -- [update($id, $name, $additionnal_params = array())](#updateid-name-additionnal_params--array-) - -## Creating a new document - - -To create an empty CouchDocument, simply instanciate the **CouchDocument** class, passing the CouchClient object as the constructor argument. - -Example : - -```php -$client = new CouchClient('http://localhost:5984/','myDB'); -$doc = new CouchDocument($client); -``` -If I set a property on $doc, it'll be registered in the database. If the property is not _id, the unique identifier will be automatically created by CouchDB, and available in the CouchDocument object. - -Example : - -```php -$doc->type="contact"; -echo $doc->id(); -// 1961f10823408cc9e1cccc145d35d10d -``` - -However if you specify _id, that one will of course be used. - -Example : - -```php -$doc = new CouchDocument($client); -$doc->_id = "some_doc"; -echo $doc->id(); -// some_doc -``` - -### set($key, $value = null) - -As we just saw, just set the property on the $doc object and it'll be recorded in the database. There are 2 ways to do it. You can either use the **set($key, $value)** method or simply use the setter **$obj->key = $value**. - -Example : - -```php -$doc = new CouchDocument($client); -$doc->_id = "some_doc"; -$doc->type = "page"; -$doc->title = "Introduction"; -``` - -### set($params) - -It's always possible to set several properties in one query using the **set($params)** method - -Example using an array : - -```php -$doc = new CouchDocument($client); -$doc->set ( - array( - '_id' => 'some_doc', - 'type' => "page", - 'title' => "Introduction" - ) -); -``` - -Example using an object - -```php -$prop = new stdClass(); -$prop->_id = "some_doc"; -$prop->type = "page"; -$prop->title = "Introduction"; - -$doc = new CouchDocument($client); -$doc->set ( $prop ); -``` - -### setAutocommit(boolean $autoCommit) - -If, for some reason, you need to disable the auto-commit feature, use the **setAutocommit()** method. In this case, you'll have to explicitely call the **record()** method to store your changes on the database. - -Example : - -```php -$doc = new CouchDocument($client); -$doc->setAutocommit(false); -$doc->_id = "some_doc"; -$doc->type = "page"; -$doc->title = "Introduction"; -$doc->record(); -``` - -### record() - -When the auto-commit feature is off, you need to apply changes manually. Calling the method **record()** apply the changes. - -Example : - -```php -$doc = new CouchDocument($client); -$doc->setAutocommit(false); -$doc->_id = "some_doc"; -$doc->type = "page"; -$doc->title = "Introduction"; -$doc->record(); -``` - -### getAutocommit() - -To know if the auto-commit feature is activated, use the **getAutocommit()** method : it returns a boolean. - - -### remove($key) - -To unset a property, just use the **unset** PHP function, as you'll do for a PHP object. You can also use the **remove($key)** function which is normally called when you du a **unset**. - -Example : - -```php -$prop = new stdClass(); -$prop->_id = "some_doc"; -$prop->type = "page"; -$prop->title = "Introduction"; - -$doc = new CouchDocument($client); -$doc->set ( $prop ); -unset($doc->title); -echo $doc->title ; // won't echo anything -``` - -### getInstance( CouchClient $client, $docId ) - -The static method **getInstance( CouchClient $client, $docId )** returns a CouchDocument when the specified id exists : - -Example : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -echo $doc->_rev."\n"; -echo $doc->type; -``` - -### getUri() - -The method **getUri()** sends back a string giving the current document URI. - -Example : - -```php -echo $doc->getUri(); -/* -db.example.com:5984/testdb/dome_doc_id -*/ -``` - -### getFields() - -To get the Couch document fields from a CouchDocument object, use the **getFields()** method - - -Example : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -print_r($doc->getFields()); -/* - stdClass object { - "_id" => "some_doc", - "_rev" => "3-234234255677684536", - "type" => "page", - "title"=> "Introduction" - } -*/ -``` - -### storeAttachment($file, $content_type = 'application/octet-stream', $filename = null) - -*When the attachment is a file on-disk* - -The method **storeAttachment($file, $content_type = 'application/octet-stream', $filename = null)** adds a new attachment, or update the attachment if it already exists. The attachment contents is located on a file. - -Example - Store the file /path/to/some/file.txt as an attachment of document id "some_doc" : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -try { - $doc->storeAttachment("/path/to/some/file.txt","text/plain"); -} catch (Exception $e) { - echo "Error: attachment storage failed : ".$e->getMessage().' ('.$e->getCode().')'; -} -``` - -### storeAsAttachment($data, $filename, $content_type = 'application/octet-stream') - -The method **storeAsAttachment($data, $filename, $content_type = 'application/octet-stream')** adds a new attachment, or update the attachment if it already exists. The attachment contents is contained in a PHP variable. - -Example - Store "Hello world !\nAnother Line" as an attachment named "file.txt" on document "some_doc" : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -try { - $doc->storeAsAttachment("Hello world !\nAnother Line", "file.txt" , "text/plain"); -} catch (Exception $e) { - echo "Error: attachment storage failed : ".$e->getMessage().' ('.$e->getCode().')'; -} -``` - -### deleteAttachment($name) - -The method **deleteAttachment($name)** permanently removes an attachment from a document. - -Example - Deletes the attachment "file.txt" of document "some_doc" : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -try { - $doc->deleteAttachment("file.txt"); -} catch (Exception $e) { - echo "Error: attachment removal failed : ".$e->getMessage().' ('.$e->getCode().')'; -} -``` - -### getAttachmentUri($name) - -The method **getAttachmentUri($name)** returns the URI of an attachment. - -Example : - -```php -$doc = CouchDocument::getInstance($client,'some_doc'); -if ( $doc->_attachments ) { - foreach ( $doc->_attachments as $name => $infos ) { - echo $name.' '.$doc->getAttachmentURI($name); - // should say something like "file.txt http://localhost:5984/dbname/some_doc/file.txt" - } -} -try { - $doc->deleteAttachment("file.txt"); -} catch (Exception $e) { - echo "Error: attachment removal failed : ".$e->getMessage().' ('.$e->getCode().')'; -} -``` - -### replicateTo($url, $create_target = false) - -The CouchDocuments instance provides an easy way to replicate a document to, or from, another database. Think about replication like a copy-paste operation of the document to CouchDB databases. - -For those methods to work, you should have included the CouchReplicator class file src/CouchReplicator.php . - - -Use the **replicateTo($url, $create_target = false)** method to replicate a CouchDocument to another CouchDB database. The create_target parameter let you create the remote database if it's not existing. - -Example : - -```php -$client = new CouchClient("http://couch.server.com:5984/","mydb"); -// load an existing document -$doc = CouchDocument::getInstance($client,"some_doc_id"); -// replicate document to another database -$doc->replicateTo("http://another.server.com:5984/mydb/"); -``` -The replicateTo can have another argument, a boolean one. If true, the database will be created on the destination server if it doesn't exist. - - -### replicateFrom($id, $url, $create_target = false) - -Use the **replicateFrom($id, $url, $create_target = false)** method to replicate a CouchDocument from another CouchDB database, and then load it into the CouchDocument instance. - -Example : - -```php -$client = new CouchClient("http://couch.server.com:5984/","mydb"); -// load an existing document -$doc = new CouchDocument($client); - -// replicate document from another database, and then load it into $doc -$doc->replicateFrom("some_doc_id","http://another.server.com:5984/mydb/"); -echo $doc->_id ; (should return "some_doc_id") -$doc->type="foo"; // doc is recorded on "http://couch.server.com:5984/mydb" - -// then replicate $doc back to http://another.server.com:5984/mydb/ -$doc->replicateTo("http://another.server.com:5984/mydb/"); -``` - -The replicateFrom can have another argument, a boolean one. If true, the database will be created on the destination server if it doesn't exist. - -### show($id, $name, $additionnal_parameters = array()) - -The **show($id,$name,$additionnal_parameters)** method parses the current document through a CouchDB show function. - -Example : the database contains the following design document : - -```php -{ - "_id": "_design/clean", - "shows": { - "html": "function (doc, req) { - send('

ID: '+doc._id+', rev: '+doc._rev+'

'); - }" - } -} -``` - -and another document that got the id "some_doc". We load the "some_doc" document as a CouchDocument object: - -```php -$doc = CouchDocument::getInstance($client,"some_doc"); -``` - -We can then request CouchDB to parse this document through a show function : - -```php -$html = $doc->show("clean","html"); -// html should contain "

ID: some_doc, rev: 3-2342342346

" -``` - -The show method is a proxy method to the **getShow()** method of **CouchClient**. - -### update($id, $name, $additionnal_params = array()) - -The **update($id,$name,$additionnal_params)** method allows to use the CouchDB [update handlers](http://wiki.apache.org/couchdb/Document_Update_Handlers) feature to update an existing document. -The CouchDocument object shouldd have an id for this to work ! Please see **CouchClient** *updateDoc* method for more infos. diff --git a/doc/couch_replicator.md b/doc/couch_replicator.md deleted file mode 100644 index 449e094..0000000 --- a/doc/couch_replicator.md +++ /dev/null @@ -1,223 +0,0 @@ -This section give details on using the CouchReplicator object. -## Table of content -- [Getting started](#getting-started) -- [Replication Basics](#replication-basics) - + [to()](#to) - + [from()](#from) - + [create_target()](#create_target) - + [doc_ids()](#doc_ids) -- [Continuous replication](#continuous-replication) - + [continuous()](#continuous) - + [cancel()](#cancel) -- [Chainable methods](#chainable-methods) - + [filter()](#filter) - + [query_params()](#query_params) -- [Replication of individual CouchDocuments](#replication-of-individual-couchdocuments) - - -## Getting started - -CouchDB supports replicating a database on other CouchDB databases. Think of replication as a copy-paste operation on databases. - -The CouchReplicator object is a simple abstraction of the CouchDB replication model. Those replication features are available in CouchDB 0.11 . At the time of this coding, canceling a continuous replication doesn't seem to always work. - -To create a new CouchReplicator object, you first have to include necessary files, and then instanciate the object, passing in argument a CouchClient instance. - -```php -to("http://another.server.com:5984/mydb"); -// database http://localhost:5984/mydb will be replicated to http://another.server.com:5984/mydb -``` - -Note that you can replicate on a local databse to, eg : - -```php -$response = $replicator->to("mydb_backup"); -// database http://localhost:5984/mydb will be replicated to http://localhost:5984/mydb_backup -``` - -### from() - -To replicate from a database to an existing database, use the **from()** method. - -```php -$response = $replicator->from("http://another.server.com:5984/mydb"); -// database http://another.server.com:5984/mydb will be replicated to http://localhost:5984/mydb -``` - -Please note that CouchDB developpers hardly suggest to use the Pull replication mode : that means to prefer the "from()" method. - - -### create_target() - - -The **create_target()** chainable method enables CouchDB to automatically create the target database, in case it doesn't exist. - -Example : - -```php -$response = $replicator->create_target()->from("http://another.server.com:5984/mydb"); -``` - -Which is equivalent to : - -```php - $replicator->create_target(); - $response = $replicator->from("http://another.server.com:5984/mydb"); -``` -If the target database already exist, the create_target() method has no use. - -### doc_ids() - -To replicate only some documents, pass their ids to the **doc_ids()** chainable method. - -Example : - -```php -$replicator->doc_ids( array ("some_doc", "some_other_doc") )->from("http://another.server.com:5984/mydb"); -``` - -This code will replicate documents "some_doc" and "some_other_doc" of database "http://another.server.com:5984/mydb" to database "http://localhost:5984/mydb" - -## Continuous replication - -A continuous replication is a replication that is permanent : once set, any change to the source database will be automatically propagated to the destination database. - -### continuous() - - -To setup a continuous replication, use the **continuous()** chainable method. - -Example : - -```php -// setup a continuous replication -$replicator->continuous()->from("http://another.server.com:5984/mydb"); -// create a CouchClient instance on the source database -$client2 = new CouchClient("http://another.server.com:5984/","mydb"); -// create and record a document on the source database -$doc = new stdClass(); -$doc->_id = "some_doc_on_another_server"; -$doc->type = "foo"; -$client2->storeDoc( $doc ); -// let some time for CouchDB to replicate -sleep(10); -// read the document from the destination database -$doc = $client->getDoc("some_doc_on_another_server"); -echo $doc->type; -``` - - -### cancel() - -To cancel a previously setup continuous replication, use the **cancel()** chainable method. - -Example : - -```php -// setup a continuous replication -$replicator->continuous()->from("http://another.server.com:5984/mydb"); -(...) //code code code -// remove the continuous replication -$replicator->cancel()->from("http://another.server.com:5984/mydb"); -``` -## Chainable methods - -### filter() - -To have a full control over which document should be replicated, setup a filter definition on the source database. Then use the **filter()** chainable method to filter replicated documents. - -```php -// create a CouchClient instance pointing to the source database -$source_client = new CouchClient("http://localhost:5984","mydb"); -// create a CouchClient instance pointing to the target database -$target_client = new CouchClient("http://another.server.com:5984","mydb") - -// create a design doc -$doc = new stdClass(); -$doc->_id = "_design/replication_rules"; -$doc->language = "javascript"; -// create a "no_design_doc" filter : only documents without the string "_design" will be replicated -$doc->filters = array ( - "no_design_doc" => "function (doc, req) { - if ( doc._id.match('_design') ) { - return false; - } else { - return true; - } - }" -); -// store the design doc in the SOURCE database -$target_client->storeDoc($doc); - -//create a CouchReplicator instance on the destination database -$replicator = new CouchReplicator($target_client); - -// replicate source database to target database, using the "no_design_doc" filter -$replicator->filter('replication_rules/no_design_doc')->from($source_client->getDatabaseUri()); -``` - -### query_params() - - -Filters can have a query parameters. This allows more generic filter codes. -Let's modify the filter code above to pass the string to compare the document id to via query parameters : - -```php -// create a CouchClient instance pointing to the source database -$source_client = new CouchClient("http://localhost:5984","mydb"); -// create a CouchClient instance pointing to the target database -$target_client = new CouchClient("http://another.server.com:5984","mydb") - -// create a design doc -$doc = new stdClass(); -$doc->_id = "_design/replication_rules"; -$doc->language = "javascript"; -// create a "no_design_doc" filter : only documents without the string "_design" will be replicated -$doc->filters = array ( - "no_str_in_doc" => "function (doc, req) { - if ( doc._id.match( req.query.needle ) ) { - return false; - } else { - return true; - } - }" -); -// store the design doc in the SOURCE database -$target_client->storeDoc($doc); - -//create a CouchReplicator instance on the destination database -$replicator = new CouchReplicator($target_client); - -// replicate source database to target database, using the "no_str_in_doc" filter, and setting needle to "_design" -$params = array ("needle"=>"_design"); -$replicator->query_params($params)->filter('replication_rules/no_str_in_doc')->from($source_client->getDatabaseUri()); -``` - -## Replication of individual CouchDocuments - -Please read the CouchDocument documentation to learn how to simply replicate a document to or from a database to another - - diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..f647641 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,19 @@ +.. PHPOnCouch documentation master file, created by sphinx-quickstart on Fri Sep 08 21:31:37 2017. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. + +Welcome to PHPOnCouch's documentation! +====================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents + + overview/index.rst + quickstart/index.rst + api/index.rst + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` +* :ref:`modindex` diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000..4d31b65 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=python -msphinx +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=PHPOnCouch + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The Sphinx module was not found. Make sure you have Sphinx installed, + echo.then set the SPHINXBUILD environment variable to point to the full + echo.path of the 'sphinx-build' executable. Alternatively you may add the + echo.Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/doc/overview/changelist/2.0.0.md b/doc/overview/changelist/2.0.0.md new file mode 100644 index 0000000..5eafb40 --- /dev/null +++ b/doc/overview/changelist/2.0.0.md @@ -0,0 +1,13 @@ +#### 2.0.0 +##### Added + +- CouchClient + + getMemberShip() + + getConfig($nodeName[,$section,$key]) + + setConfig($nodeName,$section,$key,$value) + + deleteConfig($nodeName,$section,$key) +- Composer installation now available + +##### Updated +- CouchAdmin($client,$options) +- Updated few tests cases diff --git a/doc/overview/changelist/2.0.1.md b/doc/overview/changelist/2.0.1.md new file mode 100644 index 0000000..e6ed877 --- /dev/null +++ b/doc/overview/changelist/2.0.1.md @@ -0,0 +1,25 @@ +#### 2.0.1 +##### Added + +- CouchClient + + getIndexes() + + createIndex(array $fields, $name = null, $ddoc = null, $type = 'json') + + find($selector, array $fields = null, $sort = null, $index = null) + + explain($selector, array $fields = null, $sort = null, $index = null) +- CouchClientTest + + getIndexesTest() + + createIndexTest() + + findTest() + + explainTest() +- changelist.md +- codestyle.md + +##### Updated + +- Refactored all the code to follow our code style +- Travis config to run CheckStyle +- Code example to correct syntax + +##### Fixed + +- Allow to use \_users and \_replicator databases directly diff --git a/doc/overview/changelist/2.0.2.md b/doc/overview/changelist/2.0.2.md new file mode 100644 index 0000000..c1e63d3 --- /dev/null +++ b/doc/overview/changelist/2.0.2.md @@ -0,0 +1,16 @@ +#### 2.0.2 +##### Added +- Couch + + getAdapter() + + setAdapter(CouchHttpAdapterInterface $adapter) + + initAdapter($opts) +- Adapters + + CouchHttpAdaterCurl + + CouchHttpAdapterSocket +- doc/couch.md +- changelist.md + +##### Fixed +- Removed echoes that were causing unexpected output +- Fixed some classes import +- Fixed Cookie parsing diff --git a/doc/overview/changelist/2.0.3.md b/doc/overview/changelist/2.0.3.md new file mode 100644 index 0000000..ae07a48 --- /dev/null +++ b/doc/overview/changelist/2.0.3.md @@ -0,0 +1,13 @@ +#### 2.0.3 +##### Added +- CouchClient + + Added query parameters documentation for IDE +- CouchAdmin + + setRolesToUser($user,$roles) +- Added missing tests for the library(code covered at 92%) +- Added detailed documentation for installation + +##### Updated +- Fixed continuous stream (changes, continuous replication) +- Update code examples + diff --git a/doc/overview/changelist/index.rst b/doc/overview/changelist/index.rst new file mode 100644 index 0000000..9098815 --- /dev/null +++ b/doc/overview/changelist/index.rst @@ -0,0 +1,10 @@ +Changelist +========== + +.. toctree:: + :maxdepth: 2 + + 2.0.3.md + 2.0.2.md + 2.0.1.md + 2.0.0.md \ No newline at end of file diff --git a/doc/overview/index.rst b/doc/overview/index.rst new file mode 100644 index 0000000..7917dd4 --- /dev/null +++ b/doc/overview/index.rst @@ -0,0 +1,8 @@ +Overview +******** + +.. toctree:: + :maxdepth: 2 + + intro.rst + changelist/index.rst diff --git a/doc/overview/intro.rst b/doc/overview/intro.rst new file mode 100644 index 0000000..198edbf --- /dev/null +++ b/doc/overview/intro.rst @@ -0,0 +1,14 @@ +Introduction +============ + +`PHPOnCouch `_ tries to provide an easy way to work with your `CouchDB `_ `documents `_ with `PHP `_ . + +What's new +========== + +Due to the lack of support on the last repository, I forked it and I will make sure it's kept active. Feel free to post any issue or feature request. I'm open for further developments but I don't have a lot of time. + +With the new release of 2.0, the master branch will support only this version and the next one. + +To access PHP-on-Couch for CouchDB 1.6.1, please visit `this link `_. + diff --git a/codestyle.md b/doc/quickstart/codestyle.md similarity index 100% rename from codestyle.md rename to doc/quickstart/codestyle.md diff --git a/doc/composerInstallation.gif b/doc/quickstart/composerInstallation.gif similarity index 100% rename from doc/composerInstallation.gif rename to doc/quickstart/composerInstallation.gif diff --git a/doc/quickstart/contributing.rst b/doc/quickstart/contributing.rst new file mode 100644 index 0000000..7e2c061 --- /dev/null +++ b/doc/quickstart/contributing.rst @@ -0,0 +1,6 @@ +Contributing +============ + +Feel free to make any contributions. All contributions must follow the Coding Style Guide and must also comes with valid and complete tests. + +Help is really appreciated to complete add more tests. \ No newline at end of file diff --git a/doc/quickstart/index.rst b/doc/quickstart/index.rst new file mode 100644 index 0000000..1972440 --- /dev/null +++ b/doc/quickstart/index.rst @@ -0,0 +1,10 @@ +Quickstart +********** + +.. toctree:: + :maxdepth: 2 + + installation.rst + testing.rst + contributing.rst + codestyle.md \ No newline at end of file diff --git a/doc/quickstart/installation.rst b/doc/quickstart/installation.rst new file mode 100644 index 0000000..5496b09 --- /dev/null +++ b/doc/quickstart/installation.rst @@ -0,0 +1,133 @@ + + +Installation +============ + +To install the library and actually use it, you've got two choices: + +- **Easy way** : Require the library and autoload it using `Composer `_. This also make the updates way more easier and version. +- **Manual way** : Download the library from github and import the files from `/src` to a `PHPOnCouch` folder in your project. You will need to update manually. + +Version +------- + +Before we get into the installation, you need to know that multiple versions are available at the moment. Since it's forked project, you have always access to the origin branches. For the future, here are the description of the available versions : + +- dev-master : The lastest tested sources +- 2.x.x : The PHP-on-Couch 2.0 Releases (Will be installed by default) This is the latest version that supports CouchDB 2.x.x +- 1.6.1.x-dev : The PHP-on-Couch 1.6.1 production branch. This branch contains the latest developments supporting CouchDB 1.6.1. + +From this information, it is up to you to choose the right version. By default, the latest release will be installed. + +Composer installation +--------------------- + +Once you have composer installed, you are very close to have PHP-on-Couch installed. You simply need to do : + +1. Add the root of your project, in a command shell, execute the following command : `composer require php-on-couch/php-on-couch`. + +.. note:: By default, it will take the latest release* + +2. Make sure your composer autoloader is called. If not, simply **require** the `autoload.php` file in `vendor` folder. +3. Start playing with PHPOnCouch! + +Composer demo +------------- + +.. image:: composerInstallation.gif + :alt: Composer installation demo + + +The content pasted into the `index.php` file is : + +.. code-block:: php + + databaseExists()){ + $client->createDatabase(); + } + + //We get the database info just for the demo + var_dump($client->getDatabaseInfos()); + + //Note: Every request should be inside a try catch since CouchExceptions could be thrown.For example, let's try to get a unexisting document + + try{ + $client->getDoc('the id'); + echo 'Document found'; + } + catch(Exceptions\CouchNotFoundException $ex){ + if($ex->getCode() == 404) + echo 'Document not found'; + } + + +Manual installation +------------------- + +Since you have chose the manual installation, it's a bit more complicated but still simple! As you are probably reading this, you should be on Github. First of all, you need to select the branch that you want to install. + +- Once you're on this branch, click the *Click or download* button and *Download ZIP*. +- Within the ZIP, extract the `src` folder into a folder named `PHPOnCouch` somewhere in your project. +- The only remaning step is to require the files. You can either use your own autloader or simply require the files manually. + + +Manual demo +""""""""""" + + +.. image:: manualInstallation.gif + :alt: Manual installation demo + +`index.php` file content : + +.. code-block:: php + + databaseExists()){ + $client->createDatabase(); + } + + //We get the database info just for the demo + var_dump($client->getDatabaseInfos()); + + //Note: Every request should be inside a try catch since CouchExceptions could be thrown.For example, let's try to get a unexisting document + + try{ + $client->getDoc('the id'); + echo 'Document found'; + } + catch(Exceptions\CouchNotFoundException $ex){ + if($ex->getCode() == 404) + echo 'Document not found'; + } + +And there you go! You can use the library from there following the :ref:`api_ref` \ No newline at end of file diff --git a/doc/manualInstallation.gif b/doc/quickstart/manualInstallation.gif similarity index 100% rename from doc/manualInstallation.gif rename to doc/quickstart/manualInstallation.gif diff --git a/doc/quickstart/testing.rst b/doc/quickstart/testing.rst new file mode 100644 index 0000000..683ca4a --- /dev/null +++ b/doc/quickstart/testing.rst @@ -0,0 +1,52 @@ +Testing +======= + +To test the library, you needs two things: + +- PHPUnit installed +- A CouchDB database running. + +By default, the library is binded to "http://localhost:5984". You can change the host and the port by exporting ENV variables before running the tests. + +**Variables** + ++---------+---------+-----------+-------------------------------------------------------------------------------------------------------------+ +| Name | Type | Default | Description | ++---------+---------+-----------+-------------------------------------------------------------------------------------------------------------+ +| DB_HOST | String | localhost | The host of the database (ip or dsn) | ++---------+---------+-----------+-------------------------------------------------------------------------------------------------------------+ +| DB_PORT | Integer | 5984 | The port of the database. Note: for the moment, you can't change the port if you're using the docker image. | ++---------+---------+-----------+-------------------------------------------------------------------------------------------------------------+ + +Install PHPUnit +--------------- + +The easy way to install PHPUnit is to use composer. In the project root, execute this : + +.. code-block:: bash + + composer install --dev + + +Run tests +--------- + +Recommended way +""""""""""""""" + +PHP-on-Couch provides bash scripts that setup a CouchDB instance via docker and let you test the library. If you're on Windows, you have to install Git Bash which comes with Git when you install it. + +.. warning:: Before running the scripts, make sure the port 5984 is free. Otherwise, the docker image won't be able to run and the tests will fail. Also, if you already have a local CouchDB, it's not recommended to use it for test. Tests will interact with the database and change it's current state. + +For Windows users : + +.. code-block :: bash + + sh _runLocalWin.sh + + +For Unix/OSX users : + +.. code-block:: bash + + sh _runLocalUnix.sh \ No newline at end of file diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..bda3091 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,22 @@ +Babel==2.0 +CommonMark==0.5.4 +Jinja2==2.8 +MarkupSafe==0.23 +PyYAML==3.11 +Pygments==2.0.2 +Sphinx==1.3.1 +sphinxcontrib-phpdomain==0.1.4 +alabaster==0.7.6 +argh==0.26.1 +argparse==1.2.1 +docutils==0.12 +html5lib==0.999 +meld3==0.6.10 +pathtools==0.1.2 +pytz==2015.4 +recommonmark==0.2.0 +six==1.5.2 +snowballstemmer==1.2.0 +sphinx-autobuild==0.5.2 +sphinx-rtd-theme==0.1.8 +wheel==0.24.0 \ No newline at end of file diff --git a/examples/01_databases.php b/examples/01_databases.php index d70d930..7496979 100644 --- a/examples/01_databases.php +++ b/examples/01_databases.php @@ -138,4 +138,4 @@ } echo "Database deleted. CouchDB response: ".print_r($result,true)."\n"; -echo "\nTo learn more database features : https://github.com/PHP-on-Couch/PHP-on-Couch/blob/master/doc/couch_client-database.md \n"; +echo "\nTo learn more database features : https://github.com/PHP-on-Couch/PHP-on-Couch/blob/master/doc/database.rst \n"; diff --git a/src/Couch.php b/src/Couch.php index d15b912..06dccf1 100644 --- a/src/Couch.php +++ b/src/Couch.php @@ -40,245 +40,245 @@ class Couch { - /** - * @var string database source name - */ - protected $dsn = ''; + /** + * @var string database source name + */ + protected $dsn = ''; - /** - * @var array database source name parsed - */ - protected $dsnParsed = null; + /** + * @var array database source name parsed + */ + protected $dsnParsed = null; - /** - * @var array couch options - */ - protected $options = null; + /** + * @var array couch options + */ + protected $options = null; - /** - * class constructor - * - * @param string $dsn CouchDB Data Source Name - * @param array $options Couch options - */ - public function __construct($dsn, $options = []) - { - $this->dsn = preg_replace('@/+$@', '', $dsn); - $this->options = $options; - $this->dsnParsed = parse_url($this->dsn); - if (!isset($this->dsnParsed['port'])) { - $this->dsnParsed['port'] = 80; - } - } + /** + * class constructor + * + * @param string $dsn CouchDB Data Source Name + * @param array $options Couch options + */ + public function __construct($dsn, $options = array()) + { + $this->dsn = preg_replace('@/+$@', '', $dsn); + $this->options = $options; + $this->dsnParsed = parse_url($this->dsn); + if (!isset($this->dsnParsed['port'])) { + $this->dsnParsed['port'] = 80; + } + } - /** - * Returns and init if necessary, the CouchHttpAdapter - * @returns PHPOnCouch\Adapter\CouchHttpAdapterInterface - */ - public function getAdapter() - { - if (!isset($this->adapter)) { - $this->adapter = $this->initAdapter($this->options); - } - return $this->adapter; - } + /** + * Returns and init if necessary, the CouchHttpAdapter + * @returns \PHPOnCouch\Adapter\CouchHttpAdapterInterface + */ + public function getAdapter() + { + if (!isset($this->adapter)) { + $this->adapter = $this->initAdapter($this->options); + } + return $this->adapter; + } - /** - * Set a new adapter to the Couch Class. - * @param \PHPOnCouch\Adapter\CouchHttpAdapterInterface $adapter The adapter to set - */ - public function setAdapter(CouchHttpAdapterInterface $adapter) - { - $this->adapter = $adapter; - } + /** + * Set a new adapter to the Couch Class. + * @param \PHPOnCouch\Adapter\CouchHttpAdapterInterface $adapter The adapter to set + */ + public function setAdapter(CouchHttpAdapterInterface $adapter) + { + $this->adapter = $adapter; + } - /** - * Init the HTTP Adapter with cURL if available. - * @param Array $options An array of options. - * @return \PHPOnCouch\CouchHttpAdapterSocket - */ - public function initAdapter($options) - { - if (!isset($options)) - $options = $this->options; - if (function_exists('curl_init')) - $adapter = new CouchHttpAdapterCurl($this->dsn, $options); - else - $adapter = new CouchHttpAdapterSocket($this->dsn, $options); - $this->adapter = $adapter; - return $adapter; - } + /** + * Init the HTTP Adapter with cURL if available. + * @param Array $options An array of options. + * @return \PHPOnCouch\CouchHttpAdapterSocket + */ + public function initAdapter($options) + { + if (!isset($options)) + $options = $this->options; + if (function_exists('curl_init')) + $adapter = new CouchHttpAdapterCurl($this->dsn, $options); + else + $adapter = new CouchHttpAdapterSocket($this->dsn, $options); + $this->adapter = $adapter; + return $adapter; + } - /** - * returns the DSN, untouched - * - * @return string DSN - */ - public function dsn() - { - return $this->dsn; - } + /** + * returns the DSN, untouched + * + * @return string DSN + */ + public function dsn() + { + return $this->dsn; + } - /** - * returns the options array - * - * @return string DSN - */ - public function options() - { - return $this->options; - } + /** + * returns the options array + * + * @return string DSN + */ + public function options() + { + return $this->options; + } - /** - * set the session cookie to send in the headers - * @param string $cookie the session cookie - * ( example : AuthSession=Y291Y2g6NENGNDgzNz ) - * - * @return \PHPOnCouch\Couch - */ - public function setSessionCookie($cookie) - { - return $this->getAdapter()->setSessionCookie($cookie); - } + /** + * set the session cookie to send in the headers + * @param string $cookie the session cookie + * ( example : AuthSession=Y291Y2g6NENGNDgzNz ) + * + * @return \PHPOnCouch\Couch + */ + public function setSessionCookie($cookie) + { + return $this->getAdapter()->setSessionCookie($cookie); + } - /** - * Get the current session cookie set to the class. - * @return String The cookie - */ - public function getSessionCookie() - { - return $this->getAdapter()->getSessionCookie(); - } + /** + * Get the current session cookie set to the class. + * @return String The cookie + */ + public function getSessionCookie() + { + return $this->getAdapter()->getSessionCookie(); + } - /** - * return a part of the data source name - * - * if $part parameter is empty, returns dns array - * - * @param string $part part to return - * @return string DSN part - */ - public function dsnPart($part = null) - { - if (!$part) { - return $this->dsnParsed; - } - if (isset($this->dsnParsed[$part])) { - return $this->dsnParsed[$part]; - } - } + /** + * return a part of the data source name + * + * if $part parameter is empty, returns dns array + * + * @param string $part part to return + * @return string DSN part + */ + public function dsnPart($part = null) + { + if (!$part) { + return $this->dsnParsed; + } + if (isset($this->dsnParsed[$part])) { + return $this->dsnParsed[$part]; + } + } - /** - * parse a CouchDB server response and sends back an array - * the array contains keys : - * status_code : the HTTP status code returned by the server - * status_message : the HTTP message related to the status code - * body : the response body (if any). If CouchDB server response - * Content-Type is application/json - * the body will by json_decode()d - * - * @static - * @param string|boolean $rawData data sent back by the server - * @param boolean $jsonAsArray is true, the json response will be - * decoded as an array. Is false, it's decoded as an object - * @return array CouchDB response - * @throws InvalidArgumentException - */ - public static function parseRawResponse($rawData, $jsonAsArray = false) - { - if (!strlen($rawData)) - throw new InvalidArgumentException("no data to parse"); - $httpHeader = "HTTP/1.1 100 Continue\r\n\r\n"; - while (!substr_compare($rawData, $httpHeader, 0, 25)) { - $rawData = substr($rawData, 25); - } - $response = ['body' => null]; - list($headers, $body) = explode("\r\n\r\n", $rawData, 2); - $headersArray = explode("\n", $headers); - $statusLine = reset($headersArray); - $statusArray = explode(' ', $statusLine, 3); - $response['status_code'] = trim($statusArray[1]); - $response['status_message'] = trim($statusArray[2]); - if (strlen($body)) { - $regex = '@Content-Type:\s+application/json@i'; - if (preg_match($regex, $headers)) - $response['body'] = json_decode($body, $jsonAsArray); - else - $response['body'] = $body; - } - return $response; - } + /** + * parse a CouchDB server response and sends back an array + * the array contains keys : + * status_code : the HTTP status code returned by the server + * status_message : the HTTP message related to the status code + * body : the response body (if any). If CouchDB server response + * Content-Type is application/json + * the body will by json_decode()d + * + * @static + * @param string|boolean $rawData data sent back by the server + * @param boolean $jsonAsArray is true, the json response will be + * decoded as an array. Is false, it's decoded as an object + * @return array CouchDB response + * @throws InvalidArgumentException + */ + public static function parseRawResponse($rawData, $jsonAsArray = false) + { + if (!strlen($rawData)) + throw new InvalidArgumentException("no data to parse"); + $httpHeader = "HTTP/1.1 100 Continue\r\n\r\n"; + while (!substr_compare($rawData, $httpHeader, 0, 25)) { + $rawData = substr($rawData, 25); + } + $response = array('body' => null); + list($headers, $body) = explode("\r\n\r\n", $rawData, 2); + $headersArray = explode("\n", $headers); + $statusLine = reset($headersArray); + $statusArray = explode(' ', $statusLine, 3); + $response['status_code'] = trim($statusArray[1]); + $response['status_message'] = trim($statusArray[2]); + if (strlen($body)) { + $regex = '@Content-Type:\s+application/json@i'; + if (preg_match($regex, $headers)) + $response['body'] = json_decode($body, $jsonAsArray); + else + $response['body'] = $body; + } + return $response; + } - /** - * send a query to the CouchDB server - * - * @param string $method HTTP method to use (GET, POST, ...) - * @param string $url URL to fetch - * @param array $parameters additionnal parameters to send with the request - * @param string|array|object $data request body - * @param string $contentType the content type of the sent data - * (defaults to application/json) - * - * @return string|false server response on success, false on error - */ - public function query($method, $url, $parameters = [], $data = null, $contentType = null) - { - return $this->getAdapter()->query($method, $url, $parameters, $data, $contentType); - } + /** + * send a query to the CouchDB server + * + * @param string $method HTTP method to use (GET, POST, ...) + * @param string $url URL to fetch + * @param array $parameters additionnal parameters to send with the request + * @param string|array|object $data request body + * @param string $contentType the content type of the sent data + * (defaults to application/json) + * + * @return string|false server response on success, false on error + */ + public function query($method, $url, $parameters = [], $data = null, $contentType = null) + { + return $this->getAdapter()->query($method, $url, $parameters, $data, $contentType); + } - /** - * record a file located on the disk as a CouchDB attachment - * - * @param string $url CouchDB URL to store the file to - * @param string $file path to the on-disk file - * @param string $contentType attachment content_type - * - * @return string server response - */ - public function storeFile($url, $file, $contentType) - { - return $this->getAdapter()->storeFile($url, $file, $contentType); - } + /** + * record a file located on the disk as a CouchDB attachment + * + * @param string $url CouchDB URL to store the file to + * @param string $file path to the on-disk file + * @param string $contentType attachment content_type + * + * @return string server response + */ + public function storeFile($url, $file, $contentType) + { + return $this->getAdapter()->storeFile($url, $file, $contentType); + } - /** - * store some data as a CouchDB attachment - * - * @param string $url CouchDB URL to store the file to - * @param string $data data to send as the attachment content - * @param string $contentType attachment content_type - * - * @return string server response - */ - public function storeAsFile($url, $data, $contentType) - { - return $this->getAdapter()->storeAsFile($url, $data, $contentType); - } + /** + * store some data as a CouchDB attachment + * + * @param string $url CouchDB URL to store the file to + * @param string $data data to send as the attachment content + * @param string $contentType attachment content_type + * + * @return string server response + */ + public function storeAsFile($url, $data, $contentType) + { + return $this->getAdapter()->storeAsFile($url, $data, $contentType); + } - /** - * send a query to the CouchDB server - * - * In a continuous query, the server send headers, and then a JSON object per line. - * On each line received, the $callable callback is fired, with two arguments : - * - * - the JSON object decoded as a PHP object - * - * - a couchClient instance to use to make queries inside the callback - * - * If the callable returns the boolean false , continuous reading stops. - * - * @param callable $callable PHP function name / callable array ( see http://php.net/is_callable ) - * @param string $method HTTP method to use (GET, POST, ...) - * @param string $url URL to fetch - * @param array $parameters additionnal parameters to send with the request - * @param string|array|object $data request body - * - * @return string|false server response on success, false on error - * - * @throws Exception|InvalidArgumentException|CouchException|CouchNoResponseException - */ - public function continuousQuery($callable, $method, $url, $parameters = [], $data = null) - { - return $this->getAdapter()->continuousQuery($callable, $method, $url, $parameters, $data); - } + /** + * send a query to the CouchDB server + * + * In a continuous query, the server send headers, and then a JSON object per line. + * On each line received, the $callable callback is fired, with two arguments : + * + * - the JSON object decoded as a PHP object + * + * - a couchClient instance to use to make queries inside the callback + * + * If the callable returns the boolean false , continuous reading stops. + * + * @param callable $callable PHP function name / callable array ( see http://php.net/is_callable ) + * @param string $method HTTP method to use (GET, POST, ...) + * @param string $url URL to fetch + * @param array $parameters additionnal parameters to send with the request + * @param string|array|object $data request body + * + * @return string|false server response on success, false on error + * + * @throws Exception|InvalidArgumentException|CouchException|CouchNoResponseException + */ + public function continuousQuery($callable, $method, $url, $parameters = [], $data = null) + { + return $this->getAdapter()->continuousQuery($callable, $method, $url, $parameters, $data); + } }