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