소스 검색

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();
 
 		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'
 ALTER TABLE `_feed`
+	MODIFY COLUMN `website` TEXT CHARACTER SET latin1 COLLATE latin1_bin,
 	MODIFY COLUMN `lastUpdate` BIGINT DEFAULT 0,
 	MODIFY COLUMN `pathEntries` VARCHAR(4096),
 	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);
 ALTER TABLE `_tag`
 	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;

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

@@ -106,7 +106,10 @@ $GLOBALS['SQL_UPDATE_MINOR'] = <<<'SQL'
 ALTER TABLE `_category`
 	ALTER COLUMN "name" SET DATA TYPE VARCHAR(191);
 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 "website" SET DATA TYPE VARCHAR(32768),
 	ALTER COLUMN "lastUpdate" SET DATA TYPE BIGINT,
 	ALTER COLUMN "pathEntries" SET DATA TYPE VARCHAR(4096),
 	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 {
 		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;
+	}
 }