File modules/cms/update/Update.class.php
Last commit: Wed Apr 17 00:34:07 2024 +0200 Jan Dankert New: Inputfields for coordinates; coordinates are stored in the now 64bit-number-field of the value.
1 <?php 2 3 namespace cms\update; 4 5 use cms\base\Startup; 6 use cms\base\Version; 7 use database\Database; 8 use Exception; 9 use logger\Logger; 10 11 12 class Update 13 { 14 // This is the required DB version: 15 const SUPPORTED_VERSION = 34; 16 // -----------------------^^----------------------------- 17 18 const STATUS_UPDATE_PROGRESS = 0; 19 const STATUS_UPDATE_SUCCESS = 1; 20 21 /** 22 * Detects if the database must be upgraded. 23 * 24 * @param Database $db 25 * @return bool true if database must be updated 26 */ 27 public function isUpdateRequired(Database $db) 28 { 29 $version = $this->getDbVersion($db); 30 31 Logger::debug("Need DB-Version: " . self::SUPPORTED_VERSION . "; Actual DB-Version: " . $version); 32 33 if ($version == self::SUPPORTED_VERSION) 34 // Cool, der aktuelle DB-Stand passt zu dieser Version. Das ist auch der Normalfall. Weiter so. 35 return false; 36 37 elseif ($version > self::SUPPORTED_VERSION) 38 // Oh oh, in der Datenbank ist eine neuere Version, als wir unterstützen. 39 throw new \LogicException('Actual DB version is not supported. ' . "DB-Version is $version, but " . Startup::TITLE . " " . Startup::VERSION . " only supports version " . self::SUPPORTED_VERSION); 40 41 else 42 return true; // Update required. 43 } 44 45 46 /** 47 * Update the database to a newer version. 48 * 49 * @param Database $db 50 */ 51 public function update(Database $db) 52 { 53 $version = $this->getDbVersion($db); 54 55 56 for ($installVersion = $version + 1; $installVersion <= self::SUPPORTED_VERSION; $installVersion++) { 57 if ($installVersion > 2) // Up to version 2 there was no table 'version'. 58 { 59 $sql = $db->sql('INSERT INTO {{version}} (id,version,status,installed) VALUES( {id},{version},{status},{time} )', $db->id); 60 $sql->setInt('id', $installVersion); 61 $sql->setInt('version', $installVersion); 62 $sql->setInt('status', self::STATUS_UPDATE_PROGRESS); 63 $sql->setInt('time', time()); 64 $sql->execute(); 65 } 66 67 $updaterClassName = __NAMESPACE__.'\version\DBVersion' . str_pad($installVersion, 6, '0', STR_PAD_LEFT); 68 69 /** @var \database\DbVersion $updater */ 70 $updater = new $updaterClassName($db); 71 72 $updater->update(); 73 74 if ($installVersion > 2) { 75 $sql = $db->sql('UPDATE {{version}} SET status={status},installed={time} WHERE version={version}', $db->id); 76 $sql->setInt('status', self::STATUS_UPDATE_SUCCESS); 77 $sql->setInt('version', $installVersion); 78 $sql->setInt('time', time()); 79 $sql->execute(); 80 } 81 } 82 } 83 84 85 /** 86 * Detects the actual version of the database scheme. 87 * 88 * @param Database $db 89 * @return int 90 */ 91 private function getDbVersion(Database $db) 92 { 93 $versionTableExists = $this->testQuery($db, 'SELECT 1 FROM {{version}}'); 94 95 if ($versionTableExists) { 96 // Prüfen, ob die vorherigen Updates fehlerfrei sind. 97 $sql = $db->sql(<<<SQL 98 SELECT COUNT(*) FROM {{version}} WHERE STATUS=0 99 SQL 100 , $db->id); 101 $countErrors = $sql->getOne(); 102 if ($countErrors > 0) 103 throw new \LogicException('Database error: There are dirty versions (means: versions with status 0), see table VERSION for details.'); 104 105 // Aktuelle Version ermitteln. 106 $sql = $db->sql(<<<SQL 107 SELECT MAX(version) FROM {{version}} 108 SQL 109 , $db->id); 110 $version = $sql->getOne(); 111 112 if (is_numeric($version)) 113 return $version; // Aktuelle Version.s 114 else 115 // Tabelle 'version' ist noch leer. 116 // Tabelle 'version' wurde in Version 2 angelegt. 117 return 2; 118 } else { 119 // no version table exists. 120 121 // find out if there is the project table... 122 $projectTableExists = $this->testQuery($db, 'SELECT 1 FROM {{project}}'); 123 124 if ($projectTableExists) 125 // seems to be the old baseline version without a version table. 126 return 1; 127 else 128 // there are no tables, everything must be created. 129 return 0; 130 } 131 } 132 133 134 /** 135 * Stellt fest, ob eine DB-Anfrage funktioniert. 136 * 137 * @param $db Database 138 * @param $sql 139 * @return <code>true</code> falls SQL funktioniert. 140 */ 141 private function testQuery($db, $sql) 142 { 143 try { 144 $sql = $db->sql($sql, $db->id); 145 $sql->execute(); 146 return true; // Bisher alles ok? Dann funktioniert die Query. 147 } catch (Exception $e) { 148 // Query funktioniert nicht. 149 return false; 150 } 151 } 152 } 153 154 ?>
Downloadmodules/cms/update/Update.class.php
History Wed, 17 Apr 2024 00:34:07 +0200 Jan Dankert New: Inputfields for coordinates; coordinates are stored in the now 64bit-number-field of the value. Sun, 1 Oct 2023 02:59:13 +0200 Jan Dankert New: Fixing the year 2038 problem with 8-byte-integers for the unix timestamps. Thu, 16 Feb 2023 01:04:38 +0100 Jan Dankert New: Tags for base objects. Sun, 4 Dec 2022 19:35:46 +0100 Jan Dankert Fix: For PHP8: DO NOT USE TRANSACTIONS here, because MariaDB/MySql are using an implicit commit after executing DDL. MySql > 8 will support autonomic transactions with DDL, but how do we detect this? Sun, 7 Nov 2021 23:45:50 +0100 Jan Dankert Fix: First successful migration to the new "content" table. Sat, 6 Nov 2021 01:35:17 +0100 Jan Dankert Cleanup Sat, 6 Nov 2021 00:01:59 +0100 Jan Dankert New: Status interface for health checks. Sun, 7 Mar 2021 00:10:20 +0100 Jan Dankert Refactoring: Hopefully more performance while accessing the database resultsets. Sat, 6 Mar 2021 21:45:42 +0100 Jan Dankert Refactoring: Storing all permission bits in a bitmask value Sat, 6 Mar 2021 02:09:25 +0100 Jan Dankert New: Allow permissions for guests only. Sat, 20 Feb 2021 01:34:41 +0100 Jan Dankert New: Publish-switch for templates. Mon, 4 Jan 2021 23:14:09 +0100 Jan Dankert New: Groups may contain subgroups. Users within a group inherit the permissions of all parent groups. Sat, 28 Nov 2020 00:53:41 +0100 Jan Dankert New: Lock password after a number of login fails. Sat, 31 Oct 2020 00:43:29 +0100 Jan Dankert New: Support for OpenId Connect; Removed: Support for LDAP. Sat, 26 Sep 2020 13:11:23 +0200 Jan Dankert Refactoring: No global variables any more. All constants are capsulated by classes. Sun, 23 Feb 2020 00:30:10 +0100 Jan Dankert Refactoring: Namespacing for module 'database-update', now called 'cms\update'.