Completed
Push — 2.0 ( bddf1c )
by Vermeulen
02:18
created

SqlActions::getSqlConnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace BfwSql;
4
5
use \Exception;
6
7
/**
8
 * Abstract class used for all query writer class.
9
 * 
10
 * @package bfw-sql
11
 * @author Vermeulen Maxime <[email protected]>
12
 * @version 2.0
13
 */
14
abstract class SqlActions
15
{
16
    /**
17
     * @var \BfwSql\SqlConnect $sqlConnect SqlConnect object
18
     */
19
    protected $sqlConnect;
20
    
21
    /**
22
     * @var string $assembledRequest The request will be executed
23
     */
24
    protected $assembledRequest = '';
25
    
26
    /**
27
     * @var boolean $isPreparedRequest If is a prepared request
28
     */
29
    protected $isPreparedRequest = true;
30
    
31
    /**
32
     * @var string $tableName The main table name for request
33
     */
34
    protected $tableName = '';
35
    
36
    /**
37
     * @var array $columns List of impacted columns by the request
38
     */
39
    protected $columns = array();
40
    
41
    /**
42
     * @var string[] $where All filter use in where part of the request
43
     */
44
    protected $where = array();
45
    
46
    /**
47
     * @var string[] $preparedRequestArgs Arguments used by prepared request
48
     */
49
    protected $preparedRequestArgs = array();
50
    
51
    /**
52
     * @var array $prepareDriversOptions SGBD driver option used for
53
     *  prepared request
54
     * 
55
     * @link http://php.net/manual/en/pdo.prepare.php
56
     */
57
    protected $prepareDriversOptions = array();
58
    
59
    /**
60
     * @var boolean $noResult If request has sent no result.
61
     */
62
    protected $noResult = false;
63
    
64
    /**
65
     * @var \PDOStatement $lastRequestStatement The PDOStatement pour the
66
     *  last request executed.
67
     */
68
    protected $lastRequestStatement;
69
    
70
    /**
71
     * Constructor
72
     * 
73
     * @param \BfwSql\SqlConnect $sqlConnect Instance of SGBD connexion
74
     */
75
    public function __construct(SqlConnect $sqlConnect)
76
    {
77
        $this->sqlConnect = $sqlConnect;
78
    }
79
    
80
    /**
81
     * Getter to access at sqlConnect property
82
     * 
83
     * @return \BfwSql\SqlConnect
84
     */
85
    public function getSqlConnect()
86
    {
87
        return $this->sqlConnect;
88
    }
89
    
90
    /**
91
     * Setter to enable or disable prepared request
92
     * 
93
     * @param boolean $preparedRequestStatus The new status for prepared request
94
     * 
95
     * @return void
96
     */
97
    public function setIsPreparedRequest($preparedRequestStatus)
98
    {
99
        $this->isPreparedRequest = (bool) $preparedRequestStatus;
100
    }
101
    
102
    /**
103
     * Define driver options to prepared request
104
     * 
105
     * @link http://php.net/manual/fr/pdo.prepare.php
106
     * 
107
     * @param array $driverOptions Drivers options
108
     * 
109
     * @return void
110
     */
111
    public function setPrepareDriversOptions($driverOptions)
112
    {
113
        $this->prepareDriversOptions = $driverOptions;
114
    }
115
    
116
    /**
117
     * Check if a request is assemble or not.
118
     * If not, run the method assembleRequest.
119
     * 
120
     * @return void
121
     */
122
    public function requestIsAssembled()
123
    {
124
        if($this->assembledRequest == '')
125
        {
126
            $this->assembleRequest();
127
        }
128
    }
129
    
130
    /**
131
     * Write the query
132
     * 
133
     * @return void
134
     */
135
    protected abstract function assembleRequest();
136
    
137
    /**
138
     * Return the assembled request
139
     * 
140
     * @return string
141
     */
142
    public function assemble()
143
    {
144
        $this->requestIsAssembled();
145
        return $this->assembledRequest;
146
    }
147
    
148
    /**
149
     * Execute the assembled request
150
     * 
151
     * @return array The pdo errorInfo array
152
     */
153
    protected function executeQuery()
154
    {
155
        $pdo = $this->sqlConnect->getPDO();
156
        $this->sqlConnect->upNbQuery();
157
        $this->requestIsAssembled();
158
        
159
        if ($this->isPreparedRequest) {
160
            
161
            $req = $pdo->prepare(
162
                $this->assembledRequest,
163
                $this->prepareDriversOptions
164
            );
165
            
166
            $req->execute($this->preparedRequestArgs);
167
            $error = $req->errorInfo();
168
        } else {
169
            $pdoMethodToCall = 'exec';
170
            if (get_class($this) === '\BfwSql\SqlSelect') {
171
                $pdoMethodToCall = 'query';
172
            }
173
            
174
            $req   = $pdo->{$pdoMethodToCall}($this->assembledRequest);
175
            $error = $pdo->errorInfo();
176
        }
177
        
178
        $this->lastRequestStatement = $req;
179
        
180
        return $error;
181
    }
182
    
183
    /**
184
     * Execute the assembled request and check if there are errors
185
     * Update property noResult
186
     * 
187
     * @throws \Exception If the request fail
188
     * 
189
     * @return \PDOStatement|integer
190
     */
191
    public function execute()
192
    {
193
        $error = $this->executeQuery();
194
        
195
        //Throw an exception if they are an error with the request
196
        if ($error[0] != null && $error[0] != '00000') {
197
            throw new Exception($error[2]);
198
        }
199
        
200
        if ($this->lastRequestStatement === false) {
201
            throw new Exception(
202
                'An error occurred during the execution of the request'
203
            );
204
        }
205
        
206
        $this->noResult = false;
207
        if ($this->obtainImpactedRows() === 0) {
208
            $this->noResult = true;
209
        }
210
211
        return $this->lastRequestStatement;
212
    }
213
    
214
    /**
215
     * Closes the cursor, enabling the statement to be executed again.
216
     * 
217
     * @link http://php.net/manual/fr/pdostatement.closecursor.php
218
     * 
219
     * @return void
220
     */
221
    public function closeCursor()
222
    {
223
        return $this->lastRequestStatement->closeCursor();
224
    }
225
    
226
    /**
227
     * Return the number of impacted rows by the last request
228
     * 
229
     * @return int|bool
230
     */
231
    public function obtainImpactedRows()
232
    {
233
        if ($this->lastRequestStatement === false) {
234
            return false;
235
        }
236
        
237
        if (is_object($this->lastRequestStatement)) {
238
            //If pdo::query or pdo::prepare
1 ignored issue
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
239
            return $this->lastRequestStatement->rowCount();
240
        } elseif (is_integer($this->lastRequestStatement)) {
241
            //If pdo::exec
242
            return $this->lastRequestStatement;
243
        }
244
        
245
        //Security if call without executed a request
246
        return false;
247
    }
248
    
249
    /**
250
     * To call this own request without use query writer
251
     * 
252
     * @param string $request The user request
253
     * 
254
     * @return void
255
     */
256
    public function query($request)
257
    {
258
        $this->assembledRequest = $request;
259
    }
260
    
261
    /**
262
     * Add a filter to where part of the request
263
     * 
264
     * @param string     $filter          The filter to add
265
     * @param array|null $preparedFilters (default: null) Filters to add
266
     *  in prepared request
267
     * 
268
     * @throws \Exception If key on prepared request is already used
269
     * 
270
     * @return \BfwSql\SqlActions
271
     */
272
    public function where($filter, $preparedFilters=null)
273
    {
274
        $this->where[] = $filter;
275
        
276
        if(is_array($preparedFilters))
277
        {
278
            $this->addPreparedFilters($preparedFilters);
279
        }
280
        
281
        return $this;
282
    }
283
    
284
    /**
285
     * Add filters to prepared requests
286
     * 
287
     * @param array $preparedFilters Filters to add in prepared request
288
     * 
289
     * @return void
290
     */
291
    protected function addPreparedFilters($preparedFilters)
292
    {
293
        foreach($preparedFilters as $prepareKey => $prepareValue)
294
        {
295
            $this->preparedRequestArgs[$prepareKey] = $prepareValue;
296
        }
297
    }
298
    
299
    /**
300
     * Write the where part of a sql query and return it
301
     * 
302
     * @return string
303
     */
304
    protected function generateWhere()
305
    {
306
        $where = '';
307
        
308
        //check if there are filters to write
309
        if (count($this->where) > 0) {
310
            $where = ' WHERE ';
311
            
312
            foreach ($this->where as $filter) {
313
                
314
                if ($where != ' WHERE ') {
315
                    $where .= ' AND ';
316
                }
317
                
318
                $where .= $filter;
319
            } 
320
        }
321
        
322
        return $where;
323
    }
324
    
325
    /**
326
     * Add datas to insert or update for a column.
327
     * Used by UPDATE and INSERT requests
328
     * 
329
     * @param array $columns Datas to add or update
330
     *  Format : array('sqlColumnName' => 'valueForThisColumn', ...);
331
     * 
332
     * @return \BfwSql\SqlActions
333
     */
334
    public function addDatasForColumns($columns)
335
    {
336
        foreach ($columns as $columnName => $data) {
337
            if (
338
                isset($this->columns[$columnName])
339
                && $this->columns[$columnName] != $data
340
            ) {
341
                throw new \Exception(
342
                    'A different data is already declared for the column '
343
                    .$columnName
344
                );
345
            }
346
            
347
            $this->columns[$columnName] = $data;
348
        }
349
        
350
        return $this;
351
    }
352
    
353
    /**
354
     * Send a notify to application observers
355
     * 
356
     * @return void
357
     */
358
    protected function callObserver()
359
    {
360
        $app = \BFW\Application::getInstance();
361
        $app->setContext($this);
362
        $app->notifyAction('BfwSqlRequest');
363
    }
364
}
365