Completed
Push — master ( 519f76...318dd5 )
by Raffael
24:13 queued 15:29
created

Mysql::count()   A

Complexity

Conditions 3
Paths 6

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 12
cp 0
rs 9.552
c 0
b 0
f 0
cc 3
nc 6
nop 1
crap 12
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee
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\Endpoint;
13
14
use Generator;
15
use Psr\Log\LoggerInterface;
16
use Tubee\AttributeMap\AttributeMapInterface;
17
use Tubee\Collection\CollectionInterface;
18
use Tubee\Endpoint\Mysql\Exception\InvalidQuery;
19
use Tubee\Endpoint\Mysql\Wrapper as MysqlWrapper;
20
use Tubee\EndpointObject\EndpointObjectInterface;
21
use Tubee\Workflow\Factory as WorkflowFactory;
22
23
class Mysql extends AbstractSqlDatabase
24
{
25
    /**
26
     * Kind.
27
     */
28
    public const KIND = 'MysqlEndpoint';
29
30
    /**
31
     * Init endpoint.
32
     */
33
    public function __construct(string $name, string $type, string $table, MysqlWrapper $socket, CollectionInterface $collection, WorkflowFactory $workflow, LoggerInterface $logger, array $resource = [])
34
    {
35
        $this->socket = $socket;
36
        $this->table = $table;
37
        parent::__construct($name, $type, $collection, $workflow, $logger, $resource);
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function shutdown(bool $simulate = false): EndpointInterface
44
    {
45
        $this->socket->close();
0 ignored issues
show
Bug introduced by
The method close does only exist in Tubee\Endpoint\Mysql\Wrapper, but not in Tubee\Endpoint\Pdo\Wrapper.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
46
47
        return $this;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function count(?array $query = null): int
54
    {
55
        list($filter, $values) = $this->transformQuery($query);
56
57
        if ($filter === null) {
58
            $sql = 'SELECT COUNT(*) as count FROM '.$this->table;
59
        } else {
60
            $sql = 'SELECT COUNT(*) as count FROM '.$this->table.' WHERE '.$filter;
61
        }
62
63
        try {
64
            $result = $this->socket->prepareValues($sql, $values);
65
66
            return (int) $result->get_result()->fetch_assoc()['count'];
67
        } catch (InvalidQuery $e) {
68
            $this->logger->error('failed to count number of objects from endpoint', [
69
                'class' => get_class($this),
70
                'exception' => $e,
71
            ]);
72
73
            return 0;
74
        }
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function getAll(?array $query = null): Generator
81
    {
82
        list($filter, $values) = $this->transformQuery($query);
83
        $this->logGetAll($filter);
84
85
        if ($filter === null) {
86
            $sql = 'SELECT * FROM '.$this->table;
87
        } else {
88
            $sql = 'SELECT * FROM '.$this->table.' WHERE '.$filter;
89
        }
90
91
        try {
92
            $result = $this->socket->prepareValues($sql, $values);
93
        } catch (InvalidQuery $e) {
94
            $this->logger->error('failed to fetch resources from endpoint', [
95
                'class' => get_class($this),
96
                'exception' => $e,
97
            ]);
98
99
            return 0;
100
        }
101
102
        $i = 0;
103
        $result = $result->get_result();
104
105
        while ($row = $result->fetch_assoc()) {
106
            yield $this->build($row);
107
            $i;
108
        }
109
110
        return $i;
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function getOne(array $object, array $attributes = []): EndpointObjectInterface
117
    {
118
        list($filter, $values) = $query = $this->transformQuery($this->getFilterOne($object));
119
        $this->logGetOne($filter);
120
121
        $sql = 'SELECT * FROM '.$this->table.' WHERE '.$filter;
122
        $result = $this->socket->prepareValues($sql, $values);
123
        $result = $result->get_result();
124
125
        if ($result->num_rows > 1) {
126
            throw new Exception\ObjectMultipleFound('found more than one object with filter '.$filter);
127
        }
128
        if ($result->num_rows === 0) {
129
            throw new Exception\ObjectNotFound('no object found with filter '.$filter);
130
        }
131
132
        return $this->build($result->fetch_assoc(), $query);
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function create(AttributeMapInterface $map, array $object, bool $simulate = false): ?string
139
    {
140
        $this->logCreate($object);
141
        $result = $this->prepareCreate($object, $simulate);
142
143
        if ($simulate === true) {
144
            return null;
145
        }
146
147
        return (string) $result->insert_id;
148
    }
149
}
150