TransparentDaoWorker.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2006-2007 by Konstantin V. Arkhipov                     *
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 /* $Id: TransparentDaoWorker.class.php 4687 2007-12-09 18:57:18Z voxus $ */
00012 
00021     abstract class TransparentDaoWorker extends BaseDaoWorker
00022     {
00023         abstract protected function gentlyGetByKey($key);
00024         
00026 
00027         public function get(ObjectQuery $oq)
00028         {
00029             return $this->getByQuery($oq->toSelectQuery($this->dao));
00030         }
00031         
00032         public function getById($id)
00033         {
00034             $object = $this->getCachedById($id);
00035             
00036             if ($object) {
00037                 if ($object === Cache::NOT_FOUND)
00038                     throw new ObjectNotFoundException();
00039                 else
00040                     return $object;
00041             } else {
00042                 $query =
00043                     $this->dao->makeSelectHead()->
00044                     andWhere(
00045                         Expression::eq(
00046                             DBField::create(
00047                                 $this->dao->getIdName(),
00048                                 $this->dao->getTable()
00049                             ),
00050                             $id
00051                         )
00052                     );
00053 
00054                 if ($object = $this->fetchObject($query)) {
00055                     return $this->cacheById($object);
00056                 } else {
00057                     $this->cacheNullById($id);
00058                     throw new ObjectNotFoundException();
00059                 }
00060             }
00061         }
00062         
00063         public function getByLogic(LogicalObject $logic)
00064         {
00065             return
00066                 $this->getByQuery(
00067                     $this->dao->makeSelectHead()->andWhere($logic)
00068                 );
00069         }
00070         
00071         public function getByQuery(SelectQuery $query)
00072         {
00073             $object = $this->getCachedByQuery($query);
00074             
00075             if ($object) {
00076                 
00077                 if ($object === Cache::NOT_FOUND)
00078                     throw new ObjectNotFoundException();
00079                 else
00080                     return $object;
00081                 
00082             } else {
00083                 if ($object = $this->fetchObject($query))
00084                     return $this->cacheByQuery($query, $object);
00085                 else {
00086                     $this->cacheByQuery($query, Cache::NOT_FOUND);
00087                     throw new ObjectNotFoundException();
00088                 }
00089             }
00090         }
00091         
00092         public function getCustom(SelectQuery $query)
00093         {
00094             if ($query->getLimit() > 1)
00095                 throw new WrongArgumentException(
00096                     'can not handle non-single row queries'
00097                 );
00098 
00099             $custom = $this->getCachedByQuery($query);
00100             
00101             if ($custom) {
00102                 if ($custom === Cache::NOT_FOUND)
00103                     throw new ObjectNotFoundException();
00104                 else
00105                     return $custom;
00106             } else {
00107                 $custom = DBPool::getByDao($this->dao)->queryRow($query);
00108                 
00109                 if ($custom)
00110                     return $this->cacheByQuery($query, $custom);
00111                 else {
00112                     $this->cacheByQuery($query, Cache::NOT_FOUND);
00113                     throw new ObjectNotFoundException();
00114                 }
00115             }
00116         }
00118         
00120 
00121         public function getList(ObjectQuery $oq)
00122         {
00123             return $this->getListByQuery($oq->toSelectQuery($this->dao));
00124         }
00125         
00126         public function getListByIds($ids)
00127         {
00128             $list = array();
00129             $toFetch = array();
00130             
00131             foreach ($ids as $id) {
00132                 if (
00133                     !($cached = $this->getCachedById($id))
00134                     || ($cached === Cache::NOT_FOUND)
00135                 ) {
00136                     $toFetch[] = $id;
00137                 } else {
00138                     $list[] = $cached;
00139                 }
00140             }
00141             
00142             if (!$toFetch)
00143                 return $list;
00144             
00145             try {
00146                 return
00147                     array_merge(
00148                         $list,
00149                         $this->getListByLogic(
00150                             Expression::in($this->dao->getIdName(), $toFetch)
00151                         )
00152                     );
00153             } catch (ObjectNotFoundException $e) {
00154                 // nothing to fetch
00155                 return $list;
00156             }
00157             
00158             Assert::isUnreachable();
00159         }
00160         
00161         public function getListByQuery(SelectQuery $query)
00162         {
00163             $list = $this->getCachedList($query);
00164             
00165             if ($list) {
00166                 if ($list === Cache::NOT_FOUND)
00167                     throw new ObjectNotFoundException();
00168                 else
00169                     return $list;
00170             } else {
00171                 if ($list = $this->fetchList($query))
00172                     return $this->cacheListByQuery($query, $list);
00173                 else {
00174                     $this->cacheListByQuery($query, Cache::NOT_FOUND);
00175                     throw new ObjectNotFoundException();
00176                 }
00177             }
00178             
00179             Assert::isUnreachable();
00180         }
00181         
00182         public function getListByLogic(LogicalObject $logic)
00183         {
00184             return $this->getListByQuery(
00185                 $this->dao->makeSelectHead()->andWhere($logic)
00186             );
00187         }
00188         
00189         public function getPlainList()
00190         {
00191             return $this->getListByQuery(
00192                 $this->dao->makeSelectHead()
00193             );
00194         }
00196 
00198 
00199         public function getCustomList(
00200             SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00201         )
00202         {
00203             $list = $this->getCachedByQuery($query);
00204             
00205             if ($list) {
00206                 if ($list === Cache::NOT_FOUND)
00207                     throw new ObjectNotFoundException();
00208                 else
00209                     return $list;
00210             } else {
00211                 $list = DBPool::getByDao($this->dao)->querySet($query);
00212                 
00213                 if ($list)
00214                     return $this->cacheByQuery($query, $list);
00215                 else {
00216                     $this->cacheByQuery($query, Cache::NOT_FOUND);
00217                     throw new ObjectNotFoundException();
00218                 }
00219             }
00220             
00221             Assert::isUnreachable();
00222         }
00223         
00224         public function getCustomRowList(
00225             SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00226         )
00227         {
00228             if ($query->getFieldsCount() !== 1)
00229                 throw new WrongArgumentException(
00230                     'you should select only one row when using this method'
00231                 );
00232             
00233             $list = $this->getCachedByQuery($query);
00234             
00235             if ($list) {
00236                 if ($list === Cache::NOT_FOUND)
00237                     throw new ObjectNotFoundException();
00238                 else
00239                     return $list;
00240             } else {
00241                 $list = DBPool::getByDao($this->dao)->queryColumn($query);
00242                 
00243                 if ($list)
00244                     return $this->cacheByQuery($query, $list);
00245                 else {
00246                     $this->cacheByQuery($query, Cache::NOT_FOUND);
00247                     throw new ObjectNotFoundException();
00248                 }
00249             }
00250             
00251             Assert::isUnreachable();
00252         }
00254         
00256 
00257         public function getCountedList(ObjectQuery $oq)
00258         {
00259             return $this->getQueryResult($oq->toSelectQuery($this->dao));
00260         }
00261         
00262         public function getQueryResult(SelectQuery $query)
00263         {
00264             $db = DBPool::getByDao($this->dao);
00265 
00266             $result = $this->getCachedByQuery($query);
00267             
00268             if ($result) {
00269                 return $result;
00270             } else {
00271                 $list = $this->fetchList($query);
00272                 
00273                 $count = clone $query;
00274                 
00275                 $count =
00276                     $db->queryRow(
00277                         $count->dropFields()->dropOrder()->limit(null, null)->
00278                         get(SQLFunction::create('COUNT', '*')->setAlias('count'))
00279                     );
00280                 
00281                 return
00282                     $this->cacheByQuery(
00283                         $query,
00284                         
00285                         QueryResult::create()->
00286                         setList($list)->
00287                         setCount($count['count'])->
00288                         setQuery($query)
00289                     );
00290             }
00291         }
00293 
00295 
00296         public function cacheById(Identifiable $object)
00297         {
00298             Cache::me()->mark($this->className)->
00299                 add(
00300                     $this->className.'_'.$object->getId(),
00301                     $object,
00302                     Cache::EXPIRES_FOREVER
00303                 );
00304             
00305             return $object;
00306         }
00308         
00310 
00311         public function uncacheById($id)
00312         {
00313             $this->dao->uncacheLists();
00314 
00315             return parent::uncacheById($id);
00316         }
00317         
00318         public function uncacheByIds($ids)
00319         {
00320             foreach ($ids as $id)
00321                 parent::uncacheById($id);
00322             
00323             return $this->dao->uncacheLists();
00324         }
00326         
00328 
00329         public function getCachedByQuery(SelectQuery $query)
00330         {
00331             return
00332                 $this->gentlyGetByKey(
00333                     $this->className.self::SUFFIX_QUERY.$query->getId()
00334                 );
00335         }
00336         
00337         protected function getCachedList(SelectQuery $query)
00338         {
00339             return
00340                 $this->gentlyGetByKey(
00341                     $this->className.self::SUFFIX_LIST.$query->getId()
00342                 );
00343         }
00344         
00345         protected function cacheNullById($id)
00346         {
00347             static $null = Cache::NOT_FOUND;
00348             
00349             return
00350                 Cache::me()->mark($this->className)->
00351                     add(
00352                         $this->className.'_'.$id,
00353                         $null,
00354                         Cache::EXPIRES_FOREVER
00355                     );
00356         }
00357         
00358         protected function keyToInt($key)
00359         {
00360             static $precision = null;
00361             
00362             if (!$precision) {
00363                 $precision = strlen(dechex(PHP_INT_MAX)) - 1;
00364             }
00365             
00366             return hexdec(substr(md5($key), 0, $precision)) + strlen($key);
00367         }
00369     }
00370 ?>

Generated on Sun Dec 9 21:56:23 2007 for onPHP by  doxygen 1.5.4