1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
20: App::import('Datasource', 'DboMysql');
21:
22: 23: 24: 25: 26: 27: 28: 29:
30: class DboMysqli extends DboMysqlBase {
31:
32: 33: 34: 35: 36:
37: var $description = "Mysqli DBO Driver";
38:
39: 40: 41: 42: 43:
44: var $_baseConfig = array(
45: 'persistent' => true,
46: 'host' => 'localhost',
47: 'login' => 'root',
48: 'password' => '',
49: 'database' => 'cake',
50: 'port' => '3306',
51: 'socket' => null
52: );
53:
54: 55: 56: 57: 58:
59: function connect() {
60: $config = $this->config;
61: $this->connected = false;
62:
63: $this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port'], $config['socket']);
64:
65: if ($this->connection !== false) {
66: $this->connected = true;
67: } else {
68: return false;
69: }
70:
71: $this->_useAlias = (bool)version_compare(mysqli_get_server_info($this->connection), "4.1", ">=");
72:
73: if (!empty($config['encoding'])) {
74: $this->setEncoding($config['encoding']);
75: }
76: return $this->connected;
77: }
78:
79: 80: 81: 82: 83:
84: function enabled() {
85: return extension_loaded('mysqli');
86: }
87: 88: 89: 90: 91:
92: function disconnect() {
93: if (isset($this->results) && is_resource($this->results)) {
94: mysqli_free_result($this->results);
95: }
96: $this->connected = !@mysqli_close($this->connection);
97: return !$this->connected;
98: }
99:
100: 101: 102: 103: 104: 105: 106:
107: function _execute($sql) {
108: if (preg_match('/^\s*call/i', $sql)) {
109: return $this->_executeProcedure($sql);
110: }
111: return mysqli_query($this->connection, $sql);
112: }
113:
114: 115: 116: 117: 118: 119: 120:
121: function _executeProcedure($sql) {
122: $answer = mysqli_multi_query($this->connection, $sql);
123:
124: $firstResult = mysqli_store_result($this->connection);
125:
126: if (mysqli_more_results($this->connection)) {
127: while ($lastResult = mysqli_next_result($this->connection));
128: }
129: return $firstResult;
130: }
131:
132: 133: 134: 135: 136:
137: function listSources() {
138: $cache = parent::listSources();
139: if ($cache !== null) {
140: return $cache;
141: }
142: $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
143:
144: if (!$result) {
145: return array();
146: }
147:
148: $tables = array();
149:
150: while ($line = mysqli_fetch_row($result)) {
151: $tables[] = $line[0];
152: }
153: parent::listSources($tables);
154: return $tables;
155: }
156:
157: 158: 159: 160: 161: 162: 163: 164:
165: function value($data, $column = null, $safe = false) {
166: $parent = parent::value($data, $column, $safe);
167:
168: if ($parent != null) {
169: return $parent;
170: }
171: if ($data === null || (is_array($data) && empty($data))) {
172: return 'NULL';
173: }
174: if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
175: return "''";
176: }
177: if (empty($column)) {
178: $column = $this->introspectType($data);
179: }
180:
181: switch ($column) {
182: case 'boolean':
183: return $this->boolean((bool)$data);
184: break;
185: case 'integer' :
186: case 'float' :
187: case null :
188: if ($data === '') {
189: return 'NULL';
190: }
191: if (is_float($data)) {
192: return str_replace(',', '.', strval($data));
193: }
194: if ((is_int($data) || is_float($data) || $data === '0') || (
195: is_numeric($data) && strpos($data, ',') === false &&
196: $data[0] != '0' && strpos($data, 'e') === false)) {
197: return $data;
198: }
199: default:
200: $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
201: break;
202: }
203:
204: return $data;
205: }
206:
207: 208: 209: 210: 211:
212: function lastError() {
213: if (mysqli_errno($this->connection)) {
214: return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
215: }
216: return null;
217: }
218:
219: 220: 221: 222: 223: 224:
225: function lastAffected() {
226: if ($this->_result) {
227: return mysqli_affected_rows($this->connection);
228: }
229: return null;
230: }
231:
232: 233: 234: 235: 236: 237:
238: function lastNumRows() {
239: if ($this->hasResult()) {
240: return mysqli_num_rows($this->_result);
241: }
242: return null;
243: }
244:
245: 246: 247: 248: 249: 250:
251: function lastInsertId($source = null) {
252: $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
253: if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
254: return $id[0]['insertID'];
255: }
256: return null;
257: }
258:
259: 260: 261: 262: 263:
264: function resultSet(&$results) {
265: if (isset($this->results) && is_resource($this->results) && $this->results != $results) {
266: mysqli_free_result($this->results);
267: }
268: $this->results =& $results;
269: $this->map = array();
270: $numFields = mysqli_num_fields($results);
271: $index = 0;
272: $j = 0;
273: while ($j < $numFields) {
274: $column = mysqli_fetch_field_direct($results, $j);
275: if (!empty($column->table) && strpos($column->name, $this->virtualFieldSeparator) === false) {
276: $this->map[$index++] = array($column->table, $column->name);
277: } else {
278: $this->map[$index++] = array(0, $column->name);
279: }
280: $j++;
281: }
282: }
283:
284: 285: 286: 287: 288:
289: function fetchResult() {
290: if ($row = mysqli_fetch_row($this->results)) {
291: $resultRow = array();
292: foreach ($row as $index => $field) {
293: $table = $column = null;
294: if (count($this->map[$index]) === 2) {
295: list($table, $column) = $this->map[$index];
296: }
297: $resultRow[$table][$column] = $row[$index];
298: }
299: return $resultRow;
300: }
301: return false;
302: }
303:
304: 305: 306: 307: 308:
309: function getEncoding() {
310: return mysqli_client_encoding($this->connection);
311: }
312:
313: 314: 315: 316: 317: 318:
319: function getCharsetName($name) {
320: if ((bool)version_compare(mysqli_get_server_info($this->connection), "5", ">=")) {
321: $cols = $this->query('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME= ' . $this->value($name) . ';');
322: if (isset($cols[0]['COLLATIONS']['CHARACTER_SET_NAME'])) {
323: return $cols[0]['COLLATIONS']['CHARACTER_SET_NAME'];
324: }
325: }
326: return false;
327: }
328:
329: 330: 331: 332: 333:
334: function hasResult() {
335: return is_object($this->_result);
336: }
337: }
338: