Ubiquity 2.5.2
php rapid development framework
Loading...
Searching...
No Matches
DatabaseReversor.php
Go to the documentation of this file.
1<?php
3
13
25
26 private $generator;
27
28 private $database;
29
30 private $models;
31
32 private $dbOffset;
33
34 public function __construct(DbGenerator $generator, $databaseOffset = 'default') {
35 $this->generator = $generator;
36 $this->database = $databaseOffset;
37 $this->dbOffset=$databaseOffset;
38 $config=Startup::$config;
39 $this->generator->setDatabaseWrapper($this->getWrapperInstance($config,$databaseOffset));
40 }
41
42 protected function getWrapperInstance(&$config,$databaseOffset='default'){
43 $dbOffsetConfig=DAO::getDbOffset($config,$databaseOffset);
44 if(isset($dbOffsetConfig['wrapper'])){
45 $wrapperClass=$dbOffsetConfig['wrapper'];
46 if(\class_exists($wrapperClass)){
47 return new $wrapperClass($dbOffsetConfig['type']??null);
48 }
49 throw new DBException("Wrapper class $wrapperClass does not exist!");
50 }
51 throw new DBException("Wrapper class is not set for database at offset $databaseOffset!");
52 }
53
54 public function createDatabase(string $name, bool $createDb = true): void {
55 $this->generator->setMigrationMode(true);
56 if ($createDb) {
57 $this->generator->createDatabase($name);
58 $this->generator->selectDatabase($name);
59 }
60 $config = Startup::getConfig();
61 $models = $this->models ?? CacheManager::getModels($config, true, $this->database);
62 foreach ($models as $model) {
63 $tableReversor = new TableReversor($model);
64 $tableReversor->initFromClass();
65 if ($this->generator->hasToCreateTable($tableReversor->getTable())) {
66 $tableReversor->generateSQL($this->generator);
67 } else {
68 $tableReversor->scanManyToManys($this->generator);
69 }
70 }
71 $this->generator->generateManyToManys();
72 }
73
74 public function generateTablesForModels(?array $models=null,bool $execute=false): bool {
75 if (isset($models)) {
76 $this->setModels($models);
77 }
78 $this->createDatabase('', false);
79 if ($execute) {
80 $script=\implode(';', $this->getScript());
81 return SqlCommand::executeSQLTransaction($this->dbOffset,$script);
82 }
83 return true;
84 }
85
86 private function getDbName(): ?string {
87 $config = Startup::$config;
88 $dbOffset = DAO::getDbOffset($config, $this->database);
89 if (isset($dbOffset['dbName'])) {
90 return $dbOffset['dbName'];
91 }
92 throw new UbiquityException('dbName field is required in database config!');
93 }
94
95 public function migrate(): void {
96 $this->generator->setMigrationMode(true);
97 $checker = new DatabaseChecker($this->database);
98 $dbName=$this->getDbName();
99 if (! $checker->checkDatabase()) {
100 $this->createDatabase($dbName);
101 return;
102 }
103 $tablesToCreate = $checker->getNonExistingTables();
104 if (\count($tablesToCreate)>0) {
105 $this->generator->setTablesToCreate($tablesToCreate);
106 $this->createDatabase($dbName, false);
107 }
108 //TODO check each part
109 $config = Startup::getConfig();
110 $models = $this->models ?? CacheManager::getModels($config, true, $this->database);
111 $newMissingPks=[];
112
113 foreach ($models as $model){
114 $tablereversor=new TableReversor($model);
115 $tablereversor->initFromClass();
116
117 $uFields=$checker->getUpdatedFields($model);
118 $missingFields=$uFields['missing'][$model]??[];
119 foreach ($missingFields as $missingField){
120 $this->generator->addField($missingField['table'],$missingField['name'],$missingField['attributes']);
121 }
122 $updatedFields=$uFields['updated'][$model]??[];
123 foreach ($updatedFields as $updatedField){
124 $this->generator->modifyField($updatedField['table'],$updatedField['name'],$updatedField['attributes']);
125 }
126 $missingPks=$checker->checkPrimaryKeys($model);
127 if (\count($missingPks)>0) {
128 $pks=$missingPks['primaryKeys'];
129 $tablereversor->addPrimaryKeys($this->generator,$pks);
130 }
131 $missingFks=$checker->checkManyToOne($model);
132 if (\count($missingFks)>0){
133 foreach ($missingFks as $fk){
134 $this->generator->addForeignKey($fk['table'], $fk['column'], $fk['fkTable'], $fk['fkId']);
135 }
136 }
137
138 $missingFks=$checker->checkManyToMany($model);
139 if (\count($missingFks)>0){
140 foreach ($missingFks as $fk){
141 if (!$this->generator->hasToCreateTable($fk['table'])) {
142 $this->checkManyToManyFields($checker, $fk['table'], $fk['column'],$newMissingPks);
143 $this->generator->addForeignKey($fk['table'], $fk['column'], $fk['fkTable'], $fk['fkId']);
144 }
145 }
146 }
147 }
148 foreach ($newMissingPks as $table=>$pks){
149 $this->generator->addKey($table,$pks);
150 }
151 }
152
153 private function checkManyToManyFields(DatabaseChecker $checker,string $table,string $field,&$newMissingPks): void {
154 $originalFieldInfos = $checker->getDb()->getFieldsInfos($table);
155 $pks=$checker->getDb()->getPrimaryKeys($table);
156 if (!isset($originalFieldInfos[$field])) {
157 $this->generator->addField($table, $field, ['type' => 'int']);
158 }
159 if(\array_search($field,$pks)===false){
160 $newMissingPks[$table][]=$field;
161 }
162 }
163
164 public function __toString() {
165 return $this->generator->__toString();
166 }
167
168 public function getScript(){
169 return $this->generator->getScript();
170 }
171
172 public function setModels($models) {
173 $this->models = $models;
174 }
175}
Manager for caches (Router, Rest, models).
Starts the framework.
Definition Startup.php:19
Ubiquity Generic database class.
Definition Database.php:25
static executeSQLTransaction(string $activeDbOffset, string $sql)
Definition SqlCommand.php:9
Manage Databases types.
Definition DbTypes.php:14
Gateway class between database and object model.
Definition DAO.php:33
static getDbOffset(&$config, $offset=null)
Definition DAO.php:252
getWrapperInstance(&$config, $databaseOffset='default')
checkManyToManyFields(DatabaseChecker $checker, string $table, string $field, &$newMissingPks)
createDatabase(string $name, bool $createDb=true)
__construct(DbGenerator $generator, $databaseOffset='default')
generateTablesForModels(?array $models=null, bool $execute=false)