Collection.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Database\Schema;
  16. use Cake\Database\Connection;
  17. use Cake\Database\Exception;
  18. use Cake\Database\Schema\Table;
  19. /**
  20. * Represents a database schema collection
  21. *
  22. * Used to access information about the tables,
  23. * and other data in a database.
  24. */
  25. class Collection {
  26. /**
  27. * Connection object
  28. *
  29. * @var \Cake\Database\Connection
  30. */
  31. protected $_connection;
  32. /**
  33. * Schema dialect instance.
  34. *
  35. * @var \Cake\Database\Schema\BaseSchema
  36. */
  37. protected $_dialect;
  38. /**
  39. * Constructor.
  40. *
  41. * @param \Cake\Database\Connection $connection The connection instance.
  42. */
  43. public function __construct(Connection $connection) {
  44. $this->_connection = $connection;
  45. $this->_dialect = $connection->driver()->schemaDialect();
  46. }
  47. /**
  48. * Get the list of tables available in the current connection.
  49. *
  50. * @return array The list of tables in the connected database/schema.
  51. */
  52. public function listTables() {
  53. list($sql, $params) = $this->_dialect->listTablesSql($this->_connection->config());
  54. $result = [];
  55. $statement = $this->_connection->execute($sql, $params);
  56. while ($row = $statement->fetch()) {
  57. $result[] = $row[0];
  58. }
  59. $statement->closeCursor();
  60. return $result;
  61. }
  62. /**
  63. * Get the column metadata for a table.
  64. *
  65. * Caching will be applied if `cacheMetadata` key is present in the Connection
  66. * configuration options. Defaults to _cake_model_ when true.
  67. *
  68. * ### Options
  69. *
  70. * - `forceRefresh` - Set to true to force rebuilding the cached metadata.
  71. * Defaults to false.
  72. *
  73. * @param string $name The name of the table to describe.
  74. * @param array $options The options to use, see above.
  75. * @return \Cake\Database\Schema\Table Object with column metadata.
  76. * @throws \Cake\Database\Exception when table cannot be described.
  77. */
  78. public function describe($name, array $options = []) {
  79. $config = $this->_connection->config();
  80. if (strpos($name, '.')) {
  81. list($config['schema'], $name) = explode('.', $name);
  82. }
  83. $table = new Table($name);
  84. $this->_reflect('Column', $name, $config, $table);
  85. if (count($table->columns()) === 0) {
  86. throw new Exception(sprintf('Cannot describe %s. It has 0 columns.', $name));
  87. }
  88. $this->_reflect('Index', $name, $config, $table);
  89. $this->_reflect('ForeignKey', $name, $config, $table);
  90. $this->_reflect('Options', $name, $config, $table);
  91. return $table;
  92. }
  93. /**
  94. * Helper method for running each step of the reflection process.
  95. *
  96. * @param string $stage The stage name.
  97. * @param string $name The table name.
  98. * @param array $config The config data.
  99. * @param \Cake\Database\Schema\Table $table The table instance
  100. * @return void
  101. * @throws \Cake\Database\Exception on query failure.
  102. */
  103. protected function _reflect($stage, $name, $config, $table) {
  104. $describeMethod = "describe{$stage}Sql";
  105. $convertMethod = "convert{$stage}Description";
  106. list($sql, $params) = $this->_dialect->{$describeMethod}($name, $config);
  107. if (empty($sql)) {
  108. return;
  109. }
  110. try {
  111. $statement = $this->_connection->execute($sql, $params);
  112. } catch (\PDOException $e) {
  113. throw new Exception($e->getMessage(), 500, $e);
  114. }
  115. foreach ($statement->fetchAll('assoc') as $row) {
  116. $this->_dialect->{$convertMethod}($table, $row);
  117. }
  118. $statement->closeCursor();
  119. }
  120. }