1 <?php
2
3 /**
4 * ArangoDB PHP client: single collection
5 *
6 * @package triagens\ArangoDb
7 * @author Jan Steemann
8 * @copyright Copyright 2012, triagens GmbH, Cologne, Germany
9 */
10
11 namespace triagens\ArangoDb;
12
13 /**
14 * Value object representing a collection
15 *
16 * <br>
17 *
18 * @package triagens\ArangoDb
19 * @since 0.2
20 */
21 class Collection
22 {
23 /**
24 * The collection id (might be NULL for new collections)
25 *
26 * @var mixed - collection id
27 */
28 private $_id;
29
30 /**
31 * The collection name (might be NULL for new collections)
32 *
33 * @var string - collection name
34 */
35 private $_name;
36
37 /**
38 * The collection type (might be NULL for new collections)
39 *
40 * @var int - collection type
41 */
42 private $_type;
43
44 /**
45 * The collection waitForSync value (might be NULL for new collections)
46 *
47 * @var bool - waitForSync value
48 */
49 private $_waitForSync;
50
51 /**
52 * The collection journalSize value (might be NULL for new collections)
53 *
54 * @var int - journalSize value
55 */
56 private $_journalSize;
57
58 /**
59 * The collection isSystem value (might be NULL for new collections)
60 *
61 * @var bool - isSystem value
62 */
63 private $_isSystem;
64
65 /**
66 * The collection isVolatile value (might be NULL for new collections)
67 *
68 * @var bool - isVolatile value
69 */
70 private $_isVolatile;
71
72 /**
73 * The collection numberOfShards value (might be NULL for new collections)
74 *
75 * @var int - numberOfShards value
76 */
77 private $_numberOfShards;
78
79 /**
80 * The collection shardKeys value (might be NULL for new collections)
81 *
82 * @var array - shardKeys value
83 */
84 private $_shardKeys;
85
86 /**
87 * The collection status value
88 *
89 * @var int - status value
90 */
91 private $_status;
92
93 /**
94 * The collection keyOptions value
95 *
96 * @var array - keyOptions value
97 */
98 private $_keyOptions;
99
100 /**
101 * Collection id index
102 */
103 const ENTRY_ID = 'id';
104
105 /**
106 * Collection name index
107 */
108 const ENTRY_NAME = 'name';
109
110 /**
111 * Collection type index
112 */
113 const ENTRY_TYPE = 'type';
114
115 /**
116 * Collection 'waitForSync' index
117 */
118 const ENTRY_WAIT_SYNC = 'waitForSync';
119
120 /**
121 * Collection 'journalSize' index
122 */
123 const ENTRY_JOURNAL_SIZE = 'journalSize';
124
125 /**
126 * Collection 'status' index
127 */
128 const ENTRY_STATUS = 'status';
129
130 /**
131 * Collection 'keyOptions' index
132 */
133 const ENTRY_KEY_OPTIONS = 'keyOptions';
134
135 /**
136 * Collection 'isSystem' index
137 */
138 const ENTRY_IS_SYSTEM = 'isSystem';
139
140 /**
141 * Collection 'isVolatile' index
142 */
143 const ENTRY_IS_VOLATILE = 'isVolatile';
144
145 /**
146 * Collection 'numberOfShards' index
147 */
148 const ENTRY_NUMBER_OF_SHARDS = 'numberOfShards';
149
150 /**
151 * Collection 'shardKeys' index
152 */
153 const ENTRY_SHARD_KEYS = 'shardKeys';
154
155 /**
156 * properties option
157 */
158 const OPTION_PROPERTIES = 'properties';
159
160 /**
161 * document collection type
162 */
163 const TYPE_DOCUMENT = 2;
164
165 /**
166 * edge collection type
167 */
168 const TYPE_EDGE = 3;
169
170 /**
171 * New born collection
172 */
173 const STATUS_NEW_BORN = 1;
174
175 /**
176 * Unloaded collection
177 */
178 const STATUS_UNLOADED = 2;
179
180 /**
181 * Loaded collection
182 */
183 const STATUS_LOADED = 3;
184
185 /**
186 * Collection being unloaded
187 */
188 const STATUS_BEING_UNLOADED = 4;
189
190 /**
191 * Deleted collection
192 */
193 const STATUS_DELETED = 5;
194
195 /**
196 * Constructs an empty collection
197 *
198 * @param string $name - name for the collection
199 *
200 * @throws \triagens\ArangoDb\ClientException
201 */
202 public function __construct($name = null)
203 {
204 if ($name !== null) {
205 $this->setName($name);
206 }
207 }
208
209 /**
210 * Factory method to construct a new collection
211 *
212 * @throws ClientException
213 *
214 * @param array $values - initial values for collection
215 *
216 * @return Collection
217 */
218 public static function createFromArray(array $values)
219 {
220 $collection = new self();
221
222 foreach ($values as $key => $value) {
223 $collection->set($key, $value);
224 }
225
226 return $collection;
227 }
228
229 /**
230 * Get the default collection type
231 *
232 * @return string - name
233 */
234 public static function getDefaultType()
235 {
236 return self::TYPE_DOCUMENT;
237 }
238
239 /**
240 * Clone a collection
241 *
242 * Returns the clone
243 *
244 * @magic
245 *
246 * @return void
247 */
248 public function __clone()
249 {
250 $this->_id = null;
251 $this->_name = null;
252 $this->_waitForSync = null;
253 $this->_journalSize = null;
254 $this->_isSystem = null;
255 $this->_isVolatile = null;
256 $this->_numberOfShards = null;
257 $this->_shardKeys = null;
258 }
259
260 /**
261 * Get a string representation of the collection
262 *
263 * Returns the collection as JSON-encoded string
264 *
265 * @magic
266 *
267 * @return string - JSON-encoded collection
268 */
269 public function __toString()
270 {
271 return $this->toJson();
272 }
273
274 /**
275 * Returns the collection as JSON-encoded string
276 *
277 * @return string - JSON-encoded collection
278 */
279 public function toJson()
280 {
281 return json_encode($this->getAll());
282 }
283
284 /**
285 * Returns the collection as a serialized string
286 *
287 * @return string - PHP serialized collection
288 */
289 public function toSerialized()
290 {
291 return serialize($this->getAll());
292 }
293
294 /**
295 * Get all collection attributes
296 *
297 * @return array - array of all collection attributes
298 */
299 public function getAll()
300 {
301 $result = [
302 self::ENTRY_ID => $this->_id,
303 self::ENTRY_NAME => $this->_name,
304 self::ENTRY_WAIT_SYNC => $this->_waitForSync,
305 self::ENTRY_JOURNAL_SIZE => $this->_journalSize,
306 self::ENTRY_IS_SYSTEM => $this->_isSystem,
307 self::ENTRY_IS_VOLATILE => $this->_isVolatile,
308 self::ENTRY_TYPE => $this->_type,
309 self::ENTRY_STATUS => $this->_status,
310 self::ENTRY_KEY_OPTIONS => $this->_keyOptions
311 ];
312
313 if (null !== $this->_numberOfShards) {
314 $result[self::ENTRY_NUMBER_OF_SHARDS] = $this->_numberOfShards;
315 }
316
317 if (is_array($this->_shardKeys)) {
318 $result[self::ENTRY_SHARD_KEYS] = $this->_shardKeys;
319 }
320
321 return $result;
322 }
323
324 /**
325 * Set a collection attribute
326 *
327 * The key (attribute name) must be a string.
328 *
329 * This will validate the value of the attribute and might throw an
330 * exception if the value is invalid.
331 *
332 * @throws ClientException
333 *
334 * @param string $key - attribute name
335 * @param mixed $value - value for attribute
336 *
337 * @return void
338 */
339 public function set($key, $value)
340 {
341 if (!is_string($key)) {
342 throw new ClientException('Invalid collection attribute type');
343 }
344
345 if ($key === self::ENTRY_ID) {
346 $this->setId($value);
347
348 return;
349 }
350
351 if ($key === self::ENTRY_NAME) {
352 $this->setName($value);
353
354 return;
355 }
356
357 if ($key === self::ENTRY_WAIT_SYNC) {
358 $this->setWaitForSync($value);
359
360 return;
361 }
362
363 if ($key === self::ENTRY_JOURNAL_SIZE) {
364 $this->setJournalSize($value);
365
366 return;
367 }
368
369 if ($key === self::ENTRY_IS_SYSTEM) {
370 $this->setIsSystem($value);
371
372 return;
373 }
374
375 if ($key === self::ENTRY_IS_VOLATILE) {
376 $this->setIsVolatile($value);
377
378 return;
379 }
380
381 if ($key === self::ENTRY_TYPE) {
382 $this->setType($value);
383
384 return;
385 }
386
387 if ($key === self::ENTRY_STATUS) {
388 $this->setStatus($value);
389
390 return;
391 }
392
393 if ($key === self::ENTRY_KEY_OPTIONS) {
394 $this->setKeyOptions($value);
395
396 return;
397 }
398
399 if ($key === self::ENTRY_NUMBER_OF_SHARDS) {
400 $this->setNumberOfShards($value);
401
402 return;
403 }
404
405 if ($key === self::ENTRY_SHARD_KEYS) {
406 $this->setShardKeys($value);
407
408 return;
409 }
410 // unknown attribute, will be ignored
411 }
412
413 /**
414 * Set the collection id
415 *
416 * This will throw if the id of an existing collection gets updated to some other id
417 *
418 * @throws ClientException
419 *
420 * @param mixed $id - collection id
421 *
422 * @return bool
423 */
424 public function setId($id)
425 {
426 if ($this->_id !== null && $this->_id !== $id) {
427 throw new ClientException('Should not update the id of an existing collection');
428 }
429
430 return $this->_id = (string) $id;
431 }
432
433 /**
434 * Get the collection id (if already known)
435 *
436 * Collection ids are generated on the server only.
437 *
438 * Collection ids are numeric but might be bigger than PHP_INT_MAX.
439 * To reliably store a collection id elsewhere, a PHP string should be used
440 *
441 * @return mixed - collection id, might be NULL if collection does not yet have an id
442 */
443 public function getId()
444 {
445 return $this->_id;
446 }
447
448 /**
449 * Set the collection name
450 *
451 * @throws ClientException
452 *
453 * @param string $name - name
454 *
455 * @return void
456 */
457 public function setName($name)
458 {
459 assert(is_string($name));
460
461 if ($this->_name !== null && $this->_name !== $name) {
462 throw new ClientException('Should not update the name of an existing collection');
463 }
464
465 $this->_name = (string) $name;
466 }
467
468 /**
469 * Get the collection name (if already known)
470 *
471 * @return string - name
472 */
473 public function getName()
474 {
475 return $this->_name;
476 }
477
478 /**
479 * Set the collection type.
480 *
481 * This is useful before a collection is create() 'ed in order to set a different type than the normal one.
482 * For example this must be set to 3 in order to create an edge-collection.
483 *
484 * @throws ClientException
485 *
486 * @param int $type - type = 2 -> normal collection, type = 3 -> edge-collection
487 *
488 * @return void
489 */
490 public function setType($type)
491 {
492 assert(is_int($type));
493
494 if ($this->_type !== null && $this->_type !== $type) {
495 throw new ClientException('Should not update the type of an existing collection');
496 }
497
498 if ($type !== self::TYPE_DOCUMENT && $type !== self::TYPE_EDGE) {
499 throw new ClientException('Invalid type used for collection');
500 }
501
502 $this->_type = $type;
503 }
504
505 /**
506 * Get the collection type (if already known)
507 *
508 * @return string - name
509 */
510 public function getType()
511 {
512 return $this->_type;
513 }
514
515 /**
516 * Set the collection status.
517 *
518 * This is useful before a collection is create()'ed in order to set a status.
519 *
520 * @throws ClientException
521 *
522 * @param int $status - statuses = 1 -> new born, status = 2 -> unloaded, status = 3 -> loaded, status = 4 -> being unloaded, status = 5 -> deleted
523 *
524 * @return void
525 */
526 public function setStatus($status)
527 {
528 assert(is_int($status));
529
530 if ($this->_status !== null && $this->_status !== $status) {
531 throw new ClientException('Should not update the status of an existing collection');
532 }
533
534 if (!in_array(
535 $status,
536 [
537 self::STATUS_NEW_BORN,
538 self::STATUS_UNLOADED,
539 self::STATUS_LOADED,
540 self::STATUS_BEING_UNLOADED,
541 self::STATUS_DELETED
542 ], true
543 )
544 ) {
545 throw new ClientException('Invalid status used for collection');
546 }
547
548 $this->_status = $status;
549 }
550
551 /**
552 * Get the collection status (if already known)
553 *
554 * @return int - status
555 */
556 public function getStatus()
557 {
558 return $this->_status;
559 }
560
561 /**
562 * Set the collection key options.
563 *
564 * @throws ClientException
565 *
566 * @param array $keyOptions - An associative array containing optional keys: type, allowUserKeys, increment, offset.
567 *
568 * @return void
569 */
570 public function setKeyOptions($keyOptions)
571 {
572 assert(is_array($keyOptions));
573
574 $this->_keyOptions = $keyOptions;
575 }
576
577 /**
578 * Get the collection key options (if already known)
579 *
580 * @return array - keyOptions
581 */
582 public function getKeyOptions()
583 {
584 return $this->_keyOptions;
585 }
586
587 /**
588 * Set the waitForSync value
589 *
590 * @param bool $value - waitForSync value
591 *
592 * @return void
593 */
594 public function setWaitForSync($value)
595 {
596 assert(null === $value || is_bool($value));
597 $this->_waitForSync = $value;
598 }
599
600 /**
601 * Get the waitForSync value (if already known)
602 *
603 * @return bool - waitForSync value
604 */
605 public function getWaitForSync()
606 {
607 return $this->_waitForSync;
608 }
609
610 /**
611 * Set the journalSize value
612 *
613 * @param int $value - journalSize value
614 *
615 * @return void
616 */
617 public function setJournalSize($value)
618 {
619 assert(is_numeric($value));
620 $this->_journalSize = $value;
621 }
622
623 /**
624 * Get the journalSize value (if already known)
625 *
626 * @return int - journalSize value
627 */
628 public function getJournalSize()
629 {
630 return $this->_journalSize;
631 }
632
633 /**
634 * Set the isSystem value
635 *
636 * @param bool $value - isSystem: false->user collection, true->system collection
637 *
638 * @return void
639 */
640 public function setIsSystem($value)
641 {
642 assert(null === $value || is_bool($value));
643 $this->_isSystem = $value;
644 }
645
646 /**
647 * Get the isSystem value (if already known)
648 *
649 * @return bool - isSystem value
650 */
651 public function getIsSystem()
652 {
653 return $this->_isSystem;
654 }
655
656 /**
657 * Set the isVolatile value
658 *
659 * @param bool $value - isVolatile value
660 *
661 * @return void
662 */
663 public function setIsVolatile($value)
664 {
665 assert(null === $value || is_bool($value));
666 $this->_isVolatile = $value;
667 }
668
669 /**
670 * Get the isVolatile value (if already known)
671 *
672 * @return bool - isVolatile value
673 */
674 public function getIsVolatile()
675 {
676 return $this->_isVolatile;
677 }
678
679 /**
680 * Set the numberOfShards value
681 *
682 * @param int $value - numberOfShards value
683 *
684 * @return void
685 */
686 public function setNumberOfShards($value)
687 {
688 assert(null === $value || is_numeric($value));
689 $this->_numberOfShards = $value;
690 }
691
692 /**
693 * Get the numberOfShards value (if already known)
694 *
695 * @return int - numberOfShards value
696 */
697 public function getNumberOfShards()
698 {
699 return $this->_numberOfShards;
700 }
701
702 /**
703 * Set the shardKeys value
704 *
705 * @param array $value - shardKeys value
706 *
707 * @return void
708 */
709 public function setShardKeys($value)
710 {
711 assert(null === $value || is_array($value));
712 $this->_shardKeys = $value;
713 }
714
715 /**
716 * Get the shardKeys value (if already known)
717 *
718 * @return array - shardKeys value
719 */
720 public function getShardKeys()
721 {
722 return $this->_shardKeys;
723 }
724 }
725