Passed
Branch feature-dbal (46f2dd)
by Thomas
03:08
created

Dbal::getBooleanFalse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ORM;
4
5
use ORM\Dbal\Column;
6
use ORM\Dbal\Type;
7
use ORM\Exceptions\NotScalar;
8
use ORM\Exceptions\UnsupportedDriver;
9
10
/**
11
 * Class Dbal
12
 *
13
 * This is the base class for the database abstraction layer.
14
 *
15
 * @package ORM
16
 * @author  Thomas Flori <[email protected]>
17
 */
18
abstract class Dbal
19
{
20
    /** @var EntityManager */
21
    protected $em;
22
23
    protected static $quotingCharacter = '"';
24
    protected static $identifierDivider = '.';
25
    protected static $booleanTrue = '1';
26
    protected static $booleanFalse = '0';
27
28
    protected static $registeredTypes = [];
29
    protected static $typeMapping = [];
30
31 17
    public static function setQuotingCharacter($char)
32
    {
33 17
        static::$quotingCharacter = $char;
34 17
    }
35
36 17
    public static function setIdentifierDivider($divider)
37
    {
38 17
        static::$identifierDivider = $divider;
39 17
    }
40
41 17
    public static function setBooleanTrue($true)
42
    {
43 17
        static::$booleanTrue = $true;
44 17
    }
45
46 17
    public static function setBooleanFalse($false)
47
    {
48 17
        static::$booleanFalse = $false;
49 17
    }
50
51
    /**
52
     * @return string
53
     */
54 1
    public static function getQuotingCharacter()
55
    {
56 1
        return static::$quotingCharacter;
57
    }
58
59
    /**
60
     * @return string
61
     */
62 1
    public static function getIdentifierDivider()
63
    {
64 1
        return static::$identifierDivider;
65
    }
66
67
    /**
68
     * @return string
69
     */
70 1
    public static function getBooleanTrue()
71
    {
72 1
        return static::$booleanTrue;
73
    }
74
75
    /**
76
     * @return string
77
     */
78 1
    public static function getBooleanFalse()
79
    {
80 1
        return static::$booleanFalse;
81
    }
82
83
    /**
84
     * Dbal constructor.
85
     *
86
     * @param EntityManager $entityManager
87
     */
88 278
    public function __construct(EntityManager $entityManager)
89
    {
90 278
        $this->em = $entityManager;
91 278
    }
92
93
    /**
94
     * Returns $identifier quoted for use in a sql statement
95
     *
96
     * @param string $identifier Identifier to quote
97
     * @return string
98
     */
99 163
    public function escapeIdentifier($identifier)
100
    {
101 163
        $q = static::$quotingCharacter;
102 163
        $d = static::$identifierDivider;
103 163
        return $q . str_replace($d, $q . $d . $q, $identifier) . $q;
104
    }
105
106
    /**
107
     * Returns $value formatted to use in a sql statement.
108
     *
109
     * @param  mixed  $value      The variable that should be returned in SQL syntax
110
     * @return string
111
     * @throws NotScalar
112
     */
113 162
    public function escapeValue($value)
114
    {
115 162
        switch (strtolower(gettype($value))) {
116 162
            case 'string':
117 119
                return $this->em->getConnection()->quote($value);
118
119 57
            case 'integer':
120 49
                return (string) $value;
121
122 8
            case 'double':
123 4
                return (string) $value;
124
125 4
            case 'null':
126 1
                return 'NULL';
127
128 3
            case 'boolean':
129 2
                return ($value) ? static::$booleanTrue : static::$booleanFalse;
130
131
            default:
132 1
                throw new NotScalar('$value has to be scalar data type. ' . gettype($value) . ' given');
133
        }
134
    }
135
136
    /**
137
     * Describe a table
138
     *
139
     * @param $table
140
     * @return Column[]
141
     * @throws UnsupportedDriver
142
     */
143 1
    public function describe($table)
144
    {
145 1
        throw new UnsupportedDriver('Not supported for this driver');
146
    }
147
148
    /**
149
     * Inserts $entity and returns the new ID for autoincrement or true
150
     *
151
     * @param Entity $entity
152
     * @param bool   $useAutoIncrement
153
     * @return bool|int
154
     * @throws UnsupportedDriver
155
     */
156 3
    public function insert($entity, $useAutoIncrement = true)
157
    {
158 3
        $statement = $this->buildInsertStatement($entity);
159
160 3
        if ($useAutoIncrement && $entity::isAutoIncremented()) {
161 1
            throw new UnsupportedDriver('Auto incremented column for this driver is not supported');
162
        }
163
164 2
        $this->em->getConnection()->query($statement);
165 2
        $this->em->sync($entity, true);
166 2
        return true;
167
    }
168
169
    /**
170
     * Update $entity in database
171
     *
172
     * @param Entity $entity
173
     * @return bool
174
     * @internal
175
     */
176 6
    public function update(Entity $entity)
177
    {
178 6
        $data = $entity->getData();
179 6
        $primaryKey = $entity->getPrimaryKey();
180
181 6
        $where = [];
182 6
        foreach ($primaryKey as $var => $value) {
183 6
            $col = $entity::getColumnName($var);
184 6
            $where[] = $this->escapeIdentifier($col) . ' = ' . $this->escapeValue($value);
185 6
            if (isset($data[$col])) {
186 6
                unset($data[$col]);
187
            }
188
        }
189
190 6
        $set = [];
191 6
        foreach ($data as $col => $value) {
192 6
            $set[] = $this->escapeIdentifier($col) . ' = ' . $this->escapeValue($value);
193
        }
194
195 6
        $statement = 'UPDATE ' . $this->escapeIdentifier($entity::getTableName()) . ' ' .
196 6
                     'SET ' . implode(',', $set) . ' ' .
197 6
                     'WHERE ' . implode(' AND ', $where);
198 6
        $this->em->getConnection()->query($statement);
199
200 3
        return true;
201
    }
202
203
    /**
204
     * Delete $entity from database
205
     *
206
     * This method does not delete from the map - you can still receive the entity via fetch.
207
     *
208
     * @param Entity $entity
209
     * @return bool
210
     */
211 6
    public function delete(Entity $entity)
212
    {
213 6
        $primaryKey = $entity->getPrimaryKey();
214 6
        $where = [];
215 6
        foreach ($primaryKey as $var => $value) {
216 6
            $col = $entity::getColumnName($var);
217 6
            $where[] = $this->escapeIdentifier($col) . ' = ' . $this->escapeValue($value);
218
        }
219
220 6
        $statement = 'DELETE FROM ' . $this->escapeIdentifier($entity::getTableName()) . ' ' .
221 6
                     'WHERE ' . implode(' AND ', $where);
222 6
        $this->em->getConnection()->query($statement);
223
224 4
        return true;
225
    }
226
227
    /**
228
     * Build the insert statement for $entity
229
     *
230
     * @param Entity $entity
231
     * @return string
232
     */
233 11
    protected function buildInsertStatement($entity)
234
    {
235 11
        $data = $entity->getData();
236
237
        $cols = array_map(function ($key) {
238 11
            return $this->escapeIdentifier($key);
239 11
        }, array_keys($data));
240
241 11
        $values = array_map(function ($value) use ($entity) {
242 11
            return $this->escapeValue($value);
243 11
        }, array_values($data));
244
245 11
        $statement = 'INSERT INTO ' . $this->escapeIdentifier($entity::getTableName()) . ' ' .
246 11
                     '(' . implode(',', $cols) . ') VALUES (' . implode(',', $values) . ')';
247
248 11
        return $statement;
249
    }
250
251 61
    protected function normalizeType($type)
252
    {
253 61
        $type = strtolower($type);
254
255 61
        if (($p = strpos($type, '(')) !== false && $p > 0) {
256 23
            $type = substr($type, 0, $p);
257
        }
258
259 61
        return $type;
260
    }
261
262 9
    protected function extractParenthesis($type)
263
    {
264 9
        if (preg_match('/\(([\d,]+)\)/', $type, $match)) {
265 4
            return $match[1];
266
        }
267
268 5
        return null;
269
    }
270
271 85
    protected function getType($columnDefinition)
272
    {
273 85
        if (isset(static::$typeMapping[$columnDefinition['data_type']])) {
274 76
            return (static::$typeMapping[$columnDefinition['data_type']])::factory($columnDefinition);
275
        } else {
276
//            foreach (self::$registeredTypes as $class) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
277
//                if ($type = $class::fromDefinition($columnDefinition)) {
278
//                    return $type;
279
//                }
280
//            }
281
282 9
            return new Type\Text();
283
        }
284
    }
285
}
286