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