Просмотр исходного кода

Ready for year 2038 (#5570)

* Ready for year 2038
Fix https://github.com/FreshRSS/FreshRSS/discussions/5569
Requires PHP on a 64-bit platform to take advantage of it.
https://en.wikipedia.org/wiki/Year_2038_problem

* Allows dates past 2038
Rework of https://github.com/FreshRSS/FreshRSS/pull/3259
https://github.com/FreshRSS/FreshRSS/issues/3258

* Auto alter columns

* Changelog
Alexandre Alapetite 2 лет назад
Родитель
Сommit
21a279179a

+ 2 - 1
CHANGELOG.md

@@ -5,7 +5,8 @@
 * Compatibility
 	* Require PHP 7.4+, and implement *typed properties* [#5720](https://github.com/FreshRSS/FreshRSS/pull/5720)
 * Features
-	* Increase SQL (`VARCHAR`) text fields to maximum possible [#5756](https://github.com/FreshRSS/FreshRSS/pull/5756)
+	* Increase SQL (`VARCHAR`) text fields length to maximum possible [#5756](https://github.com/FreshRSS/FreshRSS/pull/5756)
+	* Increase SQL date fields to 64-bit to be ready for year 2038+ [#5570](https://github.com/FreshRSS/FreshRSS/pull/5570)
 * Misc.
 	* Code improvements [#5511](https://github.com/FreshRSS/FreshRSS/pull/5511)
 

+ 14 - 1
app/Models/DatabaseDAO.php

@@ -20,7 +20,7 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
 	public const LENGTH_INDEX_UNICODE = 191;
 
 	public function create(): string {
-		require(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
+		require_once(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
 		$db = FreshRSS_Context::$system_conf->db;
 
 		try {
@@ -214,9 +214,22 @@ SQL;
 		return $ok;
 	}
 
+	private function ensureYear2038Compatible(): bool {
+		if ($this->pdo->dbType() !== 'sqlite') {
+			include_once(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
+			if ($this->pdo->exec($GLOBALS['SQL_UPDATE_YEAR_2038']) === false) {	//FreshRSS 1.23
+				Minz_Log::error('SQL error ' . __METHOD__ . json_encode($this->pdo->errorInfo()));
+				return false;
+			}
+		}
+		return true;
+	}
+
 	public function minorDbMaintenance(): void {
 		$catDAO = FreshRSS_Factory::createCategoryDao();
 		$catDAO->resetDefaultCategoryName();
+
+		$this->ensureYear2038Compatible();
 	}
 
 	private static function stdError(string $error): bool {

+ 0 - 2
app/Models/EntryDAO.php

@@ -123,7 +123,6 @@ SQL;
 			$valuesTmp['link'] = substr($valuesTmp['link'], 0, 32768);
 			$valuesTmp['link'] = safe_ascii($valuesTmp['link']);
 			$this->addEntryPrepared->bindParam(':link', $valuesTmp['link']);
-			$valuesTmp['date'] = min($valuesTmp['date'], 2147483647);
 			$this->addEntryPrepared->bindParam(':date', $valuesTmp['date'], PDO::PARAM_INT);
 			if (empty($valuesTmp['lastSeen'])) {
 				$valuesTmp['lastSeen'] = time();
@@ -229,7 +228,6 @@ SQL;
 			$valuesTmp['link'] = substr($valuesTmp['link'], 0, 32768);
 			$valuesTmp['link'] = safe_ascii($valuesTmp['link']);
 			$this->updateEntryPrepared->bindParam(':link', $valuesTmp['link']);
-			$valuesTmp['date'] = min($valuesTmp['date'], 2147483647);
 			$this->updateEntryPrepared->bindParam(':date', $valuesTmp['date'], PDO::PARAM_INT);
 			$this->updateEntryPrepared->bindParam(':last_seen', $valuesTmp['lastSeen'], PDO::PARAM_INT);
 			if ($valuesTmp['is_read'] === null) {

+ 16 - 5
app/SQL/install.sql.mysql.php

@@ -24,7 +24,7 @@ CREATE TABLE IF NOT EXISTS `_feed` (
 	`name` VARCHAR(191) NOT NULL,
 	`website` TEXT CHARACTER SET latin1 COLLATE latin1_bin,
 	`description` TEXT,
-	`lastUpdate` INT(11) DEFAULT 0,	-- Until year 2038
+	`lastUpdate` BIGINT DEFAULT 0,
 	`priority` TINYINT(2) NOT NULL DEFAULT 10,
 	`pathEntries` VARCHAR(65535) DEFAULT NULL,
 	`httpAuth` VARCHAR(1024) DEFAULT NULL,
@@ -47,8 +47,8 @@ CREATE TABLE IF NOT EXISTS `_entry` (
 	`author` VARCHAR(65535),
 	`content_bin` MEDIUMBLOB,	-- v0.7
 	`link` VARCHAR(32768) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
-	`date` INT(11),	-- Until year 2038
-	`lastSeen` INT(11) DEFAULT 0,	-- v1.1.1, Until year 2038
+	`date` BIGINT,
+	`lastSeen` BIGINT DEFAULT 0,
 	`hash` BINARY(16),	-- v1.1.1
 	`is_read` BOOLEAN NOT NULL DEFAULT 0,
 	`is_favorite` BOOLEAN NOT NULL DEFAULT 0,
@@ -74,8 +74,8 @@ CREATE TABLE IF NOT EXISTS `_entrytmp` (	-- v1.7
 	`author` VARCHAR(65535),
 	`content_bin` MEDIUMBLOB,
 	`link` VARCHAR(32768) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
-	`date` INT(11),
-	`lastSeen` INT(11) DEFAULT 0,
+	`date` BIGINT,
+	`lastSeen` BIGINT DEFAULT 0,
 	`hash` BINARY(16),
 	`is_read` BOOLEAN NOT NULL DEFAULT 0,
 	`is_favorite` BOOLEAN NOT NULL DEFAULT 0,
@@ -112,3 +112,14 @@ SQL;
 $GLOBALS['SQL_DROP_TABLES'] = <<<'SQL'
 DROP TABLE IF EXISTS `_entrytag`, `_tag`, `_entrytmp`, `_entry`, `_feed`, `_category`;
 SQL;
+
+$GLOBALS['SQL_UPDATE_YEAR_2038'] = <<<'SQL'
+ALTER TABLE `_entry`	-- v1.23
+	MODIFY COLUMN `date` BIGINT,
+	MODIFY COLUMN `lastSeen` BIGINT DEFAULT 0;
+ALTER TABLE `_entrytmp`
+	MODIFY COLUMN `date` BIGINT,
+	MODIFY COLUMN `lastSeen` BIGINT DEFAULT 0;
+ALTER TABLE `_feed`
+	MODIFY COLUMN `lastUpdate` BIGINT DEFAULT 0;
+SQL;

+ 16 - 5
app/SQL/install.sql.pgsql.php

@@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `_feed` (
 	"name" VARCHAR(191) NOT NULL,
 	"website" VARCHAR(32768),
 	"description" TEXT,
-	"lastUpdate" INT DEFAULT 0,
+	"lastUpdate" BIGINT DEFAULT 0,
 	"priority" SMALLINT NOT NULL DEFAULT 10,
 	"pathEntries" VARCHAR(65535) DEFAULT NULL,
 	"httpAuth" VARCHAR(1024) DEFAULT NULL,
@@ -42,8 +42,8 @@ CREATE TABLE IF NOT EXISTS `_entry` (
 	"author" VARCHAR(65535),
 	"content" TEXT,
 	"link" VARCHAR(32768) NOT NULL,
-	"date" INT,
-	"lastSeen" INT DEFAULT 0,
+	"date" BIGINT,
+	"lastSeen" BIGINT DEFAULT 0,
 	"hash" BYTEA,
 	"is_read" SMALLINT NOT NULL DEFAULT 0,
 	"is_favorite" SMALLINT NOT NULL DEFAULT 0,
@@ -70,8 +70,8 @@ CREATE TABLE IF NOT EXISTS `_entrytmp` (	-- v1.7
 	"author" VARCHAR(65535),
 	"content" TEXT,
 	"link" VARCHAR(32768) NOT NULL,
-	"date" INT,
-	"lastSeen" INT DEFAULT 0,
+	"date" BIGINT,
+	"lastSeen" BIGINT DEFAULT 0,
 	"hash" BYTEA,
 	"is_read" SMALLINT NOT NULL DEFAULT 0,
 	"is_favorite" SMALLINT NOT NULL DEFAULT 0,
@@ -101,3 +101,14 @@ SQL;
 $GLOBALS['SQL_DROP_TABLES'] = <<<'SQL'
 DROP TABLE IF EXISTS `_entrytag`, `_tag`, `_entrytmp`, `_entry`, `_feed`, `_category`;
 SQL;
+
+$GLOBALS['SQL_UPDATE_YEAR_2038'] = <<<'SQL'
+ALTER TABLE `_entry`	-- v1.23
+	ALTER COLUMN "date" SET DATA TYPE BIGINT,
+	ALTER COLUMN "lastSeen" SET DATA TYPE BIGINT;
+ALTER TABLE `_entrytmp`
+	ALTER COLUMN "date" SET DATA TYPE BIGINT,
+	ALTER COLUMN "lastSeen" SET DATA TYPE BIGINT;
+ALTER TABLE `_feed`
+	ALTER COLUMN "lastUpdate" SET DATA TYPE BIGINT;
+SQL;

+ 5 - 5
app/SQL/install.sql.sqlite.php

@@ -22,7 +22,7 @@ CREATE TABLE IF NOT EXISTS `feed` (
 	`name` VARCHAR(191) NOT NULL,
 	`website` VARCHAR(32768),
 	`description` TEXT,
-	`lastUpdate` INT(11) DEFAULT 0,	-- Until year 2038
+	`lastUpdate` BIGINT DEFAULT 0,
 	`priority` TINYINT(2) NOT NULL DEFAULT 10,
 	`pathEntries` VARCHAR(65535) DEFAULT NULL,
 	`httpAuth` VARCHAR(1024) DEFAULT NULL,
@@ -43,8 +43,8 @@ CREATE TABLE IF NOT EXISTS `entry` (
 	`author` VARCHAR(65535),
 	`content` TEXT,
 	`link` VARCHAR(32768) NOT NULL,
-	`date` INT(11),	-- Until year 2038
-	`lastSeen` INT(11) DEFAULT 0,	-- v1.1.1, Until year 2038
+	`date` BIGINT,
+	`lastSeen` BIGINT DEFAULT 0,
 	`hash` BINARY(16),	-- v1.1.1
 	`is_read` BOOLEAN NOT NULL DEFAULT 0,
 	`is_favorite` BOOLEAN NOT NULL DEFAULT 0,
@@ -69,8 +69,8 @@ CREATE TABLE IF NOT EXISTS `entrytmp` (	-- v1.7
 	`author` VARCHAR(65535),
 	`content` TEXT,
 	`link` VARCHAR(32768) NOT NULL,
-	`date` INT(11),
-	`lastSeen` INT(11) DEFAULT 0,
+	`date` BIGINT,
+	`lastSeen` BIGINT DEFAULT 0,
 	`hash` BINARY(16),
 	`is_read` BOOLEAN NOT NULL DEFAULT 0,
 	`is_favorite` BOOLEAN NOT NULL DEFAULT 0,