Completed
Push — dev-0.1.x ( 945d1b...89d2d8 )
by Josué
07:32
created

PdoOci8::getAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 8
ccs 3
cts 4
cp 0.75
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2.0625
1
<?php
2
3
namespace Jpina\PdoOci8;
4
5
use Jpina\Oci8\Oci8Connection;
6
use Jpina\Oci8\Oci8ConnectionInterface;
7
use Jpina\Oci8\Oci8Exception;
8
use Jpina\Oci8\Oci8PersistentConnection;
9
use Jpina\Oci8\Oci8StatementInterface;
10
11
/**
12
 * Custom PDO_OCI implementation via OCI8 driver
13
 *
14
 * @see http://php.net/manual/en/class.pdo.php
15
 */
16
class PdoOci8 extends \PDO
17
{
18
    const OCI_ATTR_SESSION_MODE = 8000;
19
20
    const OCI_ATTR_RETURN_LOBS = 8001;
21
22
    /**
23
     * @var Oci8ConnectionInterface
24
     */
25
    protected $connection;
26
27
    /**
28
     * @var bool
29
     */
30
    private $autoCommitMode = false;
31
32
    /** @var bool */
33
    private $isTransactionStarted = false;
34
35
    /**
36
     * @var array
37
     */
38
    protected $options = array();
39
40
    // TODO Receive Oci8ConnectionInterface?
41 14
    public function __construct($dsn, $username = '', $password = '', $options = array())
42
    {
43 14
        $this->options = array(
44 14
            \PDO::ATTR_AUTOCOMMIT         => true,
45 14
            \PDO::ATTR_CASE               => \PDO::CASE_NATURAL,
46 14
            \PDO::ATTR_CLIENT_VERSION     => '',
47 14
            \PDO::ATTR_CONNECTION_STATUS  => '',
48 14
            \PDO::ATTR_DRIVER_NAME        => 'oci',
49 14
            \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_SILENT,
50 14
            \PDO::ATTR_ORACLE_NULLS       => \PDO::NULL_NATURAL,
51 14
            \PDO::ATTR_PERSISTENT         => false,
52 14
            \PDO::ATTR_PREFETCH           => 100,
53 14
            \PDO::ATTR_SERVER_INFO        => '',
54 14
            \PDO::ATTR_SERVER_VERSION     => '',
55 14
            \PDO::ATTR_TIMEOUT            => 600,
56 14
            \PDO::ATTR_STRINGIFY_FETCHES  => false,
57 14
            \PDO::ATTR_STATEMENT_CLASS    => null,
58 14
            \PDO::ATTR_EMULATE_PREPARES   => false,
59 14
            \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_BOTH,
60 14
            static::OCI_ATTR_SESSION_MODE => OCI_DEFAULT,
61 14
            static::OCI_ATTR_RETURN_LOBS  => false,
62
        );
63
64 14 View Code Duplication
        foreach ($options as $option => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65 4
            if (array_key_exists($option, $this->options)) {
66 4
                $this->options[$option] = $value;
67 4
            }
68 14
        }
69
70 14
        foreach ($options as $attribute => $value) {
71 4
            $this->setAttribute($attribute, $value);
72 14
        }
73
74 14
        $connection = $this->getOracleConnection($dsn, $username, $password);
75 12
        $this->setAttribute(\PDO::ATTR_CLIENT_VERSION, $connection->getClientVersion());
76 12
        $this->setAttribute(\PDO::ATTR_SERVER_VERSION, $connection->getServerVersion());
77
78 12
        $autocommitMode = $this->getAttribute(\PDO::ATTR_AUTOCOMMIT);
79 12
        $this->setAutocommitMode($autocommitMode);
80 12
        if ($this->getAttribute(\PDO::ATTR_AUTOCOMMIT) === false) {
81 1
            $this->beginTransaction();
82 1
        }
83
84 12
        $this->connection = $connection;
85 12
    }
86
87
    /**
88
     * @return bool
89
     */
90 3
    protected function getAutocommitMode()
91
    {
92 3
        return $this->autoCommitMode;
93
    }
94
95
    /**
96
     * @param string $dsn
97
     * @return string
98
     */
99 13
    protected function getCharset($dsn)
100
    {
101 13
        $connectionStringItems = $this->getConnectionStringItems($dsn);
102
103 13
        return $connectionStringItems['charset'];
104
    }
105
106
    /**
107
     * @return Oci8ConnectionInterface
108
     */
109 43
    protected function getConnection()
110
    {
111 43
        return $this->connection;
112
    }
113
114
    /**
115
     * @param string $dsn
116
     * @param string $username
117
     * @param string $password
118
     * @return Oci8ConnectionInterface
119
     */
120 14
    protected function getOracleConnection($dsn, $username = null, $password = null)
121
    {
122 14
        $connectionString = $this->getConnectionString($dsn);
123 13
        $charset = $this->getCharset($dsn);
124 13
        $sessionMode = $this->getAttribute(static::OCI_ATTR_SESSION_MODE);
125
126 13
        $connection = null;
127
        try {
128 13
            if ($this->getAttribute(\PDO::ATTR_PERSISTENT)) {
129 1
                $connection = new Oci8PersistentConnection(
130 1
                    $username,
131 1
                    $password,
132 1
                    $connectionString,
133 1
                    $charset,
134
                    $sessionMode
135 1
                );
136 1
            } else {
137 12
                $connection = new Oci8Connection(
138 12
                    $username,
139 12
                    $password,
140 12
                    $connectionString,
141 12
                    $charset,
142
                    $sessionMode
143 12
                );
144
            }
145 13
        } catch (Oci8Exception $ex) {
146 1
            throw new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex);
147
        }
148
149 12
        return $connection;
150
    }
