1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Database\Drivers;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17:
18: class MySqlDriver extends Nette\Object implements Nette\Database\ISupplementalDriver
19: {
20: const ERROR_ACCESS_DENIED = 1045;
21: const ERROR_DUPLICATE_ENTRY = 1062;
22: const ERROR_DATA_TRUNCATED = 1265;
23:
24:
25: private $connection;
26:
27:
28: 29: 30: 31: 32:
33: public function __construct(Nette\Database\Connection $connection, array $options)
34: {
35: $this->connection = $connection;
36: $charset = isset($options['charset']) ? $options['charset'] : 'utf8';
37: if ($charset) {
38: $connection->query("SET NAMES '$charset'");
39: }
40: if (isset($options['sqlmode'])) {
41: $connection->query("SET sql_mode='$options[sqlmode]'");
42: }
43: $connection->query("SET time_zone='" . date('P') . "'");
44: }
45:
46:
47:
48:
49:
50: 51: 52:
53: public function delimite($name)
54: {
55:
56: return '`' . str_replace('`', '``', $name) . '`';
57: }
58:
59:
60: 61: 62:
63: public function formatBool($value)
64: {
65: return $value ? '1' : '0';
66: }
67:
68:
69: 70: 71:
72: public function formatDateTime(\DateTime $value)
73: {
74: return $value->format("'Y-m-d H:i:s'");
75: }
76:
77:
78: 79: 80:
81: public function formatLike($value, $pos)
82: {
83: $value = addcslashes(str_replace('\\', '\\\\', $value), "\x00\n\r\\'%_");
84: return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
85: }
86:
87:
88: 89: 90:
91: public function applyLimit(& $sql, $limit, $offset)
92: {
93: if ($limit >= 0 || $offset > 0) {
94:
95: $sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
96: . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
97: }
98: }
99:
100:
101: 102: 103:
104: public function normalizeRow($row, $statement)
105: {
106: return $row;
107: }
108:
109:
110:
111:
112:
113: 114: 115:
116: public function getTables()
117: {
118: 119: 120: 121: 122:
123: $tables = array();
124: foreach ($this->connection->query('SHOW FULL TABLES') as $row) {
125: $tables[] = array(
126: 'name' => $row[0],
127: 'view' => isset($row[1]) && $row[1] === 'VIEW',
128: );
129: }
130: return $tables;
131: }
132:
133:
134: 135: 136:
137: public function getColumns($table)
138: {
139: 140: 141: 142: 143:
144: $columns = array();
145: foreach ($this->connection->query('SHOW FULL COLUMNS FROM ' . $this->delimite($table)) as $row) {
146: $type = explode('(', $row['Type']);
147: $columns[] = array(
148: 'name' => $row['Field'],
149: 'table' => $table,
150: 'nativetype' => strtoupper($type[0]),
151: 'size' => isset($type[1]) ? (int) $type[1] : NULL,
152: 'unsigned' => (bool) strstr($row['Type'], 'unsigned'),
153: 'nullable' => $row['Null'] === 'YES',
154: 'default' => $row['Default'],
155: 'autoincrement' => $row['Extra'] === 'auto_increment',
156: 'primary' => $row['Key'] === 'PRI',
157: 'vendor' => (array) $row,
158: );
159: }
160: return $columns;
161: }
162:
163:
164: 165: 166:
167: public function getIndexes($table)
168: {
169: 170: 171: 172: 173: 174:
175: $indexes = array();
176: foreach ($this->connection->query('SHOW INDEX FROM ' . $this->delimite($table)) as $row) {
177: $indexes[$row['Key_name']]['name'] = $row['Key_name'];
178: $indexes[$row['Key_name']]['unique'] = !$row['Non_unique'];
179: $indexes[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY';
180: $indexes[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name'];
181: }
182: return array_values($indexes);
183: }
184:
185:
186: 187: 188:
189: public function getForeignKeys($table)
190: {
191: $keys = array();
192: $query = 'SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE '
193: . 'WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = ' . $this->connection->quote($table);
194:
195: foreach ($this->connection->query($query) as $id => $row) {
196: $keys[$id]['name'] = $row['CONSTRAINT_NAME'];
197: $keys[$id]['local'] = $row['COLUMN_NAME'];
198: $keys[$id]['table'] = $row['REFERENCED_TABLE_NAME'];
199: $keys[$id]['foreign'] = $row['REFERENCED_COLUMN_NAME'];
200: }
201:
202: return array_values($keys);
203: }
204:
205:
206: 207: 208:
209: public function isSupported($item)
210: {
211: return $item === self::SUPPORT_COLUMNS_META || $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS;
212: }
213:
214: }
215: