StorableDAO.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2005-2008 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 
00015     abstract class StorableDAO extends ProtoDAO
00016     {
00017         public function take(Identifiable $object)
00018         {
00019             return
00020                 $object->getId()
00021                     ? $this->merge($object, true)
00022                     : $this->add($object);
00023         }
00024         
00025         public function add(Identifiable $object)
00026         {
00027             return
00028                 $this->inject(
00029                     OSQL::insert(),
00030                     $object->setId(
00031                         DBPool::getByDao($this)->obtainSequence(
00032                             $this->getSequence()
00033                         )
00034                     )
00035                 );
00036         }
00037         
00038         public function save(Identifiable $object)
00039         {
00040             return
00041                 $this->inject(
00042                     $this->targetizeUpdateQuery(OSQL::update(), $object),
00043                     $object
00044                 );
00045         }
00046         
00047         public function import(Identifiable $object)
00048         {
00049             return
00050                 $this->inject(
00051                     OSQL::insert(),
00052                     $object
00053                 );
00054         }
00055         
00056         public function merge(Identifiable $object, $cacheOnly = true)
00057         {
00058             Assert::isNotNull($object->getId());
00059             
00060             $this->checkObjectType($object);
00061             
00062             $old = Cache::worker($this)->getCachedById($object->getId());
00063             
00064             if (!$old) { // unlikely
00065                 if ($cacheOnly)
00066                     return $this->save($object);
00067                 else
00068                     $old = Cache::worker($this)->getById($object->getId());
00069             }
00070             
00071             return $this->unite($object, $old);
00072         }
00073         
00074         public function unite(
00075             Identifiable $object, Identifiable $old
00076         )
00077         {
00078             Assert::isNotNull($object->getId());
00079             
00080             Assert::isTypelessEqual(
00081                 $object->getId(), $old->getId(),
00082                 'cannot merge different objects'
00083             );
00084             
00085             $query = OSQL::update($this->getTable());
00086             
00087             foreach ($this->getProtoClass()->getPropertyList() as $property) {
00088                 $getter = $property->getGetter();
00089                 
00090                 if ($property->getClassName() === null) {
00091                     $changed = ($old->$getter() !== $object->$getter());
00092                 } else {
00097                     $changed =
00098                         ($old->$getter() !== $object->$getter())
00099                         || ($old->$getter() != $object->$getter());
00100                 }
00101                 
00102                 if ($changed)
00103                     $property->fillQuery($query, $object);
00104             }
00105             
00106             if (!$query->getFieldsCount())
00107                 return $object;
00108             
00109             $this->targetizeUpdateQuery($query, $object);
00110             
00111             return $this->doInject($query, $object);
00112         }
00113         
00117         private function targetizeUpdateQuery(
00118             UpdateQuery $query,
00119             Identifiable $object
00120         )
00121         {
00122             return $query->where(Expression::eqId($this->getIdName(), $object));
00123         }
00124     }
00125 ?>