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.

Reply via email to