Passed
Push — master ( 5b283a...d58ab5 )
by Richard
01:35
created

MysqlAdapter::getCachedStmt()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 8
rs 9.4285

1 Method

Rating   Name   Duplication   Size   Complexity  
A MysqlAdapter::query() 0 6 1
1
<?php
2
namespace Maphper\DataSource;
3
class MysqlAdapter implements DatabaseAdapter {
4
	private $pdo;
5
	private $stmtCache;
6
7
	public function __construct(\PDO $pdo) {
8
		$this->pdo = $pdo;
9
		//Set to strict mode to detect 'out of range' errors, action at a distance but it needs to be set for all INSERT queries
10
		$this->pdo->query('SET sql_mode = STRICT_ALL_TABLES');
11
        $this->stmtCache = new StmtCache($pdo);
12
	}
13
14
	public function quote($str) {
15
		return '`' . str_replace('.', '`.`', trim($str, '`')) . '`';
16
	}
17
18
	public function query(\Maphper\Lib\Query $query) {
19
		$stmt = $this->stmtCache->getCachedStmt($query->getSql());
20
		$args = $query->getArgs();
21
        $stmt->execute($args);
22
23
		return $stmt;
24
	}
25
26
	private function getType($val) {
27
		if ($val instanceof \DateTime) return 'DATETIME';
28
		else if (is_int($val)) return  'INT(11)';
29
		else if (is_double($val)) return 'DECIMAL(9,' . strlen($val) - strrpos($val, '.') - 1 . ')';
30
		else if (is_string($val)) return strlen($val) < 192 ? 'VARCHAR(191)' : 'LONGBLOB';
31
		return 'VARCHAR(191)';
32
	}
33
34
	//Alter the database so that it can store $data
35
	private function createTable($table, array $primaryKey, $data) {
36
		$parts = [];
37
		foreach ($primaryKey as $key) {
38
			$pk = $data->$key;
39
			if ($pk == null) $parts[] = $key . ' INT(11) NOT NULL AUTO_INCREMENT';
40
			else $parts[] = $key . ' ' . $this->getType($pk) . ' NOT NULL';
41
		}
42
43
		$pkField = implode(', ', $parts) . ', PRIMARY KEY(' . implode(', ', $primaryKey) . ')';
44
		$this->pdo->query('CREATE TABLE IF NOT EXISTS ' . $table . ' (' . $pkField . ')');
45
	}
46
47
	public function alterDatabase($table, array $primaryKey, $data) {
48
		$this->createTable($table, $primaryKey, $data);
49
50
		foreach ($data as $key => $value) {
51
			if (is_array($value) || (is_object($value) && !($value instanceof \DateTime))) continue;
52
			if (in_array($key, $primaryKey)) continue;
53
54
			$type = $this->getType($value);
55
56
			try {
57
				if (!$this->pdo->query('ALTER TABLE ' . $table . ' ADD ' . $this->quote($key) . ' ' . $type)) throw new \Exception('Could not alter table');
58
			}
59
			catch (\Exception $e) {
60
				$this->pdo->query('ALTER TABLE ' . $table . ' MODIFY ' . $this->quote($key) . ' ' . $type);
61
			}
62
		}
63
	}
64
65
	public function lastInsertId() {
66
		return $this->pdo->lastInsertId();
67
	}
68
69
	public function addIndex($table, array $fields) {
70
		//Sort the fields so that the index is never created twice (col1, col2) then (col2, col1)
71
		sort($fields);
72
		$fields = array_map('strtolower', $fields);
73
		$fields = array_map('trim', $fields);
74
		$keyName = $this->quote(implode('_', $fields));
75
76
		$results = $this->pdo->query('SHOW INDEX FROM ' . $this->quote($table) . ' WHERE Key_Name = "' . $keyName . '"');
77
		if ($results && count($results->fetchAll()) == 0)  $this->pdo->query('CREATE INDEX ' . $keyName . ' ON ' . $this->quote($table) . ' (' . implode(', ', $fields) . ')');
78
	}
79
80
	public function optimiseColumns($table) {
81
		//TODO
82
		return;
83
	}
84
}
85