Passed
Push — master ( 7d3861...c0cfa7 )
by Radu
01:22
created

AbstractPdoDatabase::getColumn()   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 3
1
<?php
2
namespace WebServCo\Framework;
3
4
use WebServCo\Framework\Exceptions\DatabaseException;
5
6
abstract class AbstractPdoDatabase extends \WebServCo\Framework\AbstractDatabase
7
{
8
    use \WebServCo\Framework\Traits\DatabaseTrait;
9
    use \WebServCo\Framework\Traits\DatabaseAddQueryTrait;
10
11
    abstract protected function getDataSourceName($host, $port, $dbname);
12
13
    public function __construct($settings = [])
14
    {
15
        parent::__construct($settings);
16
17
        try {
18
            $dsn = $this->getDataSourceName(
19
                $this->setting('connection/host', '127.0.0.1'),
20
                $this->setting('connection/port', null),
21
                $this->setting('connection/dbname', 'test')
22
            );
23
            $this->db = new \PDO(
24
                $dsn,
25
                $this->setting('connection/username', 'root'),
26
                $this->setting('connection/passwd', ''),
27
                [
28
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
29
                    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
30
                    \PDO::ATTR_EMULATE_PREPARES => false,
31
                    \PDO::ATTR_PERSISTENT => false
32
                ]
33
            );
34
        } catch (\Exception $e) { // PDOException/RuntimeException/Exception
35
            throw new DatabaseException($e->getMessage());
36
        }
37
    }
38
39
    public function escape($string)
40
    {
41
        return $this->db->quote($string);
42
    }
43
44
    public function query($query, $params = [])
45
    {
46
        if (empty($query)) {
47
            throw new DatabaseException('No query specified');
48
        }
49
50
        try {
51
            if (!empty($params)) {
52
                $this->stmt = $this->db->prepare($query);
53
                $this->bindParams($params);
54
                $this->stmt->execute();
55
            } else {
56
                $this->stmt = $this->db->query($query);
57
            }
58
            $this->setLastInsertId();
59
            return $this->stmt;
60
        } catch (\Exception $e) { //PDOException/RuntimeException/Exception
61
            throw new DatabaseException($e->getMessage());
62
        }
63
    }
64
65
    public function transaction($queries)
66
    {
67
        try {
68
            $this->db->beginTransaction();
69
            foreach ($queries as $item) {
70
                if (!isset($item[0])) {
71
                    throw new DatabaseException('No query specified');
72
                }
73
                $params = isset($item[1]) ? $item[1] : [];
74
                $this->query($item[0], $params);
75
            }
76
            $this->db->commit();
77
            return true;
78
        } catch (\Exception $e) { //PDOException/RuntimeException/Exception
79
            $this->db->rollBack();
80
            throw new DatabaseException($e->getMessage());
81
        }
82
    }
83
84
    public function numRows()
85
    {
86
        if (!($this->stmt instanceof \PDOStatement)) {
87
            throw new DatabaseException('No Statement object available.');
88
        }
89
        if ('mysql' == $this->setting('driver')) {
90
            return $this->stmt->rowCount();
91
        }
92
        $rows = $this->rows ?: $this->stmt->fetchAll(\PDO::FETCH_ASSOC);
93
        return count($rows);
94
    }
95
96
    public function affectedRows()
97
    {
98
        if (!($this->stmt instanceof \PDOStatement)) {
99
            throw new DatabaseException('No Statement object available.');
100
        }
101
        return $this->stmt->rowCount();
102
    }
103
104
    public function getRows($query, $params = [])
105
    {
106
        $this->query($query, $params);
107
        $this->rows = $this->stmt->fetchAll(\PDO::FETCH_ASSOC);
108
        return $this->rows;
109
    }
110
111
    public function getRow($query, $params = [])
112
    {
113
        $this->query($query, $params);
114
        return $this->stmt->fetch(\PDO::FETCH_ASSOC);
115
    }
116
117
    public function getColumn($query, $params = [], $columnNumber = 0)
118
    {
119
        $this->query($query, $params);
120
        return $this->stmt->fetchColumn($columnNumber);
121
    }
122
123
    protected function bindParams($data)
124
    {
125
        if (empty($data)) {
126
            return false;
127
        }
128
129
        $i = 1;
130
        foreach ($data as $item) {
131
            if (is_array($item)) {
132
                foreach ($item as $v) {
133
                    $this->stmt->bindValue($i, $v, $this->getDataType($v));
134
                    $i++;
135
                }
136
            } else {
137
                $this->stmt->bindValue($i, $item, $this->getDataType($item));
138
                $i++;
139
            }
140
        }
141
        return true;
142
    }
143
144
    protected function getDataType($variable)
145
    {
146
        $type = gettype($variable);
147
148
        switch ($type) {
149
            case 'NULL':
150
                return \PDO::PARAM_NULL;
151
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
152
            case 'integer':
153
                return \PDO::PARAM_INT;
154
                break;
155
            case 'boolean':
156
                // casuses data not to be inserted
157
                //return \PDO::PARAM_BOOL;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
158
                //break;
159
            case 'string':
160
            case 'double':
161
            case 'array':
162
            case 'object':
163
            case 'resource':
164
            case 'resource (closed)':
165
            case 'unknown type':
166
            default:
167
                return \PDO::PARAM_STR;
168
                break;
169
        }
170
    }
171
172
    protected function setLastInsertId()
173
    {
174
        $this->lastInsertId = $this->db->lastInsertId();
175
    }
176
}
177