Completed
Push — 2.0 ( 1160ec...acba87 )
by Vermeulen
05:15
created

Common   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 2
dl 0
loc 303
c 0
b 0
f 0
rs 10

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getIsPreparedRequest() 0 4 1
A setIsPreparedRequest() 0 6 1
A getLastErrorInfos() 0 4 1
A getLastRequestStatement() 0 4 1
A getNoResult() 0 4 1
A getPrepareDriversOptions() 0 4 1
A setPrepareDriversOptions() 0 6 1
A getQuery() 0 4 1
A getSqlConnect() 0 4 1
A executeQuery() 0 19 2
A executePreparedQuery() 0 12 1
A executeNotPreparedQuery() 0 10 2
A execute() 0 26 5
A closeCursor() 0 4 1
A obtainImpactedRows() 0 13 3
A callObserver() 0 6 1
1
<?php
2
3
namespace BfwSql\Executers;
4
5
use \Exception;
6
7
class Common
8
{
9
    /**
10
     * @const ERR_EXECUTE_BAD_REQUEST Exception code if a request has fail
11
     * during execution
12
     */
13
    const ERR_EXECUTE_BAD_REQUEST = 2201001;
14
    
15
    /**
16
     * @const ERR_EXECUTED_UNKNOWN_ERROR Exception code if a request has fail
17
     * but when the error has not been returned by PDO::errorInfos()
18
     */
19
    const ERR_EXECUTED_UNKNOWN_ERROR = 2201002;
20
    
21
    /**
22
     * @var \BfwSql\Queries\AbstractQuery $query Query system object
23
     */
24
    protected $query;
25
    
26
    /**
27
     * @var \BfwSql\SqlConnect $sqlConnect SqlConnect object
28
     */
29
    protected $sqlConnect;
30
    
31
    /**
32
     * @var boolean $isPreparedRequest If is a prepared request
33
     */
34
    protected $isPreparedRequest = true;
35
    
36
    /**
37
     * @var array $lastErrorInfos The PDO::errorInfos return for the last
38
     * query executed. Empty if no request has been executed.
39
     */
40
    protected $lastErrorInfos = [];
41
    
42
    /**
43
     * @var \PDOStatement $lastRequestStatement The PDOStatement pour the
44
     *  last request executed.
45
     */
46
    protected $lastRequestStatement;
47
    
48
    /**
49
     * @var boolean $noResult If request has sent no result.
50
     */
51
    protected $noResult = false;
52
    
53
    /**
54
     * @var array $prepareDriversOptions SGBD driver option used for
55
     *  prepared request
56
     * 
57
     * @link http://php.net/manual/en/pdo.prepare.php
58
     */
59
    protected $prepareDriversOptions = array();
60
    
61
    /**
62
     * Constructor
63
     * 
64
     * @param \BfwSql\Queries\AbstractQuery $query Instance of query
65
     * system
66
     */
67
    public function __construct(\BfwSql\Queries\AbstractQuery $query)
68
    {
69
        $this->query      = $query;
70
        $this->sqlConnect = $query->getSqlConnect();
71
    }
72
73
    /**
74
     * Getter to access to isPreparedRequest property
75
     * 
76
     * @return boolean
77
     */
78
    public function getIsPreparedRequest(): bool
79
    {
80
        return $this->isPreparedRequest;
81
    }
82
    
83
    /**
84
     * Setter to enable or disable prepared request
85
     * 
86
     * @param boolean $preparedRequestStatus The new status for prepared request
87
     * 
88
     * @return $this
89
     */
90
    public function setIsPreparedRequest(bool $preparedRequestStatus): self
91
    {
92
        $this->isPreparedRequest = (bool) $preparedRequestStatus;
93
        
94
        return $this;
95
    }
96
    
97
    /**
98
     * Getter to access to lastErrorInfos property
99
     * 
100
     * @return array
101
     */
102
    public function getLastErrorInfos(): array
103
    {
104
        return $this->lastErrorInfos;
105
    }
106
107
    /**
108
     * Getter to access to lastRequestStatement property
109
     * 
110
     * @return \PDOStatement|null
111
     */
112
    public function getLastRequestStatement()
113
    {
114
        return $this->lastRequestStatement;
115
    }
116
117
    /**
118
     * Getter to access to noResult property
119
     * 
120
     * @return boolean
121
     */
122
    public function getNoResult(): bool
123
    {
124
        return $this->noResult;
125
    }
126
    
127
    /**
128
     * Getter to access at prepareDriversOptions property
129
     * 
130
     * @return array
131
     */
132
    public function getPrepareDriversOptions(): array
133
    {
134
        return $this->prepareDriversOptions;
135
    }
136
    
137
    /**
138
     * Define driver options to prepared request
139
     * 
140
     * @link http://php.net/manual/fr/pdo.prepare.php
141
     * 
142
     * @param array $driverOptions Drivers options
143
     * 
144
     * @return $this
145
     */
146
    public function setPrepareDriversOptions(array $driverOptions): self
147
    {
148
        $this->prepareDriversOptions = $driverOptions;
149
        
150
        return $this;
151
    }
152
    
153
    /**
154
     * Getter accessor to property query
155
     * 
156
     * @return \BfwSql\Queries\AbstractQuery
157
     */
158
    public function getQuery(): \BfwSql\Queries\AbstractQuery
159
    {
160
        return $this->query;
161
    }
162
    
163
    /**
164
     * Getter to access at sqlConnect property
165
     * 
166
     * @return \BfwSql\SqlConnect
167
     */
168
    public function getSqlConnect(): \BfwSql\SqlConnect
169
    {
170
        return $this->sqlConnect;
171
    }
172
    
173
    /**
174
     * Execute the assembled request
175
     * 
176
     * @return array The pdo errorInfo array
177
     */
178
    protected function executeQuery(): array
179
    {
180
        $this->sqlConnect->upNbQuery();
181
        $this->query->assemble();
182
        
183
        if ($this->isPreparedRequest) {
184
            $req = $this->executePreparedQuery();
185
        } else {
186
            $req = $this->executeNotPreparedQuery();
187
        }
188
        
189
        $error = $this->sqlConnect->getPDO()->errorInfo();
190
        
191
        $this->lastRequestStatement = $req;
0 ignored issues
show
Documentation Bug introduced by
It seems like $req can also be of type integer. However, the property $lastRequestStatement is declared as type object<PDOStatement>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
192
        $this->lastErrorInfos       = $error;
193
        $this->callObserver();
194
        
195
        return $error;
196
    }
197
    
198
    /**
199
     * Execute a prepared request
200
     * 
201
     * @return \PDOStatement
202
     */
203
    protected function executePreparedQuery(): \PDOStatement
204
    {
205
        $pdo = $this->sqlConnect->getPDO();
206
        $req = $pdo->prepare(
207
            $this->query->getAssembledRequest(),
208
            $this->prepareDriversOptions
209
        );
210
211
        $req->execute($this->query->getPreparedParams());
212
        
213
        return $req;
214
    }
215
    
216
    /**
217
     * Execute a not prepared request
218
     * 
219
     * @return \PDOStatement|integer
220
     */
221
    protected function executeNotPreparedQuery()
222
    {
223
        $pdoMethodToCall = 'exec';
224
        if ($this->query instanceof \BfwSql\Queries\Select) {
225
            $pdoMethodToCall = 'query';
226
        }
227
228
        $pdo = $this->sqlConnect->getPDO();
229
        return $pdo->{$pdoMethodToCall}($this->query->getAssembledRequest());
230
    }
231
    
232
    /**
233
     * Execute the assembled request and check if there are errors
234
     * Update property noResult
235
     * 
236
     * @throws \Exception If the request fail
237
     * 
238
     * @return \PDOStatement|integer
239
     */
240
    public function execute()
241
    {
242
        $error = $this->executeQuery();
243
        
244
        //Throw an exception if they are an error with the request
245
        if ($error[0] !== null && $error[0] !== '00000') {
246
            throw new Exception(
247
                $error[2],
248
                self::ERR_EXECUTE_BAD_REQUEST
249
            );
250
        }
251
        
252
        if ($this->lastRequestStatement === false) {
253
            throw new Exception(
254
                'An error occurred during the execution of the request',
255
                self::ERR_EXECUTED_UNKNOWN_ERROR
256
            );
257
        }
258
        
259
        $this->noResult = false;
260
        if ($this->obtainImpactedRows() === 0) {
261
            $this->noResult = true;
262
        }
263
264
        return $this->lastRequestStatement;
265
    }
266
    
267
    /**
268
     * Closes the cursor, enabling the statement to be executed again.
269
     * 
270
     * @link http://php.net/manual/fr/pdostatement.closecursor.php
271
     * 
272
     * @return void
273
     */
274
    public function closeCursor()
275
    {
276
        return $this->lastRequestStatement->closeCursor();
277
    }
278
    
279
    /**
280
     * Return the number of impacted rows by the last request
281
     * 
282
     * @return int|bool
283
     */
284
    public function obtainImpactedRows()
285
    {
286
        if (is_object($this->lastRequestStatement)) {
287
            //If pdo::query or pdo::prepare
288
            return $this->lastRequestStatement->rowCount();
289
        } elseif (is_integer($this->lastRequestStatement)) {
290
            //If pdo::exec
291
            return $this->lastRequestStatement;
292
        }
293
        
294
        //Security if call without executed a request
295
        return false;
296
    }
297
    
298
    /**
299
     * Send a notify to application observers
300
     * 
301
     * @return void
302
     */
303
    protected function callObserver()
304
    {
305
        $app     = \BFW\Application::getInstance();
306
        $subject = $app->getSubjectList()->getSubjectByName('bfw-sql');
307
        $subject->addNotification('system query', clone $this);
308
    }
309
}
310