Преглед изворни кода

Auto-update 5038 (#6279)

* Auto-update 5038
https://github.com/FreshRSS/FreshRSS/pull/5038

* PostgreSQL

* Draft for MySQL

* More draft MySQL

* Finalise

* A bit more robust
Alexandre Alapetite пре 1 година
родитељ
комит
4f57a46075
4 измењених фајлова са 45 додато и 2 уклоњено
  1. 23 2
      app/Models/DatabaseDAO.php
  2. 4 0
      app/SQL/install.sql.mysql.php
  3. 3 0
      app/SQL/install.sql.pgsql.php
  4. 15 0
      lib/Minz/ModelPdo.php

+ 23 - 2
app/Models/DatabaseDAO.php

@@ -232,8 +232,29 @@ SQL;
 		$catDAO->resetDefaultCategoryName();
 		$catDAO->resetDefaultCategoryName();
 
 
 		include_once(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
 		include_once(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
-		if (!empty($GLOBALS['SQL_UPDATE_MINOR']) && $this->pdo->exec($GLOBALS['SQL_UPDATE_MINOR']) === false) {
-			Minz_Log::error('SQL error ' . __METHOD__ . json_encode($this->pdo->errorInfo()));
+		if (!empty($GLOBALS['SQL_UPDATE_MINOR'])) {
+			$sql = $GLOBALS['SQL_UPDATE_MINOR'];
+			$isMariaDB = false;
+
+			if ($this->pdo->dbType() === 'mysql') {
+				$dbVersion = $this->fetchValue('SELECT version()') ?? '';
+				$isMariaDB = stripos($dbVersion, 'MariaDB') !== false;	// MariaDB includes its name in version, but not MySQL
+				if (!$isMariaDB) {
+					// MySQL does not support `DROP INDEX IF EXISTS` yet https://dev.mysql.com/doc/refman/8.3/en/drop-index.html
+					// but MariaDB does https://mariadb.com/kb/en/drop-index/
+					$sql = str_replace('DROP INDEX IF EXISTS', 'DROP INDEX', $sql);
+				}
+			}
+
+			if ($this->pdo->exec($sql) === false) {
+				$info = $this->pdo->errorInfo();
+				if ($this->pdo->dbType() === 'mysql' &&
+					!$isMariaDB && !empty($info[2]) && (stripos($info[2], "Can't DROP ") !== false)) {
+					// Too bad for MySQL, but ignore error
+					return;
+				}
+				Minz_Log::error('SQL error ' . __METHOD__ . json_encode($this->pdo->errorInfo()));
+			}
 		}
 		}
 	}
 	}
 
 

+ 4 - 0
app/SQL/install.sql.mysql.php

@@ -115,6 +115,7 @@ SQL;
 
 
 $GLOBALS['SQL_UPDATE_MINOR'] = <<<'SQL'
 $GLOBALS['SQL_UPDATE_MINOR'] = <<<'SQL'
 ALTER TABLE `_feed`
 ALTER TABLE `_feed`
+	MODIFY COLUMN `website` TEXT CHARACTER SET latin1 COLLATE latin1_bin,
 	MODIFY COLUMN `lastUpdate` BIGINT DEFAULT 0,
 	MODIFY COLUMN `lastUpdate` BIGINT DEFAULT 0,
 	MODIFY COLUMN `pathEntries` VARCHAR(4096),
 	MODIFY COLUMN `pathEntries` VARCHAR(4096),
 	MODIFY COLUMN `httpAuth` VARCHAR(1024) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL;
 	MODIFY COLUMN `httpAuth` VARCHAR(1024) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL;
@@ -136,4 +137,7 @@ ALTER TABLE `_entrytmp`
 	MODIFY COLUMN `tags` VARCHAR(2048);
 	MODIFY COLUMN `tags` VARCHAR(2048);
 ALTER TABLE `_tag`
 ALTER TABLE `_tag`
 	MODIFY COLUMN `name` VARCHAR(191) NOT NULL;
 	MODIFY COLUMN `name` VARCHAR(191) NOT NULL;
+ALTER TABLE `_feed`
+	DROP INDEX IF EXISTS `url`, -- IF EXISTS works with MariaDB but not with MySQL, so needs PHP workaround
+	MODIFY COLUMN `url` VARCHAR(32768) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL;
 SQL;
 SQL;

+ 3 - 0
app/SQL/install.sql.pgsql.php

@@ -106,7 +106,10 @@ $GLOBALS['SQL_UPDATE_MINOR'] = <<<'SQL'
 ALTER TABLE `_category`
 ALTER TABLE `_category`
 	ALTER COLUMN "name" SET DATA TYPE VARCHAR(191);
 	ALTER COLUMN "name" SET DATA TYPE VARCHAR(191);
 ALTER TABLE `_feed`
 ALTER TABLE `_feed`
+	DROP CONSTRAINT IF EXISTS `_feed_url_key`,
+	ALTER COLUMN "url" SET DATA TYPE VARCHAR(32768),
 	ALTER COLUMN "name" SET DATA TYPE VARCHAR(191),
 	ALTER COLUMN "name" SET DATA TYPE VARCHAR(191),
+	ALTER COLUMN "website" SET DATA TYPE VARCHAR(32768),
 	ALTER COLUMN "lastUpdate" SET DATA TYPE BIGINT,
 	ALTER COLUMN "lastUpdate" SET DATA TYPE BIGINT,
 	ALTER COLUMN "pathEntries" SET DATA TYPE VARCHAR(4096),
 	ALTER COLUMN "pathEntries" SET DATA TYPE VARCHAR(4096),
 	ALTER COLUMN "httpAuth" SET DATA TYPE VARCHAR(1024);
 	ALTER COLUMN "httpAuth" SET DATA TYPE VARCHAR(1024);

+ 15 - 0
lib/Minz/ModelPdo.php

@@ -238,4 +238,19 @@ class Minz_ModelPdo {
 	public function fetchColumn(string $sql, int $column, array $values = []): ?array {
 	public function fetchColumn(string $sql, int $column, array $values = []): ?array {
 		return $this->fetchAny($sql, $values, PDO::FETCH_COLUMN, $column);
 		return $this->fetchAny($sql, $values, PDO::FETCH_COLUMN, $column);
 	}
 	}
+
+	/** For retrieving a single value without prepared statement such as `SELECT version()` */
+	public function fetchValue(string $sql): ?string {
+		$stm = $this->pdo->query($sql);
+		if ($stm === false) {
+			Minz_Log::error('SQL error ' . json_encode($this->pdo->errorInfo()) . ' during ' . $sql);
+			return null;
+		}
+		$columns = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+		if ($columns === false) {
+			Minz_Log::error('SQL error ' . json_encode($stm->errorInfo()) . ' during ' . $sql);
+			return null;
+		}
+		return isset($columns[0]) ? (string)$columns[0] : null;
+	}
 }
 }