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