Author: maksim_ka
Date: 2010-05-07 20:54:56 +0200 (Fri, 07 May 2010)
New Revision: 29398
Added:
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/sfDoctrinePaginationOnLoop.php
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/test/
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/fixtures/
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/fixtures/testTable.sql
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/sfDoctrinePaginationOnLoopTestCase.php
Log:
init files.
Added:
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/sfDoctrinePaginationOnLoop.php
===================================================================
---
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/sfDoctrinePaginationOnLoop.php
(rev 0)
+++
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/lib/sfDoctrinePaginationOnLoop.php
2010-05-07 18:54:56 UTC (rev 29398)
@@ -0,0 +1,197 @@
+<?php
+
+/**
+ * the plugin core class.
+ *
+ * @package sfDoctrinePaginationOnLoopPlugin
+ * @subpackage lib
+ * @author Maksim Kotlyar <[email protected]>
+ */
+class sfDoctrinePaginationOnLoop
+{
+ /**
+ *
+ * @var Doctrine_Table
+ */
+ protected $_table;
+
+ /**
+ *
+ * @var Doctrine_Query
+ */
+ protected $_baseQuery;
+
+ protected $_orderByType = 'ASC';
+
+ /**
+ *
+ * @var int
+ */
+ protected $_page;
+
+ /**
+ *
+ * @var int
+ */
+ protected $_perPage;
+
+ public function __construct(Doctrine_Table $table, $page, $perPage)
+ {
+ if (!(is_numeric($page) && $page != 0)) {
+ throw new Exception('Invalid fabric id provided. It should be no zero
int but you give `'.$page.'` of type `'.gettype($page).'`');
+ }
+ if (!(is_numeric($perPage) && $perPage > 0)) {
+ throw new Exception('Invalid fabric id provided. It should be positiv
int but you give `'.$perPage.'` of type `'.gettype($perPage).'`');
+ }
+
+ $this->_table = $table;
+ $this->_orderByType = $page > 0 ? 'ASC' : 'DESC';
+ $this->_page = $page > 0 ? $page : $page * -1;
+ $this->_perPage = $perPage;
+
+ $this->setBaseQuery($table->createQuery('f'));
+ $this->setOrderByColumn('id');
+ }
+
+ public function setOrderByColumn($column)
+ {
+ $this->_baseQuery->orderBy("{$column} {$this->_orderByType}, id
{$this->_orderByType}");
+ return $this;
+ }
+
+ /**
+ *
+ * @param Doctrine_Query $baseQuery
+ *
+ * @return DataRetriverOnLoop
+ */
+ public function setBaseQuery(Doctrine_Query $baseQuery)
+ {
+ $this->_baseQuery = $baseQuery;
+ return $this;
+ }
+
+ /**
+ *
+ * @param int $page
+ * @param int $per_page
+ *
+ * @return array
+ */
+ public function find()
+ {
+ return $this->_convert($this->_find());
+ }
+
+ /**
+ *
+ * @param array $subQueries
+ *
+ * @return array
+ */
+ protected function _find()
+ {
+ $subQueries = $this->_buildSubQueries();
+ $offsetStart = $this->_getStartData() - $this->_getStart();
+ $limitFinish = $this->_getWhole() - ($this->_getFinish() -
$this->_getEndData());
+
+ $firstSubQuery = &$subQueries[0];
+ $lastSubQuery = &$subQueries[count($subQueries) - 1];
+
+ if (1 == count($subQueries)) {
+ $query = $firstSubQuery." LIMIT {$offsetStart}, {$this->_perPage}";
+ } else {
+ $firstSubQuery .= " LIMIT {$offsetStart}, {$this->_perPage}";
+ $lastSubQuery .= " LIMIT 0, {$limitFinish}";
+
+ $subQuery = '('.implode(') UNION ALL (', $subQueries).')';
+ $query = "SELECT * FROM ({$subQuery}) AS f";
+ }
+//var_dump($query);
+//die;
+ return Doctrine_Manager::connection()->fetchAssoc($query);
+ }
+
+ /**
+ *
+ * @param array $recordsArr
+ *
+ * @return array of Doctrine_Record
+ */
+ protected function _convert(array $recordsArr)
+ {
+ $records = array();
+ foreach($recordsArr as $recordArr) {
+ $records[] = $this->_convertArrayToRecord($recordArr);
+ }
+
+ return $records;
+ }
+
+ /**
+ *
+ * @param array $recordArr
+ *
+ * @return Doctrine_Record
+ */
+ protected function _convertArrayToRecord(array $recordArr)
+ {
+ $recordArrPrepared = array();
+ foreach ($recordArr as $key => $value) {
+ $key = preg_replace('/\w{1}__/', '', $key);
+ $recordArrPrepared[$key] = $value;
+ }
+
+ $record = $this->_table->getRecord();
+ $record->fromArray($recordArrPrepared);
+ $record->assignIdentifier($recordArrPrepared['id']);
+
+ return $record;
+ }
+
+ protected function _buildSubQueries()
+ {
+ $unionNum = ($this->_getFinish() - $this->_getStart()) /
$this->_getWhole();
+
+ return array_fill(0 , $unionNum, $this->_baseQuery->getSqlQuery());
+ }
+
+ protected function _getStartData()
+ {
+ return ($this->_page - 1) * $this->_perPage;
+ }
+
+ protected function _getEndData()
+ {
+ return $this->_getStartData() + $this->_perPage;
+ }
+
+ protected function _getStart()
+ {
+ $startData = $this->_getStartData();
+ $whole = $this->_getWhole();
+
+ return (int) floor($startData / $whole) * $whole;
+ }
+
+ protected function _getFinish()
+ {
+ $endData = $this->_getEndData();
+ $whole = $this->_getWhole();
+
+ $finish = ceil($endData / $whole);
+
+ return $finish ? $finish * $whole : 1;
+ }
+
+ protected function _getWhole()
+ {
+ $countQuery = clone $this->_baseQuery;
+
+ return $countQuery
+ ->select('count(*)')
+ ->execute(array(), Doctrine_Core::HYDRATE_SINGLE_SCALAR);
+
+ //return $this->_baseQuery->count();
+ }
+}
\ No newline at end of file
Added:
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/sfDoctrinePaginationOnLoopTestCase.php
===================================================================
---
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/sfDoctrinePaginationOnLoopTestCase.php
(rev 0)
+++
plugins/sfDoctrinePaginationOnLoopPlugin/branches/1.4/test/phpunit/sfDoctrinePaginationOnLoopTestCase.php
2010-05-07 18:54:56 UTC (rev 29398)
@@ -0,0 +1,162 @@
+<?php
+
+class sfDoctrinePaginationOnLoopTestCase extends sfBasePhpunitTestCase
+ implements sfPhpunitFixtureDoctrineAggregator
+{
+/**
+ * @var DbFabric
+ */
+ protected $_table;
+
+ protected function _start()
+ {
+ $this->_table = Application::getInstance()->tables()->getDbFabric();
+ }
+
+ public function testNumberOfFabricsPrecondition()
+ {
+ $this->fixture()->loadSnapshot('common');
+
+ $this->assertEquals(9, $this->_table->count());
+ }
+
+ /**
+ *
+ * @depends testNumberOfFabricsPrecondition
+ *
+ */
+ public function testFindBugReturnExistRecordWithStatusNew()
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, 1, 3);
+ $fabrics = $finder->find();
+
+ $this->assertEquals(3, count($fabrics));
+ $this->assertFalse($fabrics[0]->isNew());
+
+ }
+
+ /**
+ * Multiple divider
+ *
+ * @depends testNumberOfFabricsPrecondition
+ *
+ * @dataProvider providerFabricsOnLoopWithAAliquotDivider
+ */
+ public function testGetFabricsOnLoopWithAAliquotDivider($page, $perPage,
$firstId, $secondId, $thirdId)
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, $page, $perPage);
+ $items = $finder->find();
+ $this->assertEquals($perPage, count($items));
+ $this->assertEquals($firstId, $items[0]->getId());
+ $this->assertEquals($secondId, $items[1]->getId());
+ $this->assertEquals($thirdId, $items[2]->getId());
+ }
+
+ /**
+ * Divider is less then Number of items but is not aliquot
+ *
+ * @depends testNumberOfFabricsPrecondition
+ *
+ * @dataProvider providerFabricsOnLoopWithASmallDivider
+ */
+ public function testGetFabricsOnLoopWithASmallDivider($page, $perPage,
$firstId, $secondId)
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, $page, $perPage);
+ $items = $finder->find();
+ $this->assertEquals($perPage, count($items));
+ $this->assertEquals($firstId, $items[0]->getId());
+ $this->assertEquals($secondId, $items[6]->getId());
+ }
+
+ /**
+ * Divider is bigger then number of items
+ *
+ * @depends testNumberOfFabricsPrecondition
+ *
+ * @dataProvider providerFabricsOnLoopWithABiggerDivider
+ */
+ public function testGetFabricsOnLoopWithABiggerDivider($page, $perPage,
$firstId, $secondId)
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, $page, $perPage);
+ $fabrics = $finder->find();
+ $this->assertEquals($perPage, count($fabrics));
+ $this->assertEquals($firstId, $fabrics[0]->getId());
+ $this->assertEquals($secondId, $fabrics[10]->getId());
+ }
+
+ /**
+ * @depends testNumberOfFabricsPrecondition
+ * @expectedException Exception
+ */
+ public function testInvalidOrderingName()
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, -1, 11);
+ $finder->setOrderByColumn('XXXXXXXXXXXXXXXXXXXXXX');
+ $fabrics = $finder->find();
+ }
+
+ /**
+ * @depends testNumberOfFabricsPrecondition
+ *
+ * @dataProvider providerOrder
+ */
+ public function testOrder($orderByColumn, $firstId, $secondId, $thirdId)
+ {
+ $finder = new sfDoctrinePaginationOnLoop($this->_table, 1, 3);
+ $finder->setOrderByColumn($orderByColumn);
+ $fabrics = $finder->find();
+
+ $this->assertEquals(3, count($fabrics));
+ $this->assertEquals($firstId, $fabrics[0]->getId());
+ $this->assertEquals($secondId, $fabrics[1]->getId());
+ $this->assertEquals($thirdId, $fabrics[2]->getId());
+ }
+
+ public static function providerFabricsOnLoopWithAAliquotDivider()
+ {
+ return array(
+ //positive
+ array(1, 3, 1, 2, 3),
+ array(2, 3, 4, 5, 6),
+ array(3, 3, 7, 8, 9),
+ array(4, 3, 1, 2, 3),
+ //negative
+ array(-1, 3, 9, 8, 7),
+ array(-2, 3, 6, 5, 4),
+ array(-3, 3, 3, 2, 1),
+ array(-4, 3, 9, 8, 7));
+ }
+
+ public static function providerFabricsOnLoopWithASmallDivider()
+ {
+ return array(
+ //positive
+ array(1, 7, 1, 7),
+ array(2, 7, 8, 5),
+ array(3, 7, 6, 3),
+ //negative
+ array(-1, 7, 9, 3),
+ array(-2, 7, 2, 5),
+ array(-3, 7, 4, 7));
+ }
+
+ public static function providerFabricsOnLoopWithABiggerDivider()
+ {
+ return array(
+ //positive
+ array(1, 11, 1, 2),
+ array(2, 11, 3, 4),
+ array(3, 11, 5, 6),
+ //negative
+ array(-1, 11, 9, 8),
+ array(-2, 11, 7, 6),
+ array(-3, 11, 5, 4));
+ }
+
+ public static function providerOrder()
+ {
+ return array(
+ array('fabric_collection_id', 1, 3, 4),
+ array('price', 2, 3, 1));
+ }
+}
\ No newline at end of file
--
You received this message because you are subscribed to the Google Groups
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/symfony-svn?hl=en.