Completed
Push — master ( b659c5...c65770 )
by Michael
10:22
created

Connection   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 0
dl 0
loc 225
ccs 0
cts 70
cp 0
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A __call() 0 11 3
A beginTransaction() 0 4 1
A commit() 0 4 1
A exec() 0 4 1
A inTransaction() 0 4 1
A isExposingPdo() 0 4 1
A isSql92Mode() 0 4 1
A prepare() 0 4 1
A query() 0 7 2
A rollBack() 0 4 1
A setAttribute() 0 4 1
A setExposingPdo() 0 5 1
A setSql92Mode() 0 5 1
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * Contains class Connection.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2016-2017 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @author    Michael Cummings <[email protected]>
32
 * @copyright 2016-2017 Michael Cummings
33
 * @license   LGPL-3.0+
34
 */
35
namespace Yapeal\Sql;
36
37
/**
38
 * Class Connection is a wrapper for an underlying \PDO instance.
39
 *
40
 * This was suppose to just be a transparent wrapper around \PDO with extends. Plan was to have something to make
41
 * testing easier and have place to implement an interface but instead I've had to go beyond that to make it work like I
42
 * wanted it to.
43
 */
44
class Connection implements ConnectionInterface
45
{
46
    /**
47
     * Connection constructor.
48
     *
49
     * @param string      $dsn      The Data Source Name, or DSN, contains the information required to connect to the
50
     *                              database. In general, a DSN consists of the PDO driver name, followed by a colon,
51
     *                              followed by the PDO driver-specific connection syntax. See the docs
52
     *                              for<b>\PDO::__construct()</b> for full details.
53
     * @param string|null $username The user name for the DSN string. This parameter is optional for some PDO drivers.
54
     *                              Example: SqlLite since it just a file in a directory somewhere it doesn't need
55
     *                              this.
56
     * @param string|null $password The password for the DSN string. This parameter is optional for some PDO drivers.
57
     *                              Example: SqlLite since it just a file in a directory somewhere it doesn't need
58
     *                              this.
59
     * @param array|null  $options  A key=>value array of driver-specific connection options.
60
     *
61
     * @throws \PDOException The \PDO constructor always throws an exception even if you are setting it to use errors
62
     *                       instead. That setting will only effect any of the follow interacts with \PDO.
63
     * @see \PDO
64
     */
65
    public function __construct(string $dsn, string $username = null, string $password = null, array $options = null)
66
    {
67
        $this->pdo = new \PDO($dsn, $username, $password, $options);
68
        $this->exposingPdo = false;
69
        $this->sql92Mode = false;
70
    }
71
    /**
72
     * Allow any other underlying \PDO methods be called without having to wrap them all.
73
     *
74
     * The wrapper methods of this class are expected to cover what Yapeal-ng itself uses from \PDO but allows the rest
75
     * as well through this method.
76
     *
77
     * @param string $name      Name of any \PDO methods not defined above.
78
     * @param array  $arguments Method arguments as a name=>value array.
79
     *
80
     * @return mixed
81
     * @throws \BadMethodCallException
82
     */
83
    public function __call(string $name, array $arguments)
84
    {
85
        if (!method_exists($this->pdo, $name)) {
86
            throw new \BadMethodCallException('Unknown method ' . $name);
87
        }
88
        if (!$this->isExposingPdo()) {
89
            $mess = 'Call to an unexposed but valid \PDO method if you need to use it insure exposingPdo is true';
90
            throw new \BadMethodCallException($mess);
91
        }
92
        return call_user_func_array([$this->pdo, $name], $arguments);
93
    }
94
    /**
95
     * Initiates a transaction.
96
     *
97
     * @return bool <b>true</b> on success or may return <b>false</b> or emits <b>\PDOException</b> (depending on error
98
     * handling).
99
     * @throws \PDOException
100
     */
101
    public function beginTransaction(): bool
102
    {
103
        return (bool)$this->pdo->beginTransaction();
104
    }
105
    /**
106
     * Commits a transaction.
107
     *
108
     * @return bool <b>true</b> on success or may return <b>false</b> or emits <b>\PDOException</b> (depending on error
109
     * handling).
110
     * @throws \PDOException
111
     */
112
    public function commit(): bool
113
    {
114
        return (bool)$this->pdo->commit();
115
    }
116
    /**
117
     * Execute an SQL statement and return the number of affected rows.
118
     *
119
     * Wrapper to allow proper type hinting.
120
     *
121
     * @param string $statement This must be a valid SQL statement for the target database server. This can _not_ be
122
     *                          used with anything that returns a result set like SELECT etc. If you need that use
123
     *                          <b>\PDO::query</b> or preferably <b>\PDO::prepare</b> and <b>\PDOStatement:execute</b>
124
     *                          for better safety and improved repeated query handling.
125
     *
126
     * @return int|false <b>\PDO::exec</b> returns the number of rows that were modified or deleted by the SQL statement
127
     * you issued. If no rows were affected, <b>\PDO::exec</b> returns 0. <b>\PDO::exec<b> may return <b>false<b> or
128
     * emits <b>\PDOException</b> (depending on error handling).
129
     * @throws \PDOException
130
     */
131
    public function exec(string $statement)
132
    {
133
        return $this->pdo->exec($statement);
134
    }
135
    /**
136
     * Checks if inside a transaction.
137
     *
138
     * @return bool <b>true</b> if a transaction is currently active, and <b>false</b> if not.
139
     */
140
    public function inTransaction(): bool
141
    {
142
        return (bool)$this->pdo->inTransaction();
143
    }
144
    /**
145
     * Flag to indicate if non-wrapper methods of underlying \PDO connection can be used.
146
     *
147
     * @return bool
148
     */
149
    public function isExposingPdo(): bool
150
    {
151
        return $this->exposingPdo;
152
    }
153
    /**
154
     * Flag to mark if the under-laying PDO driver has already been set to it's most SQL-92 compatible mode or not.
155
     *
156
     * @return bool
157
     */
158
    public function isSql92Mode(): bool
159
    {
160
        return $this->sql92Mode;
161
    }
162
    /**
163
     * Prepares a statement for execution and returns a statement object.
164
     *
165
     * @param string $statement      This must be a valid SQL statement for the target database server.
166
     * @param array  $driver_options This array holds one or more key=>value pairs to set attribute values for the
167
     *                               <b>\PDOStatement</b> object that this method returns. You would most commonly
168
     *                               use this to set the <b>\PDO::ATTR_CURSOR</b> value to <b>\PDO::CURSOR_SCROLL</b>
169
     *                               to request a scrollable cursor. Some drivers have driver specific options that may
170
     *                               be set at prepare-time.
171
     *
172
     * @return \PDOStatement|false If the database server successfully prepares the statement, <b>\PDO::prepare</b>
173
     * returns a <b>\PDOStatement</b> object. If the database server cannot successfully prepare the statement,
174
     * <b>\PDO::prepare</b> returns <b>false</b> or emits <b>\PDOException</b> (depending on error handling).
175
     * @throws \PDOException
176
     */
177
    public function prepare(string $statement, array $driver_options = [])
178
    {
179
        return $this->pdo->prepare($statement, $driver_options);
180
    }
181
    /**
182
     * Executes an SQL statement, returning a result set as a PDOStatement object.
183
     *
184
     * Wrapper do to the reasons given in NOTE.
185
     *
186
     * __NOTE:__
187
     *     According to PHP this method doesn't accept any parameters including $statement which would make it kind of
188
     *     pointless. After take a look at the code for PDO I believe it has to do with a bug in how they try forcing an
189
     *     error for the no parameters case but it's some what unclear what's going on really. I'm going to give it
190
     *     something cleaner here and deal with it in Connection class wrapper.
191
     *
192
     * @param string $statement       The SQL statement to prepare and execute.
193
     * @param int    $mode            The fetch mode must be one of the \PDO::FETCH_* constants.
194
     * @param mixed  $arguments       The second and following parameters are the same as the parameters for
195
     *                                \PDOStatement::setFetchMode.
196
     *
197
     * @return false|\PDOStatement <b>\PDO::query</b> returns a PDOStatement object, or <b>\PDO::query</b> may return
198
     * <b>false</b> or emits <b>\PDOException</b> (depending on error handling).
199
     * @throws \PDOException
200
     * @see \PDOStatement::setFetchMode For a full description of the second and following parameters.
201
     */
202
    public function query(string $statement, int $mode = \PDO::FETCH_BOTH, ...$arguments)
203
    {
204
        if (0 === count($arguments)) {
205
            return $this->pdo->query($statement, $mode);
206
        }
207
        return $this->pdo->query($statement, $mode, ...$arguments);
208
    }
209
    /**
210
     * Rolls back a transaction.
211
     *
212
     * @return bool <b>true</b> on success or may return <b>false</b> or emits <b>\PDOException</b> (depending on error
213
     * handling).
214
     * @throws \PDOException
215
     */
216
    public function rollBack(): bool
217
    {
218
        return (bool)$this->pdo->rollBack();
219
    }
220
    /**
221
     * Set an attribute.
222
     *
223
     * @param int   $attribute
224
     * @param mixed $value
225
     *
226
     * @return bool <b>true</b> on success or may return <b>false</b> or emits <b>\PDOException</b> (depending on error
227
     * handling).
228
     * @throws \PDOException
229
     */
230
    public function setAttribute(int $attribute, $value): bool
231
    {
232
        return (bool)$this->pdo->setAttribute($attribute, $value);
233
    }
234
    /**
235
     * Used to decide if method pass through to the underlying \PDO connect are allowed for non-wrapper methods.
236
     *
237
     * @param bool $value
238
     *
239
     * @return self Fluent interface.
240
     */
241
    public function setExposingPdo(bool $value = false): self
242
    {
243
        $this->exposingPdo = $value;
244
        return $this;
245
    }
246
    /**
247
     * @param bool $value
248
     *
249
     * @return self Fluent interface
250
     */
251
    public function setSql92Mode(bool $value = true): self
252
    {
253
        $this->sql92Mode = $value;
254
        return $this;
255
    }
256
    /**
257
     * @var bool $exposingPdo
258
     */
259
    private $exposingPdo;
260
    /**
261
     * @var \PDO $pdo
262
     */
263
    private $pdo;
264
    /**
265
     * @var bool $sql92Mode
266
     */
267
    private $sql92Mode;
268
}
269
270