-
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathDatabaseAnalyser.php
More file actions
116 lines (90 loc) · 3.13 KB
/
Copy pathDatabaseAnalyser.php
File metadata and controls
116 lines (90 loc) · 3.13 KB
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
<?php declare(strict_types = 1);
namespace Contributte\Nextras\Orm\Generator\Analyser\Database;
use Contributte\Nextras\Orm\Generator\Analyser\IAnalyser;
use Contributte\Nextras\Orm\Generator\Entity\Column;
use Contributte\Nextras\Orm\Generator\Entity\Database;
use Contributte\Nextras\Orm\Generator\Entity\ForeignKey;
use Contributte\Nextras\Orm\Generator\Entity\Table;
use Contributte\Nextras\Orm\Generator\Utils\ColumnTypes;
use Contributte\Nextras\Orm\Generator\Utils\Helpers;
use Nette\Database\Connection;
use Nette\Database\Driver;
use Nette\Utils\Strings;
class DatabaseAnalyser implements IAnalyser
{
private Connection $connection;
private Driver $driver;
public function __construct(string $dns, ?string $username = null, ?string $password = null)
{
$this->connection = new Connection($dns, $username, $password);
$this->driver = $this->connection->getDriver();
}
public function getConnection(): Connection
{
return $this->connection;
}
public function getDriver(): Driver
{
return $this->driver;
}
public function analyse(): Database
{
$database = new Database();
foreach ($this->driver->getTables() as $tArray) {
$table = new Table();
$table->setName($tArray['name']);
$this->analyseColumns($table);
$this->analyseIndexes($table);
$database->addTable($table);
}
return $database;
}
protected function analyseColumns(Table $table): void
{
$tableName = $table->getName();
// Analyse columns
$columns = $this->driver->getColumns($tableName);
foreach ($columns as $col) {
$column = new Column();
$column->setName($col['name']);
$column->setNullable($col['nullable']);
$column->setType(Helpers::columnType($col['nativetype']));
$column->setDefault(is_scalar($col['default']) ? (string) $col['default'] : null);
$column->setOnUpdate(str_contains($col['vendor']['extra'] ?? $col['vendor']['Extra'] ?? '', 'on update'));
// Analyse ENUM
if ($col['nativetype'] === ColumnTypes::NATIVE_TYPE_ENUM) {
/** @var array<int, array<int, string>> $enum */
$enum = Strings::matchAll($col['vendor']['type'] ?? $col['vendor']['Type'], ColumnTypes::NATIVE_REGEX_ENUM, PREG_PATTERN_ORDER);
if (isset($enum[1])) {
$column->setEnum($enum[1]);
$column->setType(ColumnTypes::TYPE_ENUM);
$column->setSubtype(Helpers::columnType($col['nativetype']));
}
}
$table->addColumn($column);
}
}
protected function analyseIndexes(Table $table): void
{
$tableName = $table->getName();
// Analyse indexes
$indexes = $this->driver->getIndexes($tableName);
$keys = $this->driver->getForeignKeys($tableName);
foreach ($indexes as $index) {
foreach ($index['columns'] as $col) {
$column = $table->getColumn($col);
$column->setPrimary($index['primary']);
$column->setUnique($index['unique']);
$column->setIndex(true);
}
}
foreach ($keys as $key) {
$column = $table->getColumn($key['local']);
$column->setForeignKey($foreign = new ForeignKey());
$foreign->setSourceTable($table->getName());
$foreign->setSourceColumn($key['local']);
$foreign->setReferenceTable($key['table']);
$foreign->setReferenceColumn($key['foreign']);
}
}
}