Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00015 class CustomizableDaoSynchronizer
00016 {
00017 protected $dryRun = false;
00018 protected $reallyDelete = false;
00019
00020 protected $master = null;
00021 protected $slave = null;
00022
00023 private $masterProjection = null;
00024 private $slaveProjection = null;
00025
00026 private $masterKeyProperty = 'id';
00027 private $slaveKeyProperty = 'id';
00028
00029 private $totalUpdated = 0;
00030 private $totalInserted = 0;
00031 private $totalDeleted = 0;
00032
00036 public static function create()
00037 {
00038 return new self;
00039 }
00040
00044 public function setDryRun($dryRun)
00045 {
00046 $this->dryRun = $dryRun;
00047
00048 return $this;
00049 }
00050
00051 public function isDryRun()
00052 {
00053 return $this->dryRun;
00054 }
00055
00059 public function setReallyDelete($reallyDelete)
00060 {
00061 $this->reallyDelete = $reallyDelete;
00062
00063 return $this;
00064 }
00065
00066 public function isReallyDelete()
00067 {
00068 return $this->reallyDelete;
00069 }
00070
00074 public function setMaster(GenericDAO $master)
00075 {
00076 $this->master = $master;
00077
00078 return $this;
00079 }
00080
00084 public function getMaster()
00085 {
00086 return $this->master;
00087 }
00088
00092 public function setSlave(GenericDAO $slave)
00093 {
00094 $this->slave = $slave;
00095
00096 return $this;
00097 }
00098
00102 public function getSlave()
00103 {
00104 return $this->slave;
00105 }
00106
00110 public function setMasterKeyProperty($masterKeyProperty)
00111 {
00112 $this->masterKeyProperty = $masterKeyProperty;
00113
00114 return $this;
00115 }
00116
00117 public function getMasterKeyProperty()
00118 {
00119 return $this->masterKeyProperty;
00120 }
00121
00125 public function setSlaveKeyProperty($slaveKeyProperty)
00126 {
00127 $this->slaveKeyProperty = $slaveKeyProperty;
00128
00129 return $this;
00130 }
00131
00132 public function getSlaveKeyProperty()
00133 {
00134 return $this->slaveKeyProperty;
00135 }
00136
00140 public function setMasterProjection(ObjectProjection $masterProjection)
00141 {
00142 $this->masterProjection = $masterProjection;
00143
00144 return $this;
00145 }
00146
00150 public function getMasterProjection()
00151 {
00152 return $this->masterProjection;
00153 }
00154
00158 public function setSlaveProjection(ObjectProjection $slaveProjection)
00159 {
00160 $this->slaveProjection = $slaveProjection;
00161
00162 return $this;
00163 }
00164
00168 public function getSlaveProjection()
00169 {
00170 return $this->slaveProjection;
00171 }
00172
00176 public function run()
00177 {
00178 $masterIterator = new DaoIterator();
00179 $slaveIterator = new DaoIterator();
00180
00181 $masterIterator->setDao($this->master);
00182 $slaveIterator->setDao($this->slave);
00183
00184 if ($this->masterKeyProperty)
00185 $masterIterator->setKeyProperty($this->masterKeyProperty);
00186
00187 if ($this->slaveKeyProperty)
00188 $slaveIterator->setKeyProperty($this->slaveKeyProperty);
00189
00190 if ($this->masterProjection)
00191 $masterIterator->setProjection($this->masterProjection);
00192
00193 if ($this->slaveProjection)
00194 $slaveIterator->setProjection($this->slaveProjection);
00195
00196 $this->totalDeleted = 0;
00197 $this->totalInserted = 0;
00198 $this->totalUpdated = 0;
00199
00200 while ($masterIterator->valid() || $slaveIterator->valid()) {
00201 $masterObject = $masterIterator->current();
00202 $slaveObject = $slaveIterator->current();
00203
00204 $masterObject = $this->convertMasterObjectToSlave($masterObject);
00205
00206 $masterGetter = 'get'.ucfirst($this->masterKeyProperty);
00207 $slaveGetter = 'get'.ucfirst($this->slaveKeyProperty);
00208
00209 if (
00210 $masterObject && $slaveObject
00211 && (
00212 $masterObject->$masterGetter()
00213 == $slaveObject->$slaveGetter()
00214 )
00215 ) {
00216 if ($this->sync($slaveObject, $masterObject))
00217 $this->totalUpdated++;
00218
00219 $masterIterator->next();
00220 $slaveIterator->next();
00221 } elseif (
00222 !$masterObject
00223 || (
00224 $slaveObject
00225 && $this->compareKeys(
00226 $masterObject->$masterGetter(),
00227 $slaveObject->$slaveGetter()
00228 ) > 0
00229 )
00230 ) {
00231 if ($this->delete($slaveObject))
00232 $this->totalDeleted++;
00233
00234 $slaveIterator->next();
00235 } elseif (
00236 !$slaveObject
00237 || (
00238 $masterObject
00239 && $this->compareKeys(
00240 $masterObject->$masterGetter(),
00241 $slaveObject->$slaveGetter()
00242 ) < 0
00243 )
00244 ) {
00245 if ($this->insert($masterObject))
00246 $this->totalInserted++;
00247
00248 $masterIterator->next();
00249
00250 } else {
00251 Assert::isUnreachable('how did you get here?');
00252 }
00253 }
00254
00255 return $this;
00256 }
00257
00258 public function getTotalInserted()
00259 {
00260 return $this->totalInserted;
00261 }
00262
00263 public function getTotalDeleted()
00264 {
00265 return $this->totalDeleted;
00266 }
00267
00268 public function getTotalUpdated()
00269 {
00270 return $this->totalUpdated;
00271 }
00272
00273 protected function sync($old, $object)
00274 {
00275 if (!$this->dryRun)
00276 $this->slave->merge($object);
00277
00278 return true;
00279 }
00280
00281 protected function delete($slaveObject)
00282 {
00283 $slaveGetter = 'get'.ucfirst($this->slaveKeyProperty);
00284
00285 Assert::methodExists($slaveObject, $slaveGetter);
00286
00287 if (!$this->dryRun && $this->reallyDelete)
00288 $this->slave->dropById($slaveObject->$slaveGetter());
00289
00290 return true;
00291 }
00292
00293 protected function insert($masterObject)
00294 {
00295 if (!$this->dryRun)
00296 $this->slave->import($masterObject);
00297
00298 return true;
00299 }
00300
00301 protected function compareKeys($min, $sub)
00302 {
00303 if ($min > $sub)
00304 return 1;
00305 elseif ($min < $sub)
00306 return -1;
00307
00308 return 0;
00309 }
00310
00311 private function convertMasterObjectToSlave($masterObject)
00312 {
00313 if (
00314 $masterObject
00315 && (
00316 call_user_func(
00317 array($this->slave->getObjectName(), 'create')
00318 )
00319 instanceof SynchronizableObject
00320 )
00321 )
00322 $masterObject = call_user_func(
00323 array(
00324 $this->slave->getObjectName(),
00325 'createFromMasterObject'
00326 ),
00327 $masterObject
00328 );
00329
00330 return $masterObject;
00331 }
00332 }
00333 ?>