Quellcode durchsuchen

SQL : compression côté base de données (attention, perte de compatibilité)

Ça y est, j'ai tout cassé...
Contribue à https://github.com/marienfressinaud/FreshRSS/issues/204
Compatible MySQL 5.0.
Commentaires souhaités avant l'implémentation de la recherche côté base
de données.
Pour l'instant, je n'ai pas fait de script de mise à jour, car la
manière précédente `base64_encode(gzdeflate(serialize($content)))` est
difficile à traiter côté MySQL et nécessite une boucle en PHP.
Avec la nouvelle approche de ce patch, nous pourrons plus facilement
changer d'avis sans perte de compatibilité.
Alexandre Alapetite vor 12 Jahren
Ursprung
Commit
e98b7ab13e
5 geänderte Dateien mit 48 neuen und 73 gelöschten Zeilen
  1. 1 1
      README.md
  2. 16 66
      app/models/Entry.php
  3. 22 0
      app/models/Feed.php
  4. 1 1
      app/models/RSSPaginator.php
  5. 8 5
      public/install.php

+ 1 - 1
README.md

@@ -22,7 +22,7 @@ Privilégiez pour cela des demandes sur GitHub
 * PHP 5.2+ (PHP 5.3.3+ recommandé)
  * Requis : [libxml](http://php.net/xml), [cURL](http://php.net/curl), [PDO_MySQL](http://php.net/pdo-mysql)
  * Recommandés : [Zlib](http://php.net/zlib), [mbstring](http://php.net/mbstring), [iconv](http://php.net/iconv)
-* MySQL 5.0.3+ (SQLite à venir)
+* MySQL 5.0.3+ (ou SQLite 3.7.4+ à venir)
 * Un navigateur Web récent tel Firefox, Chrome, Opera, Safari, Internet Explorer 9+
  * Fonctionne aussi sur mobile
 

+ 16 - 66
app/models/Entry.php

@@ -199,7 +199,8 @@ class Entry extends Model {
 
 class EntryDAO extends Model_pdo {
 	public function addEntry ($valuesTmp) {
-		$sql = 'INSERT INTO `' . $this->prefix . 'entry`(id, guid, title, author, content, link, date, is_read, is_favorite, id_feed, tags) VALUES(CAST(? * 1000000 AS SIGNED INTEGER), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
+		$sql = 'INSERT INTO `' . $this->prefix . 'entry`(id, guid, title, author, content_bin, link, date, is_read, is_favorite, id_feed, tags) '
+		     . 'VALUES(CAST(? * 1000000 AS SIGNED INTEGER), ?, ?, ?, COMPRESS(?), ?, ?, ?, ?, ?, ?)';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array (
@@ -207,7 +208,7 @@ class EntryDAO extends Model_pdo {
 			substr($valuesTmp['guid'], 0, 760),
 			substr($valuesTmp['title'], 0, 255),
 			substr($valuesTmp['author'], 0, 255),
-			base64_encode (gzdeflate (serialize ($valuesTmp['content']))),
+			$valuesTmp['content'],
 			substr($valuesTmp['link'], 0, 1023),
 			$valuesTmp['date'],
 			$valuesTmp['is_read'],
@@ -231,33 +232,6 @@ class EntryDAO extends Model_pdo {
 		}
 	}
 
-	/*public function updateEntry ($id, $valuesTmp) {
-		if (isset ($valuesTmp['content'])) {
-			$valuesTmp['content'] = base64_encode (gzdeflate (serialize ($valuesTmp['content'])));
-		}
-
-		$set = '';
-		foreach ($valuesTmp as $key => $v) {
-			$set .= $key . '=?, ';
-		}
-		$set = substr ($set, 0, -2);
-
-		$sql = 'UPDATE `' . $this->prefix . 'entry` SET ' . $set . ' WHERE id=?';
-		$stm = $this->bd->prepare ($sql);
-
-		foreach ($valuesTmp as $v) {
-			$values[] = $v;
-		}
-		$values[] = $id;
-
-		if ($stm && $stm->execute ($values)) {
-			return $stm->rowCount();
-		} else {
-			$info = $stm->errorInfo();
-			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
-			return false;
-		}
-	}*/
 	public function markFavorite ($id, $is_favorite = true) {
 		$sql = 'UPDATE `' . $this->prefix . 'entry` e '
 		     . 'SET e.is_favorite = ? '
@@ -443,35 +417,9 @@ class EntryDAO extends Model_pdo {
 		}
 	}
 
-	/*public function updateEntries ($valuesTmp) {
-		if (isset ($valuesTmp['content'])) {
-			$valuesTmp['content'] = base64_encode (gzdeflate (serialize ($valuesTmp['content'])));
-		}
-
-		$set = '';
-		foreach ($valuesTmp as $key => $v) {
-			$set .= $key . '=?, ';
-		}
-		$set = substr ($set, 0, -2);
-
-		$sql = 'UPDATE `' . $this->prefix . 'entry` SET ' . $set;
-		$stm = $this->bd->prepare ($sql);
-
-		foreach ($valuesTmp as $v) {
-			$values[] = $v;
-		}
-
-		if ($stm && $stm->execute ($values)) {
-			return $stm->rowCount();
-		} else {
-			$info = $stm->errorInfo();
-			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
-			return false;
-		}
-	}*/
-
 	public function cleanOldEntries ($date_min) {
-		$sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE e.id <= ? AND e.is_favorite = 0 AND f.keep_history = 0';
+		$sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id '
+		     . 'WHERE e.id <= ? AND e.is_favorite = 0 AND f.keep_history = 0';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array (
@@ -489,7 +437,8 @@ class EntryDAO extends Model_pdo {
 
 	public function searchByGuid ($feed_id, $id) {
 		// un guid est unique pour un flux donné
-		$sql = 'SELECT * FROM `' . $this->prefix . 'entry` WHERE id_feed=? AND guid=?';
+		$sql = 'SELECT id, guid, title, author, UNCOMPRESS(content_bin) AS content, link, date, is_read, is_favorite, id_feed, tags '
+		     . 'FROM `' . $this->prefix . 'entry` WHERE id_feed=? AND guid=?';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array (
@@ -509,7 +458,8 @@ class EntryDAO extends Model_pdo {
 	}
 
 	public function searchById ($id) {
-		$sql = 'SELECT * FROM `' . $this->prefix . 'entry` WHERE id=?';
+		$sql = 'SELECT id, guid, title, author, UNCOMPRESS(content_bin) AS content, link, date, is_read, is_favorite, id_feed, tags '
+		     . 'FROM `' . $this->prefix . 'entry` WHERE id=?';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array ($id);
@@ -541,8 +491,9 @@ class EntryDAO extends Model_pdo {
 			$order = '';
 		}
 
-		$sql = 'SELECT e.* FROM `' . $this->prefix . 'entry` e'
-		     . ' INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id' . $where
+		$sql = 'SELECT e.id, e.guid, e.title, e.author, UNCOMPRESS(e.content_bin) AS content, e.link, e.date, e.is_read, e.is_favorite, e.id_feed, e.tags '
+		     . 'FROM `' . $this->prefix . 'entry` e '
+		     . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' . $where
 		     . ' ORDER BY e.id' . $order;
 
 		if (empty($limitCount)) {
@@ -558,16 +509,16 @@ class EntryDAO extends Model_pdo {
 		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
 	}
 	public function listEntries ($state, $order = 'high_to_low', $limitFromId = '', $limitCount = '') {
-		return $this->listWhere (' WHERE priority > 0', $state, $order, $limitFromId, $limitCount);
+		return $this->listWhere ('WHERE priority > 0', $state, $order, $limitFromId, $limitCount);
 	}
 	public function listFavorites ($state, $order = 'high_to_low', $limitFromId = '', $limitCount = '') {
-		return $this->listWhere (' WHERE is_favorite = 1', $state, $order, $limitFromId, $limitCount);
+		return $this->listWhere ('WHERE is_favorite = 1', $state, $order, $limitFromId, $limitCount);
 	}
 	public function listByCategory ($cat, $state, $order = 'high_to_low', $limitFromId = '', $limitCount = '') {
-		return $this->listWhere (' WHERE category = ?', $state, $order, $limitFromId, $limitCount, array ($cat));
+		return $this->listWhere ('WHERE category = ?', $state, $order, $limitFromId, $limitCount, array ($cat));
 	}
 	public function listByFeed ($feed, $state, $order = 'high_to_low', $limitFromId = '', $limitCount = '') {
-		return $this->listWhere (' WHERE id_feed = ?', $state, $order, $limitFromId, $limitCount, array ($feed));
+		return $this->listWhere ('WHERE id_feed = ?', $state, $order, $limitFromId, $limitCount, array ($feed));
 	}
 
 	public function listLastGuidsByFeed($id, $n) {
@@ -648,7 +599,6 @@ class HelperEntry {
 		$break_after = false;
 		$next = '';
 		foreach ($listDAO as $key => $dao) {
-			$dao['content'] = unserialize (gzinflate (base64_decode ($dao['content'])));
 			$dao['tags'] = preg_split('/[\s#]/', $dao['tags']);
 
 			if (self::tagsMatchEntry ($dao) &&

+ 22 - 0
app/models/Feed.php

@@ -408,6 +408,16 @@ class FeedDAO extends Model_pdo {
 	}
 
 	public function deleteFeed ($id) {
+		/*//For MYISAM (MySQL 5.5-) without FOREIGN KEY
+		$sql = 'DELETE FROM `' . $this->prefix . 'entry` WHERE id_feed=?';
+		$stm = $this->bd->prepare ($sql);
+		$values = array ($id);
+		if (!($stm && $stm->execute ($values))) {
+			$info = $stm->errorInfo();
+			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
+			return false;
+		}*/
+
 		$sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE id=?';
 		$stm = $this->bd->prepare ($sql);
 
@@ -422,6 +432,18 @@ class FeedDAO extends Model_pdo {
 		}
 	}
 	public function deleteFeedByCategory ($id) {
+		/*//For MYISAM (MySQL 5.5-) without FOREIGN KEY
+		$sql = 'DELETE FROM `' . $this->prefix . 'entry` e '
+		     . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id '
+		     . 'WHERE f.category=?';
+		$stm = $this->bd->prepare ($sql);
+		$values = array ($id);
+		if (!($stm && $stm->execute ($values))) {
+			$info = $stm->errorInfo();
+			Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR);
+			return false;
+		}*/
+
 		$sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE category=?';
 		$stm = $this->bd->prepare ($sql);
 

+ 1 - 1
app/models/RSSPaginator.php

@@ -24,7 +24,7 @@ class RSSPaginator {
 	}
 
 	public function peek () {
-		return empty($this->items) ? null : $this->items[0];
+		return isset($this->items[0]) ? $this->items[0] : null;
 	}
 
 	public function render ($view, $getteur) {

+ 8 - 5
public/install.php

@@ -18,7 +18,8 @@ define ('SQL_REQ_CAT', 'CREATE TABLE IF NOT EXISTS `%scategory` (
   `color` char(7) NOT NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY (`name`)	-- v0.7
-) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;');
+) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
+ENGINE = INNODB;');
 
 define ('SQL_REQ_FEED', 'CREATE TABLE IF NOT EXISTS `%sfeed` (
   `id` SMALLINT NOT NULL AUTO_INCREMENT,	-- v0.7
@@ -41,14 +42,15 @@ define ('SQL_REQ_FEED', 'CREATE TABLE IF NOT EXISTS `%sfeed` (
   INDEX (`name`),	-- v0.7
   INDEX (`priority`),	-- v0.7
   INDEX (`keep_history`)	-- v0.7
-) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;');
+) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
+ENGINE = INNODB;');
 
 define ('SQL_REQ_ENTRY', 'CREATE TABLE IF NOT EXISTS `%sentry` (
   `id` bigint NOT NULL,	-- v0.7
   `guid` varchar(760) CHARACTER SET latin1 NOT NULL,	-- Maximum for UNIQUE is 767B
   `title` varchar(255) NOT NULL,
   `author` varchar(255) NOT NULL,
-  `content` text NOT NULL,
+  `content_bin` blob NOT NULL,	-- v0.7
   `link` varchar(1023) CHARACTER SET latin1 NOT NULL,
   `date` int(11) NOT NULL,
   `is_read` boolean NOT NULL DEFAULT 0,
@@ -59,8 +61,9 @@ define ('SQL_REQ_ENTRY', 'CREATE TABLE IF NOT EXISTS `%sentry` (
   FOREIGN KEY (`id_feed`) REFERENCES `%sfeed`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
   UNIQUE KEY (`id_feed`,`guid`),	-- v0.7
   INDEX (`is_favorite`),	-- v0.7
-  INDEX (`is_read`)	-- v0.7
-) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;');
+  INDEX (`is_read`),	-- v0.7
+) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
+ENGINE = INNODB;');
 
 
 function writeLine ($f, $line) {