151
152
    /**
153
     * @param string $dsn
154
     * @return string
155
     */
156 14
    protected function getConnectionString($dsn)
157
    {
158 14
        $connectionStringItems = $this->getConnectionStringItems($dsn);
159 13
        $hostname = $connectionStringItems['hostname'];
160 13
        $port = $connectionStringItems['port'];
161 13
        $database = $connectionStringItems['database'];
162 13
        $connectionString = "//{$hostname}:{$port}/{$database}";
163
164 13
        return $connectionString;
165
    }
166
167
    /**
168
     * @param string $dsn
169
     * @return array
170
     */
171 14
    protected function getConnectionStringItems($dsn)
172
    {
173 14
        $dsnRegex = $this->getDsnRegex();
174 14
        $matches = array();
175 14
        if (preg_match("/^{$dsnRegex}$/i", $dsn, $matches) !== 1) {
176 1
            throw new PdoOci8Exception('Invalid DSN');
177
        }
178
179
        // TODO Remove the variables below
180 13
        $hostname = 'localhost';
181 13
        $port     = 1521;
182 13
        $database = null;
0 ignored issues
show
Unused Code introduced by
$database is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
183 13
        $charset  = 'AL32UTF8';
184
185 13
        switch (count($matches)) {
186 13
            case 16:
187 11
                $charset  = empty($matches[15]) ? $charset : $matches[15];
188
                // fall through next case to get the rest of the variables
189 13
            case 14:
190 13
                $port     = empty($matches[12]) ? $port : (int)$matches[12];
191 13
                $hostname = $matches[4];
192 13
                $database = $matches[13];
193 13
                break;
194
            default:
195
                $database = $matches[1];
196 13
        }
197
198
        return array(
199 13
            'hostname' => $hostname,
200 13
            'port'     => $port,
201 13
            'database' => $database,
202 13
            'charset'  => $charset,
203 13
        );
204
    }
205
206
    /**
207
     * @return string
208
     */
209 14
    protected function getDsnRegex()
210
    {
211 14
        $hostnameRegrex = "(([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])\.)*([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])";
212
        $validIpAddressRegex = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}" .
213 14
            "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])";
214 14
        $hostnameOrIpAddressRegrex = "\/\/({$hostnameRegrex}|{$validIpAddressRegex})";
215 14
        $databaseRegex = "([a-z_][a-z\-_\d]*)|({$hostnameOrIpAddressRegrex}(:(\d+))?\/([a-z_][a-z\-_\d]*))";
216 14
        $charsetRegex = "(charset=([a-z\d\-_]+))?";
217 14
        $dsnRegex = "oci\:database=({$databaseRegex});?{$charsetRegex}";
218
219 14
        return $dsnRegex;
220
    }
221
222
    /**
223
     * @param array $overrideOptions
224
     * @return array
225
     */
226 38
    protected function getOptions($overrideOptions = array())
227
    {
228 38
        $options = array_merge($this->options, $overrideOptions);
229
230 38
        return $options;
231
    }
232
233
    /**
234
     * @link http://php.net/manual/en/pdo.begintransaction.php
235
     * @return bool
236
     */
237 5
    public function beginTransaction()
238
    {
239 5
        if ($this->inTransaction()) {
240 2
            return false;
241
        }
242
243 5
        $this->setAttribute(\PDO::ATTR_AUTOCOMMIT, false);
244 5
        $this->isTransactionStarted = true;
245
246 5
        return true;
247
    }
248
249
    /**
250
     * @link http://php.net/manual/en/pdo.commit.php
251
     * @return bool
252
     */
253 1
    public function commit()
254
    {
255
        try {
256 1
            $isSuccess = $this->getConnection()->commit();
257 1
        } catch (Oci8Exception $ex) {
258
            $isSuccess = false;
259
        }
260
261 1
        $this->restoreAutocommitMode();
262
263 1
        return $isSuccess;
264
    }
