These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * SQLite schema manager class |
||
5 | * |
||
6 | * @package SQLite3 |
||
7 | */ |
||
8 | class SQLite3SchemaManager extends DBSchemaManager |
||
0 ignored issues
–
show
|
|||
9 | { |
||
10 | |||
11 | /** |
||
12 | * Instance of the database controller this schema belongs to |
||
13 | * |
||
14 | * @var SQLite3Database |
||
15 | */ |
||
16 | protected $database = null; |
||
17 | |||
18 | /** |
||
19 | * Flag indicating whether or not the database has been checked and repaired |
||
20 | * |
||
21 | * @var boolean |
||
22 | */ |
||
23 | protected static $checked_and_repaired = false; |
||
24 | |||
25 | /** |
||
26 | * Should schema be vacuumed during checkeAndRepairTable? |
||
27 | * |
||
28 | * @var boolean |
||
29 | */ |
||
30 | public static $vacuum = true; |
||
31 | |||
32 | public function createDatabase($name) |
||
33 | { |
||
34 | // Ensure that any existing database is cleared before connection |
||
35 | $this->dropDatabase($name); |
||
36 | } |
||
37 | |||
38 | public function dropDatabase($name) |
||
39 | { |
||
40 | // No need to delete database files if operating purely within memory |
||
41 | if ($this->database->getLivesInMemory()) { |
||
42 | return; |
||
43 | } |
||
44 | |||
45 | // If using file based database ensure any existing file is removed |
||
46 | $parameters = $this->database->getParameters(); |
||
47 | $fullpath = $parameters['path'] . '/' . $name; |
||
48 | if (is_writable($fullpath)) { |
||
49 | unlink($fullpath); |
||
50 | } |
||
51 | } |
||
52 | |||
53 | public function databaseList() |
||
54 | { |
||
55 | $parameters = $this->database->getParameters(); |
||
56 | |||
57 | // If in-memory use the current database name only |
||
58 | if ($this->database->getLivesInMemory()) { |
||
59 | return array($parameters['database']); |
||
60 | } |
||
61 | |||
62 | // If using file based database enumerate files in the database directory |
||
63 | $directory = $parameters['path']; |
||
64 | $files = scandir($directory); |
||
65 | |||
66 | // Filter each file in this directory |
||
67 | $databases = array(); |
||
68 | if ($files !== false) { |
||
69 | foreach ($files as $file) { |
||
70 | |||
71 | // Filter non-files |
||
72 | if (!is_file("$directory/$file")) { |
||
73 | continue; |
||
74 | } |
||
75 | |||
76 | // Filter those with correct extension |
||
77 | if (!SQLite3Database::is_valid_database_name($file)) { |
||
78 | continue; |
||
79 | } |
||
80 | |||
81 | $databases[] = $file; |
||
82 | } |
||
83 | } |
||
84 | return $databases; |
||
85 | } |
||
86 | |||
87 | public function databaseExists($name) |
||
88 | { |
||
89 | $databases = $this->databaseList(); |
||
90 | return in_array($name, $databases); |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * Empties any cached enum values |
||
95 | */ |
||
96 | public function flushCache() |
||
97 | { |
||
98 | $this->enum_map = array(); |
||
99 | } |
||
100 | |||
101 | public function schemaUpdate($callback) |
||
102 | { |
||
103 | // Set locking mode |
||
104 | $this->database->setPragma('locking_mode', 'EXCLUSIVE'); |
||
105 | $this->checkAndRepairTable(); |
||
106 | $this->flushCache(); |
||
107 | |||
108 | // Initiate schema update |
||
109 | $error = null; |
||
110 | try { |
||
111 | parent::schemaUpdate($callback); |
||
112 | } catch (Exception $ex) { |
||
113 | $error = $ex; |
||
114 | } |
||
115 | |||
116 | // Revert locking mode |
||
117 | $this->database->setPragma('locking_mode', SQLite3Database::$default_pragma['locking_mode']); |
||
118 | |||
119 | if ($error) { |
||
120 | throw $error; |
||
121 | } |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Empty a specific table |
||
126 | * |
||
127 | * @param string $table |
||
128 | */ |
||
129 | public function clearTable($table) |
||
130 | { |
||
131 | if ($table != 'SQLiteEnums') { |
||
132 | $this->dbConn->query("DELETE FROM \"$table\""); |
||
0 ignored issues
–
show
The property
dbConn does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
Loading history...
|
|||
133 | } |
||
134 | } |
||
135 | |||
136 | public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) |
||
137 | { |
||
138 | if (!isset($fields['ID'])) { |
||
139 | $fields['ID'] = $this->IdColumn(); |
||
140 | } |
||
141 | |||
142 | $fieldSchemata = array(); |
||
143 | if ($fields) { |
||
0 ignored issues
–
show
The expression
$fields of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
144 | foreach ($fields as $k => $v) { |
||
145 | $fieldSchemata[] = "\"$k\" $v"; |
||
146 | } |
||
147 | } |
||
148 | $fieldSchemas = implode(",\n", $fieldSchemata); |
||
149 | |||
150 | // Switch to "CREATE TEMPORARY TABLE" for temporary tables |
||
151 | $temporary = empty($options['temporary']) ? "" : "TEMPORARY"; |
||
152 | $this->query("CREATE $temporary TABLE \"$table\" ( |
||
153 | $fieldSchemas |
||
154 | )"); |
||
155 | |||
156 | if ($indexes) { |
||
157 | foreach ($indexes as $indexName => $indexDetails) { |
||
158 | $this->createIndex($table, $indexName, $indexDetails); |
||
159 | } |
||
160 | } |
||
161 | |||
162 | return $table; |
||
163 | } |
||
164 | |||
165 | public function alterTable($tableName, $newFields = null, $newIndexes = null, $alteredFields = null, |
||
166 | $alteredIndexes = null, $alteredOptions = null, $advancedOptions = null |
||
167 | ) { |
||
168 | if ($newFields) { |
||
169 | foreach ($newFields as $fieldName => $fieldSpec) { |
||
170 | $this->createField($tableName, $fieldName, $fieldSpec); |
||
171 | } |
||
172 | } |
||
173 | |||
174 | if ($alteredFields) { |
||
175 | foreach ($alteredFields as $fieldName => $fieldSpec) { |
||
176 | $this->alterField($tableName, $fieldName, $fieldSpec); |
||
177 | } |
||
178 | } |
||
179 | |||
180 | if ($newIndexes) { |
||
181 | foreach ($newIndexes as $indexName => $indexSpec) { |
||
182 | $this->createIndex($tableName, $indexName, $indexSpec); |
||
183 | } |
||
184 | } |
||
185 | |||
186 | if ($alteredIndexes) { |
||
187 | foreach ($alteredIndexes as $indexName => $indexSpec) { |
||
188 | $this->alterIndex($tableName, $indexName, $indexSpec); |
||
189 | } |
||
190 | } |
||
191 | } |
||
192 | |||
193 | public function renameTable($oldTableName, $newTableName) |
||
194 | { |
||
195 | $this->query("ALTER TABLE \"$oldTableName\" RENAME TO \"$newTableName\""); |
||
196 | } |
||
197 | |||
198 | public function checkAndRepairTable($tableName = null) |
||
199 | { |
||
200 | $ok = true; |
||
201 | |||
202 | if (!SapphireTest::using_temp_db() && !self::$checked_and_repaired) { |
||
203 | $this->alterationMessage("Checking database integrity", "repaired"); |
||
204 | |||
205 | // Check for any tables with failed integrity |
||
206 | if ($messages = $this->query('PRAGMA integrity_check')) { |
||
207 | foreach ($messages as $message) { |
||
208 | if ($message['integrity_check'] != 'ok') { |
||
209 | Debug::show($message['integrity_check']); |
||
210 | $ok = false; |
||
211 | } |
||
212 | } |
||
213 | } |
||
214 | |||
215 | // If enabled vacuum (clean and rebuild) the database |
||
216 | if (self::$vacuum) { |
||
217 | $this->query('VACUUM', E_USER_NOTICE); |
||
218 | $message = $this->database->getConnector()->getLastError(); |
||
219 | if (preg_match('/authoriz/', $message)) { |
||
220 | $this->alterationMessage("VACUUM | $message", "error"); |
||
221 | } else { |
||
222 | $this->alterationMessage("VACUUMing", "repaired"); |
||
223 | } |
||
224 | } |
||
225 | self::$checked_and_repaired = true; |
||
226 | } |
||
227 | |||
228 | return $ok; |
||
229 | } |
||
230 | |||
231 | public function createField($table, $field, $spec) |
||
232 | { |
||
233 | $this->query("ALTER TABLE \"$table\" ADD \"$field\" $spec"); |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * Change the database type of the given field. |
||
238 | * @param string $tableName The name of the tbale the field is in. |
||
239 | * @param string $fieldName The name of the field to change. |
||
240 | * @param string $fieldSpec The new field specification |
||
241 | */ |
||
242 | public function alterField($tableName, $fieldName, $fieldSpec) |
||
243 | { |
||
244 | $oldFieldList = $this->fieldList($tableName); |
||
245 | $fieldNameList = '"' . implode('","', array_keys($oldFieldList)) . '"'; |
||
246 | |||
247 | if (!empty($_REQUEST['avoidConflict']) && Director::isDev()) { |
||
248 | $fieldSpec = preg_replace('/\snot null\s/i', ' NOT NULL ON CONFLICT REPLACE ', $fieldSpec); |
||
249 | } |
||
250 | |||
251 | // Skip non-existing columns |
||
252 | if (!array_key_exists($fieldName, $oldFieldList)) { |
||
253 | return; |
||
254 | } |
||
255 | |||
256 | // Update field spec |
||
257 | $newColsSpec = array(); |
||
258 | foreach ($oldFieldList as $name => $oldSpec) { |
||
259 | $newColsSpec[] = "\"$name\" " . ($name == $fieldName ? $fieldSpec : $oldSpec); |
||
260 | } |
||
261 | |||
262 | $queries = array( |
||
263 | "BEGIN TRANSACTION", |
||
264 | "CREATE TABLE \"{$tableName}_alterfield_{$fieldName}\"(" . implode(',', $newColsSpec) . ")", |
||
265 | "INSERT INTO \"{$tableName}_alterfield_{$fieldName}\" SELECT {$fieldNameList} FROM \"$tableName\"", |
||
266 | "DROP TABLE \"$tableName\"", |
||
267 | "ALTER TABLE \"{$tableName}_alterfield_{$fieldName}\" RENAME TO \"$tableName\"", |
||
268 | "COMMIT" |
||
269 | ); |
||
270 | |||
271 | // Remember original indexes |
||
272 | $indexList = $this->indexList($tableName); |
||
273 | |||
274 | // Then alter the table column |
||
275 | foreach ($queries as $query) { |
||
276 | $this->query($query.';'); |
||
277 | } |
||
278 | |||
279 | // Recreate the indexes |
||
280 | foreach ($indexList as $indexName => $indexSpec) { |
||
281 | $this->createIndex($tableName, $indexName, $indexSpec); |
||
282 | } |
||
283 | } |
||
284 | |||
285 | public function renameField($tableName, $oldName, $newName) |
||
286 | { |
||
287 | $oldFieldList = $this->fieldList($tableName); |
||
288 | |||
289 | // Skip non-existing columns |
||
290 | if (!array_key_exists($oldName, $oldFieldList)) { |
||
291 | return; |
||
292 | } |
||
293 | |||
294 | // Determine column mappings |
||
295 | $oldCols = array(); |
||
296 | $newColsSpec = array(); |
||
297 | foreach ($oldFieldList as $name => $spec) { |
||
298 | $oldCols[] = "\"$name\"" . (($name == $oldName) ? " AS $newName" : ''); |
||
299 | $newColsSpec[] = "\"" . (($name == $oldName) ? $newName : $name) . "\" $spec"; |
||
300 | } |
||
301 | |||
302 | // SQLite doesn't support direct renames through ALTER TABLE |
||
303 | $queries = array( |
||
304 | "BEGIN TRANSACTION", |
||
305 | "CREATE TABLE \"{$tableName}_renamefield_{$oldName}\" (" . implode(',', $newColsSpec) . ")", |
||
306 | "INSERT INTO \"{$tableName}_renamefield_{$oldName}\" SELECT " . implode(',', $oldCols) . " FROM \"$tableName\"", |
||
307 | "DROP TABLE \"$tableName\"", |
||
308 | "ALTER TABLE \"{$tableName}_renamefield_{$oldName}\" RENAME TO \"$tableName\"", |
||
309 | "COMMIT" |
||
310 | ); |
||
311 | |||
312 | // Remember original indexes |
||
313 | $oldIndexList = $this->indexList($tableName); |
||
314 | |||
315 | // Then alter the table column |
||
316 | foreach ($queries as $query) { |
||
317 | $this->query($query.';'); |
||
318 | } |
||
319 | |||
320 | // Recreate the indexes |
||
321 | foreach ($oldIndexList as $indexName => $indexSpec) { |
||
322 | // Rename columns to new columns |
||
323 | $indexSpec['value'] = preg_replace("/\"$oldName\"/i", "\"$newName\"", $indexSpec['value']); |
||
324 | $this->createIndex($tableName, $indexName, $indexSpec); |
||
325 | } |
||
326 | } |
||
327 | |||
328 | public function fieldList($table) |
||
329 | { |
||
330 | $sqlCreate = $this->preparedQuery( |
||
331 | 'SELECT sql FROM sqlite_master WHERE type = ? AND name = ?', |
||
332 | array('table', $table) |
||
333 | )->record(); |
||
334 | |||
335 | $fieldList = array(); |
||
336 | if ($sqlCreate && $sqlCreate['sql']) { |
||
0 ignored issues
–
show
The expression
$sqlCreate of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
337 | preg_match('/^[\s]*CREATE[\s]+TABLE[\s]+[\'"]?[a-zA-Z0-9_\\\]+[\'"]?[\s]*\((.+)\)[\s]*$/ims', |
||
338 | $sqlCreate['sql'], $matches |
||
339 | ); |
||
340 | $fields = isset($matches[1]) |
||
341 | ? preg_split('/,(?=(?:[^\'"]*$)|(?:[^\'"]*[\'"][^\'"]*[\'"][^\'"]*)*$)/x', $matches[1]) |
||
342 | : array(); |
||
343 | foreach ($fields as $field) { |
||
344 | $details = preg_split('/\s/', trim($field)); |
||
345 | $name = array_shift($details); |
||
346 | $name = str_replace('"', '', trim($name)); |
||
347 | $fieldList[$name] = implode(' ', $details); |
||
348 | } |
||
349 | } |
||
350 | return $fieldList; |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * Create an index on a table. |
||
355 | * |
||
356 | * @param string $tableName The name of the table. |
||
357 | * @param string $indexName The name of the index. |
||
358 | * @param array $indexSpec The specification of the index, see Database::requireIndex() for more details. |
||
359 | */ |
||
360 | public function createIndex($tableName, $indexName, $indexSpec) |
||
361 | { |
||
362 | $parsedSpec = $this->parseIndexSpec($indexName, $indexSpec); |
||
363 | $sqliteName = $this->buildSQLiteIndexName($tableName, $indexName); |
||
364 | $columns = $parsedSpec['value']; |
||
365 | $unique = ($parsedSpec['type'] == 'unique') ? 'UNIQUE' : ''; |
||
366 | $this->query("CREATE $unique INDEX IF NOT EXISTS \"$sqliteName\" ON \"$tableName\" ($columns)"); |
||
367 | } |
||
368 | |||
369 | public function alterIndex($tableName, $indexName, $indexSpec) |
||
370 | { |
||
371 | // Drop existing index |
||
372 | $sqliteName = $this->buildSQLiteIndexName($tableName, $indexName); |
||
373 | $this->query("DROP INDEX IF EXISTS \"$sqliteName\""); |
||
374 | |||
375 | // Create the index |
||
376 | $this->createIndex($tableName, $indexName, $indexSpec); |
||
0 ignored issues
–
show
$indexSpec is of type string , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Builds the internal SQLLite index name given the silverstripe table and index name. |
||
381 | * |
||
382 | * The name is built using the table and index name in order to prevent name collisions |
||
383 | * between indexes of the same name across multiple tables |
||
384 | * |
||
385 | * @param string $tableName |
||
386 | * @param string $indexName |
||
387 | * @return string The SQLite3 name of the index |
||
388 | */ |
||
389 | protected function buildSQLiteIndexName($tableName, $indexName) |
||
390 | { |
||
391 | return "{$tableName}_{$indexName}"; |
||
392 | } |
||
393 | |||
394 | protected function parseIndexSpec($name, $spec) |
||
395 | { |
||
396 | $spec = parent::parseIndexSpec($name, $spec); |
||
397 | |||
398 | // Only allow index / unique index types |
||
399 | if (!in_array($spec['type'], array('index', 'unique'))) { |
||
400 | $spec['type'] = 'index'; |
||
401 | } |
||
402 | |||
403 | return $spec; |
||
404 | } |
||
405 | |||
406 | public function indexKey($table, $index, $spec) |
||
407 | { |
||
408 | return $this->buildSQLiteIndexName($table, $index); |
||
409 | } |
||
410 | |||
411 | public function indexList($table) |
||
412 | { |
||
413 | $indexList = array(); |
||
414 | |||
415 | // Enumerate each index and related fields |
||
416 | foreach ($this->query("PRAGMA index_list(\"$table\")") as $index) { |
||
417 | |||
418 | // The SQLite internal index name, not the actual Silverstripe name |
||
419 | $indexName = $index["name"]; |
||
420 | $indexType = $index['unique'] ? 'unique' : 'index'; |
||
421 | |||
422 | // Determine a clean list of column names within this index |
||
423 | $list = array(); |
||
424 | foreach ($this->query("PRAGMA index_info(\"$indexName\")") as $details) { |
||
425 | $list[] = preg_replace('/^"?(.*)"?$/', '$1', $details['name']); |
||
426 | } |
||
427 | |||
428 | // Safely encode this spec |
||
429 | $indexList[$indexName] = $this->parseIndexSpec($indexName, array( |
||
430 | 'name' => $indexName, |
||
431 | 'value' => $this->implodeColumnList($list), |
||
432 | 'type' => $indexType |
||
433 | )); |
||
434 | } |
||
435 | |||
436 | return $indexList; |
||
437 | } |
||
438 | |||
439 | public function tableList() |
||
440 | { |
||
441 | $tables = array(); |
||
442 | $result = $this->preparedQuery('SELECT name FROM sqlite_master WHERE type = ?', array('table')); |
||
443 | foreach ($result as $record) { |
||
444 | $table = reset($record); |
||
445 | $tables[strtolower($table)] = $table; |
||
446 | } |
||
447 | return $tables; |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * Return a boolean type-formatted string |
||
452 | * |
||
453 | * @params array $values Contains a tokenised list of info about this data type |
||
454 | * @return string |
||
455 | */ |
||
456 | public function boolean($values) |
||
457 | { |
||
458 | $default = empty($values['default']) ? 0 : (int)$values['default']; |
||
459 | return "BOOL NOT NULL DEFAULT $default"; |
||
460 | } |
||
461 | |||
462 | /** |
||
463 | * Return a date type-formatted string |
||
464 | * |
||
465 | * @params array $values Contains a tokenised list of info about this data type |
||
466 | * @return string |
||
467 | */ |
||
468 | public function date($values) |
||
0 ignored issues
–
show
|
|||
469 | { |
||
470 | return "TEXT"; |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * Return a decimal type-formatted string |
||
475 | * |
||
476 | * @params array $values Contains a tokenised list of info about this data type |
||
477 | * @return string |
||
478 | */ |
||
479 | public function decimal($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
480 | { |
||
481 | $default = isset($values['default']) && is_numeric($values['default']) ? $values['default'] : 0; |
||
482 | return "NUMERIC NOT NULL DEFAULT $default"; |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Cached list of enum values indexed by table.column |
||
487 | * |
||
488 | * @var array |
||
489 | */ |
||
490 | protected $enum_map = array(); |
||
491 | |||
492 | /** |
||
493 | * Return a enum type-formatted string |
||
494 | * |
||
495 | * enums are not supported. as a workaround to store allowed values we creates an additional table |
||
496 | * |
||
497 | * @params array $values Contains a tokenised list of info about this data type |
||
498 | * @return string |
||
499 | */ |
||
500 | public function enum($values) |
||
501 | { |
||
502 | $tablefield = $values['table'] . '.' . $values['name']; |
||
503 | $enumValues = implode(',', $values['enums']); |
||
504 | |||
505 | // Ensure the cache table exists |
||
506 | if (empty($this->enum_map)) { |
||
507 | $this->query("CREATE TABLE IF NOT EXISTS \"SQLiteEnums\" (\"TableColumn\" TEXT PRIMARY KEY, \"EnumList\" TEXT)"); |
||
508 | } |
||
509 | |||
510 | // Ensure the table row exists |
||
511 | if (empty($this->enum_map[$tablefield]) || $this->enum_map[$tablefield] != $enumValues) { |
||
512 | $this->preparedQuery( |
||
513 | "REPLACE INTO SQLiteEnums (TableColumn, EnumList) VALUES (?, ?)", |
||
514 | array($tablefield, $enumValues) |
||
515 | ); |
||
516 | $this->enum_map[$tablefield] = $enumValues; |
||
517 | } |
||
518 | |||
519 | // Set default |
||
520 | if (!empty($values['default'])) { |
||
521 | $default = str_replace(array('"', "'", "\\", "\0"), "", $values['default']); |
||
522 | return "TEXT DEFAULT '$default'"; |
||
523 | } else { |
||
524 | return 'TEXT'; |
||
525 | } |
||
526 | } |
||
527 | |||
528 | /** |
||
529 | * Return a set type-formatted string |
||
530 | * This type doesn't exist in SQLite either |
||
531 | * |
||
532 | * @see SQLite3SchemaManager::enum() |
||
533 | * |
||
534 | * @params array $values Contains a tokenised list of info about this data type |
||
535 | * @return string |
||
536 | */ |
||
537 | public function set($values) |
||
538 | { |
||
539 | return $this->enum($values); |
||
540 | } |
||
541 | |||
542 | /** |
||
543 | * Return a float type-formatted string |
||
544 | * |
||
545 | * @params array $values Contains a tokenised list of info about this data type |
||
546 | * @return string |
||
547 | */ |
||
548 | public function float($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
549 | { |
||
550 | return "REAL"; |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * Return a Double type-formatted string |
||
555 | * |
||
556 | * @params array $values Contains a tokenised list of info about this data type |
||
557 | * @return string |
||
558 | */ |
||
559 | public function double($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
560 | { |
||
561 | return "REAL"; |
||
562 | } |
||
563 | |||
564 | /** |
||
565 | * Return a int type-formatted string |
||
566 | * |
||
567 | * @params array $values Contains a tokenised list of info about this data type |
||
568 | * @return string |
||
569 | */ |
||
570 | public function int($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
571 | { |
||
572 | return "INTEGER({$values['precision']}) " . strtoupper($values['null']) . " DEFAULT " . (int)$values['default']; |
||
573 | } |
||
574 | |||
575 | /** |
||
576 | * Return a bigint type-formatted string |
||
577 | * |
||
578 | * @params array $values Contains a tokenised list of info about this data type |
||
579 | * @return string |
||
580 | */ |
||
581 | public function bigint($values, $asDbValue = false) |
||
582 | { |
||
583 | return $this->int($values, $asDbValue); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Return a datetime type-formatted string |
||
588 | * For SQLite3, we simply return the word 'TEXT', no other parameters are necessary |
||
589 | * |
||
590 | * @params array $values Contains a tokenised list of info about this data type |
||
591 | * @return string |
||
592 | */ |
||
593 | public function ss_datetime($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
594 | { |
||
595 | return "DATETIME"; |
||
596 | } |
||
597 | |||
598 | /** |
||
599 | * Return a text type-formatted string |
||
600 | * |
||
601 | * @params array $values Contains a tokenised list of info about this data type |
||
602 | * @return string |
||
603 | */ |
||
604 | public function text($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
605 | { |
||
606 | return 'TEXT'; |
||
607 | } |
||
608 | |||
609 | /** |
||
610 | * Return a time type-formatted string |
||
611 | * |
||
612 | * @params array $values Contains a tokenised list of info about this data type |
||
613 | * @return string |
||
614 | */ |
||
615 | public function time($values) |
||
0 ignored issues
–
show
|
|||
616 | { |
||
617 | return "TEXT"; |
||
618 | } |
||
619 | |||
620 | /** |
||
621 | * Return a varchar type-formatted string |
||
622 | * |
||
623 | * @params array $values Contains a tokenised list of info about this data type |
||
624 | * @return string |
||
625 | */ |
||
626 | public function varchar($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
627 | { |
||
628 | return "VARCHAR({$values['precision']}) COLLATE NOCASE"; |
||
629 | } |
||
630 | |||
631 | /* |
||
632 | * Return a 4 digit numeric type. MySQL has a proprietary 'Year' type. |
||
633 | * For SQLite3 we use TEXT |
||
634 | */ |
||
635 | public function year($values, $asDbValue = false) |
||
0 ignored issues
–
show
|
|||
636 | { |
||
637 | return "TEXT"; |
||
638 | } |
||
639 | |||
640 | public function IdColumn($asDbValue = false, $hasAutoIncPK = true) |
||
641 | { |
||
642 | return 'INTEGER PRIMARY KEY AUTOINCREMENT'; |
||
643 | } |
||
644 | |||
645 | public function hasTable($tableName) |
||
646 | { |
||
647 | return (bool)$this->preparedQuery( |
||
648 | 'SELECT name FROM sqlite_master WHERE type = ? AND name = ?', |
||
649 | array('table', $tableName) |
||
650 | )->first(); |
||
651 | } |
||
652 | |||
653 | /** |
||
654 | * Return enum values for the given field |
||
655 | * |
||
656 | * @return array |
||
657 | */ |
||
658 | public function enumValuesForField($tableName, $fieldName) |
||
659 | { |
||
660 | $tablefield = "$tableName.$fieldName"; |
||
661 | |||
662 | // Check already cached values for this field |
||
663 | if (!empty($this->enum_map[$tablefield])) { |
||
664 | return explode(',', $this->enum_map[$tablefield]); |
||
665 | } |
||
666 | |||
667 | // Retrieve and cache these details from the database |
||
668 | $classnameinfo = $this->preparedQuery( |
||
669 | "SELECT EnumList FROM SQLiteEnums WHERE TableColumn = ?", |
||
670 | array($tablefield) |
||
671 | )->first(); |
||
672 | if ($classnameinfo) { |
||
0 ignored issues
–
show
The expression
$classnameinfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
673 | $valueList = $classnameinfo['EnumList']; |
||
674 | $this->enum_map[$tablefield] = $valueList; |
||
675 | return explode(',', $valueList); |
||
676 | } |
||
677 | |||
678 | // Fallback to empty list |
||
679 | return array(); |
||
680 | } |
||
681 | |||
682 | public function dbDataType($type) |
||
683 | { |
||
684 | $values = array( |
||
685 | 'unsigned integer' => 'INT' |
||
686 | ); |
||
687 | |||
688 | if (isset($values[$type])) { |
||
689 | return $values[$type]; |
||
690 | } else { |
||
691 | return ''; |
||
692 | } |
||
693 | } |
||
694 | } |
||
695 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.