00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00019 class CommonDaoWorker extends BaseDaoWorker
00020 {
00022
00023 public function getById($id, $expires = Cache::EXPIRES_MEDIUM)
00024 {
00025 if (
00026 ($expires !== Cache::DO_NOT_CACHE)
00027 && ($object = $this->getCachedById($id))
00028 ) {
00029 if ($object === Cache::NOT_FOUND)
00030 throw new CachedObjectNotFoundException();
00031
00032 return $this->dao->completeObject($object);
00033 } else {
00034 $query =
00035 $this->dao->
00036 makeSelectHead()->
00037 andWhere(
00038 Expression::eq(
00039 DBField::create(
00040 $this->dao->getIdName(),
00041 $this->dao->getTable()
00042 ),
00043 $id
00044 )
00045 );
00046
00047 if ($expires === Cache::DO_NOT_CACHE) {
00048 $object = $this->fetchObject($query);
00049 } else {
00050 $object = $this->cachedFetchObject($query, $expires, true);
00051 }
00052
00053 if ($object) {
00054 return $object;
00055 } else {
00056 throw new ObjectNotFoundException(
00057 "there is no such object for '".$this->dao->getObjectName()
00058 .(
00059 defined('__LOCAL_DEBUG__')
00060 ?
00061 "' with query == "
00062 .$query->toDialectString(
00063 DBPool::me()->getByDao($this->dao)->
00064 getDialect()
00065 )
00066 : null
00067 )
00068 );
00069 }
00070 }
00071 }
00072
00073 public function getByLogic(
00074 LogicalObject $logic, $expires = Cache::DO_NOT_CACHE
00075 )
00076 {
00077 return
00078 $this->getByQuery(
00079 $this->dao->makeSelectHead()->andWhere($logic), $expires
00080 );
00081 }
00082
00083 public function getByQuery(
00084 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00085 )
00086 {
00087 if (
00088 ($expires !== Cache::DO_NOT_CACHE)
00089 && ($object = $this->getCachedByQuery($query))
00090 ) {
00091 if ($object === Cache::NOT_FOUND)
00092 throw new CachedObjectNotFoundException();
00093
00094 return $this->dao->completeObject($object);
00095 } else {
00096 if ($expires === Cache::DO_NOT_CACHE)
00097 $object = $this->fetchObject($query);
00098 else
00099 $object = $this->cachedFetchObject($query, $expires, false);
00100
00101 if ($object)
00102 return $object;
00103 else
00104 throw new ObjectNotFoundException(
00105 "there is no such object for '".$this->dao->getObjectName()
00106 .(
00107 defined('__LOCAL_DEBUG__')
00108 ?
00109 "' with query == "
00110 .$query->toDialectString(
00111 DBPool::me()->getByDao($this->dao)->
00112 getDialect()
00113 )
00114 : null
00115 )
00116 );
00117 }
00118 }
00119
00120 public function getCustom(
00121 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00122 )
00123 {
00124 if ($query->getLimit() > 1)
00125 throw new WrongArgumentException(
00126 'can not handle non-single row queries'
00127 );
00128
00129 $db = DBPool::getByDao($this->dao);
00130
00131 if (
00132 ($expires !== Cache::DO_NOT_CACHE)
00133 && ($object = $this->getCachedByQuery($query))
00134 ) {
00135 if ($object === Cache::NOT_FOUND)
00136 throw new CachedObjectNotFoundException();
00137
00138 return $object;
00139
00140 } elseif ($object = $db->queryRow($query)) {
00141 if ($expires === Cache::DO_NOT_CACHE)
00142 return $object;
00143 else
00144 return $this->cacheByQuery($query, $object, $expires);
00145 } else {
00146 throw new ObjectNotFoundException(
00147 "zero"
00148 .(
00149 defined('__LOCAL_DEBUG__')
00150 ?
00151 "for query == "
00152 .$query->toDialectString(
00153 DBPool::me()->getByDao($this->dao)->
00154 getDialect()
00155 )
00156 : null
00157 )
00158 );
00159 }
00160 }
00162
00164
00165 public function getListByIds(
00166 array $ids,
00167 $expires = Cache::EXPIRES_MEDIUM
00168 )
00169 {
00170 $list = array();
00171
00172
00173 $ids = array_unique($ids);
00174
00175 if ($expires !== Cache::DO_NOT_CACHE) {
00176 $toFetch = array();
00177 $prefixed = array();
00178
00179 foreach ($ids as $id)
00180 $prefixed[$id] = $this->makeIdKey($id);
00181
00182 if (
00183 $cachedList
00184 = Cache::me()->mark($this->className)->getList($prefixed)
00185 ) {
00186 $proto = $this->dao->getProtoClass();
00187
00188 $proto->beginPrefetch();
00189
00190 foreach ($cachedList as $cached) {
00191 if ($cached && ($cached !== Cache::NOT_FOUND)) {
00192 $list[] = $this->dao->completeObject($cached);
00193
00194 unset($prefixed[$cached->getId()]);
00195 }
00196 }
00197
00198 $proto->endPrefetch($list);
00199 }
00200
00201 $toFetch += array_keys($prefixed);
00202
00203 if ($toFetch) {
00204 try {
00205 $list =
00206 array_merge(
00207 $list,
00208 $this->getListByLogic(
00209 Expression::in(
00210 new DBField(
00211 $this->dao->getIdName(),
00212 $this->dao->getTable()
00213 ),
00214 $toFetch
00215 ),
00216 Cache::DO_NOT_CACHE
00217 )
00218 );
00219 } catch (ObjectNotFoundException $e) {
00220
00221 }
00222 }
00223 } elseif (count($ids)) {
00224 try {
00225 $list =
00226 $this->getListByLogic(
00227 Expression::in(
00228 new DBField(
00229 $this->dao->getIdName(),
00230 $this->dao->getTable()
00231 ),
00232 $ids
00233 ),
00234 Cache::DO_NOT_CACHE
00235 );
00236 } catch (ObjectNotFoundException $e) {}
00237 }
00238
00239 return $list;
00240 }
00241
00242 public function getListByQuery(
00243 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00244 )
00245 {
00246 if (
00247 ($expires !== Cache::DO_NOT_CACHE)
00248 && ($list = $this->getCachedByQuery($query))
00249 ) {
00250 if ($list === Cache::NOT_FOUND)
00251 throw new CachedObjectNotFoundException();
00252
00253 return $list;
00254 } elseif ($list = $this->fetchList($query)) {
00255 if (Cache::DO_NOT_CACHE === $expires) {
00256 return $list;
00257 } else {
00258 return $this->cacheByQuery($query, $list, $expires);
00259 }
00260 } else {
00261 throw new ObjectNotFoundException(
00262 "empty list"
00263 .(
00264 defined('__LOCAL_DEBUG__')
00265 ?
00266 " for such query - "
00267 .$query->toDialectString(
00268 DBPool::me()->getByDao($this->dao)->
00269 getDialect()
00270 )
00271 : null
00272 )
00273 );
00274 }
00275 }
00276
00277 public function getListByLogic(
00278 LogicalObject $logic, $expires = Cache::DO_NOT_CACHE
00279 )
00280 {
00281 return
00282 $this->getListByQuery(
00283 $this->dao->makeSelectHead()->andWhere($logic), $expires
00284 );
00285 }
00286
00287 public function getPlainList($expires = Cache::EXPIRES_MEDIUM)
00288 {
00289 return $this->getListByQuery(
00290 $this->dao->makeSelectHead(), $expires
00291 );
00292 }
00293
00294 public function getTotalCount($expires = Cache::DO_NOT_CACHE)
00295 {
00296 $count = $this->getCustom(
00297 $this->dao->makeTotalCountQuery(), $expires
00298 );
00299
00300 return current($count);
00301 }
00303
00305
00306 public function getCustomList(
00307 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00308 )
00309 {
00310 if (
00311 ($expires !== Cache::DO_NOT_CACHE)
00312 && ($list = $this->getCachedByQuery($query))
00313 ) {
00314 if ($list === Cache::NOT_FOUND)
00315 throw new CachedObjectNotFoundException();
00316
00317 return $list;
00318 } elseif ($list = DBPool::getByDao($this->dao)->querySet($query)) {
00319 if (Cache::DO_NOT_CACHE === $expires) {
00320 return $list;
00321 } else {
00322 return $this->cacheByQuery($query, $list, $expires);
00323 }
00324 } else {
00325 throw new ObjectNotFoundException(
00326 "empty list"
00327 .(
00328 defined('__LOCAL_DEBUG__')
00329 ?
00330 " for such query - "
00331 .$query->toDialectString(
00332 DBPool::me()->getByDao($this->dao)->
00333 getDialect()
00334 )
00335 : null
00336 )
00337 );
00338 }
00339 }
00340
00341 public function getCustomRowList(
00342 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00343 )
00344 {
00345 if ($query->getFieldsCount() !== 1)
00346 throw new WrongArgumentException(
00347 'you should select only one row when using this method'
00348 );
00349
00350 if (
00351 ($expires !== Cache::DO_NOT_CACHE)
00352 && ($list = $this->getCachedByQuery($query))
00353 ) {
00354 if ($list === Cache::NOT_FOUND)
00355 throw new CachedObjectNotFoundException();
00356
00357 return $list;
00358 } elseif ($list = DBPool::getByDao($this->dao)->queryColumn($query)) {
00359 if (Cache::DO_NOT_CACHE === $expires) {
00360 return $list;
00361 } else {
00362 return $this->cacheByQuery($query, $list, $expires);
00363 }
00364 } else {
00365 throw new ObjectNotFoundException(
00366 "empty list"
00367 .(
00368 defined('__LOCAL_DEBUG__')
00369 ?
00370 " for such query - "
00371 .$query->toDialectString(
00372 DBPool::me()->getByDao($this->dao)->
00373 getDialect()
00374 )
00375 : null
00376 )
00377 );
00378 }
00379 }
00381
00383
00384 public function getQueryResult(
00385 SelectQuery $query, $expires = Cache::DO_NOT_CACHE
00386 )
00387 {
00388 if (
00389 ($expires !== Cache::DO_NOT_CACHE)
00390 && ($list = $this->getCachedByQuery($query))
00391 ) {
00392 return $list;
00393 } else {
00394 $list = $this->fetchList($query);
00395
00396 $count = clone $query;
00397
00398 $count =
00399 DBPool::getByDao($this->dao)->queryRow(
00400 $count->dropFields()->dropOrder()->limit(null, null)->
00401 get(SQLFunction::create('COUNT', '*')->setAlias('count'))
00402 );
00403
00404 return
00405 $this->cacheByQuery(
00406 $query,
00407
00408 $list
00409 ?
00410 QueryResult::create()->
00411 setList($list)->
00412 setCount($count['count'])->
00413 setQuery($query)
00414 :
00415 QueryResult::create(),
00416
00417 $expires
00418 );
00419 }
00420 }
00422
00424
00425 protected function cacheById(
00426 Identifiable $object, $expires = Cache::EXPIRES_MEDIUM
00427 )
00428 {
00429 if ($expires !== Cache::DO_NOT_CACHE) {
00430
00431 Cache::me()->mark($this->className)->
00432 add(
00433 $this->makeIdKey($object->getId()),
00434 $object,
00435 $expires
00436 );
00437 }
00438
00439 return $object;
00440 }
00441
00442 protected function cacheByQuery(
00443 SelectQuery $query,
00444 $object,
00445 $expires = Cache::DO_NOT_CACHE
00446 )
00447 {
00448 if ($expires !== Cache::DO_NOT_CACHE) {
00449
00450 Cache::me()->mark($this->className)->
00451 add(
00452 $this->makeQueryKey($query, self::SUFFIX_QUERY),
00453 $object,
00454 $expires
00455 );
00456 }
00457
00458 return $object;
00459 }
00460
00461 protected function cacheListByQuery(
00462 SelectQuery $query,
00463 $array
00464 )
00465 {
00466 throw new UnimplementedFeatureException();
00467 }
00469
00471
00472 public function dropById($id)
00473 {
00474 $result = parent::dropById($id);
00475
00476 $this->dao->uncacheLists();
00477
00478 return $result;
00479 }
00481
00483
00484 public function uncacheById($id)
00485 {
00486 $this->dao->uncacheLists();
00487
00488 return parent::uncacheById($id);
00489 }
00490
00491 public function uncacheByIds($ids)
00492 {
00493 foreach ($ids as $id)
00494 parent::uncacheById($id);
00495
00496 return $this->dao->uncacheLists();
00497 }
00498
00499
00500 public function uncacheLists()
00501 {
00502
00503 return $this->uncacheByQuery($this->dao->makeSelectHead());
00504 }
00506 }
00507 ?>