DaoIterator.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2009 by Ivan Y. Khvostishkov                            *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class DaoIterator implements Iterator
00016     {
00017         private $dao            = null;
00018         private $projection     = null;
00019         private $keyProperty    = 'id';
00020         
00021         private $chunkSize      = 42;
00022         
00023         private $chunk          = null;
00024         private $offset         = 0;
00025         
00026         public function setDao(ProtoDao $dao)
00027         {
00028             $this->dao = $dao;
00029             
00030             return $this;
00031         }
00032         
00036         public function getDao()
00037         {
00038             return $this->dao;
00039         }
00040         
00041         public function setProjection(ObjectProjection $projection)
00042         {
00043             $this->projection = $projection;
00044             
00045             return $this;
00046         }
00047         
00051         public function getProjection()
00052         {
00053             return $this->projection;
00054         }
00055         
00056         public function setChunkSize($chunkSize)
00057         {
00058             $this->chunkSize = $chunkSize;
00059             
00060             return $this;
00061         }
00062         
00063         public function getChunkSize()
00064         {
00065             return $this->chunkSize;
00066         }
00067         
00068         public function setKeyProperty($keyProperty)
00069         {
00070             $this->keyProperty = $keyProperty;
00071             
00072             return $this;
00073         }
00074         
00075         public function getKeyProperty()
00076         {
00077             return $this->keyProperty;
00078         }
00079         
00080         public function rewind()
00081         {
00082             $this->loadNextChunk(null);
00083             
00084             return $this;
00085         }
00086         
00087         public function current()
00088         {
00089             if (!$this->valid())
00090                 return null;
00091             
00092             return $this->chunk[$this->offset];
00093         }
00094         
00095         public function key()
00096         {
00097             $method = 'get'.ucfirst($this->keyProperty);
00098             
00099             Assert::methodExists($this->current(), $method);
00100             
00101             return $this->current()->$method();
00102         }
00103         
00104         public function next()
00105         {
00106             if (!$this->valid())
00107                 return null;
00108             
00109             $key = $this->key();
00110             
00111             ++$this->offset;
00112             
00113             if ($this->offset >= $this->chunkSize) {
00114                 $this->loadNextChunk($key);
00115             }
00116             
00117             return $this;
00118         }
00119         
00120         public function valid()
00121         {
00122             if ($this->chunk === null)
00123                 $this->loadNextChunk(null);
00124             
00125             return isset($this->chunk[$this->offset]);
00126         }
00127         
00128         private function loadNextChunk($id)
00129         {
00130             Assert::isNotNull($this->dao);
00131             
00132             $this->offset = 0;
00133             
00134             $criteria = Criteria::create($this->dao);
00135             
00136             if ($this->projection)
00137                 $criteria->setProjection($this->projection);
00138             
00139             $criteria->
00140                 addOrder($this->keyProperty)->
00141                 setLimit($this->chunkSize);
00142             
00143             if ($id !== null)
00144                 $criteria->add(
00145                     Expression::gt($this->keyProperty, $id)
00146                 );
00147             
00148             // preserving memory bloat
00149             $this->dao->dropIdentityMap();
00150             
00151             $this->chunk = $criteria->getList();
00152             
00153             return $this->chunk;
00154         }
00155     }
00156 ?>