Skip to content

Commit

Permalink
added entites for Table, Column, Index, ForeignKey (BC break)
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Jan 2, 2023
1 parent 2e236a3 commit 861a0f6
Show file tree
Hide file tree
Showing 19 changed files with 389 additions and 271 deletions.
8 changes: 4 additions & 4 deletions src/Database/Driver.php
Expand Up @@ -75,25 +75,25 @@ function applyLimit(string &$sql, ?int $limit, ?int $offset): void;
/********************* reflection ****************d*g**/

/**
* Returns list of tables as tuples [(string) name, (bool) view, [(string) fullName]]
* @return Reflection\Table[]
*/
function getTables(): array;

/**
* Returns metadata for all columns in a table.
* As tuples [(string) name, (string) table, (string) nativetype, (int) size, (bool) nullable, (mixed) default, (bool) autoincrement, (bool) primary, (array) vendor]]
* @return Reflection\Column[]
*/
function getColumns(string $table): array;

/**
* Returns metadata for all indexes in a table.
* As tuples [(string) name, (string[]) columns, (bool) unique, (bool) primary]
* @return Reflection\Index[]
*/
function getIndexes(string $table): array;

/**
* Returns metadata for all foreign keys in a table.
* As tuples [(string) name, (string) local, (string) table, (string) foreign]
* @return Reflection\ForeignKey[]
*/
function getForeignKeys(string $table): array;

Expand Down
46 changes: 20 additions & 26 deletions src/Database/Drivers/MsSqlDriver.php
Expand Up @@ -65,15 +65,10 @@ public function applyLimit(string &$sql, ?int $limit, ?int $offset): void

public function getTables(): array
{
$tables = [];
foreach ($this->pdo->query('SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES') as $row) {
$tables[] = [
'name' => $row['TABLE_SCHEMA'] . '.' . $row['TABLE_NAME'],
'view' => ($row['TABLE_TYPE'] ?? null) === 'VIEW',
];
}

return $tables;
return $this->pdo->query('SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES')->fetchAll(
\PDO::FETCH_FUNC,
fn($schema, $name, $type) => new Nette\Database\Reflection\Table($schema . '.' . $name, $type === 'VIEW'),
);
}


Expand All @@ -99,18 +94,17 @@ public function getColumns(string $table): array
X;

foreach ($this->pdo->query($query, \PDO::FETCH_ASSOC) as $row) {
$columns[] = [
'name' => $row['COLUMN_NAME'],
'table' => $table,
'nativetype' => $row['DATA_TYPE'],
'size' => $row['CHARACTER_MAXIMUM_LENGTH'] ?? ($row['NUMERIC_PRECISION'] ?? null),
'unsigned' => false,
'nullable' => $row['IS_NULLABLE'] === 'YES',
'default' => $row['COLUMN_DEFAULT'],
'autoincrement' => $row['DOMAIN_NAME'] === 'COUNTER',
'primary' => $row['COLUMN_NAME'] === 'ID',
'vendor' => $row,
];
$columns[] = new Nette\Database\Reflection\Column(
name: $row['COLUMN_NAME'],
table: $table,
nativeType: $row['DATA_TYPE'],
size: $row['CHARACTER_MAXIMUM_LENGTH'] ?? $row['NUMERIC_PRECISION'] ?? null,
nullable: $row['IS_NULLABLE'] === 'YES',
default: $row['COLUMN_DEFAULT'],
autoIncrement: $row['DOMAIN_NAME'] === 'COUNTER',
primary: $row['COLUMN_NAME'] === 'ID',
vendor: $row,
);
}

return $columns;
Expand Down Expand Up @@ -148,7 +142,7 @@ public function getIndexes(string $table): array
$indexes[$id]['columns'][$row['id_column'] - 1] = $row['name_column'];
}

return array_values($indexes);
return array_map(fn($data) => new Nette\Database\Reflection\Index(...$data), array_values($indexes));
}


Expand Down Expand Up @@ -184,12 +178,12 @@ public function getForeignKeys(string $table): array
foreach ($this->pdo->query($query) as $row) {
$id = $row['fk_name'];
$keys[$id]['name'] = $id;
$keys[$id]['local'][] = $row['column'];
$keys[$id]['table'] = $table_schema . '.' . $row['referenced_table'];
$keys[$id]['foreign'][] = $row['referenced_column'];
$keys[$id]['columns'][] = $row['column'];
$keys[$id]['targetTable'] = $table_schema . '.' . $row['referenced_table'];
$keys[$id]['targetColumns'][] = $row['referenced_column'];
}

return array_values($keys);
return array_map(fn($data) => new Nette\Database\Reflection\ForeignKey(...$data), array_values($keys));
}


Expand Down
45 changes: 20 additions & 25 deletions src/Database/Drivers/MySqlDriver.php
Expand Up @@ -112,15 +112,10 @@ public function applyLimit(string &$sql, ?int $limit, ?int $offset): void

