فهرست منبع

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 12 سال پیش
والد
کامیت
e98b7ab13e
5فایلهای تغییر یافته به همراه48 افزوده شده و 73 حذف شده
  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é)
 * 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)
  * 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)
  * 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+
 * Un navigateur Web récent tel Firefox, Chrome, Opera, Safari, Internet Explorer 9+
  * Fonctionne aussi sur mobile
  * Fonctionne aussi sur mobile
 
 

+ 16 - 66
app/models/Entry.php

@@ -199,7 +199,8 @@ class Entry extends Model {
 
 
 class EntryDAO extends Model_pdo {
 class EntryDAO extends Model_pdo {
 	public function addEntry ($valuesTmp) {
 	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);
 		$stm = $this->bd->prepare ($sql);
 
 
 		$values = array (
 		$values = array (
@@ -207,7 +208,7 @@ class EntryDAO extends Model_pdo {
 			substr($valuesTmp['guid'], 0, 760),
 			substr($valuesTmp['guid'], 0, 760),
 			substr($valuesTmp['title'], 0, 255),
 			substr($valuesTmp['title'], 0, 255),
 			substr($valuesTmp['author'], 0, 255),
 			substr($valuesTmp['author'], 0, 255),
-			base64_encode (gzdeflate (serialize ($valuesTmp['content']))),
+			$valuesTmp['content'],
 			substr($valuesTmp['link'], 0, 1023),
 			substr($valuesTmp['link'], 0, 1023),
 			$valuesTmp['date'],
 			$valuesTmp['date'],
 			$valuesTmp['is_read'],
 			$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) {
 	public function markFavorite ($id, $is_favorite = true) {
 		$sql = 'UPDATE `' . $this->prefix . 'entry` e '
 		$sql = 'UPDATE `' . $this->prefix . 'entry` e '
 		     . 'SET e.is_favorite = ? '
 		     . '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) {
 	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);
 		$stm = $this->bd->prepare ($sql);
 
 
 		$values = array (
 		$values = array (
@@ -489,7 +437,8 @@ class EntryDAO extends Model_pdo {
 
 
 	public function searchByGuid ($feed_id, $id) {
 	public function searchByGuid ($feed_id, $id) {
 		// un guid est unique pour un flux donné
 		// 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);
 		$stm = $this->bd->prepare ($sql);
 
 
 		$values = array (
 		$values = array (
@@ -509,7 +458,8 @@ class EntryDAO extends Model_pdo {
 	}
 	}
 
 
 	public function searchById ($id) {
 	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);
 		$stm = $this->bd->prepare ($sql);
 
 
 		$values = array ($id);
 		$values = array ($id);
@@ -541,8 +491,9 @@ class EntryDAO extends Model_pdo {
 			$order = '';
 			$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;
 		     . ' ORDER BY e.id' . $order;
 
 
 		if (empty($limitCount)) {
 		if (empty($limitCount)) {
@@ -558,16 +509,16 @@ class EntryDAO extends Model_pdo {
 		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
 		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
 	}
 	}
 	public function listEntries ($state, $order = 'high_to_low', $limitFromId = '', $limitCount = '') {
 	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 = '') {
 	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 = '') {
 	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 = '') {
 	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) {
 	public function listLastGuidsByFeed($id, $n) {
@@ -648,7 +599,6 @@ class HelperEntry {
 		$break_after = false;
 		$break_after = false;
 		$next = '';
 		$next = '';
 		foreach ($listDAO as $key => $dao) {
 		foreach ($listDAO as $key => $dao) {
-			$dao['content'] = unserialize (gzinflate (base64_decode ($dao['content'])));
 			$dao['tags'] = preg_split('/[\s#]/', $dao['tags']);
 			$dao['tags'] = preg_split('/[\s#]/', $dao['tags']);
 
 
 			if (self::tagsMatchEntry ($dao) &&
 			if (self::tagsMatchEntry ($dao) &&

+ 22 - 0
app/models/Feed.php

@@ -408,6 +408,16 @@ class FeedDAO extends Model_pdo {
 	}
 	}
 
 
 	public function deleteFeed ($id) {
 	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=?';
 		$sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE id=?';
 		$stm = $this->bd->prepare ($sql);
 		$stm = $this->bd->prepare ($sql);
 
 
@@ -422,6 +432,18 @@ class FeedDAO extends Model_pdo {
 		}
 		}
 	}
 	}
 	public function deleteFeedByCategory ($id) {
 	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=?';
 		$sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE category=?';
 		$stm = $this->bd->prepare ($sql);
 		$stm = $this->bd->prepare ($sql);
 
 

+ 1 - 1
app/models/RSSPaginator.php

@@ -24,7 +24,7 @@ class RSSPaginator {
 	}
 	}
 
 
 	public function peek () {
 	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) {
 	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,
   `color` char(7) NOT NULL,
   PRIMARY KEY (`id`),
   PRIMARY KEY (`id`),
   UNIQUE KEY (`name`)	-- v0.7
   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` (
 define ('SQL_REQ_FEED', 'CREATE TABLE IF NOT EXISTS `%sfeed` (
   `id` SMALLINT NOT NULL AUTO_INCREMENT,	-- v0.7
   `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 (`name`),	-- v0.7
   INDEX (`priority`),	-- v0.7
   INDEX (`priority`),	-- v0.7
   INDEX (`keep_history`)	-- 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` (
 define ('SQL_REQ_ENTRY', 'CREATE TABLE IF NOT EXISTS `%sentry` (
   `id` bigint NOT NULL,	-- v0.7
   `id` bigint NOT NULL,	-- v0.7
   `guid` varchar(760) CHARACTER SET latin1 NOT NULL,	-- Maximum for UNIQUE is 767B
   `guid` varchar(760) CHARACTER SET latin1 NOT NULL,	-- Maximum for UNIQUE is 767B
   `title` varchar(255) NOT NULL,
   `title` varchar(255) NOT NULL,
   `author` 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,
   `link` varchar(1023) CHARACTER SET latin1 NOT NULL,
   `date` int(11) NOT NULL,
   `date` int(11) NOT NULL,
   `is_read` boolean NOT NULL DEFAULT 0,
   `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,
   FOREIGN KEY (`id_feed`) REFERENCES `%sfeed`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
   UNIQUE KEY (`id_feed`,`guid`),	-- v0.7
   UNIQUE KEY (`id_feed`,`guid`),	-- v0.7
   INDEX (`is_favorite`),	-- 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) {
 function writeLine ($f, $line) {