11 * to license@zend.com so we can send you a copy immediately. |
11 * to license@zend.com so we can send you a copy immediately. |
12 * |
12 * |
13 * @category Zend |
13 * @category Zend |
14 * @package Zend_Cloud |
14 * @package Zend_Cloud |
15 * @subpackage DocumentService |
15 * @subpackage DocumentService |
16 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
16 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
17 * @license http://framework.zend.com/license/new-bsd New BSD License |
17 * @license http://framework.zend.com/license/new-bsd New BSD License |
18 */ |
18 */ |
19 |
19 |
20 require_once 'Zend/Cloud/DocumentService/Adapter/AbstractAdapter.php'; |
20 require_once 'Zend/Cloud/DocumentService/Adapter/AbstractAdapter.php'; |
21 require_once 'Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php'; |
21 require_once 'Zend/Cloud/DocumentService/Adapter/SimpleDb/Query.php'; |
27 * SimpleDB adapter for document service. |
27 * SimpleDB adapter for document service. |
28 * |
28 * |
29 * @category Zend |
29 * @category Zend |
30 * @package Zend_Cloud |
30 * @package Zend_Cloud |
31 * @subpackage DocumentService |
31 * @subpackage DocumentService |
32 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
32 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
33 * @license http://framework.zend.com/license/new-bsd New BSD License |
33 * @license http://framework.zend.com/license/new-bsd New BSD License |
34 */ |
34 */ |
35 class Zend_Cloud_DocumentService_Adapter_SimpleDb |
35 class Zend_Cloud_DocumentService_Adapter_SimpleDb |
36 extends Zend_Cloud_DocumentService_Adapter_AbstractAdapter |
36 extends Zend_Cloud_DocumentService_Adapter_AbstractAdapter |
37 { |
37 { |
38 /* |
38 /* |
39 * Options array keys for the SimpleDB adapter. |
39 * Options array keys for the SimpleDB adapter. |
40 */ |
40 */ |
41 const AWS_ACCESS_KEY = 'aws_accesskey'; |
41 const AWS_ACCESS_KEY = 'aws_accesskey'; |
42 const AWS_SECRET_KEY = 'aws_secretkey'; |
42 const AWS_SECRET_KEY = 'aws_secretkey'; |
43 |
43 |
44 const ITEM_NAME = 'ItemName'; |
44 const ITEM_NAME = 'ItemName'; |
45 |
45 |
46 const MERGE_OPTION = "merge"; |
46 const MERGE_OPTION = "merge"; |
47 const RETURN_DOCUMENTS = "return_documents"; |
47 const RETURN_DOCUMENTS = "return_documents"; |
48 |
48 |
49 const DEFAULT_QUERY_CLASS = 'Zend_Cloud_DocumentService_Adapter_SimpleDb_Query'; |
49 const DEFAULT_QUERY_CLASS = 'Zend_Cloud_DocumentService_Adapter_SimpleDb_Query'; |
50 |
50 |
52 /** |
52 /** |
53 * SQS service instance. |
53 * SQS service instance. |
54 * @var Zend_Service_Amazon_SimpleDb |
54 * @var Zend_Service_Amazon_SimpleDb |
55 */ |
55 */ |
56 protected $_simpleDb; |
56 protected $_simpleDb; |
57 |
57 |
58 /** |
58 /** |
59 * Class to utilize for new query objects |
59 * Class to utilize for new query objects |
60 * @var string |
60 * @var string |
61 */ |
61 */ |
62 protected $_queryClass = 'Zend_Cloud_DocumentService_Adapter_SimpleDb_Query'; |
62 protected $_queryClass = 'Zend_Cloud_DocumentService_Adapter_SimpleDb_Query'; |
63 |
63 |
64 /** |
64 /** |
65 * Constructor |
65 * Constructor |
66 * |
66 * |
67 * @param array|Zend_Config $options |
67 * @param array|Zend_Config $options |
68 * @return void |
68 * @return void |
69 */ |
69 */ |
70 public function __construct($options = array()) |
70 public function __construct($options = array()) |
71 { |
71 { |
72 if ($options instanceof Zend_Config) { |
72 if ($options instanceof Zend_Config) { |
73 $options = $options->toArray(); |
73 $options = $options->toArray(); |
74 } |
74 } |
75 |
75 |
80 $this->_simpleDb = new Zend_Service_Amazon_SimpleDb( |
80 $this->_simpleDb = new Zend_Service_Amazon_SimpleDb( |
81 $options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY] |
81 $options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY] |
82 ); |
82 ); |
83 |
83 |
84 if (isset($options[self::HTTP_ADAPTER])) { |
84 if (isset($options[self::HTTP_ADAPTER])) { |
85 $this->_sqs->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); |
85 $this->_simpleDb->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); |
86 } |
86 } |
87 |
87 |
88 if (isset($options[self::DOCUMENT_CLASS])) { |
88 if (isset($options[self::DOCUMENT_CLASS])) { |
89 $this->setDocumentClass($options[self::DOCUMENT_CLASS]); |
89 $this->setDocumentClass($options[self::DOCUMENT_CLASS]); |
90 } |
90 } |
91 |
91 |
103 * |
103 * |
104 * @param string $name |
104 * @param string $name |
105 * @param array $options |
105 * @param array $options |
106 * @return void |
106 * @return void |
107 */ |
107 */ |
108 public function createCollection($name, $options = null) |
108 public function createCollection($name, $options = null) |
109 { |
109 { |
110 try { |
110 try { |
111 $this->_simpleDb->createDomain($name); |
111 $this->_simpleDb->createDomain($name); |
112 } catch(Zend_Service_Amazon_Exception $e) { |
112 } catch(Zend_Service_Amazon_Exception $e) { |
113 throw new Zend_Cloud_DocumentService_Exception('Error on domain creation: '.$e->getMessage(), $e->getCode(), $e); |
113 throw new Zend_Cloud_DocumentService_Exception('Error on domain creation: '.$e->getMessage(), $e->getCode(), $e); |
119 * |
119 * |
120 * @param string $name |
120 * @param string $name |
121 * @param array $options |
121 * @param array $options |
122 * @return void |
122 * @return void |
123 */ |
123 */ |
124 public function deleteCollection($name, $options = null) |
124 public function deleteCollection($name, $options = null) |
125 { |
125 { |
126 try { |
126 try { |
127 $this->_simpleDb->deleteDomain($name); |
127 $this->_simpleDb->deleteDomain($name); |
128 } catch(Zend_Service_Amazon_Exception $e) { |
128 } catch(Zend_Service_Amazon_Exception $e) { |
129 throw new Zend_Cloud_DocumentService_Exception('Error on collection deletion: '.$e->getMessage(), $e->getCode(), $e); |
129 throw new Zend_Cloud_DocumentService_Exception('Error on collection deletion: '.$e->getMessage(), $e->getCode(), $e); |
155 * |
155 * |
156 * @param string $collectionName Name of collection for which to list documents |
156 * @param string $collectionName Name of collection for which to list documents |
157 * @param array|null $options |
157 * @param array|null $options |
158 * @return Zend_Cloud_DocumentService_DocumentSet |
158 * @return Zend_Cloud_DocumentService_DocumentSet |
159 */ |
159 */ |
160 public function listDocuments($collectionName, array $options = null) |
160 public function listDocuments($collectionName, array $options = null) |
161 { |
161 { |
162 $query = $this->select('*')->from($collectionName); |
162 $query = $this->select('*')->from($collectionName); |
163 $items = $this->query($collectionName, $query, $options); |
163 $items = $this->query($collectionName, $query, $options); |
164 return $items; |
164 return $items; |
165 } |
165 } |
174 */ |
174 */ |
175 public function insertDocument($collectionName, $document, $options = null) |
175 public function insertDocument($collectionName, $document, $options = null) |
176 { |
176 { |
177 if (is_array($document)) { |
177 if (is_array($document)) { |
178 $document = $this->_getDocumentFromArray($document); |
178 $document = $this->_getDocumentFromArray($document); |
179 } |
179 } |
180 |
180 |
181 if (!$document instanceof Zend_Cloud_DocumentService_Document) { |
181 if (!$document instanceof Zend_Cloud_DocumentService_Document) { |
182 throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); |
182 throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); |
183 } |
183 } |
184 |
184 |
185 try { |
185 try { |
186 $this->_simpleDb->putAttributes( |
186 $this->_simpleDb->putAttributes( |
187 $collectionName, |
187 $collectionName, |
188 $document->getID(), |
188 $document->getID(), |
189 $this->_makeAttributes($document->getID(), $document->getFields()) |
189 $this->_makeAttributes($document->getID(), $document->getFields()) |
193 } |
193 } |
194 } |
194 } |
195 |
195 |
196 /** |
196 /** |
197 * Replace an existing document with a new version |
197 * Replace an existing document with a new version |
198 * |
198 * |
199 * @param string $collectionName |
199 * @param string $collectionName |
200 * @param array|Zend_Cloud_DocumentService_Document $document |
200 * @param array|Zend_Cloud_DocumentService_Document $document |
201 * @param array $options |
201 * @param array $options |
202 * @return void |
202 * @return void |
203 */ |
203 */ |
204 public function replaceDocument($collectionName, $document, $options = null) |
204 public function replaceDocument($collectionName, $document, $options = null) |
205 { |
205 { |
206 if (is_array($document)) { |
206 if (is_array($document)) { |
207 $document = $this->_getDocumentFromArray($document); |
207 $document = $this->_getDocumentFromArray($document); |
208 } |
208 } |
209 |
209 |
210 if (!$document instanceof Zend_Cloud_DocumentService_Document) { |
210 if (!$document instanceof Zend_Cloud_DocumentService_Document) { |
211 throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); |
211 throw new Zend_Cloud_DocumentService_Exception('Invalid document supplied'); |
212 } |
212 } |
213 |
213 |
214 // Delete document first, then insert. PutAttributes always keeps any |
214 // Delete document first, then insert. PutAttributes always keeps any |
215 // fields not referenced in the payload, but present in the document |
215 // fields not referenced in the payload, but present in the document |
216 $documentId = $document->getId(); |
216 $documentId = $document->getId(); |
217 $fields = $document->getFields(); |
217 $fields = $document->getFields(); |
218 $docClass = get_class($document); |
218 $docClass = get_class($document); |
219 $this->deleteDocument($collectionName, $document, $options); |
219 $this->deleteDocument($collectionName, $document, $options); |
220 |
220 |
221 $document = new $docClass($fields, $documentId); |
221 $document = new $docClass($fields, $documentId); |
222 $this->insertDocument($collectionName, $document); |
222 $this->insertDocument($collectionName, $document); |
223 } |
223 } |
224 |
224 |
225 /** |
225 /** |
226 * Update document. The new document replaces the existing document. |
226 * Update document. The new document replaces the existing document. |
227 * |
227 * |
228 * Option 'merge' specifies to add all attributes (if true) or |
228 * Option 'merge' specifies to add all attributes (if true) or |
229 * specific attributes ("attr" => true) instead of replacing them. |
229 * specific attributes ("attr" => true) instead of replacing them. |
230 * By default, attributes are replaced. |
230 * By default, attributes are replaced. |
231 * |
231 * |
232 * @param string $collectionName |
232 * @param string $collectionName |
233 * @param mixed|Zend_Cloud_DocumentService_Document $documentId Document ID, adapter-dependent |
233 * @param mixed|Zend_Cloud_DocumentService_Document $documentId Document ID, adapter-dependent |
234 * @param array|Zend_Cloud_DocumentService_Document $fieldset Set of fields to update |
234 * @param array|Zend_Cloud_DocumentService_Document $fieldset Set of fields to update |
235 * @param array $options |
235 * @param array $options |
236 * @return boolean |
236 * @return boolean |
246 if (empty($documentId)) { |
246 if (empty($documentId)) { |
247 $documentId = $fieldset->getId(); |
247 $documentId = $fieldset->getId(); |
248 } |
248 } |
249 $fieldset = $fieldset->getFields(); |
249 $fieldset = $fieldset->getFields(); |
250 } |
250 } |
251 |
251 |
252 $replace = array(); |
252 $replace = array(); |
253 if (empty($options[self::MERGE_OPTION])) { |
253 if (empty($options[self::MERGE_OPTION])) { |
254 // no merge option - we replace all |
254 // no merge option - we replace all |
255 foreach ($fieldset as $key => $value) { |
255 foreach ($fieldset as $key => $value) { |
256 $replace[$key] = true; |
256 $replace[$key] = true; |
261 // if there's merge key, we add it, otherwise we replace it |
261 // if there's merge key, we add it, otherwise we replace it |
262 $replace[$key] = true; |
262 $replace[$key] = true; |
263 } |
263 } |
264 } |
264 } |
265 } // otherwise $replace is empty - all is merged |
265 } // otherwise $replace is empty - all is merged |
266 |
266 |
267 try { |
267 try { |
268 $this->_simpleDb->putAttributes( |
268 $this->_simpleDb->putAttributes( |
269 $collectionName, |
269 $collectionName, |
270 $documentId, |
270 $documentId, |
271 $this->_makeAttributes($documentId, $fieldset), |
271 $this->_makeAttributes($documentId, $fieldset), |
316 return $this->_resolveAttributes($attributes, true); |
316 return $this->_resolveAttributes($attributes, true); |
317 } catch(Zend_Service_Amazon_Exception $e) { |
317 } catch(Zend_Service_Amazon_Exception $e) { |
318 throw new Zend_Cloud_DocumentService_Exception('Error on fetching document: '.$e->getMessage(), $e->getCode(), $e); |
318 throw new Zend_Cloud_DocumentService_Exception('Error on fetching document: '.$e->getMessage(), $e->getCode(), $e); |
319 } |
319 } |
320 } |
320 } |
321 |
321 |
322 /** |
322 /** |
323 * Query for documents stored in the document service. If a string is passed in |
323 * Query for documents stored in the document service. If a string is passed in |
324 * $query, the query string will be passed directly to the service. |
324 * $query, the query string will be passed directly to the service. |
325 * |
325 * |
326 * @param string $collectionName Collection name |
326 * @param string $collectionName Collection name |
365 if (!$query instanceof $defaultClass) { |
365 if (!$query instanceof $defaultClass) { |
366 throw new Zend_Cloud_DocumentService_Exception('Query class must extend ' . self::DEFAULT_QUERY_CLASS); |
366 throw new Zend_Cloud_DocumentService_Exception('Query class must extend ' . self::DEFAULT_QUERY_CLASS); |
367 } |
367 } |
368 |
368 |
369 $query->select($fields); |
369 $query->select($fields); |
370 return $query; |
370 return $query; |
371 } |
371 } |
372 |
372 |
373 /** |
373 /** |
374 * Get the concrete service client |
374 * Get the concrete service client |
375 * |
375 * |
376 * @return Zend_Service_Amazon_SimpleDb |
376 * @return Zend_Service_Amazon_SimpleDb |
377 */ |
377 */ |
378 public function getClient() |
378 public function getClient() |
379 { |
379 { |
380 return $this->_simpleDb; |
380 return $this->_simpleDb; |
381 } |
381 } |
382 |
382 |
383 /** |
383 /** |
384 * Convert array of key-value pairs to array of Amazon attributes |
384 * Convert array of key-value pairs to array of Amazon attributes |
385 * |
385 * |
386 * @param string $name |
386 * @param string $name |
387 * @param array $attributes |
387 * @param array $attributes |
388 * @return array |
388 * @return array |
389 */ |
389 */ |
390 protected function _makeAttributes($name, $attributes) |
390 protected function _makeAttributes($name, $attributes) |
393 foreach ($attributes as $key => $attr) { |
393 foreach ($attributes as $key => $attr) { |
394 $result[] = new Zend_Service_Amazon_SimpleDb_Attribute($name, $key, $attr); |
394 $result[] = new Zend_Service_Amazon_SimpleDb_Attribute($name, $key, $attr); |
395 } |
395 } |
396 return $result; |
396 return $result; |
397 } |
397 } |
398 |
398 |
399 /** |
399 /** |
400 * Convert array of Amazon attributes to array of key-value pairs |
400 * Convert array of Amazon attributes to array of key-value pairs |
401 * |
401 * |
402 * @param array $attributes |
402 * @param array $attributes |
403 * @return array |
403 * @return array |
404 */ |
404 */ |
405 protected function _resolveAttributes($attributes, $returnDocument = false) |
405 protected function _resolveAttributes($attributes, $returnDocument = false) |
406 { |
406 { |
448 return new $documentClass($document, $key); |
448 return new $documentClass($document, $key); |
449 } |
449 } |
450 |
450 |
451 /** |
451 /** |
452 * Create a DocumentSet from a SimpleDb resultset |
452 * Create a DocumentSet from a SimpleDb resultset |
453 * |
453 * |
454 * @param Zend_Service_Amazon_SimpleDb_Page $resultSet |
454 * @param Zend_Service_Amazon_SimpleDb_Page $resultSet |
455 * @param bool $returnDocs |
455 * @param bool $returnDocs |
456 * @return Zend_Cloud_DocumentService_DocumentSet |
456 * @return Zend_Cloud_DocumentService_DocumentSet |
457 */ |
457 */ |
458 protected function _getDocumentSetFromResultSet(Zend_Service_Amazon_SimpleDb_Page $resultSet, $returnDocs = true) |
458 protected function _getDocumentSetFromResultSet(Zend_Service_Amazon_SimpleDb_Page $resultSet, $returnDocs = true) |
459 { |
459 { |
460 $docs = array(); |
460 $docs = array(); |