public function getTables(): array
{
$tables = [];
foreach ($this->pdo->query('SHOW FULL TABLES') as $row) {
$tables[] = [
'name' => $row[0],
'view' => ($row[1] ?? null) === 'VIEW',
];
}

return $tables;
return $this->pdo->query('SHOW FULL TABLES')->fetchAll(
\PDO::FETCH_FUNC,
fn($name, $type) => new Nette\Database\Reflection\Table($name, $type === 'VIEW'),
);
}


Expand All @@ -129,17 +124,17 @@ public function getColumns(string $table): array
$columns = [];
foreach ($this->pdo->query('SHOW FULL COLUMNS FROM ' . $this->delimite($table), \PDO::FETCH_ASSOC) as $row) {
$type = explode('(', $row['Type']);
$columns[] = [
'name' => $row['Field'],
'table' => $table,
'nativetype' => $type[0],
'size' => isset($type[1]) ? (int) $type[1] : null,
'nullable' => $row['Null'] === 'YES',
'default' => $row['Default'],
'autoincrement' => $row['Extra'] === 'auto_increment',
'primary' => $row['Key'] === 'PRI',
'vendor' => $row,
];
$columns[] = new Nette\Database\Reflection\Column(
name: $row['Field'],
table: $table,
nativeType: $type[0],
size: isset($type[1]) ? (int) $type[1] : null,
nullable: $row['Null'] === 'YES',
default: $row['Default'],
autoIncrement: $row['Extra'] === 'auto_increment',
primary: $row['Key'] === 'PRI',
vendor: $row,
);
}

return $columns;
Expand All @@ -157,7 +152,7 @@ public function getIndexes(string $table): array
$indexes[$id]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name'];
}

return array_values($indexes);
return array_map(fn($data) => new Nette\Database\Reflection\Index(...$data), array_values($indexes));
}


Expand All @@ -173,12 +168,12 @@ public function getForeignKeys(string $table): array
X) as $row) {
$id = $row['CONSTRAINT_NAME'];
$keys[$id]['name'] = $id;
$keys[$id]['local'][] = $row['COLUMN_NAME'];
$keys[$id]['table'] = $row['REFERENCED_TABLE_NAME'];
$keys[$id]['foreign'][] = $row['REFERENCED_COLUMN_NAME'];
$keys[$id]['columns'][] = $row['COLUMN_NAME'];
$keys[$id]['targetTable'] = $row['REFERENCED_TABLE_NAME'];
$keys[$id]['targetColumns'][] = $row['REFERENCED_COLUMN_NAME'];
}

return array_values($keys);
return array_map(fn($data) => new Nette\Database\Reflection\ForeignKey(...$data), array_values($keys));
}


Expand Down
35 changes: 19 additions & 16 deletions src/Database/Drivers/PgSqlDriver.php
Expand Up @@ -95,9 +95,9 @@ public function getTables(): array
{
return $this->pdo->query(<<<'X'
SELECT DISTINCT ON (c.relname)
c.relname::varchar AS name,
c.relkind IN ('v', 'm') AS view,
n.nspname::varchar || '.' || c.relname::varchar AS "fullName"
c.relname::varchar,
c.relkind IN ('v', 'm'),
n.nspname::varchar || '.' || c.relname::varchar
FROM
pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
Expand All @@ -106,7 +106,10 @@ public function getTables(): array
AND n.nspname = ANY (pg_catalog.current_schemas(FALSE))
ORDER BY
c.relname
X)->fetchAll(\PDO::FETCH_ASSOC);
X)->fetchAll(
\PDO::FETCH_FUNC,
fn($name, $view, $full) => new Nette\Database\Reflection\Table($name, $view, $full),
);
}


Expand All @@ -117,11 +120,11 @@ public function getColumns(string $table): array
SELECT
a.attname::varchar AS name,
c.relname::varchar AS table,
t.typname AS nativetype,
t.typname AS "nativeType",
CASE WHEN a.atttypmod = -1 THEN NULL ELSE a.atttypmod -4 END AS size,
NOT (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS nullable,
pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass)::varchar AS default,
coalesce(co.contype = 'p' AND (seq.relname IS NOT NULL OR strpos(pg_catalog.pg_get_expr(ad.adbin, ad.adrelid), 'nextval') = 1), FALSE) AS autoincrement,
coalesce(co.contype = 'p' AND (seq.relname IS NOT NULL OR strpos(pg_catalog.pg_get_expr(ad.adbin, ad.adrelid), 'nextval') = 1), FALSE) AS "autoIncrement",
coalesce(co.contype = 'p', FALSE) AS primary,
coalesce(seq.relname, substring(pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass) from 'nextval[(]''"?([^''"]+)')) AS sequence
FROM
Expand All @@ -139,11 +142,11 @@ public function getColumns(string $table): array
AND NOT a.attisdropped
ORDER BY
a.attnum
X, \PDO::FETCH_ASSOC) as $column) {
$column['vendor'] = $column;
unset($column['sequence']);

$columns[] = $column;
X, \PDO::FETCH_ASSOC) as $row
) {
$row['vendor'] = $row;
unset($row['sequence']);
$columns[] = new Nette\Database\Reflection\Column(...$row);
}

