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