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