return $columns;
Expand Down Expand Up @@ -175,7 +178,7 @@ public function getIndexes(string $table): array
$indexes[$id]['columns'][] = $row['column'];
}

return array_values($indexes);
return array_map(fn($data) => new Nette\Database\Reflection\Index(...$data), array_values($indexes));
}


Expand Down Expand Up @@ -203,12 +206,12 @@ public function getForeignKeys(string $table): array
X) as $row) {
$id = $row['name'];
$keys[$id]['name'] = $id;
$keys[$id]['local'][] = $row['local'];
$keys[$id]['table'] = $row['table'];
$keys[$id]['foreign'][] = $row['foreign'];
$keys[$id]['columns'][] = $row['local'];
$keys[$id]['targetTable'] = $row['table'];
$keys[$id]['targetColumns'][] = $row['foreign'];
}

return array_values($keys);
return array_map(fn($data) => new Nette\Database\Reflection\ForeignKey(...$data), array_values($keys));
}


Expand Down
59 changes: 27 additions & 32 deletions src/Database/Drivers/SqliteDriver.php
Expand Up @@ -105,24 +105,19 @@ public function applyLimit(string &$sql, ?int $limit, ?int $offset): void

public function getTables(): array
{
$tables = [];
foreach ($this->pdo->query(<<<'X'
SELECT name, type = 'view' as view
return $this->pdo->query(<<<'X'
SELECT name, type = 'view'
FROM sqlite_master
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
UNION ALL
SELECT name, type = 'view' as view
FROM sqlite_temp_master
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
ORDER BY name
X) as $row) {
$tables[] = [
'name' => $row['name'],
'view' => (bool) $row['view'],
];
}

return $tables;
X)->fetchAll(
\PDO::FETCH_FUNC,
fn($name, $view) => new Nette\Database\Reflection\Table($name, (bool) $view),
);
}


Expand All @@ -143,17 +138,17 @@ public function getColumns(string $table): array
$column = $row['name'];
$pattern = "/(\"$column\"|`$column`|\\[$column\\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";
$type = explode('(', $row['type']);
$columns[] = [
'name' => $column,
'table' => $table,
'nativetype' => strtoupper($type[0]),
'size' => isset($type[1]) ? (int) $type[1] : null,
'nullable' => !$row['notnull'],
'default' => $row['dflt_value'],
'autoincrement' => $meta && preg_match($pattern, (string) $meta['sql']),
'primary' => $row['pk'] > 0,
'vendor' => $row,
];
$columns[] = new Nette\Database\Reflection\Column(
name: $column,
table: $table,
nativeType: $type[0],
size: isset($type[1]) ? (int) $type[1] : null,
nullable: !$row['notnull'],
default: $row['dflt_value'],
autoIncrement: $meta && preg_match($pattern, (string) $meta['sql']),
primary: $row['pk'] > 0,
vendor: $row,
);
}

return $columns;
Expand All @@ -180,8 +175,8 @@ public function getIndexes(string $table): array
foreach ($indexes as $index => $values) {
$column = $indexes[$index]['columns'][0];
foreach ($columns as $info) {
if ($column === $info['name']) {
$indexes[$index]['primary'] = (bool) $info['primary'];
if ($column === $info->name) {
$indexes[$index]['primary'] = $info->primary;
break;
}
}
Expand All @@ -201,7 +196,7 @@ public function getIndexes(string $table): array
}
}

return array_values($indexes);
return array_map(fn($data) => new Nette\Database\Reflection\Index(...$data), array_values($indexes));
}


Expand All @@ -210,16 +205,16 @@ public function getForeignKeys(string $table): array
$keys = [];
foreach ($this->pdo->query("PRAGMA foreign_key_list({$this->delimite($table)})") as $row) {
$id = $row['id'];
$keys[$id]['name'] = $id;
$keys[$id]['local'][] = $row['from'];
$keys[$id]['table'] = $row['table'];
$keys[$id]['foreign'][] = $row['to'];
if ($keys[$id]['foreign'][0] == null) {
$keys[$id]['foreign'] = [];
$keys[$id]['name'] = (string) $id;
$keys[$id]['columns'][] = $row['from'];
$keys[$id]['targetTable'] = $row['table'];
$keys[$id]['targetColumns'][] = $row['to'];
if ($keys[$id]['targetColumns'][0] == null) {
$keys[$id]['targetColumns'] = [];
}
}

return array_values($keys);
return array_map(fn($data) => new Nette\Database\Reflection\ForeignKey(...$data), array_values($keys));
}


Expand Down

0 comments on commit 861a0f6

Please sign in to comment.