Collection.php 4.2 KB

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