Mysql::setOptions()   D
last analyzed

Complexity

Conditions 9
Paths 9

Size

Total Lines 33
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 4.909
c 0
b 0
f 0
cc 9
eloc 26
nc 9
nop 1
1
<?php
2
declare(strict_types = 1);
3
4
/**
5
 * Micro
6
 *
7
 * @author    Raffael Sahli <[email protected]>
8
 * @copyright Copyright (c) 2017 gyselroth GmbH (https://gyselroth.com)
9
 * @license   MIT https://opensource.org/licenses/MIT
10
 */
11
12
namespace Micro\Db\Wrapper;
13
14
use \Psr\Log\LoggerInterface;
15
use \Mysqli;
16
use \mysqli_stmt;
17
use \mysqli_result;
18
19
class Mysql
20
{
21
22
    /**
23
     * Logger
24
     *
25
     * @var Logger
26
     */
27
    protected $logger;
28
29
30
    /**
31
     * Host
32
     *
33
     * @var string
34
     */
35
    protected $host = 'localhost';
36
37
38
    /**
39
     * Port
40
     *
41
     * @var int
42
     */
43
    protected $port = 3306;
44
45
46
    /**
47
     * Username
48
     *
49
     * @var string
50
     */
51
    protected $username = 'root';
52
53
54
    /**
55
     * Password
56
     *
57
     * @var string
58
     */
59
    protected $password = '';
60
61
62
    /**
63
     * Database
64
     *
65
     * @var string
66
     */
67
    protected $database = '';
68
69
70
    /**
71
     * Charset
72
     *
73
     * @var string
74
     */
75
    protected $charset = 'utf8';
76
77
78
    /**
79
     * Connection resource
80
     *
81
     * @var resource
82
     */
83
    protected $connection;
84
85
86
    /**
87
     * Last inserted id
88
     *
89
     * @var array
90
     */
91
    protected $last_inserted_ids;
92
93
94
    /**
95
     * construct
96
     *
97
     * @param   Iterable $config
98
     * @param   LoggerInterface   $logger
99
     */
100
    public function __construct(? Iterable $config, LoggerInterface $logger)
101
    {
102
        $this->setOptions($config);
103
        $this->logger = $logger;
0 ignored issues
show
Documentation Bug introduced by
It seems like $logger of type object<Psr\Log\LoggerInterface> is incompatible with the declared type object<Micro\Db\Wrapper\Logger> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
104
    }
105
106
107
    /**
108
     * Connect
109
     *
110
     * @return Mysql
111
     */
112
    public function connect(): Mysql
113
    {
114
        $this->connection = new Mysqli($this->host, $this->username, $this->password, $this->database, $this->port);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Mysqli($this->host,...>database, $this->port) of type object<mysqli> is incompatible with the declared type resource of property $connection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
115
        $this->connection->set_charset($this->charset);
116
117
        if (!$this->connection->connect_errno) {
118
            $this->logger->info('connection to mysql server ['.$this->host.'] was succesful', [
119
                'category' => get_class($this),
120
            ]);
121
        } else {
122
            throw new Exception('failed to connect to mysql server, error: '.$this->connection->connect_error.' ('.$this->connection->connect_errno.')');
123
        }
124
125
        return $this;
126
    }
127
128
129
    /**
130
     * Forward calls
131
     *
132
     * @param  array $method
133
     * @param  array $arguments
134
     * @return mixed
135
     */
136
    public function __call(string $method, array $arguments = [])
137
    {
138
        return call_user_func_array([&$this->connection, $method], $arguments);
139
    }
140
141
142
    /**
143
     * Set options
144
     *
145
     * @param  Iterable $config
146
     * @return Mysql
147
     */
148
    public function setOptions(? Iterable $config = null) : Mysql
149
    {
150
        if ($config === null) {
151
            return $this;
152
        }
153
154
        foreach ($config as $option => $value) {
155
            switch ($option) {
156
                case 'host':
157
                    $this->host = (string)$value;
158
                    break;
159
                case 'port':
160
                    $this->port = (int)$value;
161
                    break;
162
                case 'username':
163
                    $this->username = (string)$value;
164
                    break;
165
                case 'password':
166
                    $this->password = (string)$value;
167
                    break;
168
                case 'database':
169
                    $this->database = (string)$value;
170
                    break;
171
                case 'charset':
172
                    $this->charset = (string)$value;
173
                    break;
174
                default:
175
                    throw new Exception('invalid option '.$option.' given');
176
            }
177
        }
178
179
        return $this;
180
    }
181
182
183
    /**
184
     * Get connection
185
     *
186
     * @return resource
187
     */
188
    public function getResource()
189
    {
190
        if ($this->connection === null) {
191
            $this->connect();
192
        }
193
194
        return $this->connection;
195
    }
196
197
198
    /**
199
     * Query
200
     *
201
     * @param  string $query
202
     * @return mysqli_result
203
     */
204
    public function select(string $query): mysqli_result
205
    {
206
        $this->logger->debug('execute sql query ['.$query.']', [
207
            'category' => get_class($this),
208
        ]);
209
210
        $link   = $this->getResource();
211
        $result = $link->query($query);
0 ignored issues
show
Bug introduced by
The method query cannot be called on $link (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
212
213
        if ($result === false) {
214
            throw new Exception('failed to execute sql query with error '.$link->error.' ('.$link->errno.')');
215
        }
216
217
        return $result;
218
    }
219
220
221
    /**
222
     * Select query
223
     *
224
     * @param  string $query
225
     * @return bool
226
     */
227
    public function query(string $query): bool
228
    {
229
        $this->logger->debug('execute sql query ['.$query.']', [
230
            'category' => get_class($this),
231
        ]);
232
233
        $link   = $this->getResource();
234
        $result = $link->query($query);
0 ignored issues
show
Bug introduced by
The method query cannot be called on $link (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
235
236
        if ($result === false) {
237
            throw new Exception('failed to execute sql query with error '.$link->error.' ('.$link->errno.')');
238
        }
239
240
        return $result;
241
    }
242
243
244
    /**
245
     * Prepare query
246
     *
247
     * @param  string $query
248
     * @param  Iterable $values
249
     * @return mysqli_stmt
250
     */
251
    public function prepare(string $query, Iterable $values): mysqli_stmt
252
    {
253
        $this->logger->debug('prepare and execute sql query ['.$query.'] with values [{values}]', [
254
            'category' => get_class($this),
255
            'values'   => $values
256
        ]);
257
258
        $link  = $this->getResource();
259
        $stmt  = $link->prepare($query);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $link (of type resource).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
260
261
        if (!($stmt instanceof mysqli_stmt)) {
262
            throw new Exception('failed to prepare sql query with error '.$link->error.' ('.$link->errno.')');
263
        }
264
265
        $types = '';
266
        foreach ($values as $attr => $value) {
267
            $types .= 's';
268
        }
269
270
        $stmt->bind_param($types, ...$values);
271
        $stmt->execute();
272
273
        if ($stmt->error) {
274
            throw new Exception($stmt->error);
275
        }
276
277
        return $stmt;
278
    }
279
}
280