265
266
    /**
267
     * @link http://php.net/manual/en/pdo.errorcode.php
268
     * @return null|string
269
     */
270 1 View Code Duplication
    public function errorCode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
    {
272 1
        $connection = $this->getConnection();
273 1
        $driverError = $connection->getError();
274 1
        if (!$driverError) {
275 1
            return null;
276
        }
277
278
        $error = $this->errorInfo();
279
        $sqlStateErrorCode = $error[0];
280
281
        return $sqlStateErrorCode;
282
    }
283
284
    /**
285
     * @link http://php.net/manual/en/pdo.errorinfo.php
286
     * @return array
287
     */
288 1
    public function errorInfo()
289
    {
290 1
        $error = $this->getConnection()->getError();
291 1
        if (is_array($error)) {
292
            $errorInfo = array(
293
                OracleSqlStateCode::getSqlStateErrorCode((int)$error['code']),
294
                $error['message'],
295
                $error['code']
296
            );
297
        } else {
298
            $errorInfo = array(
299 1
                '00000',
300 1
                null,
301
                null
302 1
            );
303
        }
304
305 1
        return $errorInfo;
306
    }
307
308
    /**
309
     * @param string $statement
310
     *
311
     * @link http://php.net/manual/en/pdo.exec.php
312
     * @return bool|int
313
     */
314 4
    public function exec($statement)
315
    {
316 4
        $statement = $this->prepare($statement);
317 4
        $type      = $this->getStatementType($statement);
0 ignored issues
show
Security Bug introduced by
It seems like $statement defined by $this->prepare($statement) on line 316 can also be of type false; however, Jpina\PdoOci8\PdoOci8::getStatementType() does only seem to accept object<Jpina\PdoOci8\PdoOci8Statement>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
318 4
        if ($type === 'SELECT') {
319 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::exec of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
320
        }
321 3
        $statement->execute();
322
323 3
        return $statement->rowCount();
324
    }
325
326
    /**
327
     * @param PdoOci8Statement $statement
328
     * @return string
329
     */
330 4
    protected function getStatementType($statement)
331
    {
332 4
        $class = new \ReflectionClass($statement);
333 4
        $property = $class->getProperty('statement');
334 4
        $property->setAccessible(true);
335
        /** @var Oci8StatementInterface $rawStatement */
336 4
        $oci8Statement = $property->getValue($statement);
337 4
        $type = $oci8Statement->getType();
338
339 4
        return $type;
340
    }
341
342
    /**
343
     * @param int $attribute
344
     *
345
     * @link http://php.net/manual/en/pdo.getattribute.php
346
     * @return mixed
347
     */
348 13
    public function getAttribute($attribute)
349
    {
350 13
        if (array_key_exists($attribute, $this->options)) {
351 13
            return $this->options[$attribute];
352
        }
353
354
        return null;
355
    }
356
357
    /**
358
     * @link http://php.net/manual/en/pdo.getavailabledrivers.php
359
     * @return array
360
     */
361 1
    public static function getAvailableDrivers()
362
    {
363 1
        return array('oci');
364
    }
365
366
    /**
367
     * @link http://php.net/manual/en/pdo.intransaction.php
368
     * @return bool
369
     */
370 6
    public function inTransaction()
371
    {
372 6
        return $this->isTransactionStarted;
373
    }
374
375
    /**
376
     * @param string $name
377
     *
378
     * @link http://php.net/manual/en/pdo.lastinsertid.php
379
     * @return string
380
     */
381
    public function lastInsertId($name = null)
382
    {
383
        $statement = $this->query("select {$name}.currval from dual");
384
        $lastInsertedId = $statement->fetch();
385
386
        return $lastInsertedId;
387
    }
388
389
    /**
390
     * @param string $statement
391
     * @param array $driver_options
392
     *
393
     * @link http://php.net/manual/en/pdo.prepare.php
394
     * @return bool|PdoOci8Statement
395
     */
396 38
    public function prepare($statement, $driver_options = array())
397
    {
398
        // TODO Use $driver_options, eg. configure a cursor
399 38
        $exception = null;
0 ignored issues
show
Unused Code introduced by
$exception is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
400
        try {
401 38
            $options = $this->getOptions($driver_options);
402 38
            return new PdoOci8Statement($this->getConnection(), $statement, $options);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return new \Jpina\PdoOci... $statement, $options); (Jpina\PdoOci8\PdoOci8Statement) is incompatible with the return type of the parent method PDO::prepare of type PDOStatement.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
403
        } catch (\Exception $ex) {
404
            $exception = new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex);
405
        }
406
407
        // TODO Create error handler
408
        $errorMode = $this->getAttribute(\PDO::ATTR_ERRMODE);
