Completed
Push — master ( 26b715...aab764 )
by Terry
02:50
created

AbstractPdo::setLogger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/**
3
 * @package Terah\FluentPdoModel
4
 *
5
 * Licensed under The MIT License
6
 * For full copyright and license information, please see the LICENSE.txt
7
 * Redistributions of files must retain the above copyright notice.
8
 *
9
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
10
 */
11
12
namespace Terah\FluentPdoModel\Drivers;
13
14
use Psr\Log\AbstractLogger;
15
use \PDO;
16
use function Terah\Assert\Assert;
17
use function Terah\Assert\Validate;
18
use Terah\RedisCache\RedisCacheTrait;
19
use Psr\Log\LoggerAwareTrait;
20
/**
21
 * Class AbstractPdo
22
 *
23
 * @package Terah\FluentPdoModel\Drivers
24
 * @author  Terry Cullen - [email protected]
25
 */
26
abstract class AbstractPdo extends PDO implements DriverInterface
27
{
28
    use RedisCacheTrait;
29
    use LoggerAwareTrait;
30
31
    /**
32
     * @var array
33
     */
34
    protected $_config = [];
35
36
    /**
37
     * @var bool
38
     */
39
    protected $_transactionCount = 0;
40
41
    /**
42
     * @return AbstractLogger
43
     */
44
    public function getLogger()
45
    {
46
        return $this->logger;
47
    }
48
49
    /**
50
     * @param array  $config
51
     * @param string $dsn
52
     * @return $this
53
     */
54
    public function setConfig(array $config = [], $dsn='')
55
    {
56
        if ( $dsn )
57
        {
58
            $driver = ucfirst(strtolower(substr($dsn, 0, strpos($dsn, ':'))));
59
            $dsn    = preg_replace("/^{$driver}:/i", '', $dsn);
60
            $parts  = explode(';', $dsn);
61
            foreach ( $parts as $conf )
62
            {
63
                $conf = explode('=', $conf);
64
                $config[$conf[0]] = isset($conf[1]) ? $conf[1] : true;
65
            }
66
            $this->_config['driver'] = $driver;
67
        }
68
        $this->_config = $config;
69
        return $this;
70
    }
71
72
    /**
73
     * @param $key
74
     * @return mixed
75
     */
76
    public function getConfig($key)
77
    {
78
        return isset($this->_config[$key]) ? $this->_config[$key] : null;
79
    }
80
81
    /**
82
     * @return array
83
     */
84
    public function getAllConfig()
85
    {
86
        return $this->_config;
87
    }
88
89
    /**
90
     * @return bool
91
     */
92
    public function logQueries()
93
    {
94
        return !empty( $this->_config['log_queries'] ) && $this->_config['log_queries'] ? true : false;
95
    }
96
97
    /**
98
     * @return bool
99
     */
100
    public function getTransactionDepth()
101
    {
102
        return $this->_transactionCount;
103
    }
104
105
    /**
106
     * @return bool
107
     */
108
    public function beginTransaction()
109
    {
110
        $this->_transactionCount++;
111
        if ( $this->_transactionCount === 1 )
112
        {
113
            return parent::beginTransaction();
114
        }
115
        return true;
116
    }
117
118
    /**
119
     * @return bool
120
     */
121
    public function commit()
122
    {
123
        $this->_transactionCount--;
124
        $this->_transactionCount = $this->_transactionCount < 0 ? 0 : $this->_transactionCount;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->_transactionCount...this->_transactionCount can also be of type integer. However, the property $_transactionCount is declared as type boolean. 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...
125
        if ( $this->_transactionCount === 0 )
126
        {
127
            return parent::commit();
128
        }
129
        return true;
130
    }
131
132
    /**
133
     * @return bool
134
     */
135
    public function rollback()
136
    {
137
        if ( $this->_transactionCount > 0 )
138
        {
139
            $this->_transactionCount = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $_transactionCount was declared of type boolean, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
140
            return parent::rollBack();
141
        }
142
        return true;
143
    }
144
145
    /**
146
     * @param string $query
147
     * @param integer $limit
148
     * @param null|integer $offset
149
     * @return string
150
     */
151
    public function setLimit($query, $limit=null, $offset=null)
152
    {
153
        Assert($query)->string()->notEmpty();
154
        Assert($limit)->nullOr()->integer();
155
        Assert($offset)->nullOr()->integer();
156
        if ( $limit )
0 ignored issues
show
Bug Best Practice introduced by
The expression $limit of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
157
        {
158
            $query .= " LIMIT {$limit}";
159
        }
160
        if ( $offset )
0 ignored issues
show
Bug Best Practice introduced by
The expression $offset of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
161
        {
162
            $query .= " OFFSET {$offset}";
163
        }
164
        return $query;
165
    }
166
167
    /**
168
     * @param bool $include_views
169
     * @return array
170
     */
171
    abstract public function getTables($include_views=false);
172
173
    /**
174
     * @param bool $include_views
175
     * @param null $table
176
     * @return array|null
177
     */
178
    abstract public function getColumns($include_views=false, $table=null);
179
180
    /**
181
     * @param null $table
182
     * @return array
183
     */
184
    abstract public function getForeignKeys($table = null);
185
186
    /**
187
     * @param bool|false $include_views
188
     * @param null|string $table
189
     * @return array
190
     */
191
    abstract public function getTableCounts($include_views=false, $table=null);
192
193
}