summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-11-06 17:36:54 +0100
committerBernhard Posselt <dev@bernhard-posselt.com>2014-11-06 17:36:54 +0100
commit23dcd8e5bff6a2e366b085ac373638206652f055 (patch)
tree0bafb8ac92d7bfa3948369d4c0772758fda3c738
parent31975bfab7d8f94ce3d2f438caa50ac21547d655 (diff)
fix mysql
-rw-r--r--appinfo/application.php10
-rw-r--r--db/mapperfactory.php40
-rw-r--r--db/mysql/itemmapper.php66
-rw-r--r--tests/integration/db/ItemMapperTest.php3
-rw-r--r--tests/integration/fixtures/items.json38
-rw-r--r--tests/unit/db/MapperFactoryTest.php50
-rw-r--r--tests/unit/db/mysql/ItemMapperTest.php119
7 files changed, 305 insertions, 21 deletions
diff --git a/appinfo/application.php b/appinfo/application.php
index 5c1978459..84b0440f3 100644
--- a/appinfo/application.php
+++ b/appinfo/application.php
@@ -44,6 +44,7 @@ use \OCA\News\Service\ItemService;
use \OCA\News\Db\FolderMapper;
use \OCA\News\Db\FeedMapper;
use \OCA\News\Db\ItemMapper;
+use \OCA\News\Db\MapperFactory;
use \OCA\News\Db\StatusFlag;
use \OCA\News\Utility\OPMLExporter;
@@ -230,6 +231,13 @@ class Application extends App {
/**
* Mappers
*/
+ $container->registerService('MapperFactory', function($c) {
+ return new MapperFactory(
+ $c->query('DatabaseType'),
+ $c->query('Db')
+ );
+ });
+
$container->registerService('FolderMapper', function($c) {
return new FolderMapper(
$c->query('Db')
@@ -243,7 +251,7 @@ class Application extends App {
});
$container->registerService('ItemMapper', function($c) {
- return new ItemMapper(
+ return $c->query('MapperFactory')->getItemMapper(
$c->query('Db')
);
});
diff --git a/db/mapperfactory.php b/db/mapperfactory.php
new file mode 100644
index 000000000..50dfa1d9b
--- /dev/null
+++ b/db/mapperfactory.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Alessandro Cosentino <cosenal@gmail.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Alessandro Cosentino 2012
+ * @copyright Bernhard Posselt 2012, 2014
+ */
+
+namespace OCA\News\Db;
+
+use \OCP\IDb;
+use \OCA\News\Db\Mysql\ItemMapper as MysqlItemMapper;
+
+class MapperFactory {
+
+ private $dbType;
+ private $db;
+
+ public function __construct($dbType, IDb $db) {
+ $this->dbType = $dbType;
+ $this->db = $db;
+ }
+
+
+ public function getItemMapper() {
+ switch($this->dbType) {
+ case 'mysql':
+ return new MysqlItemMapper($this->db);
+ default:
+ return new ItemMapper($this->db);
+ }
+ }
+
+
+}
diff --git a/db/mysql/itemmapper.php b/db/mysql/itemmapper.php
new file mode 100644
index 000000000..c58036350
--- /dev/null
+++ b/db/mysql/itemmapper.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Alessandro Cosentino <cosenal@gmail.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Alessandro Cosentino 2012
+ * @copyright Bernhard Posselt 2012, 2014
+ */
+
+namespace OCA\News\Db\Mysql;
+
+use \OCP\IDb;
+
+use \OCA\News\Db\StatusFlag;
+
+
+class ItemMapper extends \OCA\News\Db\ItemMapper {
+
+ public function __construct(IDb $db){
+ parent::__construct($db);
+ }
+
+
+ /**
+ * Delete all items for feeds that have over $threshold unread and not
+ * starred items
+ */
+ public function deleteReadOlderThanThreshold($threshold){
+ $status = StatusFlag::STARRED | StatusFlag::UNREAD;
+ $sql = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`, ' .
+ '`feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
+ 'FROM `*PREFIX*news_items` `items` ' .
+ 'JOIN `*PREFIX*news_feeds` `feeds` ' .
+ 'ON `feeds`.`id` = `items`.`feed_id` ' .
+ 'AND NOT ((`items`.`status` & ?) > 0) ' .
+ 'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
+ 'HAVING COUNT(*) > ?';
+ $params = [$status, $threshold];
+ $result = $this->execute($sql, $params);
+
+ while($row = $result->fetch()) {
+
+ $size = (int) $row['size'];
+ $limit = $size - $threshold;
+
+ if($limit > 0) {
+ $params = [$status, $row['feed_id'], $limit];
+
+ $sql = 'DELETE FROM `*PREFIX*news_items` ' .
+ 'WHERE NOT ((`status` & ?) > 0) ' .
+ 'AND `feed_id` = ? ' .
+ 'ORDER BY `id` ASC ' .
+ 'LIMIT ?';
+
+ $this->execute($sql, $params);
+ }
+ }
+
+ }
+
+
+}
diff --git a/tests/integration/db/ItemMapperTest.php b/tests/integration/db/ItemMapperTest.php
index 53ade4c79..b0b979f8f 100644
--- a/tests/integration/db/ItemMapperTest.php
+++ b/tests/integration/db/ItemMapperTest.php
@@ -54,7 +54,8 @@ class ItemMapperTest extends NewsIntegrationTest {
$this->userId);
$this->itemMapper->find($this->items['a title2']->getId(),
$this->userId);
- $this->itemMapper->find($this->items['a title3']->getId(), $this->userId);
+ $this->itemMapper->find($this->items['a title3']->getId(),
+ $this->userId);
$this->itemMapper->find($this->items['del3']->getId(), $this->userId);
$this->itemMapper->find($this->items['del4']->getId(), $this->userId);
}
diff --git a/tests/integration/fixtures/items.json b/tests/integration/fixtures/items.json
index 780796afe..7f6b6c9c4 100644
--- a/tests/integration/fixtures/items.json
+++ b/tests/integration/fixtures/items.json
@@ -1,11 +1,11 @@
{
"first feed": [
{
- "status": 2,
+ "status": 4,
"body": "this is a body",
- "title": "a title1",
+ "title": "a title2",
"author": "my author",
- "guid": "abc",
+ "guid": "def",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -13,11 +13,11 @@
"enclosureLink": "http://google.de/web.webm"
},
{
- "status": 0,
+ "status": 6,
"body": "this is a body",
- "title": "del1",
+ "title": "a title3",
"author": "my author",
- "guid": "del1",
+ "guid": "gih",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -25,11 +25,11 @@
"enclosureLink": "http://google.de/web.webm"
},
{
- "status": 0,
+ "status": 2,
"body": "this is a body",
- "title": "del2",
+ "title": "a title1",
"author": "my author",
- "guid": "del2",
+ "guid": "abc",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -39,9 +39,9 @@
{
"status": 0,
"body": "this is a body",
- "title": "del3",
+ "title": "del1",
"author": "my author",
- "guid": "del3",
+ "guid": "del1",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -51,9 +51,9 @@
{
"status": 0,
"body": "this is a body",
- "title": "del4",
+ "title": "del2",
"author": "my author",
- "guid": "del4",
+ "guid": "del2",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -61,11 +61,11 @@
"enclosureLink": "http://google.de/web.webm"
},
{
- "status": 4,
+ "status": 0,
"body": "this is a body",
- "title": "a title2",
+ "title": "del3",
"author": "my author",
- "guid": "def",
+ "guid": "del3",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
@@ -73,11 +73,11 @@
"enclosureLink": "http://google.de/web.webm"
},
{
- "status": 6,
+ "status": 0,
"body": "this is a body",
- "title": "a title3",
+ "title": "del4",
"author": "my author",
- "guid": "gih",
+ "guid": "del4",
"url": "http://google.de",
"pubDate": 2323,
"lastModified": 113,
diff --git a/tests/unit/db/MapperFactoryTest.php b/tests/unit/db/MapperFactoryTest.php
new file mode 100644
index 000000000..cb84e78f5
--- /dev/null
+++ b/tests/unit/db/MapperFactoryTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Alessandro Cosentino <cosenal@gmail.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Alessandro Cosentino 2012
+ * @copyright Bernhard Posselt 2012, 2014
+ */
+
+namespace OCA\News\Db;
+
+
+class MapperFactoryTest extends \PHPUnit_Framework_TestCase {
+
+ private $db;
+ private $settings;
+
+ public function setUp() {
+ $this->db = $this->getMockBuilder('\OCP\IDb')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+
+ public function testGetItemMapperSqlite() {
+ $factory = new MapperFactory('sqlite', $this->db);
+
+ $this->assertTrue($factory->getItemMapper() instanceof ItemMapper);
+ }
+
+
+ public function testGetItemMapperPostgres() {
+ $factory = new MapperFactory('pgsql', $this->db);
+
+ $this->assertTrue($factory->getItemMapper() instanceof ItemMapper);
+ }
+
+
+ public function testGetItemMapperMysql() {
+ $factory = new MapperFactory('mysql', $this->db);
+
+ $this->assertTrue($factory->getItemMapper() instanceof \OCA\News\Db\Mysql\ItemMapper);
+ }
+
+
+} \ No newline at end of file
diff --git a/tests/unit/db/mysql/ItemMapperTest.php b/tests/unit/db/mysql/ItemMapperTest.php
new file mode 100644
index 000000000..84c9f5dc3
--- /dev/null
+++ b/tests/unit/db/mysql/ItemMapperTest.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * ownCloud - News
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Alessandro Cosentino <cosenal@gmail.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @copyright Alessandro Cosentino 2012
+ * @copyright Bernhard Posselt 2012, 2014
+ */
+
+namespace OCA\News\Db\Mysql;
+
+use \OCA\News\Db\Item;
+use \OCA\News\Db\StatusFlag;
+
+
+class ItemMapperTest extends \Test\AppFramework\Db\MapperTestUtility {
+
+ private $mapper;
+ private $items;
+ private $newestItemId;
+ private $limit;
+ private $user;
+ private $offset;
+ private $updatedSince;
+ private $status;
+
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->mapper = new ItemMapper($this->db);
+
+ // create mock items
+ $item1 = new Item();
+ $item2 = new Item();
+
+ $this->items = [$item1, $item2];
+
+ $this->userId = 'john';
+ $this->id = 3;
+ $this->folderId = 2;
+
+ $this->row = [['id' => $this->items[0]->getId()]];
+
+ $this->rows = [
+ ['id' => $this->items[0]->getId()],
+ ['id' => $this->items[1]->getId()]
+ ];
+
+ $this->user = 'john';
+ $this->limit = 10;
+ $this->offset = 3;
+ $this->id = 11;
+ $this->status = 333;
+ $this->updatedSince = 323;
+ $this->newestItemId = 2;
+
+ }
+
+
+ public function testDeleteReadOlderThanThresholdDoesNotDeleteBelow(){
+ $status = StatusFlag::STARRED | StatusFlag::UNREAD;
+ $sql = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`' .
+ ', `feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
+ 'FROM `*PREFIX*news_items` `items` ' .
+ 'JOIN `*PREFIX*news_feeds` `feeds` ' .
+ 'ON `feeds`.`id` = `items`.`feed_id` ' .
+ 'AND NOT ((`items`.`status` & ?) > 0) ' .
+ 'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
+ 'HAVING COUNT(*) > ?';
+
+ $threshold = 10;
+ $rows = [['feed_id' => 30, 'size' => 9]];
+ $params = [$status, $threshold];
+
+ $this->setMapperResult($sql, $params, $rows);
+ $this->mapper->deleteReadOlderThanThreshold($threshold);
+
+
+ }
+
+
+ public function testDeleteReadOlderThanThreshold(){
+ $threshold = 10;
+ $status = StatusFlag::STARRED | StatusFlag::UNREAD;
+
+ $sql1 = 'SELECT (COUNT(*) - `feeds`.`articles_per_update`) AS `size`' .
+ ', `feeds`.`id` AS `feed_id`, `feeds`.`articles_per_update` ' .
+ 'FROM `*PREFIX*news_items` `items` ' .
+ 'JOIN `*PREFIX*news_feeds` `feeds` ' .
+ 'ON `feeds`.`id` = `items`.`feed_id` ' .
+ 'AND NOT ((`items`.`status` & ?) > 0) ' .
+ 'GROUP BY `feeds`.`id`, `feeds`.`articles_per_update` ' .
+ 'HAVING COUNT(*) > ?';
+ $params1 = [$status, $threshold];
+
+
+ $row = ['feed_id' => 30, 'size' => 11];
+
+ $sql2 = 'DELETE FROM `*PREFIX*news_items` ' .
+ 'WHERE NOT ((`status` & ?) > 0) ' .
+ 'AND `feed_id` = ? ' .
+ 'ORDER BY `id` ASC ' .
+ 'LIMIT ?';
+ $params2 = [$status, 30, 1];
+
+
+ $this->setMapperResult($sql1, $params1, [$row]);
+ $this->setMapperResult($sql2, $params2);
+
+ $this->mapper->deleteReadOlderThanThreshold($threshold);
+ }
+
+
+} \ No newline at end of file