409
        switch ($errorMode) {
410
            case \PDO::ERRMODE_EXCEPTION:
411
                throw $exception;
412
            case \PDO::ERRMODE_WARNING:
413
                trigger_error($exception->getMessage(), E_WARNING);
414
                break;
415
            case \PDO::ERRMODE_SILENT:
416
            default:
417
        }
418
419
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::prepare of type PDOStatement.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
420
    }
421
422
    /**
423
     * @param string $statement
424
     * @param int $mode
425
     * @param int|string|object $arg3
426
     * @param array $ctorargs
427
     *
428
     * @link http://php.net/manual/en/pdo.query.php
429
     * @return bool|PdoOci8Statement
430
     */
431 3
    public function query($statement, $mode = \PDO::ATTR_DEFAULT_FETCH_MODE, $arg3 = null, $ctorargs = array())
432
    {
433 3
        $result = false;
434
        try {
435 3
            $statement = $this->prepare($statement);
436
            switch ($mode) {
437 3
                case \PDO::FETCH_CLASS:
438
                    $statement->setFetchMode($mode, $arg3, $ctorargs);
439
                    break;
440 3
                case \PDO::FETCH_INTO:
441
                    $statement->setFetchMode($mode, $arg3);
442
                    break;
443 3
                case \PDO::FETCH_COLUMN:
444 3
                default:
445 3
                    $statement->setFetchMode($mode);
446 3
            }
447 3
            $statement->execute();
448 3
            $result = $statement;
449 3
        } catch (\PDOException $ex) {
450
            //TODO Handle Exception
451
        }
452
453 3
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $result; (Jpina\PdoOci8\PdoOci8Statement|false) is incompatible with the return type of the parent method PDO::query of type PDOStatement.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
454
    }
455
456
    /**
457
     * @param string $string
458
     * @param int $parameter_type
459
     *
460
     * @link http://php.net/manual/en/pdo.quote.php
461
     * @return bool|string
462
     */
463 5
    public function quote($string, $parameter_type = \PDO::PARAM_STR)
464
    {
465 5
        if (!is_scalar($string)) {
466 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::quote of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
467
        }
468
469
        try {
470 4
            if ($parameter_type !== \PDO::PARAM_STR) {
471 1
                $quotedString = (string)$string;
472 1
                $quotedString = "'" . $quotedString . "'";
473 1
                return $quotedString;
474
            }
475 4
        } catch (\Exception $ex) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $ex) { return false; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
476
            return false;
477
        }
478
479 4
        $quotedString = str_replace("\'", "'", $string);
480 4
        $quotedString = str_replace("'", "''", $quotedString);
481 4
        $quotedString = "'" . $quotedString . "'";
482
483 4
        return $quotedString;
484
    }
485
486 3
    protected function restoreAutocommitMode()
487
    {
488 3
        $autocommitMode = $this->getAutocommitMode();
489 3
        $this->setAttribute(\PDO::ATTR_AUTOCOMMIT, $autocommitMode);
490 3
    }
491
492
    /**
493
     * @link http://php.net/manual/en/pdo.rollback.php
494
     * @return bool
495
     */
496 3
    public function rollback()
497
    {
498 3
        if (!$this->inTransaction()) {
499 1
            throw new PdoOci8Exception('There is no active transaction');
500
        }
501
502
        try {
503 2
            $isSuccess = $this->getConnection()->rollback();
504 2
        } catch (Oci8Exception $ex) {
505
            $isSuccess = false;
506
        }
507
508 2
        $this->restoreAutocommitMode();
509
510 2
        return $isSuccess;
511
    }
512
513
    /**
514
     * @param bool $onOff
515
     */
516 12
    protected function setAutocommitMode($onOff)
517
    {
518 12
        $this->autoCommitMode = $onOff;
519 12
    }
520
521
    /**
522
     * @param int $attribute
523
     * @param mixed $value
524
     *
525
     * @link http://php.net/manual/en/pdo.setattribute.php
526
     * @return bool
527
     */
528 12
    public function setAttribute($attribute, $value)
529
    {
530
        $readOnlyAttributes = array(
531 12
            \PDO::ATTR_CLIENT_VERSION,
532 12
            \PDO::ATTR_CONNECTION_STATUS,
533 12
            \PDO::ATTR_DRIVER_NAME,
534 12
            \PDO::ATTR_PERSISTENT,
535 12
            \PDO::ATTR_SERVER_INFO,
536 12
            \PDO::ATTR_SERVER_VERSION,
537 12
        );
538
539 12 View Code Duplication
        if (array_search($attribute, $readOnlyAttributes) !== false ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
540 12
            !array_key_exists($attribute, $this->options)) {
541 12
            return false;
542
        }
543
544 6
        $this->options[$attribute] = $value;
545
546 6
        return true;
547
    }
548
}
549