CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.5 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.5
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • Mysql
  • Postgres
  • Sqlite
  • Sqlserver
  1: <?php
  2: /**
  3:  * MySQL layer for DBO
  4:  *
  5:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7:  *
  8:  * Licensed under The MIT License
  9:  * For full copyright and license information, please see the LICENSE.txt
 10:  * Redistributions of files must retain the above copyright notice.
 11:  *
 12:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 13:  * @link          http://cakephp.org CakePHP(tm) Project
 14:  * @package       Cake.Model.Datasource.Database
 15:  * @since         CakePHP(tm) v 0.10.5.1790
 16:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 17:  */
 18: 
 19: App::uses('DboSource', 'Model/Datasource');
 20: 
 21: /**
 22:  * MySQL DBO driver object
 23:  *
 24:  * Provides connection and SQL generation for MySQL RDMS
 25:  *
 26:  * @package       Cake.Model.Datasource.Database
 27:  */
 28: class Mysql extends DboSource {
 29: 
 30: /**
 31:  * Datasource description
 32:  *
 33:  * @var string
 34:  */
 35:     public $description = "MySQL DBO Driver";
 36: 
 37: /**
 38:  * Base configuration settings for MySQL driver
 39:  *
 40:  * @var array
 41:  */
 42:     protected $_baseConfig = array(
 43:         'persistent' => true,
 44:         'host' => 'localhost',
 45:         'login' => 'root',
 46:         'password' => '',
 47:         'database' => 'cake',
 48:         'port' => '3306',
 49:         'flags' => array()
 50:     );
 51: 
 52: /**
 53:  * Reference to the PDO object connection
 54:  *
 55:  * @var PDO
 56:  */
 57:     protected $_connection = null;
 58: 
 59: /**
 60:  * Start quote
 61:  *
 62:  * @var string
 63:  */
 64:     public $startQuote = "`";
 65: 
 66: /**
 67:  * End quote
 68:  *
 69:  * @var string
 70:  */
 71:     public $endQuote = "`";
 72: 
 73: /**
 74:  * use alias for update and delete. Set to true if version >= 4.1
 75:  *
 76:  * @var bool
 77:  */
 78:     protected $_useAlias = true;
 79: 
 80: /**
 81:  * List of engine specific additional field parameters used on table creating
 82:  *
 83:  * @var array
 84:  */
 85:     public $fieldParameters = array(
 86:         'charset' => array('value' => 'CHARACTER SET', 'quote' => false, 'join' => ' ', 'column' => false, 'position' => 'beforeDefault'),
 87:         'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => ' ', 'column' => 'Collation', 'position' => 'beforeDefault'),
 88:         'comment' => array('value' => 'COMMENT', 'quote' => true, 'join' => ' ', 'column' => 'Comment', 'position' => 'afterDefault'),
 89:         'unsigned' => array(
 90:             'value' => 'UNSIGNED', 'quote' => false, 'join' => ' ', 'column' => false, 'position' => 'beforeDefault',
 91:             'noVal' => true,
 92:             'options' => array(true),
 93:             'types' => array('integer', 'float', 'decimal', 'biginteger')
 94:         )
 95:     );
 96: 
 97: /**
 98:  * List of table engine specific parameters used on table creating
 99:  *
100:  * @var array
101:  */
102:     public $tableParameters = array(
103:         'charset' => array('value' => 'DEFAULT CHARSET', 'quote' => false, 'join' => '=', 'column' => 'charset'),
104:         'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => '=', 'column' => 'Collation'),
105:         'engine' => array('value' => 'ENGINE', 'quote' => false, 'join' => '=', 'column' => 'Engine')
106:     );
107: 
108: /**
109:  * MySQL column definition
110:  *
111:  * @var array
112:  */
113:     public $columns = array(
114:         'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'),
115:         'string' => array('name' => 'varchar', 'limit' => '255'),
116:         'text' => array('name' => 'text'),
117:         'biginteger' => array('name' => 'bigint', 'limit' => '20'),
118:         'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
119:         'float' => array('name' => 'float', 'formatter' => 'floatval'),
120:         'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'),
121:         'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
122:         'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
123:         'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
124:         'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
125:         'binary' => array('name' => 'blob'),
126:         'boolean' => array('name' => 'tinyint', 'limit' => '1')
127:     );
128: 
129: /**
130:  * Mapping of collation names to character set names
131:  *
132:  * @var array
133:  */
134:     protected $_charsets = array();
135: 
136: /**
137:  * Connects to the database using options in the given configuration array.
138:  *
139:  * MySQL supports a few additional options that other drivers do not:
140:  *
141:  * - `unix_socket` Set to the path of the MySQL sock file. Can be used in place
142:  *   of host + port.
143:  * - `ssl_key` SSL key file for connecting via SSL. Must be combined with `ssl_cert`.
144:  * - `ssl_cert` The SSL certificate to use when connecting via SSL. Must be
145:  *   combined with `ssl_key`.
146:  * - `ssl_ca` The certificate authority for SSL connections.
147:  *
148:  * @return bool True if the database could be connected, else false
149:  * @throws MissingConnectionException
150:  */
151:     public function connect() {
152:         $config = $this->config;
153:         $this->connected = false;
154: 
155:         $flags = $config['flags'] + array(
156:             PDO::ATTR_PERSISTENT => $config['persistent'],
157:             PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
158:             PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
159:         );
160: 
161:         if (!empty($config['encoding'])) {
162:             $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding'];
163:         }
164:         if (!empty($config['ssl_key']) && !empty($config['ssl_cert'])) {
165:             $flags[PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key'];
166:             $flags[PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert'];
167:         }
168:         if (!empty($config['ssl_ca'])) {
169:             $flags[PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca'];
170:         }
171:         if (empty($config['unix_socket'])) {
172:             $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}";
173:         } else {
174:             $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
175:         }
176: 
177:         try {
178:             $this->_connection = new PDO(
179:                 $dsn,
180:                 $config['login'],
181:                 $config['password'],
182:                 $flags
183:             );
184:             $this->connected = true;
185:             if (!empty($config['settings'])) {
186:                 foreach ($config['settings'] as $key => $value) {
187:                     $this->_execute("SET $key=$value");
188:                 }
189:             }
190:         } catch (PDOException $e) {
191:             throw new MissingConnectionException(array(
192:                 'class' => get_class($this),
193:                 'message' => $e->getMessage()
194:             ));
195:         }
196: 
197:         $this->_charsets = array();
198:         $this->_useAlias = (bool)version_compare($this->getVersion(), "4.1", ">=");
199: 
200:         return $this->connected;
201:     }
202: 
203: /**
204:  * Check whether the MySQL extension is installed/loaded
205:  *
206:  * @return bool
207:  */
208:     public function enabled() {
209:         return in_array('mysql', PDO::getAvailableDrivers());
210:     }
211: 
212: /**
213:  * Returns an array of sources (tables) in the database.
214:  *
215:  * @param mixed $data List of tables.
216:  * @return array Array of table names in the database
217:  */
218:     public function listSources($data = null) {
219:         $cache = parent::listSources();
220:         if ($cache) {
221:             return $cache;
222:         }
223:         $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']));
224: 
225:         if (!$result) {
226:             $result->closeCursor();
227:             return array();
228:         }
229:         $tables = array();
230: 
231:         while ($line = $result->fetch(PDO::FETCH_NUM)) {
232:             $tables[] = $line[0];
233:         }
234: 
235:         $result->closeCursor();
236:         parent::listSources($tables);
237:         return $tables;
238:     }
239: 
240: /**
241:  * Builds a map of the columns contained in a result
242:  *
243:  * @param PDOStatement $results The results to format.
244:  * @return void
245:  */
246:     public function resultSet($results) {
247:         $this->map = array();
248:         $numFields = $results->columnCount();
249:         $index = 0;
250: 
251:         while ($numFields-- > 0) {
252:             $column = $results->getColumnMeta($index);
253:             if ($column['len'] === 1 && (empty($column['native_type']) || $column['native_type'] === 'TINY')) {
254:                 $type = 'boolean';
255:             } else {
256:                 $type = empty($column['native_type']) ? 'string' : $column['native_type'];
257:             }
258:             if (!empty($column['table']) && strpos($column['name'], $this->virtualFieldSeparator) === false) {
259:                 $this->map[$index++] = array($column['table'], $column['name'], $type);
260:             } else {
261:                 $this->map[$index++] = array(0, $column['name'], $type);
262:             }
263:         }
264:     }
265: 
266: /**
267:  * Fetches the next row from the current result set
268:  *
269:  * @return mixed array with results fetched and mapped to column names or false if there is no results left to fetch
270:  */
271:     public function fetchResult() {
272:         if ($row = $this->_result->fetch(PDO::FETCH_NUM)) {
273:             $resultRow = array();
274:             foreach ($this->map as $col => $meta) {
275:                 list($table, $column, $type) = $meta;
276:                 $resultRow[$table][$column] = $row[$col];
277:                 if ($type === 'boolean' && $row[$col] !== null) {
278:                     $resultRow[$table][$column] = $this->boolean($resultRow[$table][$column]);
279:                 }
280:             }
281:             return $resultRow;
282:         }
283:         $this->_result->closeCursor();
284:         return false;
285:     }
286: 
287: /**
288:  * Gets the database encoding
289:  *
290:  * @return string The database encoding
291:  */
292:     public function getEncoding() {
293:         return $this->_execute('SHOW VARIABLES LIKE ?', array('character_set_client'))->fetchObject()->Value;
294:     }
295: 
296: /**
297:  * Query charset by collation
298:  *
299:  * @param string $name Collation name
300:  * @return string Character set name
301:  */
302:     public function getCharsetName($name) {
303:         if ((bool)version_compare($this->getVersion(), "5", "<")) {
304:             return false;
305:         }
306:         if (isset($this->_charsets[$name])) {
307:             return $this->_charsets[$name];
308:         }
309:         $r = $this->_execute(
310:             'SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?',
311:             array($name)
312:         );
313:         $cols = $r->fetch(PDO::FETCH_ASSOC);
314: 
315:         if (isset($cols['CHARACTER_SET_NAME'])) {
316:             $this->_charsets[$name] = $cols['CHARACTER_SET_NAME'];
317:         } else {
318:             $this->_charsets[$name] = false;
319:         }
320:         return $this->_charsets[$name];
321:     }
322: 
323: /**
324:  * Returns an array of the fields in given table name.
325:  *
326:  * @param Model|string $model Name of database table to inspect or model instance
327:  * @return array Fields in table. Keys are name and type
328:  * @throws CakeException
329:  */
330:     public function describe($model) {
331:         $key = $this->fullTableName($model, false);
332:         $cache = parent::describe($key);
333:         if ($cache) {
334:             return $cache;
335:         }
336:         $table = $this->fullTableName($model);
337: 
338:         $fields = false;
339:         $cols = $this->_execute('SHOW FULL COLUMNS FROM ' . $table);
340:         if (!$cols) {
341:             throw new CakeException(__d('cake_dev', 'Could not describe table for %s', $table));
342:         }
343: 
344:         while ($column = $cols->fetch(PDO::FETCH_OBJ)) {
345:             $fields[$column->Field] = array(
346:                 'type' => $this->column($column->Type),
347:                 'null' => ($column->Null === 'YES' ? true : false),
348:                 'default' => $column->Default,
349:                 'length' => $this->length($column->Type)
350:             );
351:             if (in_array($fields[$column->Field]['type'], $this->fieldParameters['unsigned']['types'], true)) {
352:                 $fields[$column->Field]['unsigned'] = $this->_unsigned($column->Type);
353:             }
354:             if ($fields[$column->Field]['type'] === 'timestamp' && strtoupper($column->Default) === 'CURRENT_TIMESTAMP') {
355:                 $fields[$column->Field]['default'] = null;
356:             }
357:             if (!empty($column->Key) && isset($this->index[$column->Key])) {
358:                 $fields[$column->Field]['key'] = $this->index[$column->Key];
359:             }
360:             foreach ($this->fieldParameters as $name => $value) {
361:                 if (!empty($column->{$value['column']})) {
362:                     $fields[$column->Field][$name] = $column->{$value['column']};
363:                 }
364:             }
365:             if (isset($fields[$column->Field]['collate'])) {
366:                 $charset = $this->getCharsetName($fields[$column->Field]['collate']);
367:                 if ($charset) {
368:                     $fields[$column->Field]['charset'] = $charset;
369:                 }
370:             }
371:         }
372:         $this->_cacheDescription($key, $fields);
373:         $cols->closeCursor();
374:         return $fields;
375:     }
376: 
377: /**
378:  * Generates and executes an SQL UPDATE statement for given model, fields, and values.
379:  *
380:  * @param Model $model The model to update.
381:  * @param array $fields The fields to update.
382:  * @param array $values The values to set.
383:  * @param mixed $conditions The conditions to use.
384:  * @return array
385:  */
386:     public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
387:         if (!$this->_useAlias) {
388:             return parent::update($model, $fields, $values, $conditions);
389:         }
390: 
391:         if (!$values) {
392:             $combined = $fields;
393:         } else {
394:             $combined = array_combine($fields, $values);
395:         }
396: 
397:         $alias = $joins = false;
398:         $fields = $this->_prepareUpdateFields($model, $combined, empty($conditions), !empty($conditions));
399:         $fields = implode(', ', $fields);
400:         $table = $this->fullTableName($model);
401: 
402:         if (!empty($conditions)) {
403:             $alias = $this->name($model->alias);
404:             if ($model->name === $model->alias) {
405:                 $joins = implode(' ', $this->_getJoins($model));
406:             }
407:         }
408:         $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
409: 
410:         if ($conditions === false) {
411:             return false;
412:         }
413: 
414:         if (!$this->execute($this->renderStatement('update', compact('table', 'alias', 'joins', 'fields', 'conditions')))) {
415:             $model->onError();
416:             return false;
417:         }
418:         return true;
419:     }
420: 
421: /**
422:  * Generates and executes an SQL DELETE statement for given id/conditions on given model.
423:  *
424:  * @param Model $model The model to delete from.
425:  * @param mixed $conditions The conditions to use.
426:  * @return bool Success
427:  */
428:     public function delete(Model $model, $conditions = null) {
429:         if (!$this->_useAlias) {
430:             return parent::delete($model, $conditions);
431:         }
432:         $alias = $this->name($model->alias);
433:         $table = $this->fullTableName($model);
434:         $joins = implode(' ', $this->_getJoins($model));
435: 
436:         if (empty($conditions)) {
437:             $alias = $joins = false;
438:         }
439:         $complexConditions = false;
440:         foreach ((array)$conditions as $key => $value) {
441:             if (strpos($key, $model->alias) === false) {
442:                 $complexConditions = true;
443:                 break;
444:             }
445:         }
446:         if (!$complexConditions) {
447:             $joins = false;
448:         }
449: 
450:         $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
451:         if ($conditions === false) {
452:             return false;
453:         }
454:         if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) {
455:             $model->onError();
456:             return false;
457:         }
458:         return true;
459:     }
460: 
461: /**
462:  * Sets the database encoding
463:  *
464:  * @param string $enc Database encoding
465:  * @return bool
466:  */
467:     public function setEncoding($enc) {
468:         return $this->_execute('SET NAMES ' . $enc) !== false;
469:     }
470: 
471: /**
472:  * Returns an array of the indexes in given datasource name.
473:  *
474:  * @param string $model Name of model to inspect
475:  * @return array Fields in table. Keys are column and unique
476:  */
477:     public function index($model) {
478:         $index = array();
479:         $table = $this->fullTableName($model);
480:         $old = version_compare($this->getVersion(), '4.1', '<=');
481:         if ($table) {
482:             $indexes = $this->_execute('SHOW INDEX FROM ' . $table);
483:             // @codingStandardsIgnoreStart
484:             // MySQL columns don't match the cakephp conventions.
485:             while ($idx = $indexes->fetch(PDO::FETCH_OBJ)) {
486:                 if ($old) {
487:                     $idx = (object)current((array)$idx);
488:                 }
489:                 if (!isset($index[$idx->Key_name]['column'])) {
490:                     $col = array();
491:                     $index[$idx->Key_name]['column'] = $idx->Column_name;
492: 
493:                     if ($idx->Index_type === 'FULLTEXT') {
494:                         $index[$idx->Key_name]['type'] = strtolower($idx->Index_type);
495:                     } else {
496:                         $index[$idx->Key_name]['unique'] = (int)($idx->Non_unique == 0);
497:                     }
498:                 } else {
499:                     if (!empty($index[$idx->Key_name]['column']) && !is_array($index[$idx->Key_name]['column'])) {
500:                         $col[] = $index[$idx->Key_name]['column'];
501:                     }
502:                     $col[] = $idx->Column_name;
503:                     $index[$idx->Key_name]['column'] = $col;
504:                 }
505:                 if (!empty($idx->Sub_part)) {
506:                     if (!isset($index[$idx->Key_name]['length'])) {
507:                         $index[$idx->Key_name]['length'] = array();
508:                     }
509:                     $index[$idx->Key_name]['length'][$idx->Column_name] = $idx->Sub_part;
510:                 }
511:             }
512:             // @codingStandardsIgnoreEnd
513:             $indexes->closeCursor();
514:         }
515:         return $index;
516:     }
517: 
518: /**
519:  * Generate a MySQL Alter Table syntax for the given Schema comparison
520:  *
521:  * @param array $compare Result of a CakeSchema::compare()
522:  * @param string $table The table name.
523:  * @return array Array of alter statements to make.
524:  */
525:     public function alterSchema($compare, $table = null) {
526:         if (!is_array($compare)) {
527:             return false;
528:         }
529:         $out = '';
530:         $colList = array();
531:         foreach ($compare as $curTable => $types) {
532:             $indexes = $tableParameters = $colList = array();
533:             if (!$table || $table === $curTable) {
534:                 $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
535:                 foreach ($types as $type => $column) {
536:                     if (isset($column['indexes'])) {
537:                         $indexes[$type] = $column['indexes'];
538:                         unset($column['indexes']);
539:                     }
540:                     if (isset($column['tableParameters'])) {
541:                         $tableParameters[$type] = $column['tableParameters'];
542:                         unset($column['tableParameters']);
543:                     }
544:                     switch ($type) {
545:                         case 'add':
546:                             foreach ($column as $field => $col) {
547:                                 $col['name'] = $field;
548:                                 $alter = 'ADD ' . $this->buildColumn($col);
549:                                 if (isset($col['after'])) {
550:                                     $alter .= ' AFTER ' . $this->name($col['after']);
551:                                 }
552:                                 $colList[] = $alter;
553:                             }
554:                             break;
555:                         case 'drop':
556:                             foreach ($column as $field => $col) {
557:                                 $col['name'] = $field;
558:                                 $colList[] = 'DROP ' . $this->name($field);
559:                             }
560:                             break;
561:                         case 'change':
562:                             foreach ($column as $field => $col) {
563:                                 if (!isset($col['name'])) {
564:                                     $col['name'] = $field;
565:                                 }
566:                                 $colList[] = 'CHANGE ' . $this->name($field) . ' ' . $this->buildColumn($col);
567:                             }
568:                             break;
569:                     }
570:                 }
571:                 $colList = array_merge($colList, $this->_alterIndexes($curTable, $indexes));
572:                 $colList = array_merge($colList, $this->_alterTableParameters($curTable, $tableParameters));
573:                 $out .= "\t" . implode(",\n\t", $colList) . ";\n\n";
574:             }
575:         }
576:         return $out;
577:     }
578: 
579: /**
580:  * Generate a "drop table" statement for the given table
581:  *
582:  * @param type $table Name of the table to drop
583:  * @return string Drop table SQL statement
584:  */
585:     protected function _dropTable($table) {
586:         return 'DROP TABLE IF EXISTS ' . $this->fullTableName($table) . ";";
587:     }
588: 
589: /**
590:  * Generate MySQL table parameter alteration statements for a table.
591:  *
592:  * @param string $table Table to alter parameters for.
593:  * @param array $parameters Parameters to add & drop.
594:  * @return array Array of table property alteration statements.
595:  */
596:     protected function _alterTableParameters($table, $parameters) {
597:         if (isset($parameters['change'])) {
598:             return $this->buildTableParameters($parameters['change']);
599:         }
600:         return array();
601:     }
602: 
603: /**
604:  * Format indexes for create table
605:  *
606:  * @param array $indexes An array of indexes to generate SQL from
607:  * @param string $table Optional table name, not used
608:  * @return array An array of SQL statements for indexes
609:  * @see DboSource::buildIndex()
610:  */
611:     public function buildIndex($indexes, $table = null) {
612:         $join = array();
613:         foreach ($indexes as $name => $value) {
614:             $out = '';
615:             if ($name === 'PRIMARY') {
616:                 $out .= 'PRIMARY ';
617:                 $name = null;
618:             } else {
619:                 if (!empty($value['unique'])) {
620:                     $out .= 'UNIQUE ';
621:                 }
622:                 $name = $this->startQuote . $name . $this->endQuote;
623:             }
624:             if (isset($value['type']) && strtolower($value['type']) === 'fulltext') {
625:                 $out .= 'FULLTEXT ';
626:             }
627:             $out .= 'KEY ' . $name . ' (';
628: 
629:             if (is_array($value['column'])) {
630:                 if (isset($value['length'])) {
631:                     $vals = array();
632:                     foreach ($value['column'] as $column) {
633:                         $name = $this->name($column);
634:                         if (isset($value['length'])) {
635:                             $name .= $this->_buildIndexSubPart($value['length'], $column);
636:                         }
637:                         $vals[] = $name;
638:                     }
639:                     $out .= implode(', ', $vals);
640:                 } else {
641:                     $out .= implode(', ', array_map(array(&$this, 'name'), $value['column']));
642:                 }
643:             } else {
644:                 $out .= $this->name($value['column']);
645:                 if (isset($value['length'])) {
646:                     $out .= $this->_buildIndexSubPart($value['length'], $value['column']);
647:                 }
648:             }
649:             $out .= ')';
650:             $join[] = $out;
651:         }
652:         return $join;
653:     }
654: 
655: /**
656:  * Generate MySQL index alteration statements for a table.
657:  *
658:  * @param string $table Table to alter indexes for
659:  * @param array $indexes Indexes to add and drop
660:  * @return array Index alteration statements
661:  */
662:     protected function _alterIndexes($table, $indexes) {
663:         $alter = array();
664:         if (isset($indexes['drop'])) {
665:             foreach ($indexes['drop'] as $name => $value) {
666:                 $out = 'DROP ';
667:                 if ($name === 'PRIMARY') {
668:                     $out .= 'PRIMARY KEY';
669:                 } else {
670:                     $out .= 'KEY ' . $this->startQuote . $name . $this->endQuote;
671:                 }
672:                 $alter[] = $out;
673:             }
674:         }
675:         if (isset($indexes['add'])) {
676:             $add = $this->buildIndex($indexes['add']);
677:             foreach ($add as $index) {
678:                 $alter[] = 'ADD ' . $index;
679:             }
680:         }
681:         return $alter;
682:     }
683: 
684: /**
685:  * Format length for text indexes
686:  *
687:  * @param array $lengths An array of lengths for a single index
688:  * @param string $column The column for which to generate the index length
689:  * @return string Formatted length part of an index field
690:  */
691:     protected function _buildIndexSubPart($lengths, $column) {
692:         if ($lengths === null) {
693:             return '';
694:         }
695:         if (!isset($lengths[$column])) {
696:             return '';
697:         }
698:         return '(' . $lengths[$column] . ')';
699:     }
700: 
701: /**
702:  * Returns a detailed array of sources (tables) in the database.
703:  *
704:  * @param string $name Table name to get parameters
705:  * @return array Array of table names in the database
706:  */
707:     public function listDetailedSources($name = null) {
708:         $condition = '';
709:         if (is_string($name)) {
710:             $condition = ' WHERE name = ' . $this->value($name);
711:         }
712:         $result = $this->_connection->query('SHOW TABLE STATUS ' . $condition, PDO::FETCH_ASSOC);
713: 
714:         if (!$result) {
715:             $result->closeCursor();
716:             return array();
717:         }
718:         $tables = array();
719:         foreach ($result as $row) {
720:             $tables[$row['Name']] = (array)$row;
721:             unset($tables[$row['Name']]['queryString']);
722:             if (!empty($row['Collation'])) {
723:                 $charset = $this->getCharsetName($row['Collation']);
724:                 if ($charset) {
725:                     $tables[$row['Name']]['charset'] = $charset;
726:                 }
727:             }
728:         }
729:         $result->closeCursor();
730:         if (is_string($name) && isset($tables[$name])) {
731:             return $tables[$name];
732:         }
733:         return $tables;
734:     }
735: 
736: /**
737:  * Converts database-layer column types to basic types
738:  *
739:  * @param string $real Real database-layer column type (i.e. "varchar(255)")
740:  * @return string Abstract column type (i.e. "string")
741:  */
742:     public function column($real) {
743:         if (is_array($real)) {
744:             $col = $real['name'];
745:             if (isset($real['limit'])) {
746:                 $col .= '(' . $real['limit'] . ')';
747:             }
748:             return $col;
749:         }
750: 
751:         $col = str_replace(')', '', $real);
752:         $limit = $this->length($real);
753:         if (strpos($col, '(') !== false) {
754:             list($col, $vals) = explode('(', $col);
755:         }
756: 
757:         if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
758:             return $col;
759:         }
760:         if (($col === 'tinyint' && $limit === 1) || $col === 'boolean') {
761:             return 'boolean';
762:         }
763:         if (strpos($col, 'bigint') !== false || $col === 'bigint') {
764:             return 'biginteger';
765:         }
766:         if (strpos($col, 'int') !== false) {
767:             return 'integer';
768:         }
769:         if (strpos($col, 'char') !== false || $col === 'tinytext') {
770:             return 'string';
771:         }
772:         if (strpos($col, 'text') !== false) {
773:             return 'text';
774:         }
775:         if (strpos($col, 'blob') !== false || $col === 'binary') {
776:             return 'binary';
777:         }
778:         if (strpos($col, 'float') !== false || strpos($col, 'double') !== false) {
779:             return 'float';
780:         }
781:         if (strpos($col, 'decimal') !== false || strpos($col, 'numeric') !== false) {
782:             return 'decimal';
783:         }
784:         if (strpos($col, 'enum') !== false) {
785:             return "enum($vals)";
786:         }
787:         if (strpos($col, 'set') !== false) {
788:             return "set($vals)";
789:         }
790:         return 'text';
791:     }
792: 
793: /**
794:  * Gets the schema name
795:  *
796:  * @return string The schema name
797:  */
798:     public function getSchemaName() {
799:         return $this->config['database'];
800:     }
801: 
802: /**
803:  * Check if the server support nested transactions
804:  *
805:  * @return bool
806:  */
807:     public function nestedTransactionSupported() {
808:         return $this->useNestedTransactions && version_compare($this->getVersion(), '4.1', '>=');
809:     }
810: 
811: /**
812:  * Check if column type is unsigned
813:  *
814:  * @param string $real Real database-layer column type (i.e. "varchar(255)")
815:  * @return bool True if column is unsigned, false otherwise
816:  */
817:     protected function _unsigned($real) {
818:         return strpos(strtolower($real), 'unsigned') !== false;
819:     }
820: 
821: }
822: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs