Passed
Push — master ( 3896ee...e50616 )
by Raffael
05:45
created

Factory::getAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 7
cts 7
cp 1
rs 9.7333
c 0
b 0
f 0
cc 2
nc 2
nop 5
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee.io
7
 *
8
 * @copyright   Copryright (c) 2017-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Tubee\Collection;
13
14
use Generator;
15
use MongoDB\BSON\ObjectIdInterface;
16
use MongoDB\Database;
17
use Psr\Log\LoggerInterface;
18
use Tubee\Collection;
19
use Tubee\DataObject\Factory as DataObjectFactory;
20
use Tubee\Endpoint\Factory as EndpointFactory;
21
use Tubee\Resource\Factory as ResourceFactory;
22
use Tubee\ResourceNamespace\ResourceNamespaceInterface;
23
use Tubee\Schema;
24
25
class Factory extends ResourceFactory
26
{
27
    /**
28
     * Collection name.
29
     */
30
    public const COLLECTION_NAME = 'collections';
31
32
    /**
33
     * Object factory.
34
     *
35
     * @var DataObjectFactory
36
     */
37
    protected $object_factory;
38
39
    /**
40
     * Endpoint.
41
     *
42
     * @var EndpointFactory
43
     */
44
    protected $endpoint_factory;
45
46
    /**
47
     * Initialize.
48
     */
49 11
    public function __construct(Database $db, EndpointFactory $endpoint_factory, DataObjectFactory $object_factory, LoggerInterface $logger)
50
    {
51 11
        $this->endpoint_factory = $endpoint_factory;
52 11
        $this->object_factory = $object_factory;
53 11
        parent::__construct($db, $logger);
54 11
    }
55
56
    /**
57
     * Has namespace.
58
     */
59 9
    public function has(ResourceNamespaceInterface $namespace, string $name): bool
60
    {
61 9
        return $this->db->{self::COLLECTION_NAME}->count([
62 9
            'name' => $name,
63 9
            'namespace' => $namespace->getName(),
64 9
        ]) > 0;
65
    }
66
67
    /**
68
     * Get all.
69
     */
70 3
    public function getAll(ResourceNamespaceInterface $namespace, ?array $query = null, ?int $offset = null, ?int $limit = null, ?array $sort = null): Generator
71
    {
72
        $filter = [
73 3
            'namespace' => $namespace->getName(),
74
        ];
75
76 3
        if (!empty($query)) {
77
            $filter = [
78 1
                '$and' => [$filter, $query],
79
            ];
80
        }
81
82 3
        return $this->getAllFrom($this->db->{self::COLLECTION_NAME}, $filter, $offset, $limit, $sort, function (array $resource) use ($namespace) {
83 3
            return $this->build($resource, $namespace);
84 3
        });
85
    }
86
87
    /**
88
     * Get one.
89
     */
90 4
    public function getOne(ResourceNamespaceInterface $namespace, string $name): CollectionInterface
91
    {
92 4
        $result = $this->db->{self::COLLECTION_NAME}->findOne([
93 4
            'name' => $name,
94 4
            'namespace' => $namespace->getName(),
95
        ], [
96 4
            'projection' => ['history' => 0],
97
        ]);
98
99 4
        if ($result === null) {
100 2
            throw new Exception\NotFound('collection '.$name.' is not registered');
101
        }
102
103 2
        return $this->build($result, $namespace);
104
    }
105
106
    /**
107
     * Delete by name.
108
     */
109 2
    public function deleteOne(ResourceNamespaceInterface $namespace, string $name): bool
110
    {
111 2
        $resource = $this->getOne($namespace, $name);
112
113 1
        return $this->deleteFrom($this->db->{self::COLLECTION_NAME}, $resource->getId());
114
    }
115
116
    /**
117
     * Add namespace.
118
     */
119 8
    public function add(ResourceNamespaceInterface $namespace, array $resource): ObjectIdInterface
120
    {
121 8
        $resource['kind'] = 'Collection';
122 8
        $resource = $this->validate($resource);
123
124 8
        if ($this->has($namespace, $resource['name'])) {
125 1
            throw new Exception\NotUnique('collection '.$resource['name'].' does already exists');
126
        }
127
128 8
        $resource['namespace'] = $namespace->getName();
129
130 8
        return $this->addTo($this->db->{self::COLLECTION_NAME}, $resource);
131
    }
132
133
    /**
134
     * Update.
135
     */
136
    public function update(CollectionInterface $resource, array $data): bool
137
    {
138
        $data['name'] = $resource->getName();
139
        $data['kind'] = 'Collection';
140
        $data = $this->validate($data);
141
142
        return $this->updateIn($this->db->{self::COLLECTION_NAME}, $resource, $data);
143
    }
144
145
    /**
146
     * Change stream.
147
     */
148
    public function watch(ResourceNamespaceInterface $namespace, ?ObjectIdInterface $after = null, bool $existing = true, ?array $query = null, ?int $offset = null, ?int $limit = null, ?array $sort = null): Generator
149
    {
150
        return $this->watchFrom($this->db->{self::COLLECTION_NAME}, $after, $existing, $query, function (array $resource) use ($namespace) {
151
            return $this->build($resource, $namespace);
152
        }, $offset, $limit, $sort);
153
    }
154
155
    /**
156
     * Build instance.
157
     */
158 5
    public function build(array $resource, ResourceNamespaceInterface $namespace): CollectionInterface
159
    {
160 5
        $schema = new Schema($resource['data']['schema'], $this->logger);
161
162 5
        return $this->initResource(new Collection($resource['name'], $namespace, $this->endpoint_factory, $this->object_factory, $schema, $this->logger, $resource));
163
    }
164
}
165