A simple PHP extension for CouchDB.
-
libcurl
-
PHP 8 or newer
-
async.h
Because couchdb is an extension built on top of libcurl, installation of said utility is a mandatory prerequisite for using this tool.
Installing libcurl can be done by typing the following in a console of your choosing.
$ sudo apt-get install libcurl4-openssl-dev
The asynchrony in the couchdb extension - that powers its transaction feature - is a caller-based fork-join model. Considering couchdb
cannot work without async.h, you will have to install the library in any one of several possible global include directories (/usr/include
, /usr/local/include
, /usr/local/opt/include
).
You can install the said library - by executing the async.sh
shell script in this project's root directory - by typing the following.
$ chmod a+x async.sh
$ ./async.sh
If you have downloaded the library yourself, you can supply the path to the library directory - directly to the async.sh
script - as a command line argument.
$ ./async.sh path/to/async.h
Upon successfully installing each of the aforedescribed dependencies, proceed to type the following to install couchdb
.
$ phpize
$ ./configure --enable-couchdb --with-curl="/path/to/libcurl"
$ make && sudo make install
Remember to add the
couchdb
shared object file (extension=couchdb
) to yourphp.ini
file to operationalize the extension.
If you intend to run the tests, the following should suffice.
$ make test
The snippet below demonstrates how to configure CouchDB for local installations, determine if the service is available - and subsequently generate five Universally Unique Identifiers (UUIDs).
$basic = CouchDb::connect();
if (!$basic->isAvailable()) {
exit();
}
echo $basic->uuids(5);
class CouchDb
{
/* Constants */
public const RETURN_ARRAY;
public const RETURN_JSON;
/* Methods */
public static connect( array $config ) : CouchDb;
public session() : CouchDb;
public isAvailable() : bool;
public uuids( int $count ) : string|array;
public databases() : string|array;
public database( string $database ) : string|array;
public createDatabase( string $database ) : bool;
public deleteDatabase( string $database ) : bool;
public insertDocuments( string $database [, array $documents ] ) : bool;
public document( string $database [, string $documentId ] ) : string|array;
public documents( string $database [, array $keys = null ] ) : string|array;
public updateDocuments( string $database [, array $documents ] ) : bool;
public deleteDocuments( string $database [, array $documents ] ) : bool;
public find( string $database [, array $query ] ) : string|array;
public createIndex( string $database [, array $options ] ) : bool;
public createDesignDocument( string $database [, string $designDocument [, array $options ]] ) : bool;
public view( string $database [, string $designDocument [, string $view [, array $options ]]] ) : string|array;
public changes( string $database [, array $options = null ] ) : bool;
public transaction( array $transactions ) : array;
}
Parametrically instantiates the CouchDb class.
public CouchDb::connect(array $config);
Establishes the parameters for Basic Auth-enabled CouchDB interactions.
- config (array) - List of configuration options
- host (string) - Base URI for CouchDB interactions
- user (string) - Arbitrary CouchDB username
- pass (string) - Arbitrary CouchDB password
- port (string) - CouchDB port
- timeout (string) - Timeout for requests made to CouchDB server
- type (integer) - Return type for request data
// default parameters
$basic = CouchDb::connect(
[
'host' => 'http://127.0.0.1',
'user' => '',
'pass' => '',
'token' => '',
'port' => 5984,
'timeout' => 60,
'type' => CouchDb::RETURN_JSON,
],
);
Retrieves auth token from CouchDB.
public CouchDb::session();
This method effectively exchanges the user
and password
information specified in class instantiation for an auth token and thence places the said token in the CouchDb object's parameterized state. It jettisons previously assigned user
and password
information.
session
persists all non-credential configuration from a previousconnect
call and is an opt-in feature.
None
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
'type' => CouchDb::RETURN_ARRAY,
],
);
$session = $basic->session();
Checks if a CouchDB instance is available the specified address.
public CouchDb::available();
None
$basic = CouchDb::connect();
if ($basic->available()) {
echo 'Up and running!' . PHP_EOL;
}
Retrieves, from CouchDB, a specified number of Universally Unique Identifiers (UUIDs).
public CouchDb::uuids(int $count);
- count (integer) - The number of UUIDs to generate
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
echo $basic->uuids(2);
Creates a new database.
public CouchDb::createDatabase(string $database);
- database (string) - The name of the database to create
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
if ($basic->createDatabase('recipes')) {
echo 'Database created' . PHP_EOL;
}
Returns a list containing the names of all the databases available to a user.
public CouchDb::databases();
None
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
echo $basic->databases();
Retrieves information about a specified database.
public CouchDb::database(string $database);
- database (string) - The name of the database the information about which you intend to retrieve
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
echo $basic->database('recipes');
Deletes a specified database.
public CouchDb::deleteDatabase(string $database);
- database (string) - The database you intend to delete
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
$session = $basic->session();
if ($session->deleteDatabase('vehicles')) {
echo 'Successfully purged!' . PHP_EOL;
}
Retrieves the contents of a specified document.
public CouchDb::document(string $database, string $documentId);
- database (string) - The database from which to retrieve the document
- documentId (string) - The unique identifier (
_id
) of the document whose information is to be retrieved
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
'type' => CouchDb::RETURN_ARRAY,
],
);
$session = $basic->session();
echo $session->document('recipes', 'BeefStew');
Retrieves several documents in a single call.
public CouchDb::documents(string $database, array $keys = null);
The method retrieves all documents in a specified database if a set of keys is not specified.
- database (string) - The database from which you intend to retrieve a set of documents
- keys (array) - A list of document identifiers with which to tune the server response
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
echo $basic->documents('recipes', ['FishStew', 'LambStew']);
Creates multiple documents.
public CouchDb::insertDocuments(string $database, array $documents);
- database (string) - The database in which to insert documents
- documents (array) - The document data to insert into a specified database
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
$session = $basic->session();
if (
$session->insertDocuments(
'recipes',
[
[
'_id' => 'FishStew',
'subtitle' => 'Delicious with freshly baked bread',
],
[
'_id' => 'LambStew',
'subtitle' => 'Serve with a whole meal scone topping',
],
],
)
) {
echo 'Documents successfully created!' . PHP_EOL;
}
Updates multiple documents.
public updateDocuments(string $database, array $documents);
- database (string) - The database whose documents you intend to modify
- documents (array) - The list of contents, inclusive of
_id
and_rev
keys with which to update entries in a database
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
if (
$basic->updateDocuments(
'recipes',
[
[
'_id' => 'FishStew',
'_rev' => '1-41669894c7d25a634f5de4fef75fb982',
'servings' => 4,
],
[
'_id' => 'LambStew',
'_rev' => '1-599acfa0c7b36889599bde56276e444c',
'servings' => 6,
],
],
)
) {
echo 'Database successfully updated!' . PHP_EOL;
}
Deletes multiple documents.
public deleteDocuments(string $database, array $documents);
- database (string) - The database whose documents you intend to delete
- documents (array) - The list containing
_id
and_rev
keys of the documents you intend to delete
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
$session = $basic->session();
if (
$session->deleteDocuments(
'recipes',
[
[
'_id' => 'Pilau',
'_rev' => '1-599acfa0c7b36889599bde56276e444c',
],
[
'_id' => 'Katogo',
'_rev' => '1-41669894c7d25a634f5de4fef75fb982',
],
],
)
) {
echo 'Documents successfully deleted!' . PHP_EOL;
}
Performs a parameterized Mango Query-powered database search.
public CouchDb::find(string $database, array $query);
- database (string) - The database on which you intend to perform the search
- query (array) - The database query parameters
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
'type' => CouchDb::RETURN_ARRAY,
],
);
echo $basic->find(
'recipes',
[
'execution_stats' => false,
'fields' => ['_id', 'servings'],
'selector' => [
'_id' => ['$regex' => '(?i)eef'],
],
],
);
Creates a CouchDB index for a specified database.
public CouchDb::createIndex(string $database, array $options);
- database (string) - The database on which to define the index
- options (array) - The list of options with which to configure the index
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
$session = $basic->session();
if (
$session->createIndex(
'recipes',
[
'ddoc' => 'servings-index',
'type' => 'json',
'index' => [
'fields' => ['_id', 'servings', 'subtitle'],
],
],
)
) {
echo 'Index successfully created!' . PHP_EOL;
}
Creates a design document in a specified database.
public CouchDb::createDesignDocument(
string $database,
string $designDocument,
array $options
);
This method is especially useful for creating views the display parameters for which can be tuned via CouchDB map-reduce functions.
- database (string) - The database in which to create the design document
- designDocument (string) - The name of the design document
- options (array) - The list of options with which to configure the design document
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
if (
$basic->createDesignDocument(
'recipes',
'recipesDoc',
[
'language' => 'javascript',
'views' => [
'servings-view' => [
'map' => 'function (doc) { emit(doc._id, doc.servings) }'
],
],
],
)
) {
echo 'Successfully created design document' . PHP_EOL;
}
Queries a view and retrieves all the records it is configured to project.
public CouchDb::view(
string $database,
string $designDocument,
string $view
array $options = null
);
- database (string) - The database the data in which the view projects
- designDocument (string) - The identifier of the design document
- view (string) - The name of the view
- options (array) - Additional non-mandatory query options
$basic = CouchDb::connect(
[
'user' => 'admin',
'pass' => 'root',
],
);
$session = $basic->session();
echo $basic->view(
'recipes',
'recipesDoc',
'servings-view',
[
'descending' => true,
'conflicts' => false,
'update' => true,
],
);
Retrieves a history of all actions performed on a database.
public CouchDb::changes(string $database, array $options = null);
- database (string) - The database whose history you intend to track
- options (array) - A list of options with which to tune the CouchDB response
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
],
);
echo $basic->changes(
'recipes',
[
'conflicts' => true,
'include_docs' => true,
'descending' => true,
],
);
Concurrently executes multiple CouchDB actions in a fashion akin to transactions in SQL.
public CouchDb::transaction(array $actions);
This function throws an exception in situations where the requisite protothreads library is not installed.
- actions (array) - A list of PHP functions in which to subsume extension-supported CouchDB operations
$basic = CouchDb::connect(
[
'user' => 'root',
'pass' => 'admin',
'type' => CouchDb::RETURN_ARRAY,
],
);
$session = $basic->session();
print_r(
$session->transaction(
[
// create a database
fn () => $session->database('recipes'),
// insert documents in database
fn () =>
$session->insertDocuments(
'recipes',
[
[
'_id' => 'FishStew',
'servings' => 4,
'subtitle' => 'Delicious with freshly baked bread',
],
[
'_id' => 'LambStew',
'servings' => 6,
'subtitle' => 'Serve with a whole meal scone topping',
],
],
),
// create index
fn () =>
$session->createIndex(
'recipes',
[
'ddoc' => 'servings-index',
'type' => 'json',
'index' => [
'fields' => ['servings', 'subtitle'],
],
],
),
// create design document
fn () =>
$session->createDesignDocument(
'recipes',
'recipesDoc',
[
'language' => 'javascript',
'views' => [
'servings-view' => [
'map' => 'function (doc) { emit(doc._id, doc.servings) }'
],
],
],
),
],
),
);
Endeavor to create an issue on GitHub when the need arises or send an email to [email protected]
Consider buying me a coffee if you appreciate the offerings of the project and/or would like to provide more impetus for me to continue working on it.