00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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 ?>