mirror of
https://github.com/doctrine/KeyValueStore.git
synced 2026-03-24 16:52:17 +01:00
Compare commits
84 Commits
ReferenceL
...
v0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c174bdb7a | ||
|
|
bcf6d01c3f | ||
|
|
9fa9ffb5c6 | ||
|
|
b895ef4bca | ||
|
|
46be2da6eb | ||
|
|
1c02f0d875 | ||
|
|
4bebd86417 | ||
|
|
b8f709dd43 | ||
|
|
479258335d | ||
|
|
d168c890ac | ||
|
|
5ea631e50b | ||
|
|
9b600cc221 | ||
|
|
4309604e0a | ||
|
|
a5d3b1ca49 | ||
|
|
1af55b26bd | ||
|
|
2dd2d84cff | ||
|
|
66d7ba901f | ||
|
|
f164523b41 | ||
|
|
a275c44aa0 | ||
|
|
90cd03dbfd | ||
|
|
12c2abd9e4 | ||
|
|
12bfc80c81 | ||
|
|
a7771b6e58 | ||
|
|
a4ad1d1f43 | ||
|
|
c118048b81 | ||
|
|
11baf2e373 | ||
|
|
fb19abf8c2 | ||
|
|
48d611fb17 | ||
|
|
20d78eade9 | ||
|
|
c447e28a93 | ||
|
|
b3e42ba4f5 | ||
|
|
e53055b5b2 | ||
|
|
5de2e52135 | ||
|
|
780da5e7af | ||
|
|
1dec23f010 | ||
|
|
2d01d5b08c | ||
|
|
aebdfbcd49 | ||
|
|
f175e595db | ||
|
|
2c1b550d31 | ||
|
|
d315cec820 | ||
|
|
f43bed12ac | ||
|
|
5d9013d8ef | ||
|
|
8fe303c6f0 | ||
|
|
fa5e715d86 | ||
|
|
2269b27326 | ||
|
|
e72ef607ef | ||
|
|
a43f35c2ec | ||
|
|
3a39f01c83 | ||
|
|
e4b84b9558 | ||
|
|
992bdd1ac5 | ||
|
|
ee75cfee7b | ||
|
|
4bd4073206 | ||
|
|
0d7c5f02c6 | ||
|
|
a21f94d723 | ||
|
|
948f402c6f | ||
|
|
3ddf79a3d5 | ||
|
|
b0ef144d7e | ||
|
|
91f1752831 | ||
|
|
ad20d188e6 | ||
|
|
3ae0b7ead4 | ||
|
|
f942e51a6e | ||
|
|
c5b8c1931d | ||
|
|
e4e5e14a79 | ||
|
|
20687435bd | ||
|
|
479e2cf739 | ||
|
|
46f58250de | ||
|
|
066b047c13 | ||
|
|
aea2dadbc4 | ||
|
|
801400d4e9 | ||
|
|
c7050ddb96 | ||
|
|
f8c3d9d725 | ||
|
|
f4ba01af29 | ||
|
|
76530e8b5d | ||
|
|
692e0ca38d | ||
|
|
2c1a79a3ea | ||
|
|
995d06fbc5 | ||
|
|
9fb87141b8 | ||
|
|
9bdb28fe3c | ||
|
|
0f974c26d2 | ||
|
|
208936d26a | ||
|
|
c277f42c8f | ||
|
|
b5cc4ee7c3 | ||
|
|
cbbcffaade | ||
|
|
b88ed9e58f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
vendor
|
||||
*phpunit.xml
|
||||
docs/_build
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "docs/_theme"]
|
||||
path = docs/_theme
|
||||
url = git://github.com/doctrine/doctrine-sphinx-theme.git
|
||||
151
README.md
151
README.md
@@ -1,8 +1,6 @@
|
||||
# Doctrine Key Value Stores
|
||||
|
||||
This is a work in progress design document for this component
|
||||
|
||||
The Persistence interfaces are rather overkill for many implementations in the NoSQL world that are only key-value stores with some additional features on top. Doctrine Key Value Store for the rescue. This project offers a much simpler lightweight API that is centered on a key-value API to fetch/save objects.
|
||||
The Persistence interfaces are rather overkill for many implementations in the NoSQL world that are only key-value stores with some additional features on top. Doctrine Key Value Store to the rescue. This project offers a much simpler lightweight API that is centered on a key-value API to fetch/save objects.
|
||||
|
||||
* Single- or multi-value primary keys
|
||||
* Unstructured/schema-less values that are mapped onto objects
|
||||
@@ -22,11 +20,12 @@ Following vendors are targeted:
|
||||
* Microsoft Azure Table (Implemented)
|
||||
* Doctrine\Common\Cache provider (Implemented)
|
||||
* RDBMS (Implemented)
|
||||
* Couchbase
|
||||
* Couchbase (Implemented)
|
||||
* Amazon DynamoDB
|
||||
* CouchDB
|
||||
* MongoDB
|
||||
* Riak
|
||||
* MongoDB (Implemented)
|
||||
* Riak (Implemented)
|
||||
* Redis (Implemented)
|
||||
|
||||
We happily accept contributions for any of the drivers.
|
||||
|
||||
@@ -34,39 +33,67 @@ We happily accept contributions for any of the drivers.
|
||||
|
||||
Suppose we track e-mail campaigns based on campaign id and recipients.
|
||||
|
||||
use Doctrine\KeyValueStore\Mapping\Annotations as KeyValue;
|
||||
```php
|
||||
<?php
|
||||
use Doctrine\KeyValueStore\Mapping\Annotations as KeyValue;
|
||||
|
||||
/**
|
||||
* @KeyValue\Entity(storageName="responses")
|
||||
*/
|
||||
class Response
|
||||
/**
|
||||
* @KeyValue\Entity(storageName="responses")
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
const RECEIVE = 0;
|
||||
const OPEN = 10;
|
||||
const CLICK = 20;
|
||||
const ACTION = 30;
|
||||
|
||||
/** @KeyValue\Id */
|
||||
private $campaign;
|
||||
/** @KeyValue\Id */
|
||||
private $recipient;
|
||||
private $status;
|
||||
private $date;
|
||||
|
||||
public function __construct($campaign, $recipient, $status)
|
||||
{
|
||||
const RECIEVE = 0;
|
||||
const OPEN = 10;
|
||||
const CLICK = 20;
|
||||
const ACTION = 30;
|
||||
|
||||
/** @KeyValue\Id */
|
||||
private $campaign;
|
||||
/** @KeyValue\Id */
|
||||
private $recipient;
|
||||
private $status;
|
||||
private $date;
|
||||
|
||||
public function __construct($campaign, $recipient, $status)
|
||||
{
|
||||
$this->campaign = $campaign;
|
||||
$this->recipient = $recipient;
|
||||
$this->status = $status;
|
||||
}
|
||||
$this->campaign = $campaign;
|
||||
$this->recipient = $recipient;
|
||||
$this->status = $status;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
$response = new Response("1234", "kontakt@beberlei.de", Response::RECIEVE);
|
||||
### Create
|
||||
|
||||
$entityManager->persist($response);
|
||||
//.... persists as much as you can :-)
|
||||
```php
|
||||
<?php
|
||||
$response = new Response("1234", "kontakt@beberlei.de", Response::RECEIVE);
|
||||
|
||||
$entityManager->flush();
|
||||
$entityManager->persist($response);
|
||||
//.... persists as much as you can :-)
|
||||
|
||||
$entityManager->flush();
|
||||
```
|
||||
|
||||
### Read
|
||||
|
||||
```php
|
||||
<?php
|
||||
$response = $entityManager->find("Response",array("campaign" => "1234","recipient" => "kontakt@beberlei.de"));
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
same as create, just reuse the same id.
|
||||
|
||||
### Delete
|
||||
|
||||
```php
|
||||
<?php
|
||||
$response = $entityManager->find("Response",array("1234","kontakt@beberlei.de"));
|
||||
$entityManager->remove($response);
|
||||
$entityManager->flush();
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -74,37 +101,49 @@ There is no factory yet that simplifies the creation process, here is the
|
||||
full code necessary to instantiate a KeyValue EntityManager with a Doctrine
|
||||
Cache backend:
|
||||
|
||||
use Doctrine\KeyValueStore\EntityManager;
|
||||
use Doctrine\KeyValueStore\Mapping\AnnotationDriver;
|
||||
use Doctrine\KeyValueStore\Storage\DoctrineCacheStorage;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
```php
|
||||
<?php
|
||||
use Doctrine\KeyValueStore\EntityManager;
|
||||
use Doctrine\KeyValueStore\Configuration;
|
||||
use Doctrine\KeyValueStore\Mapping\AnnotationDriver;
|
||||
use Doctrine\KeyValueStore\Storage\DoctrineCacheStorage;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
|
||||
$storage = new DoctrineCacheStorage($cache);
|
||||
$cache = new ArrayCache;
|
||||
$metadata = new AnnotationDriver(new AnnotationReader);
|
||||
$entityManager = new EntityManager($storage, $cache, $metadata);
|
||||
$cache = new ArrayCache;
|
||||
$storage = new DoctrineCacheStorage($cache);
|
||||
|
||||
$reader = new AnnotationReader();
|
||||
$metadata = new AnnotationDriver($reader);
|
||||
$config = new Configuration();
|
||||
$config->setMappingDriverImpl($metadata);
|
||||
$config->setMetadataCache($cache);
|
||||
|
||||
$entityManager = new EntityManager($storage, $config);
|
||||
```
|
||||
|
||||
If you want to use WindowsAzure Table you can use the following configuration
|
||||
to instantiate the storage:
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\WindowsAzureTableStorage;
|
||||
use Doctrine\KeyValueStore\Storage\WindowsAzureTable\SharedKeyLiteAuthorization;
|
||||
use Doctrine\KeyValueStore\Http\SocketClient;
|
||||
```php
|
||||
use Doctrine\KeyValueStore\Storage\AzureSdkTableStorage;
|
||||
use WindowsAzure\Common\ServicesBuilder;
|
||||
|
||||
$name = ""; // Windows Azure Storage Account Name
|
||||
$key = ""; // Windows Azure Storage Account Key
|
||||
$connectionString = ""; // Windows Azure Connection string
|
||||
$builder = ServicesBuilder::getInstance();
|
||||
$client = $builder->createTableService($connectionString);
|
||||
|
||||
$auth = new SharedKeyLiteAuthorization($name, $key);
|
||||
$storage = new WindowsAzureTableStorage(new SocketClient(), $name, $auth);
|
||||
$storage = new AzureSdkTableStorage($client);
|
||||
```
|
||||
|
||||
If you want to use Doctrine DBAL as backend:
|
||||
|
||||
$params = array();
|
||||
$tableName = "storage";
|
||||
$idColumnName = "id";
|
||||
$dataColumnName = "serialized_data";
|
||||
|
||||
$conn = DriverManager::getConnection($params);
|
||||
$storage = new DBALStorage($conn, $tableName, $idColumnName, $dataColumnName);
|
||||
```php
|
||||
$params = array();
|
||||
$tableName = "storage";
|
||||
$idColumnName = "id";
|
||||
$dataColumnName = "serialized_data";
|
||||
|
||||
$conn = DriverManager::getConnection($params);
|
||||
$storage = new DBALStorage($conn, $tableName, $idColumnName, $dataColumnName);
|
||||
```
|
||||
|
||||
@@ -3,6 +3,23 @@
|
||||
"require": {
|
||||
"doctrine/common": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"riak/riak-client": "dev-master",
|
||||
"microsoft/windowsazure": "dev-master"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "pear",
|
||||
"url": "http://pear.php.net"
|
||||
}
|
||||
],
|
||||
"suggest": {
|
||||
"riak/riak-client": "to use the Riak storage",
|
||||
"ext-couchbase": "to use the Couchbase storage",
|
||||
"aws/aws-sdk-php": "to use the DynamoDB storage"
|
||||
},
|
||||
"description": "Simple Key-Value Store Abstraction Layer that maps to PHP objects, allowing for many backends.",
|
||||
"license": "MIT",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\KeyValueStore\\": "lib/"
|
||||
|
||||
753
composer.lock
generated
753
composer.lock
generated
@@ -1,9 +1,752 @@
|
||||
{
|
||||
"hash": "09b80610c08784c764e1df9edca9b53f",
|
||||
"hash": "bf53cb71537abb0dbed5002bbc4411f1",
|
||||
"packages": [
|
||||
{
|
||||
"package": "doctrine\/common",
|
||||
"version": "master-dev"
|
||||
"name": "doctrine/annotations",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/annotations.git",
|
||||
"reference": "v1.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/annotations/archive/v1.0.zip",
|
||||
"reference": "v1.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"doctrine/lexer": "1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "1.*"
|
||||
},
|
||||
"time": "2013-01-12 19:23:32",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Annotations\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Docblock Annotations Parser",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"annotations",
|
||||
"parser",
|
||||
"docblock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "v1.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/cache/archive/v1.0.zip",
|
||||
"reference": "v1.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"time": "2013-01-10 22:43:46",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Caching library offering an object-oriented API for many cache backends",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/collections.git",
|
||||
"reference": "v1.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/collections/archive/v1.0.zip",
|
||||
"reference": "v1.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"time": "2013-01-12 16:36:50",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Collections\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Collections Abstraction library",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"collections",
|
||||
"iterator",
|
||||
"array"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/common",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/common",
|
||||
"reference": "f0b548aa55bb7dac36d79061270a085dd38635b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/common/archive/a5482b347530bb8522e355b399e5ff4983433a40.zip",
|
||||
"reference": "a5482b347530bb8522e355b399e5ff4983433a40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"doctrine/inflector": "1.*",
|
||||
"doctrine/cache": "1.*",
|
||||
"doctrine/collections": "1.*",
|
||||
"doctrine/lexer": "1.*",
|
||||
"doctrine/annotations": "1.*"
|
||||
},
|
||||
"time": "2012-06-18 14:14:07",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Common Library for Doctrine projects",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"collections",
|
||||
"spl",
|
||||
"eventmanager",
|
||||
"annotations",
|
||||
"persistence"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/inflector.git",
|
||||
"reference": "v1.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/inflector/archive/v1.0.zip",
|
||||
"reference": "v1.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"time": "2013-01-10 21:49:15",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Inflector\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"string",
|
||||
"inflection",
|
||||
"singuarlize",
|
||||
"pluarlize"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/lexer.git",
|
||||
"reference": "v1.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/doctrine/lexer/archive/v1.0.zip",
|
||||
"reference": "v1.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"time": "2013-01-12 18:59:04",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Lexer\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"parser",
|
||||
"lexer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "microsoft/windowsazure",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/WindowsAzure/azure-sdk-for-php",
|
||||
"reference": "d8daa05ad1852e0c70a85d15a6db88f7e3b23405"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/WindowsAzure/azure-sdk-for-php/archive/d8daa05ad1852e0c70a85d15a6db88f7e3b23405.zip",
|
||||
"reference": "d8daa05ad1852e0c70a85d15a6db88f7e3b23405",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"pear-pear/http_request2": "*",
|
||||
"pear-pear/mail_mime": "*",
|
||||
"pear-pear/mail_mimedecode": "*"
|
||||
},
|
||||
"time": "2012-12-17 23:41:42",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"WindowsAzure\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Azure PHP SDK",
|
||||
"email": "azurephpsdk@microsoft.com"
|
||||
}
|
||||
],
|
||||
"description": "This project provides a set of PHP client libraries that make it easy to access Windows Azure tables, blobs, queues, service runtime and service management APIs.",
|
||||
"keywords": [
|
||||
"php",
|
||||
"sdk",
|
||||
"azure"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Archive_Tar",
|
||||
"version": "1.3.10",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Archive_Tar-1.3.10.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.3.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/archive_tar": "== 1.3.10.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "This class provides handling of tar files in PHP.\nIt supports creating, listing, extracting and adding to tar files.\nGzip support is available if PHP has the zlib extension built-in or\nloaded. Bz2 compression is also supported with the bz2 extension loaded."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Console_Getopt",
|
||||
"version": "1.3.1",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Console_Getopt-1.3.1.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.3.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/console_getopt": "== 1.3.1.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "This is a PHP implementation of "getopt" supporting both\nshort and long options."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/HTTP_Request2",
|
||||
"version": "2.1.1",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/HTTP_Request2-2.1.1.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0.0",
|
||||
"pear-pear.php.net/net_url2": ">=2.0.0.0",
|
||||
"pear-pear.php.net/pear": ">=1.9.2.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/http_request2": "== 2.1.1.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "PHP5 rewrite of HTTP_Request package (with parts of HTTP_Client). Provides\ncleaner API and pluggable Adapters:\n * Socket adapter, based on old HTTP_Request code,\n * Curl adapter, wraps around PHP's cURL extension,\n * Mock adapter, to use for testing packages dependent on HTTP_Request2.\nSupports POST requests with data and file uploads, basic and digest\nauthentication, cookies, managing cookies across requests, proxies, gzip and\ndeflate encodings, redirects, monitoring the request progress with Observers..."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Mail_Mime",
|
||||
"version": "1.8.7",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Mail_Mime-1.8.7.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.3.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/mail_mime": "== 1.8.7.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "Mail_Mime provides classes to deal with the creation and manipulation of MIME messages.\nIt allows people to create e-mail messages consisting of:\n* Text Parts\n* HTML Parts\n* Inline HTML Images\n* Attachments\n* Attached messages\n\nIt supports big messages, base64 and quoted-printable encodings and\nnon-ASCII characters in filenames, subjects, recipients, etc. encoded\nusing RFC2047 and/or RFC2231."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Mail_mimeDecode",
|
||||
"version": "1.5.5",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Mail_mimeDecode-1.5.5.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.3.0.0",
|
||||
"pear-pear.php.net/mail_mime": ">1.4.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/mail_mimedecode": "== 1.5.5.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "Provides a class to deal with the decoding and interpreting of mime messages.\n This package used to be part of the Mail_Mime package, but has been split off."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Net_URL2",
|
||||
"version": "2.0.0",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Net_URL2-2.0.0.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.0.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/net_url2": "== 2.0.0.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "Provides parsing of URLs into their constituent parts (scheme, host, path etc.), URL generation, and resolving of relative URLs."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/PEAR",
|
||||
"version": "1.9.4",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/PEAR-1.9.4.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.4.0.0,!=5.0.0.0,!=5.1.0.0,!=5.1.1.0,!=5.1.2.0,!=5.1.3.0,!=5.1.4.0,!=5.1.5.0",
|
||||
"pear-pear.php.net/archive_tar": ">=1.3.7.0",
|
||||
"pear-pear.php.net/structures_graph": ">=1.0.2.0",
|
||||
"pear-pear.php.net/console_getopt": ">=1.2.0.0",
|
||||
"pear-pear.php.net/xml_util": ">=1.2.0.0",
|
||||
"ext-xml": "*",
|
||||
"ext-pcre": "*"
|
||||
},
|
||||
"conflict": {
|
||||
"pear-pear.php.net/pear_frontend_web": "<=0.4.0.0",
|
||||
"pear-pear.php.net/pear_frontend_gtk": "<0.4.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/pear": "== 1.9.4.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "The PEAR package contains:\n * the PEAR installer, for creating, distributing\n and installing packages\n * the PEAR_Exception PHP5 error handling mechanism\n * the PEAR_ErrorStack advanced error handling mechanism\n * the PEAR_Error error handling mechanism\n * the OS_Guess class for retrieving info about the OS\n where PHP is running on\n * the System class for quick handling of common operations\n with files and directories\n * the PEAR base class\n Features in a nutshell:\n * full support for channels\n * pre-download dependency validation\n * new package.xml 2.0 format allows tremendous flexibility while maintaining BC\n * support for optional dependency groups and limited support for sub-packaging\n * robust dependency support\n * full dependency validation on uninstall\n * remote install for hosts with only ftp access - no more problems with\n restricted host installation\n * full support for mirroring\n * support for bundling several packages into a single tarball\n * support for static dependencies on a url-based package\n * support for custom file roles and installation tasks"
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/Structures_Graph",
|
||||
"version": "1.0.4",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/Structures_Graph-1.0.4.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.2.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/structures_graph": "== 1.0.4.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed\nand undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing\nas well as for characteristic extraction from the graph topology."
|
||||
},
|
||||
{
|
||||
"name": "pear-pear.php.net/XML_Util",
|
||||
"version": "1.2.1",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "http://pear.php.net/get/XML_Util-1.2.1.tgz",
|
||||
"reference": null,
|
||||
"shasum": null
|
||||
},
|
||||
"require": {
|
||||
"php": ">=4.3.0.0",
|
||||
"ext-pcre": "*"
|
||||
},
|
||||
"replace": {
|
||||
"pear-pear/xml_util": "== 1.2.1.0"
|
||||
},
|
||||
"type": "pear-library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
""
|
||||
]
|
||||
},
|
||||
"include-path": [
|
||||
"/"
|
||||
],
|
||||
"description": "Selection of methods that are often needed when working with XML documents. Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more."
|
||||
},
|
||||
{
|
||||
"name": "riak/riak-client",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nacmartin/riak-client",
|
||||
"reference": "cea446f04d759caaef44020a2064a38b41cbdfab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/nacmartin/riak-client/archive/cea446f04d759caaef44020a2064a38b41cbdfab.zip",
|
||||
"reference": "cea446f04d759caaef44020a2064a38b41cbdfab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"time": "2012-04-29 11:47:45",
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Riak": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache 2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nacho Martín",
|
||||
"email": "nitram.ohcan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Kevin Burns"
|
||||
},
|
||||
{
|
||||
"name": "Jeffrey Massung"
|
||||
},
|
||||
{
|
||||
"name": "Mark Phillips"
|
||||
},
|
||||
{
|
||||
"name": "Bryank Fink"
|
||||
},
|
||||
{
|
||||
"name": "Abel Perez"
|
||||
},
|
||||
{
|
||||
"name": "Scoyy Lystig Fritchie"
|
||||
},
|
||||
{
|
||||
"name": "Jon Meredith"
|
||||
},
|
||||
{
|
||||
"name": "dreverri"
|
||||
},
|
||||
{
|
||||
"name": "fakepop"
|
||||
}
|
||||
],
|
||||
"description": "Riak client",
|
||||
"homepage": "http://wiki.basho.com/Riak.html",
|
||||
"keywords": [
|
||||
"persistence",
|
||||
"riak"
|
||||
]
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"riak/riak-client": 20,
|
||||
"microsoft/windowsazure": 20
|
||||
}
|
||||
}
|
||||
|
||||
153
docs/Makefile
Normal file
153
docs/Makefile
Normal file
@@ -0,0 +1,153 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DoctrineKeyValueStore.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DoctrineKeyValueStore.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/DoctrineKeyValueStore"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DoctrineKeyValueStore"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
1
docs/_theme
Submodule
1
docs/_theme
Submodule
Submodule docs/_theme added at 5aa024c928
242
docs/conf.py
Normal file
242
docs/conf.py
Normal file
@@ -0,0 +1,242 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Doctrine KeyValueStore documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Jan 27 16:47:49 2013.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sys, os
|
||||
|
||||
# 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.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- 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 = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Doctrine KeyValueStore'
|
||||
copyright = u'2013, Doctrine Team'
|
||||
|
||||
# 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 = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- 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 = 'doctrine'
|
||||
|
||||
# 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 themes here, relative to this directory.
|
||||
html_theme_path = ['_theme']
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# 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']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'DoctrineKeyValueStoredoc'
|
||||
|
||||
|
||||
# -- 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': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'DoctrineKeyValueStore.tex', u'Doctrine KeyValueStore Documentation',
|
||||
u'Doctrine Team', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'doctrinekeyvaluestore', u'Doctrine KeyValueStore Documentation',
|
||||
[u'Doctrine Team'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- 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 = [
|
||||
('index', 'DoctrineKeyValueStore', u'Doctrine KeyValueStore Documentation',
|
||||
u'Doctrine Team', 'DoctrineKeyValueStore', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
17
docs/index.rst
Normal file
17
docs/index.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
Welcome to Doctrine KeyValueStore's documentation!
|
||||
==================================================
|
||||
|
||||
The Doctrine KeyValueStore project allows you to map PHP Objects
|
||||
to a large number of key-value databases. To some degree these
|
||||
databases are exchangeable, when working on a CRUD level.
|
||||
|
||||
For some databases range queries are also supported that allow
|
||||
you to do range queries with parititioning.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
reference/configuration
|
||||
|
||||
190
docs/make.bat
Normal file
190
docs/make.bat
Normal file
@@ -0,0 +1,190 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\DoctrineKeyValueStore.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\DoctrineKeyValueStore.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
142
docs/reference/configuration.rst
Normal file
142
docs/reference/configuration.rst
Normal file
@@ -0,0 +1,142 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The configuration of the KeyValueStore consists of two steps.
|
||||
|
||||
* Mapping Configuration
|
||||
* Storage Configuration
|
||||
|
||||
Mapping Configuration
|
||||
---------------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\KeyValueStore\Configuration;
|
||||
use Doctrine\KeyValueStore\Mapping\AnnotationDriver;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
|
||||
// 1. create Configuration instance
|
||||
$config = new Configuration();
|
||||
|
||||
// 2. Caching for Metadata
|
||||
$cache = new ArrayCache();
|
||||
$config->setMetadataCache($cache);
|
||||
|
||||
// 3. Annotation Metadata Driver
|
||||
$reader = new AnnotationReader();
|
||||
$metadata = new AnnotationDriver($reader);
|
||||
$config->setMappingDriverImpl($metadata);
|
||||
|
||||
The mapping configuration is handled through a configuration object.
|
||||
|
||||
1. In the first step, a configuration object is created.
|
||||
2. We need a caching mechanism for the configuration for performance. This
|
||||
should be different in development and production. The ``ArrayCache`` is a
|
||||
request-based cache, which is useful in development. Have a look at the
|
||||
`Doctrine Common documentation
|
||||
<http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/caching.html>`_
|
||||
for production caches.
|
||||
3. Finally you have to create a metadata driver, in this example the
|
||||
``AnnotationDriver`` that allows configurating mapping with Docblock
|
||||
annotations.
|
||||
|
||||
Storage Configuration
|
||||
---------------------
|
||||
|
||||
Independent from the mapping configuration, which is the same for all key-value
|
||||
database backends, you have to configure the actual storage you want to use.
|
||||
|
||||
This configuration is obviously specific to all the different storage drivers.
|
||||
So far the following drivers exist (and are documented here):
|
||||
|
||||
* Doctrine Cache Backend
|
||||
* SQL Backend with Doctrine DBAL
|
||||
* Microsoft Windows Azure Table
|
||||
* Couchbase
|
||||
* MongoDB
|
||||
* Riak
|
||||
|
||||
Also all those storage backends obviously have different dependencies in terms
|
||||
of PHP libraries or PHP PECL extensions.
|
||||
|
||||
Doctrine Cache Backend
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The Doctrine Cache Backend uses the `Caching Framework
|
||||
<https://github.com/doctrine/cache>`_ from Doctrine as a backend. Depending on
|
||||
the cache driver you get a persistent or in-memory key value store with this
|
||||
solution. See the `Doctrine Common documentation
|
||||
<http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/caching.html>`_
|
||||
for more details about the different supported drivers.
|
||||
|
||||
Here is an example of configurating the Cache Storage using Redis:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\Common\Cache\RedisCache;
|
||||
use Doctrine\KeyValueStore\Storage\DoctrineCacheStorage;
|
||||
use Redis;
|
||||
|
||||
$conn = new Redis(/** connection **/);
|
||||
$cache = new RedisCache();
|
||||
$cache->setRedis($conn);
|
||||
$storage = new DoctrineCacheStorage($cache);
|
||||
|
||||
Doctrine DBAL Backend
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use a relational database as backend. It uses a very simple
|
||||
table as storage with one primary key and a blob field that stores
|
||||
the properties.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\KeyValueStore\Storage\DBALStorage;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
|
||||
$tableName = 'storage';
|
||||
$keyColumn = 'id';
|
||||
$dataColumn = 'serialized_data';
|
||||
|
||||
$conn = DriverManager::getConnection(array(
|
||||
// configuration
|
||||
));
|
||||
$storage = new DBALStorage($conn, $tableName, $keyColumn, $dataColumn);
|
||||
|
||||
Microsoft Windows Azure Table
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Microsoft offers a NoSQL solution as part of their `Windows Azure
|
||||
<http://www.windowsazure.com/en-us/>`_ service. You can use that
|
||||
as a storage layer through the Windows Azure PHP SDK:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\KeyValueStore\Storage\AzureSdkTableStorage;
|
||||
use WindowsAzure\Common\ServicesBuilder;
|
||||
|
||||
$connectionString = ""; // Windows Azure Connection string
|
||||
$builder = ServicesBuilder::getInstance();
|
||||
$client = $builder->createTableService($connectionString);
|
||||
|
||||
$storage = new AzureSdkTableStorage($client);
|
||||
|
||||
Couchbase
|
||||
^^^^^^^^^
|
||||
|
||||
To be written
|
||||
|
||||
MongoDB
|
||||
^^^^^^^
|
||||
|
||||
To be written
|
||||
|
||||
Riak
|
||||
^^^^
|
||||
|
||||
to be written
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Doctrine\KeyValueStore;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\KeyValueStore\Id\IdConverterStrategy;
|
||||
use Doctrine\KeyValueStore\Id\NullIdConverter;
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -22,8 +22,6 @@ namespace Doctrine\KeyValueStore;
|
||||
use Doctrine\KeyValueStore\Storage\Storage;
|
||||
use Doctrine\KeyValueStore\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\KeyValueStore\Query\RangeQuery;
|
||||
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
|
||||
/**
|
||||
* EntityManager for KeyValue stored objects.
|
||||
@@ -33,12 +31,12 @@ use Doctrine\Common\Cache\Cache;
|
||||
class EntityManager
|
||||
{
|
||||
/**
|
||||
* @var Doctrine\KeyValueStore\UnitOfWork
|
||||
* @var UnitOfWork
|
||||
*/
|
||||
private $unitOfWork;
|
||||
|
||||
/**
|
||||
* @var Doctrine\KeyValueStore\Storage\Storage
|
||||
* @var Storage
|
||||
*/
|
||||
private $storageDriver;
|
||||
|
||||
@@ -119,7 +117,7 @@ class EntityManager
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine\KeyValueStore\Storage\Storage
|
||||
* @return Storage
|
||||
*/
|
||||
public function unwrap()
|
||||
{
|
||||
@@ -141,11 +139,11 @@ class EntityManager
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @return \Doctrine\KeyValueStore\Mapping\ClassMetadata
|
||||
* @return Mapping\ClassMetadata
|
||||
*/
|
||||
public function getClassMetadata($className)
|
||||
{
|
||||
return $this->unitOfwork->getClassMetadata($className);
|
||||
return $this->unitOfWork->getClassMetadata($className);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
namespace Doctrine\KeyValueStore\Http;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -59,7 +59,7 @@ class AnnotationDriver implements MappingDriver
|
||||
if ($idAnnot) {
|
||||
$metadata->mapIdentifier($property->getName());
|
||||
} else if ($transientAnnot) {
|
||||
$metdata->skipTransientField($property->getName());
|
||||
$metadata->skipTransientField($property->getName());
|
||||
} else {
|
||||
$metadata->mapField(array('fieldName' => $property->getName()));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,9 @@ class ClassMetadata implements BaseClassMetadata
|
||||
|
||||
public function skipTransientField($fieldName)
|
||||
{
|
||||
// it's necessary to unset because ClassMetadataFactory::initializeReflection has already run
|
||||
// and the fields have all been mapped -- even the transient ones
|
||||
unset($this->fields[$fieldName]);
|
||||
$this->transientFields[$fieldName] = true;
|
||||
}
|
||||
|
||||
@@ -75,7 +78,7 @@ class ClassMetadata implements BaseClassMetadata
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return array('fields', 'isCompositeKey', 'identifier', 'name');
|
||||
return array('fields', 'isCompositeKey', 'identifier', 'name', 'storageName');
|
||||
}
|
||||
|
||||
public function getIdentifierValues($object)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
throw new \InvalidArgumentException("aliasing is not supported.");
|
||||
}
|
||||
|
||||
protected function doLoadMetadata($class, $parent, $rootEntityFound)
|
||||
protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
|
||||
{
|
||||
$this->getDriver()->loadMetadataForClass($class->name, $class);
|
||||
|
||||
@@ -94,5 +94,13 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* copied from doctrine/common - tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php
|
||||
*/
|
||||
protected function isEntity(ClassMetadata $class)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
lib/Doctrine/KeyValueStore/NotFoundException.php
Normal file
26
lib/Doctrine/KeyValueStore/NotFoundException.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore;
|
||||
|
||||
class NotFoundException extends KeyValueStoreException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -51,7 +51,7 @@ class RangeQuery
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rangeConditions = array();
|
||||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* Limit result to only a set of entities.
|
||||
@@ -205,11 +205,16 @@ class RangeQuery
|
||||
throw new \RuntimeException("The storage backend " . $this->storage->getName() . " does not support range queries.");
|
||||
}
|
||||
|
||||
$uow = $em->getUnitOfWork();
|
||||
$uow = $this->em->getUnitOfWork();
|
||||
$class = $this->em->getClassMetadata($this->className);
|
||||
|
||||
return $storage>executeRangeQuery($this, $class->storageName, $class->identifiers, function ($row) use($uow, $class) {
|
||||
return $uow->createEntity($class, $data);
|
||||
return $storage->executeRangeQuery($this, $class->storageName, $class->identifier, function ($row) use($uow, $class) {
|
||||
$key = array();
|
||||
foreach ($class->identifier as $id) {
|
||||
$key[$id] = $row[$id];
|
||||
}
|
||||
|
||||
return $uow->createEntity($class, $key, $row);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
247
lib/Doctrine/KeyValueStore/Storage/AzureSdkTableStorage.php
Normal file
247
lib/Doctrine/KeyValueStore/Storage/AzureSdkTableStorage.php
Normal file
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use WindowsAzure\Table\TableRestProxy;
|
||||
use WindowsAzure\Table\Models\Entity;
|
||||
use WindowsAzure\Table\Models\EdmType;
|
||||
use WindowsAzure\Common\ServiceException;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
use Doctrine\KeyValueStore\Query\RangeQuery;
|
||||
use Doctrine\KeyValueStore\Query\RangeQueryStorage;
|
||||
|
||||
/**
|
||||
* Storage implementation for Microsoft Windows Azure Table using the PHP SDK.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class AzureSdkTableStorage implements Storage, RangeQueryStorage
|
||||
{
|
||||
/**
|
||||
* @var \WindowsAzure\Table\TableRestProxy
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(TableRestProxy $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$entity = $this->createEntity($key, $data);
|
||||
|
||||
try {
|
||||
$this->client->insertEntity($storageName, $entity);
|
||||
} catch(ServiceException $e){
|
||||
if ($e->getCode() == 404) {
|
||||
$this->client->createTable($storageName);
|
||||
} else {
|
||||
throw new StorageException(
|
||||
"Could not save entity in table, WindowsAzure SDK client reported error: " . $e->getMessage(),
|
||||
$e->getCode(), $e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$entity = $this->createEntity($key, $data);
|
||||
|
||||
try {
|
||||
$this->client->updateEntity($storageName, $entity);
|
||||
} catch(ServiceException $e){
|
||||
throw new StorageException(
|
||||
"Could not update entity in table, WindowsAzure SDK client reported error: " . $e->getMessage(),
|
||||
$e->getCode(), $e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
list ($partitonKey, $rowKey) = array_values($key);
|
||||
|
||||
try {
|
||||
$this->client->deleteEntity($storageName, $partitonKey, $rowKey);
|
||||
} catch(ServiceException $e) {
|
||||
throw new StorageException(
|
||||
"Could not delete entity in table, WindowsAzure SDK client reported error: " . $e->getMessage(),
|
||||
$e->getCode(), $e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
list ($partitonKey, $rowKey) = array_values($key);
|
||||
|
||||
try {
|
||||
$result = $this->client->getEntity($storageName, $partitonKey, $rowKey);
|
||||
} catch(ServiceException $e) {
|
||||
if ($e->getCode() === 404) {
|
||||
throw new NotFoundException();
|
||||
} else {
|
||||
throw new StorageException(
|
||||
"Could not find entity in table, WindowsAzure SDK client reported error: " . $e->getMessage(),
|
||||
$e->getCode(), $e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getProperties($result->getEntity());
|
||||
}
|
||||
|
||||
private function getProperties(Entity $entity)
|
||||
{
|
||||
$properties = array();
|
||||
|
||||
foreach ($entity->getProperties() as $name => $property) {
|
||||
if ($name === 'PartitionKey') {
|
||||
$name = 'dist';
|
||||
} else if ($name === 'RowKey') {
|
||||
$name = 'range';
|
||||
}
|
||||
|
||||
$properties[$name] = $property->getValue();
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'azure_table_sdk';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function executeRangeQuery(RangeQuery $query, $storageName, $key, \Closure $hydrateRow = null)
|
||||
{
|
||||
$filters = array("PartitionKey eq " . $this->quoteFilterValue($query->getPartitionKey()));
|
||||
|
||||
foreach ($query->getConditions() as $condition) {
|
||||
if ( ! in_array($condition[0], array('eq', 'neq', 'le', 'lt', 'ge', 'gt'))) {
|
||||
throw new \InvalidArgumentException("Windows Azure Table only supports eq, neq, le, lt, ge, gt as conditions.");
|
||||
}
|
||||
$filters[] = "RowKey " . $condition[0] . " " . $this->quoteFilterValue($condition[1]);
|
||||
}
|
||||
|
||||
$filter = '(' . implode(" and ", $filters) . ')';
|
||||
$result = $this->client->queryEntities($storageName, $filter);
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($result->getEntities() as $entity) {
|
||||
$row = $this->getProperties($entity);
|
||||
$rows[] = $hydrateRow ? $hydrateRow($row) : $row;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function quoteFilterValue($value)
|
||||
{
|
||||
return "'" . str_replace("'", "", $value) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create entity object with key and data values.
|
||||
*
|
||||
* @param array $key
|
||||
* @param array $data
|
||||
* @return \WindowsAzure\Table\Model\Entity
|
||||
*/
|
||||
private function createEntity(array $key, array $data)
|
||||
{
|
||||
list ($partitonKey, $rowKey) = array_values($key);
|
||||
|
||||
$entity = new Entity();
|
||||
$entity->setPartitionKey((string)$partitonKey);
|
||||
$entity->setRowKey((string)$rowKey);
|
||||
|
||||
foreach ($data as $variable => $value) {
|
||||
$type = $this->getPropertyType($value);
|
||||
$entity->addProperty($variable, $type, $value);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infer the property type of variables.
|
||||
*/
|
||||
private function getPropertyType($propertyValue)
|
||||
{
|
||||
if ($propertyValue instanceof \DateTime) {
|
||||
return EdmType::DATETIME;
|
||||
} else if (is_float($propertyValue)) {
|
||||
return EdmType::DOUBLE;
|
||||
} else if (is_int($propertyValue)) {
|
||||
return EdmType::INT32;
|
||||
} else if (is_bool($propertyValue)) {
|
||||
return EdmType::BOOLEAN;
|
||||
}
|
||||
|
||||
return EdmType::STRING;
|
||||
}
|
||||
}
|
||||
116
lib/Doctrine/KeyValueStore/Storage/CouchbaseStorage.php
Normal file
116
lib/Doctrine/KeyValueStore/Storage/CouchbaseStorage.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
|
||||
/**
|
||||
* @author Simon Schick <simonsimcity@gmail.com>
|
||||
*/
|
||||
class CouchbaseStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Couchbase
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Couchbase $couchbase
|
||||
*/
|
||||
public function __construct(\Couchbase $couchbase)
|
||||
{
|
||||
$this->client = $couchbase;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$this->client->add($key, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$this->client->replace($key, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$this->client->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$value = $this->client->get($key);
|
||||
|
||||
if ($value === null) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name of the underlying storage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'couchbase';
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,15 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* Relational databased backed system.
|
||||
*
|
||||
@@ -125,12 +128,19 @@ class DBALStorage implements Storage
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$sql = "SELECT " . $this->dataColumn . " FROM " . $this->table . " " .
|
||||
$this->keyColumn = " = ?";
|
||||
$stmt = $this->conn->executeQuery($sql, array($key));
|
||||
$qb = $this->conn->createQueryBuilder();
|
||||
|
||||
$qb->select("s.{$this->dataColumn}")
|
||||
->from($this->table, 's')
|
||||
->where("{$this->keyColumn} = ?")
|
||||
->setParameters(array($key));
|
||||
|
||||
$stmt = $qb->execute();
|
||||
|
||||
$data = $stmt->fetchColumn();
|
||||
|
||||
if (!$data) {
|
||||
return null;
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return unserialize($data);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
206
lib/Doctrine/KeyValueStore/Storage/DynamoDbStorage.php
Normal file
206
lib/Doctrine/KeyValueStore/Storage/DynamoDbStorage.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
use Aws\DynamoDb\DynamoDbClient;
|
||||
use Aws\DynamoDb\Exception\ResourceNotFoundException;
|
||||
use Aws\DynamoDb\Iterator\ItemIterator;
|
||||
|
||||
/**
|
||||
* DyanmoDb storage
|
||||
*
|
||||
* @author Stan Lemon <stosh1985@gmail.com>
|
||||
*/
|
||||
class DynamoDbStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Aws\DynamoDb\DynamoDbClient
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Aws\DynamoDb\DynamoDbClient $client
|
||||
*/
|
||||
public function __construct(DynamoDbClient $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$this->createTable($storageName);
|
||||
|
||||
$this->prepareData($key, $data);
|
||||
|
||||
$result = $this->client->putItem(array(
|
||||
'TableName' => $storageName,
|
||||
'Item' => $this->client->formatAttributes($data),
|
||||
'ReturnConsumedCapacity' => 'TOTAL'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$this->prepareData($key, $data);
|
||||
|
||||
unset($data['id']);
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
$data[$k] = array(
|
||||
"Value" => $this->client->formatValue($v),
|
||||
);
|
||||
}
|
||||
|
||||
$result = $this->client->updateItem(array(
|
||||
'TableName' => $storageName,
|
||||
'Key' => array(
|
||||
"id" => array('S' => $key)
|
||||
),
|
||||
"AttributeUpdates" => $data,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$result = $this->client->deleteItem(array(
|
||||
'TableName' => $storageName,
|
||||
'Key' => array(
|
||||
'id' => array('S' => $key),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$iterator = new ItemIterator($this->client->getScanIterator(array(
|
||||
"TableName" => $storageName,
|
||||
"Key" => array(
|
||||
"Id" => array('S' => $key),
|
||||
),
|
||||
)));
|
||||
|
||||
$results = $iterator->toArray();
|
||||
|
||||
if (count($results)) {
|
||||
return array_shift($results);
|
||||
}
|
||||
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name of the underlying storage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'dynamodb';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
*/
|
||||
protected function createTable($tableName)
|
||||
{
|
||||
try {
|
||||
$this->client->describeTable(array(
|
||||
'TableName' => $tableName,
|
||||
));
|
||||
} catch(ResourceNotFoundException $e) {
|
||||
$this->client->createTable(array(
|
||||
'AttributeDefinitions' => array(
|
||||
array(
|
||||
'AttributeName' => 'id',
|
||||
'AttributeType' => 'S',
|
||||
),
|
||||
),
|
||||
'TableName' => $tableName,
|
||||
'KeySchema' => array(
|
||||
array(
|
||||
'AttributeName' => 'id',
|
||||
'KeyType' => 'HASH',
|
||||
),
|
||||
),
|
||||
'ProvisionedThroughput' => array(
|
||||
'ReadCapacityUnits' => 1,
|
||||
'WriteCapacityUnits' => 1,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
*/
|
||||
protected function prepareData($key, &$data)
|
||||
{
|
||||
$data = array_merge($data, array(
|
||||
'id' => $key,
|
||||
));
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if ($value === null || $value === array() || $value === '') {
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
171
lib/Doctrine/KeyValueStore/Storage/MongoDbStorage.php
Normal file
171
lib/Doctrine/KeyValueStore/Storage/MongoDbStorage.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
|
||||
/**
|
||||
* MongoDb storage
|
||||
*
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class MongoDbStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Mongo
|
||||
*/
|
||||
protected $mongo;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $dbOptions;
|
||||
|
||||
/**
|
||||
* @var \MongoCollection
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Mongo $mongo
|
||||
* @param array $dbOptions
|
||||
*/
|
||||
public function __construct(\Mongo $mongo, array $dbOptions = array())
|
||||
{
|
||||
$this->mongo = $mongo;
|
||||
$this->dbOptions = array_merge(array(
|
||||
'database' => '',
|
||||
'collection' => '',
|
||||
), $dbOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the mongodb collection
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
if (null !== $this->collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->dbOptions['database'])) {
|
||||
throw new \RuntimeException('The option "database" must be set');
|
||||
}
|
||||
if (empty($this->dbOptions['collection'])) {
|
||||
throw new \RuntimeException('The option "collection" must be set');
|
||||
}
|
||||
|
||||
$this->collection = $this->mongo->selectDB($this->dbOptions['database'])->selectCollection($this->dbOptions['collection']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$value = array(
|
||||
'key' => $key,
|
||||
'value' => $data,
|
||||
);
|
||||
|
||||
$this->collection->insert($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$value = array(
|
||||
'key' => $key,
|
||||
'value' => $data,
|
||||
);
|
||||
|
||||
$this->collection->update(array('key' => $key), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$this->collection->remove(array('key' => $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
$value = $this->collection->findOne(array('key' => $key), array('value'));
|
||||
|
||||
if ($value) {
|
||||
return $value['value'];
|
||||
}
|
||||
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name of the underlying storage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'mongodb';
|
||||
}
|
||||
}
|
||||
148
lib/Doctrine/KeyValueStore/Storage/RedisStorage.php
Normal file
148
lib/Doctrine/KeyValueStore/Storage/RedisStorage.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
|
||||
/**
|
||||
* @author Marcel Araujo <admin@marcelaraujo.me>
|
||||
*/
|
||||
class RedisStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Redis
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $dbOptions;
|
||||
|
||||
/**
|
||||
* Redis Key Prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $keyPrefix = 'doctrine:storage:';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Redis $redis
|
||||
* @param array $dbOptions
|
||||
*/
|
||||
public function __construct($redis, $dbOptions = array())
|
||||
{
|
||||
$this->client = $redis;
|
||||
|
||||
$this->dbOptions = array_merge(array(
|
||||
'keyPrefix' => $this->keyPrefix
|
||||
), $dbOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$this->client->set($this->getKeyName($key), json_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$this->client->set($this->getKeyName($key), json_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$key = $this->getKeyName($key);
|
||||
|
||||
if ($this->client->exists($key)) {
|
||||
$this->client->delete($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$key = $this->getKeyName($key);
|
||||
|
||||
if (! $this->client->exists($key)) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return json_decode($this->client->get($key), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name of the underlying storage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'redis';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add prefix to Redis key space name
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyName($key)
|
||||
{
|
||||
return $this->keyPrefix . $key;
|
||||
}
|
||||
}
|
||||
137
lib/Doctrine/KeyValueStore/Storage/RiakStorage.php
Normal file
137
lib/Doctrine/KeyValueStore/Storage/RiakStorage.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
|
||||
use Riak\Client;
|
||||
|
||||
/**
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class RiakStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Riak\Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Riak\Client $riak
|
||||
* @param string $bucketName
|
||||
*/
|
||||
public function __construct(Client $riak)
|
||||
{
|
||||
$this->client = $riak;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$bucket = $this->client->bucket($storageName);
|
||||
$object = $bucket->newObject($key, $data);
|
||||
$object->store();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
$bucket = $this->client->bucket($storageName);
|
||||
/** @var $object \Riak\Object */
|
||||
$object = $bucket->get($key);
|
||||
|
||||
$object->setData($data);
|
||||
$object->store();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$bucket = $this->client->bucket($storageName);
|
||||
|
||||
/** @var $object \Riak\Object */
|
||||
$object = $bucket->get($key);
|
||||
|
||||
if (!$object->exists()) {
|
||||
// object does not exist, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
$object->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$bucket = $this->client->bucket($storageName);
|
||||
|
||||
/** @var $object \Riak\Object */
|
||||
$object = $bucket->get($key);
|
||||
|
||||
if (!$object->exists()) {
|
||||
throw new NotFoundException;
|
||||
}
|
||||
|
||||
return $object->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'riak';
|
||||
}
|
||||
}
|
||||
183
lib/Doctrine/KeyValueStore/Storage/SimpleDbStorage.php
Normal file
183
lib/Doctrine/KeyValueStore/Storage/SimpleDbStorage.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
use Doctrine\KeyValueStore\KeyValueStoreException;
|
||||
use Aws\SimpleDb\SimpleDbClient;
|
||||
use Aws\SimpleDb\Exception\NoSuchDomainException;
|
||||
use Aws\SimpleDb\Exception\SimpleDbException;
|
||||
|
||||
/**
|
||||
* SimpleDb storage
|
||||
*
|
||||
* @author Stan Lemon <stosh1985@gmail.com>
|
||||
*/
|
||||
class SimpleDbStorage implements Storage
|
||||
{
|
||||
/**
|
||||
* @var \Aws\SimpleDb\SimpleDbClient
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Aws\SimpleDb\SimpleDbClient $client
|
||||
*/
|
||||
public function __construct(SimpleDbClient $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsPartialUpdates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function requiresCompositePrimaryKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function insert($storageName, $key, array $data)
|
||||
{
|
||||
$this->createDomain($storageName);
|
||||
|
||||
$this->client->putAttributes(array(
|
||||
'DomainName' => $storageName,
|
||||
'ItemName' => $key,
|
||||
'Attributes' => $this->makeAttributes($data),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function update($storageName, $key, array $data)
|
||||
{
|
||||
return $this->insert($storageName, $key, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function delete($storageName, $key)
|
||||
{
|
||||
$this->client->deleteAttributes(array(
|
||||
'DomainName' => $storageName,
|
||||
'ItemName' => $key,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($storageName, $key)
|
||||
{
|
||||
$select = "select * from {$storageName} where itemName() = '{$key}'";
|
||||
|
||||
$iterator = $this->client->select(array(
|
||||
'SelectExpression' => $select,
|
||||
));
|
||||
|
||||
$results = $iterator->get('Items');
|
||||
|
||||
if (count($results)) {
|
||||
$result = array_shift($results);
|
||||
|
||||
$data = array('id' => $result['Name']);
|
||||
|
||||
foreach ($result['Attributes'] as $attribute) {
|
||||
$data[$attribute['Name']] = $attribute['Value'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a name of the underlying storage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'simpledb';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
*/
|
||||
protected function createDomain($domainName)
|
||||
{
|
||||
try {
|
||||
$domain = $this->client->domainMetadata(array('DomainName' => $domainName));
|
||||
} catch (NoSuchDomainException $e) {
|
||||
$this->client->createDomain(array('DomainName' => $domainName));
|
||||
|
||||
$domain = $this->client->domainMetadata(array('DomainName' => $domainName));
|
||||
} catch (SimpleDbException $e) {
|
||||
throw new KeyValueStoreException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
*/
|
||||
protected function makeAttributes($data)
|
||||
{
|
||||
$attributes = array();
|
||||
|
||||
foreach ($data as $name => $value) {
|
||||
if ($value !== null && $value !== array() && $value !== '') {
|
||||
$attributes[] = array(
|
||||
'Name' => $name,
|
||||
'Value' => $value,
|
||||
'Replace' => true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -97,6 +97,8 @@ interface Storage
|
||||
*
|
||||
* Important note: The returned array does contain the identifier (again)!
|
||||
*
|
||||
* @throws Doctrine\KeyValueStore\NotFoundException When data with key is not found.
|
||||
*
|
||||
* @param string $storageName
|
||||
* @param array|string $key
|
||||
* @return array
|
||||
|
||||
21
lib/Doctrine/KeyValueStore/Storage/StorageException.php
Normal file
21
lib/Doctrine/KeyValueStore/Storage/StorageException.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine KeyValueStore
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\KeyValueStoreException;
|
||||
|
||||
class StorageException extends KeyValueStoreException
|
||||
{
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
namespace Doctrine\KeyValueStore\Storage\WindowsAzureTable;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine Key Value Store
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore\Storage\WindowsAzureTable;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\StorageException;
|
||||
|
||||
class HttpStorageException extends StorageException
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
@@ -21,8 +21,10 @@ namespace Doctrine\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\Http\Client;
|
||||
use Doctrine\KeyValueStore\Storage\WindowsAzureTable\AuthorizationSchema;
|
||||
use Doctrine\KeyValueStore\Storage\WindowsAzureTable\HttpStorageException;
|
||||
use Doctrine\KeyValueStore\Query\RangeQuery;
|
||||
use Doctrine\KeyValueStore\Query\RangeQueryStorage;
|
||||
use Doctrine\KeyValueStore\NotFoundException;
|
||||
|
||||
/**
|
||||
* Storage implementation for Microsoft Windows Azure Table.
|
||||
@@ -30,6 +32,7 @@ use Doctrine\KeyValueStore\Query\RangeQueryStorage;
|
||||
* Using a HTTP client to communicate with the REST API of Azure Table.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @deprecated Use the AzureSdkTableStorage instead, this will be unmaintained.
|
||||
*/
|
||||
class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
{
|
||||
@@ -148,11 +151,27 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
$response = $this->request('POST', $url, $xml, $headers);
|
||||
|
||||
if ($response->getStatusCode() == 404) {
|
||||
|
||||
$this->createTable($tableName);
|
||||
$this->insert($storageName, $key, $data);
|
||||
} else if ($response->getStatusCode() >= 400) {
|
||||
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
}
|
||||
|
||||
private function convertResponseToException($response)
|
||||
{
|
||||
$dom = new \DomDocument('1.0', 'UTF-8');
|
||||
$dom->loadXML($response->getBody());
|
||||
|
||||
$node = $dom->getElementsByTagName('Message')->item(0);
|
||||
|
||||
throw new HttpStorageException(
|
||||
$node ? $node->nodeValue : "An error has occured"
|
||||
);
|
||||
}
|
||||
|
||||
public function createTable($tableName)
|
||||
{
|
||||
$headers = array(
|
||||
@@ -167,6 +186,10 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
$url = $this->baseUrl . '/Tables';
|
||||
$response = $this->request('POST', $url, $xml, $headers);
|
||||
|
||||
if ($response->getStatusCode() != 201) {
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -197,6 +220,10 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
$xml = $dom->saveXML();
|
||||
|
||||
$response = $this->request('PUT', $url, $xml, $headers);
|
||||
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($storageName, $key)
|
||||
@@ -213,7 +240,11 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
$keys = array_values($key);
|
||||
$url = $this->baseUrl . '/' . $tableName . rawurlencode("(PartitionKey='" . $keys[0] . "', RowKey='" . $keys[1] . "')");
|
||||
|
||||
$this->request('DELETE', $url, '', $headers);
|
||||
$response = $this->request('DELETE', $url, '', $headers);
|
||||
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function find($storageName, $key)
|
||||
@@ -231,8 +262,12 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
|
||||
$response = $this->request('GET', $url, '', $headers);
|
||||
|
||||
if ($response->getStatusCode() != 200) {
|
||||
// Todo: do stuff
|
||||
if ($response->getStatusCode() == 404) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
|
||||
$dom = new \DomDocument('1.0', 'UTF-8');
|
||||
@@ -310,8 +345,8 @@ class WindowsAzureTableStorage implements Storage, RangeQueryStorage
|
||||
|
||||
$response = $this->request('GET', $url, '', $headers);
|
||||
|
||||
if ($response->getStatusCode() != 200) {
|
||||
// Todo: do stuff
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
$this->convertResponseToException($response);
|
||||
}
|
||||
|
||||
$dom = new \DomDocument('1.0', 'UTF-8');
|
||||
|
||||
@@ -13,13 +13,15 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\KeyValueStore;
|
||||
|
||||
use Doctrine\KeyValueStore\Id\NullIdConverter;
|
||||
use Doctrine\KeyValueStore\Id\IdHandlingStrategy;
|
||||
use Doctrine\KeyValueStore\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\KeyValueStore\Storage\Storage;
|
||||
|
||||
/**
|
||||
* UnitOfWork to handle all KeyValueStore entities based on the configured
|
||||
@@ -29,8 +31,17 @@ use Doctrine\KeyValueStore\Id\NullIdConverter;
|
||||
*/
|
||||
class UnitOfWork
|
||||
{
|
||||
/**
|
||||
* @var ClassMetadataFactory
|
||||
*/
|
||||
private $cmf;
|
||||
/**
|
||||
* @var Storage
|
||||
*/
|
||||
private $storageDriver;
|
||||
/**
|
||||
* @var IdHandlingStrategy
|
||||
*/
|
||||
private $idHandler;
|
||||
|
||||
/**
|
||||
@@ -49,7 +60,7 @@ class UnitOfWork
|
||||
private $identityMap = array();
|
||||
private $idConverter;
|
||||
|
||||
public function __construct($cmf, $storageDriver, $config = null)
|
||||
public function __construct(ClassMetadataFactory $cmf, Storage $storageDriver, Configuration $config = null)
|
||||
{
|
||||
$this->cmf = $cmf;
|
||||
$this->storageDriver = $storageDriver;
|
||||
@@ -59,11 +70,16 @@ class UnitOfWork
|
||||
new Id\SingleIdHandler();
|
||||
}
|
||||
|
||||
private function tryGetById($id)
|
||||
public function getClassMetadata($className)
|
||||
{
|
||||
return $this->cmf->getMetadataFor($className);
|
||||
}
|
||||
|
||||
private function tryGetById($className, $id)
|
||||
{
|
||||
$idHash = $this->idHandler->hash($id);
|
||||
if (isset($this->identityMap[$idHash])) {
|
||||
return $this->identityMap[$idHash];
|
||||
if (isset($this->identityMap[$className][$idHash])) {
|
||||
return $this->identityMap[$className][$idHash];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -74,6 +90,10 @@ class UnitOfWork
|
||||
$id = $this->idHandler->normalizeId($class, $key);
|
||||
$data = $this->storageDriver->find($class->storageName, $id);
|
||||
|
||||
if (!$data) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return $this->createEntity($class, $id, $data);
|
||||
}
|
||||
|
||||
@@ -87,7 +107,7 @@ class UnitOfWork
|
||||
}
|
||||
unset($data['php_class']);
|
||||
|
||||
$object = $this->tryGetById($id);
|
||||
$object = $this->tryGetById($class->name, $id);
|
||||
if ( $object) {
|
||||
return $object;
|
||||
}
|
||||
@@ -106,9 +126,9 @@ class UnitOfWork
|
||||
}
|
||||
}
|
||||
|
||||
$idHash = $this->idHandler->hash($id);
|
||||
$this->identityMap[$idHash] = $object;
|
||||
$this->identifiers[$oid] = $id;
|
||||
$idHash = $this->idHandler->hash($id);
|
||||
$this->identityMap[$class->name][$idHash] = $object;
|
||||
$this->identifiers[$oid] = $id;
|
||||
|
||||
return $object;
|
||||
}
|
||||
@@ -166,12 +186,12 @@ class UnitOfWork
|
||||
|
||||
$idHash = $this->idHandler->hash($id);
|
||||
|
||||
if (isset($this->identityMap[$idHash])) {
|
||||
if (isset($this->identityMap[$class->name][$idHash])) {
|
||||
throw new \RuntimeException("Object with ID already exists.");
|
||||
}
|
||||
|
||||
$this->scheduledInsertions[$oid] = $object;
|
||||
$this->identityMap[$idHash] = $object;
|
||||
$this->scheduledInsertions[$oid] = $object;
|
||||
$this->identityMap[$class->name][$idHash] = $object;
|
||||
}
|
||||
|
||||
public function scheduleForDelete($object)
|
||||
@@ -185,24 +205,26 @@ class UnitOfWork
|
||||
|
||||
private function processIdentityMap()
|
||||
{
|
||||
foreach ($this->identityMap as $object) {
|
||||
$hash = spl_object_hash($object);
|
||||
foreach ($this->identityMap as $className => $entities) {
|
||||
foreach ($entities as $object) {
|
||||
$hash = spl_object_hash($object);
|
||||
|
||||
if ( isset($this->scheduledInsertions[$hash])) {
|
||||
continue;
|
||||
}
|
||||
if ( isset($this->scheduledInsertions[$hash])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$metadata = $this->cmf->getMetadataFor(get_class($object));
|
||||
$changeSet = $this->computeChangeSet($metadata, $object);
|
||||
$metadata = $this->cmf->getMetadataFor($className);
|
||||
$changeSet = $this->computeChangeSet($metadata, $object);
|
||||
|
||||
if ($changeSet) {
|
||||
$changeSet['php_class'] = $metadata->name;
|
||||
$this->storageDriver->update($metadata->storageName, $this->identifiers[$hash], $changeSet);
|
||||
if ($changeSet) {
|
||||
$changeSet['php_class'] = $metadata->name;
|
||||
$this->storageDriver->update($metadata->storageName, $this->identifiers[$hash], $changeSet);
|
||||
|
||||
if ($this->storageDriver->supportsPartialUpdates()) {
|
||||
$this->originalData[$hash] = array_merge($this->originalData[$hash], $changeSet);
|
||||
} else {
|
||||
$this->originalData[$hash] = $changeSet;
|
||||
if ($this->storageDriver->supportsPartialUpdates()) {
|
||||
$this->originalData[$hash] = array_merge($this->originalData[$hash], $changeSet);
|
||||
} else {
|
||||
$this->originalData[$hash] = $changeSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,9 +249,9 @@ class UnitOfWork
|
||||
|
||||
$this->storageDriver->insert($class->storageName, $id, $data);
|
||||
|
||||
$this->originalData[$oid] = $data;
|
||||
$this->identifiers[$oid] = $id;
|
||||
$this->identityMap[$idHash] = $object;
|
||||
$this->originalData[$oid] = $data;
|
||||
$this->identifiers[$oid] = $id;
|
||||
$this->identityMap[$class->name][$idHash] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +265,7 @@ class UnitOfWork
|
||||
|
||||
$this->storageDriver->delete($class->storageName, $id);
|
||||
|
||||
unset($this->identifiers[$oid], $this->originalData[$oid], $this->identityMap[$idHash]);
|
||||
unset($this->identifiers[$oid], $this->originalData[$oid], $this->identityMap[$class->name][$idHash]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\KeyValueStore\Functional\Storage;
|
||||
|
||||
use Doctrine\Tests\KeyValueStoreTestCase;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\AzureSdkTableStorage;
|
||||
use Doctrine\KeyValueStore\Query\RangeQuery;
|
||||
|
||||
use WindowsAzure\Common\ServicesBuilder;
|
||||
|
||||
class AzureSdkTableTest extends KeyValueStoreTestCase
|
||||
{
|
||||
private $storage;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (empty($GLOBALS['DOCTRINE_KEYVALUE_AZURE_NAME']) || empty($GLOBALS['DOCTRINE_KEYVALUE_AZURE_KEY'])) {
|
||||
$this->markTestSkipped("Missing Azure credentials.");
|
||||
}
|
||||
|
||||
$connectionString = sprintf(
|
||||
"DefaultEndpointsProtocol=http;AccountName=%s;AccountKey=%s",
|
||||
$GLOBALS['DOCTRINE_KEYVALUE_AZURE_NAME'],
|
||||
$GLOBALS['DOCTRINE_KEYVALUE_AZURE_KEY']
|
||||
);
|
||||
$tableProxy = ServicesBuilder::getInstance()->createTableService($connectionString);
|
||||
|
||||
$this->storage = new AzureSdkTableStorage($tableProxy);
|
||||
}
|
||||
|
||||
public function testCrud()
|
||||
{
|
||||
$storage = $this->storage;
|
||||
|
||||
$key = array("dist" => "sdktest", "range" => time());
|
||||
$storage->insert("test", $key, array("foo" => "bar"));
|
||||
$data = $storage->find("test", $key);
|
||||
|
||||
$this->assertInstanceOf('DateTime', $data['Timestamp']);
|
||||
$this->assertEquals('bar', $data['foo']);
|
||||
$this->assertEquals('sdktest', $data['dist']);
|
||||
$this->assertEquals($key['range'], $data['range']);
|
||||
|
||||
$storage->update("test", $key, array("foo" => "baz", "bar" => "baz"));
|
||||
$data = $storage->find("test", $key);
|
||||
|
||||
$this->assertEquals('baz', $data['foo']);
|
||||
$this->assertEquals('baz', $data['bar']);
|
||||
|
||||
$storage->delete("test", $key);
|
||||
|
||||
$this->setExpectedException("Doctrine\KeyValueStore\NotFoundException");
|
||||
$storage->find("test", $key);
|
||||
}
|
||||
|
||||
public function testTypes()
|
||||
{
|
||||
$storage = $this->storage;
|
||||
|
||||
$data = array(
|
||||
"string" => "foo",
|
||||
"date" => new \DateTime("now"),
|
||||
"int" => 1234,
|
||||
"float" => 123.45,
|
||||
"bool" => false,
|
||||
);
|
||||
|
||||
$key = array("dist" => "sdktest", "range" => time()+1);
|
||||
$storage->insert("test", $key, $data);
|
||||
$data = $storage->find("test", $key);
|
||||
|
||||
$this->assertInstanceOf('DateTime', $data['date']);
|
||||
$this->assertInternalType('string', $data['string']);
|
||||
$this->assertInternalType('int', $data['int']);
|
||||
$this->assertInternalType('float', $data['float']);
|
||||
$this->assertInternalType('bool', $data['bool']);
|
||||
}
|
||||
|
||||
public function testQueryRange()
|
||||
{
|
||||
$rangeQuery = new RangeQuery($this->createManager(), 'test', 'sdktest');
|
||||
$rangeQuery->rangeLessThan(time());
|
||||
|
||||
$data = $this->storage->executeRangeQuery($rangeQuery, 'test', array('dist', 'range'), function($row) {
|
||||
return $row;
|
||||
});
|
||||
|
||||
$this->assertTrue(count($data) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,9 @@ class WindowsAzureTableTest extends KeyValueStoreTestCase
|
||||
$this->assertEquals('baz', $data['bar']);
|
||||
|
||||
$storage->delete("test", $key);
|
||||
$data = $storage->find("test", $key);
|
||||
$this->assertEquals(array(), $data);
|
||||
|
||||
$this->setExpectedException("Doctrine\KeyValueStore\NotFoundException");
|
||||
$storage->find("test", $key);
|
||||
}
|
||||
|
||||
public function testQueryRange()
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\CouchbaseStorage;
|
||||
|
||||
/**
|
||||
* Couchbase storage testcase
|
||||
*
|
||||
* @author Simon Schick <simonsimcity@gmail.com>
|
||||
*/
|
||||
class CouchbaseStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $couchbase;
|
||||
|
||||
/**
|
||||
* @var CouchbaseStorage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
if (!class_exists('\Couchbase'))
|
||||
$this->markTestSkipped("The PHP extension 'couchbase' is not installed");
|
||||
|
||||
$this->couchbase = $this->getMockBuilder('\Couchbase')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->storage = new CouchbaseStorage($this->couchbase);
|
||||
}
|
||||
|
||||
public function testSupportsPartialUpdates()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsPartialUpdates());
|
||||
}
|
||||
|
||||
public function testSupportsCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testRequiresCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->requiresCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testInsert()
|
||||
{
|
||||
$data = array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->couchbase->expects($this->once())
|
||||
->method('add')
|
||||
->will($this->returnCallback(function($key, $data) use (&$dbDataset) {
|
||||
$dbDataset[] = array('key' => $key, 'value' => $data);
|
||||
}));
|
||||
|
||||
$this->storage->insert('', '1', $data);
|
||||
$this->assertCount(1, $dbDataset);
|
||||
|
||||
$this->assertEquals(array(array('key' => '1', 'value' => $data)), $dbDataset);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$data = array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->couchbase->expects($this->once())
|
||||
->method('replace')
|
||||
->will($this->returnCallback(function($key, $data) use (&$dbDataset) {
|
||||
$dbDataset[$key] = $data;
|
||||
}));
|
||||
|
||||
$this->storage->update('', '1', $data);
|
||||
|
||||
$this->assertEquals(array('1' => $data), $dbDataset);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$dataset = array(
|
||||
'foobar' => array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
),
|
||||
);
|
||||
|
||||
$this->couchbase->expects($this->once())
|
||||
->method('delete')
|
||||
->will($this->returnCallback(function($key) use (&$dataset) {
|
||||
foreach ($dataset as $id => $row) {
|
||||
if ($id === $key) {
|
||||
unset($dataset[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
$this->storage->delete('test', 'foobar');
|
||||
|
||||
$this->assertCount(0, $dataset);
|
||||
}
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
$dataset = array(
|
||||
'foobar' => array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
),
|
||||
);
|
||||
|
||||
$this->couchbase->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnCallback(function($key) use (&$dataset) {
|
||||
if (isset($dataset[$key])) {
|
||||
return $dataset[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
$data = $this->storage->find('test', 'foobar');
|
||||
|
||||
$this->assertEquals($dataset['foobar'], $data);
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertEquals('couchbase', $this->storage->getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\MongoDbStorage;
|
||||
|
||||
/**
|
||||
* MongoDb storage testcase
|
||||
*
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class MongoDbStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
if ( ! extension_loaded('mongodb')) {
|
||||
$this->markTestSkipped('MongoDB Extension is not installed.');
|
||||
}
|
||||
|
||||
$this->mongo = $this->getMock('\Mongo');
|
||||
|
||||
$this->mongodb = $this->getMockBuilder('\MongoDB')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->mongo->expects($this->any())
|
||||
->method('selectDB')
|
||||
->will($this->returnValue($this->mongodb));
|
||||
|
||||
$this->collection = $this->getMockBuilder('MongoCollection')->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->mongodb->expects($this->once())
|
||||
->method('selectCollection')
|
||||
->will($this->returnValue($this->collection));
|
||||
|
||||
$this->storage = new MongoDbStorage($this->mongo, array(
|
||||
'collection' => 'test',
|
||||
'database' => 'test'
|
||||
));
|
||||
}
|
||||
|
||||
public function testInsert()
|
||||
{
|
||||
$data = array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->collection->expects($this->once())
|
||||
->method('insert')
|
||||
->will($this->returnCallback(function($data) use (&$dbDataset) {
|
||||
$dbDataset[] = $data;
|
||||
}));
|
||||
|
||||
$this->storage->insert('mongodb', '1', $data);
|
||||
$this->assertCount(1, $dbDataset);
|
||||
|
||||
$this->assertEquals(array(array('key' => '1', 'value' => $data)), $dbDataset);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$data = array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->collection->expects($this->once())
|
||||
->method('update')
|
||||
->will($this->returnCallback(function($citeria, $data) use (&$dbDataset) {
|
||||
$dbDataset = array($citeria, $data);
|
||||
}));
|
||||
|
||||
$this->storage->update('mongodb', '1', $data);
|
||||
|
||||
$this->assertEquals(array('key' => '1'), $dbDataset[0]);
|
||||
$this->assertEquals(array('key' => '1', 'value' => $data), $dbDataset[1]);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$dataset = array(
|
||||
array(
|
||||
'key' => 'foobar',
|
||||
'value' => array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->collection->expects($this->once())
|
||||
->method('remove')
|
||||
->will($this->returnCallback(function($citeria) use (&$dataset) {
|
||||
foreach ($dataset as $key => $row) {
|
||||
if ($row['key'] === $citeria['key']) {
|
||||
unset($dataset[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
$this->storage->delete('test', 'foobar');
|
||||
|
||||
$this->assertCount(0, $dataset);
|
||||
}
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
$dataset = array(
|
||||
array(
|
||||
'key' => 'foobar',
|
||||
'value' => array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->collection->expects($this->once())
|
||||
->method('findOne')
|
||||
->will($this->returnCallback(function($citeria, $fields) use (&$dataset) {
|
||||
foreach ($dataset as $key => $row) {
|
||||
if ($row['key'] === $citeria['key']) {
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
$data = $this->storage->find('test', 'foobar');
|
||||
|
||||
$this->assertEquals($dataset[0]['value'], $data);
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->storage->initialize();
|
||||
|
||||
$this->assertEquals('mongodb', $this->storage->getName());
|
||||
}
|
||||
}
|
||||
103
tests/Doctrine/Tests/KeyValueStore/Storage/RedisStorageTest.php
Normal file
103
tests/Doctrine/Tests/KeyValueStore/Storage/RedisStorageTest.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\RedisStorage;
|
||||
|
||||
/**
|
||||
* @author Marcel Araujo <admin@marcelaraujo.me>
|
||||
*/
|
||||
class RedisStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var RedisStorage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $redis;
|
||||
|
||||
protected function setup()
|
||||
{
|
||||
if ( ! extension_loaded('redis')) {
|
||||
$this->markTestSkipped('Redis Extension is not installed.');
|
||||
}
|
||||
|
||||
$this->redis = $this->getMockBuilder('\Redis')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->redis->expects($this->any())
|
||||
->method('connect')
|
||||
->with('127.0.0.1', '6379')
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->storage = new RedisStorage($this->redis);
|
||||
}
|
||||
|
||||
public function testSupportsPartialUpdates()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsPartialUpdates());
|
||||
}
|
||||
|
||||
public function testSupportsCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testRequiresCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->requiresCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testInsert()
|
||||
{
|
||||
$data = array(
|
||||
'author' => 'John Doe',
|
||||
'title' => 'example book',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->redis->expects($this->once())
|
||||
->method('set')
|
||||
->will($this->returnCallback(function($key, $data) use (&$dbDataset) {
|
||||
$dbDataset[] = array('key' => $key, 'value' => $data);
|
||||
}));
|
||||
|
||||
$this->storage->insert('redis', '1', $data);
|
||||
|
||||
$this->assertCount(1, $dbDataset);
|
||||
$this->assertEquals(array(array('key' => $this->storage->getKeyName('1'), 'value' => json_encode($data))), $dbDataset);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
|
||||
$data = array(
|
||||
'author' => 'John Doe Updated',
|
||||
'title' => 'example book updated',
|
||||
);
|
||||
|
||||
$dbDataset = array();
|
||||
|
||||
$this->redis->expects($this->once())
|
||||
->method('set')
|
||||
->will($this->returnCallback(function($key, $data) use (&$dbDataset) {
|
||||
$dbDataset[] = array('key' => $key, 'value' => $data);
|
||||
}));
|
||||
|
||||
|
||||
$this->storage->update('redis', '1', $data);
|
||||
|
||||
$this->assertCount(1, $dbDataset);
|
||||
$this->assertEquals(array(array('key' => $this->storage->getKeyName('1'), 'value' => json_encode($data))), $dbDataset);
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertEquals('redis', $this->storage->getName());
|
||||
}
|
||||
}
|
||||
233
tests/Doctrine/Tests/KeyValueStore/Storage/RiakStorageTest.php
Normal file
233
tests/Doctrine/Tests/KeyValueStore/Storage/RiakStorageTest.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\KeyValueStore\Storage;
|
||||
|
||||
use Doctrine\KeyValueStore\Storage\RiakStorage;
|
||||
|
||||
/**
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class RiakStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var RiakStorage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $riak;
|
||||
|
||||
protected function setup()
|
||||
{
|
||||
$this->riak = $this->getMockBuilder('Riak\\Client')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
||||
$this->storage = new RiakStorage($this->riak);
|
||||
}
|
||||
|
||||
public function testSupportsPartialUpdates()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsPartialUpdates());
|
||||
}
|
||||
|
||||
public function testSupportsCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->supportsCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testRequiresCompositePrimaryKeys()
|
||||
{
|
||||
$this->assertFalse($this->storage->requiresCompositePrimaryKeys());
|
||||
}
|
||||
|
||||
public function testInsert()
|
||||
{
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('store');
|
||||
|
||||
|
||||
$that = $this;
|
||||
$bucket->expects($this->once())
|
||||
->method('newObject')
|
||||
->will($this->returnCallback(function($key, $data) use ($objectMock, $that) {
|
||||
$that->assertEquals('foobar', $key);
|
||||
$that->assertEquals(array('title' => 'Riak test'), $data);
|
||||
return $objectMock;
|
||||
}));
|
||||
|
||||
$this->storage->insert('riak-test', 'foobar', array('title' => 'Riak test'));
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$bucket->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue($objectMock));
|
||||
|
||||
|
||||
$that = $this;
|
||||
$objectMock->expects($this->once())
|
||||
->method('setData')
|
||||
->will($this->returnCallback(function($data) use ($that) {
|
||||
$that->assertEquals(array('title' => 'Riak cookbook'), $data);
|
||||
}));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('store');
|
||||
|
||||
$this->storage->update('riak-test', 'foobar', array('title' => 'Riak cookbook'));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$bucket->expects($this->once())
|
||||
->method('get')
|
||||
->with('foobar')
|
||||
->will($this->returnValue($objectMock));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('exists')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('delete');
|
||||
|
||||
$this->storage->delete('riak-test', 'foobar');
|
||||
}
|
||||
|
||||
public function testDeleteWithNotExistKey()
|
||||
{
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$bucket->expects($this->once())
|
||||
->method('get')
|
||||
->with('foobar')
|
||||
->will($this->returnValue($objectMock));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('exists')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$objectMock->expects($this->never())
|
||||
->method('delete');
|
||||
|
||||
$this->storage->delete('riak-test', 'foobar');
|
||||
}
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$bucket->expects($this->once())
|
||||
->method('get')
|
||||
->with('foobar')
|
||||
->will($this->returnValue($objectMock));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('exists')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('getData')
|
||||
->will($this->returnValue(array('title' => 'Riak Test')));
|
||||
|
||||
$this->assertEquals(array('title' => 'Riak Test'), $this->storage->find('riaktest', 'foobar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\KeyValueStore\NotFoundException
|
||||
*/
|
||||
public function testFindWithNotExistKey()
|
||||
{
|
||||
$objectMock = $this->getMockBuilder('Riak\Object')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$bucket = $this->getMockBuilder('Riak\Bucket')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->riak->expects($this->once())
|
||||
->method('bucket')
|
||||
->will($this->returnValue($bucket));
|
||||
|
||||
$bucket->expects($this->once())
|
||||
->method('get')
|
||||
->with('foobar')
|
||||
->will($this->returnValue($objectMock));
|
||||
|
||||
$objectMock->expects($this->once())
|
||||
->method('exists')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$objectMock->expects($this->never())
|
||||
->method('getData');
|
||||
|
||||
$this->storage->find('riak-test', 'foobar');
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertEquals('riak', $this->storage->getName());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
if (!@include __DIR__ . '/../vendor/.composer/autoload.php') {
|
||||
if (!@include __DIR__ . '/../vendor/autoload.php') {
|
||||
die(<<<'EOT'
|
||||
You must set up the project dependencies, run the following commands:
|
||||
wget http://getcomposer.org/composer.phar
|
||||
|
||||
Reference in New Issue
Block a user