| Current Path : /home/rtorresani/www/vendor/laminas/laminas-db/src/Metadata/Source/ |
| Current File : //home/rtorresani/www/vendor/laminas/laminas-db/src/Metadata/Source/PostgresqlMetadata.php |
<?php
namespace Laminas\Db\Metadata\Source;
use DateTime;
use Laminas\Db\Adapter\Adapter;
use function array_change_key_case;
use function array_walk;
use function implode;
use function is_array;
use function is_string;
use function key;
use const CASE_LOWER;
class PostgresqlMetadata extends AbstractSource
{
protected function loadSchemaData()
{
if (isset($this->data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$p = $this->adapter->getPlatform();
$sql = 'SELECT ' . $p->quoteIdentifier('schema_name')
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'schemata'])
. ' WHERE ' . $p->quoteIdentifier('schema_name')
. ' != \'information_schema\''
. ' AND ' . $p->quoteIdentifier('schema_name') . " NOT LIKE 'pg_%'";
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$schemas = [];
foreach ($results->toArray() as $row) {
$schemas[] = $row['schema_name'];
}
$this->data['schemas'] = $schemas;
}
/**
* @param string $schema
* @return void
*/
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['t', 'table_name'],
['t', 'table_type'],
['v', 'view_definition'],
['v', 'check_option'],
['v', 'is_updatable'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t'
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'views']) . ' v'
. ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['v', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['v', 'table_name'])
. ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_type'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema !== self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' != \'information_schema\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$tables = [];
foreach ($results->toArray() as $row) {
$tables[$row['table_name']] = [
'table_type' => $row['table_type'],
'view_definition' => $row['view_definition'],
'check_option' => $row['check_option'],
'is_updatable' => 'YES' === $row['is_updatable'],
];
}
$this->data['table_names'][$schema] = $tables;
}
/**
* @param string $table
* @param string $schema
* @return void
*/
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
$platform = $this->adapter->getPlatform();
$isColumns = [
'table_name',
'column_name',
'ordinal_position',
'column_default',
'is_nullable',
'data_type',
'character_maximum_length',
'character_octet_length',
'numeric_precision',
'numeric_scale',
];
array_walk($isColumns, function (&$c) use ($platform) {
$c = $platform->quoteIdentifier($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $platform->quoteIdentifier('information_schema')
. $platform->getIdentifierSeparator() . $platform->quoteIdentifier('columns')
. ' WHERE ' . $platform->quoteIdentifier('table_schema')
. ' != \'information\''
. ' AND ' . $platform->quoteIdentifier('table_name')
. ' = ' . $platform->quoteTrustedValue($table);
if ($schema !== '__DEFAULT_SCHEMA__') {
$sql .= ' AND ' . $platform->quoteIdentifier('table_schema')
. ' = ' . $platform->quoteTrustedValue($schema);
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$columns = [];
foreach ($results->toArray() as $row) {
$columns[$row['column_name']] = [
'ordinal_position' => $row['ordinal_position'],
'column_default' => $row['column_default'],
'is_nullable' => 'YES' === $row['is_nullable'],
'data_type' => $row['data_type'],
'character_maximum_length' => $row['character_maximum_length'],
'character_octet_length' => $row['character_octet_length'],
'numeric_precision' => $row['numeric_precision'],
'numeric_scale' => $row['numeric_scale'],
'numeric_unsigned' => null,
'erratas' => [],
];
}
$this->data['columns'][$schema][$table] = $columns;
}
/**
* @param string $table
* @param string $schema
* @return void
*/
protected function loadConstraintData($table, $schema)
{
// phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$isColumns = [
['t', 'table_name'],
['tc', 'constraint_name'],
['tc', 'constraint_type'],
['kcu', 'column_name'],
['cc', 'check_clause'],
['rc', 'match_option'],
['rc', 'update_rule'],
['rc', 'delete_rule'],
['referenced_table_schema' => 'kcu2', 'table_schema'],
['referenced_table_name' => 'kcu2', 'table_name'],
['referenced_column_name' => 'kcu2', 'column_name'],
];
$p = $this->adapter->getPlatform();
array_walk($isColumns, function (&$c) use ($p) {
$alias = key($c);
$c = $p->quoteIdentifierChain($c);
if (is_string($alias)) {
$c .= ' ' . $p->quoteIdentifier($alias);
}
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['information_schema', 'table_constraints']) . ' tc'
. ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['tc', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['tc', 'table_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'table_name'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'check_constraints']) . ' cc'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'referential_constraints']) . ' rc'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu2'
. ' ON ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_name'])
. ' AND ' . $p->quoteIdentifierChain(['kcu', 'position_in_unique_constraint'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'ordinal_position'])
. ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteTrustedValue($table)
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_type'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema !== self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' != \'information_schema\'';
}
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['tc', 'constraint_type'])
. " WHEN 'PRIMARY KEY' THEN 1"
. " WHEN 'UNIQUE' THEN 2"
. " WHEN 'FOREIGN KEY' THEN 3"
. " WHEN 'CHECK' THEN 4"
. " ELSE 5 END"
. ', ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ', ' . $p->quoteIdentifierChain(['kcu', 'ordinal_position']);
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$name = null;
$constraints = [];
foreach ($results->toArray() as $row) {
if ($row['constraint_name'] !== $name) {
$name = $row['constraint_name'];
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => $row['constraint_type'],
'table_name' => $row['table_name'],
];
if ('CHECK' === $row['constraint_type']) {
$constraints[$name]['check_clause'] = $row['check_clause'];
continue;
}
$constraints[$name]['columns'] = [];
$isFK = 'FOREIGN KEY' === $row['constraint_type'];
if ($isFK) {
$constraints[$name]['referenced_table_schema'] = $row['referenced_table_schema'];
$constraints[$name]['referenced_table_name'] = $row['referenced_table_name'];
$constraints[$name]['referenced_columns'] = [];
$constraints[$name]['match_option'] = $row['match_option'];
$constraints[$name]['update_rule'] = $row['update_rule'];
$constraints[$name]['delete_rule'] = $row['delete_rule'];
}
}
$constraints[$name]['columns'][] = $row['column_name'];
if ($isFK) {
$constraints[$name]['referenced_columns'][] = $row['referenced_column_name'];
}
}
$this->data['constraints'][$schema][$table] = $constraints;
// phpcs:enable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps
}
/**
* @param string $schema
* @return void
*/
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
'trigger_name',
'event_manipulation',
'event_object_catalog',
'event_object_schema',
'event_object_table',
'action_order',
'action_condition',
'action_statement',
'action_orientation',
['action_timing' => 'condition_timing'],
['action_reference_old_table' => 'condition_reference_old_table'],
['action_reference_new_table' => 'condition_reference_new_table'],
'created',
];
array_walk($isColumns, function (&$c) use ($p) {
if (is_array($c)) {
$alias = key($c);
$c = $p->quoteIdentifierChain($c);
if (is_string($alias)) {
$c .= ' ' . $p->quoteIdentifier($alias);
}
} else {
$c = $p->quoteIdentifier($c);
}
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'triggers'])
. ' WHERE ';
if ($schema !== self::DEFAULT_SCHEMA) {
$sql .= $p->quoteIdentifier('trigger_schema')
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= $p->quoteIdentifier('trigger_schema')
. ' != \'information_schema\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$row = array_change_key_case($row, CASE_LOWER);
$row['action_reference_old_row'] = 'OLD';
$row['action_reference_new_row'] = 'NEW';
if (null !== $row['created']) {
$row['created'] = new DateTime($row['created']);
}
$data[$row['trigger_name']] = $row;
}
$this->data['triggers'][$schema] = $data;
}
}