[Beeframework-svn] SF.net SVN: beeframework:[29] trunk/framework
Brought to you by:
b_hartmann,
m_plomer
From: <m_p...@us...> - 2013-05-07 07:25:52
|
Revision: 29 http://sourceforge.net/p/beeframework/code/29 Author: m_plomer Date: 2013-05-07 07:25:49 +0000 (Tue, 07 May 2013) Log Message: ----------- - intermediate commit Modified Paths: -------------- trunk/framework/Bee/Annotations/Utils.php trunk/framework/Bee/Framework.php trunk/framework/Bee/Persistence/Doctrine/DaoBase.php trunk/framework/Bee/Persistence/Pdo/Template.php trunk/framework/composer.json Added Paths: ----------- trunk/framework/Bee/Persistence/Behaviors/ trunk/framework/Bee/Persistence/Behaviors/Ordered/ trunk/framework/Bee/Persistence/Behaviors/Ordered/IDelegate.php trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php trunk/framework/Bee/Persistence/Doctrine2/ trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php trunk/framework/Bee/Persistence/Pdo/Behaviors/ trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php Modified: trunk/framework/Bee/Annotations/Utils.php =================================================================== --- trunk/framework/Bee/Annotations/Utils.php 2013-05-02 13:54:25 UTC (rev 28) +++ trunk/framework/Bee/Annotations/Utils.php 2013-05-07 07:25:49 UTC (rev 29) @@ -16,6 +16,7 @@ */ use Addendum\ReflectionAnnotatedClass; +use Addendum\ReflectionAnnotatedMethod; /** * User: mp * Date: Feb 19, 2010 @@ -56,5 +57,3 @@ return new ReflectionAnnotatedMethod($method->getDeclaringClass(), $method->getName()); } } - -?> \ No newline at end of file Modified: trunk/framework/Bee/Framework.php =================================================================== --- trunk/framework/Bee/Framework.php 2013-05-02 13:54:25 UTC (rev 28) +++ trunk/framework/Bee/Framework.php 2013-05-07 07:25:49 UTC (rev 29) @@ -338,6 +338,10 @@ return self::$productionMode; } + /** + * @param string $className + * @return Logger + */ public static function getLoggerForClass($className) { return Logger::getLogger(str_replace('_', '.', str_replace('\\', '.', $className))); } Added: trunk/framework/Bee/Persistence/Behaviors/Ordered/IDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/Ordered/IDelegate.php (rev 0) +++ trunk/framework/Bee/Persistence/Behaviors/Ordered/IDelegate.php 2013-05-07 07:25:49 UTC (rev 29) @@ -0,0 +1,54 @@ +<?php +namespace Bee\Persistence\Behaviors\Ordered; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 05.05.13 + * Time: 23:07 + */ +interface IDelegate { + + /** + * @param mixed $orderedEntity + * @param mixed $restriction + * @return int + */ + public function getPosition($orderedEntity, $restriction); + + /** + * @param mixed $orderedEntity + * @param mixed $restriction + * @return int + */ + public function getMaxPosition($orderedEntity, $restriction = false); + + /** + * @param mixed $orderedEntity + * @param int $newPos + * @param int $oldPos + * @param $restriction + */ + public function shiftPosition($orderedEntity, $newPos, $oldPos, $restriction); + + /** + * @param mixed $orderedEntity + * @param int $newPos + * @param mixed $restriction + */ + public function setPosition($orderedEntity, $newPos, $restriction); +} Added: trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php =================================================================== --- trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php (rev 0) +++ trunk/framework/Bee/Persistence/Behaviors/Ordered/Strategy.php 2013-05-07 07:25:49 UTC (rev 29) @@ -0,0 +1,87 @@ +<?php +namespace Bee\Persistence\Behaviors\Ordered; + + /* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 05.05.13 + * Time: 23:08 + */ +class Strategy { + + /** + * @var IDelegate + */ + private $delegate; + + /** + * @param mixed $subject + * @param mixed $ref + * @param mixed $groupRestriction + */ + public function moveBefore($subject, $ref, $groupRestriction = false) { + $this->moveRelative($subject, $ref, true, $groupRestriction); + } + + /** + * @param mixed $subject + * @param mixed $ref + * @param mixed $groupRestriction + */ + public function moveBehind($subject, $ref, $groupRestriction = false) { + $this->moveRelative($subject, $ref, false, $groupRestriction); + } + + /** + * @param mixed $subject + * @param mixed $ref + * @param bool $before + * @param mixed $groupRestriction + */ + public function moveRelative($subject, $ref, $before = true, $groupRestriction = false) { + // determine previous position of subject + $oldPos = $this->delegate->getPosition($subject, $groupRestriction); + + // is there a reference element given? + if ($ref) { + // yes, drop on the position following the referenced element (or on its position proper, in case the moved + // element preceded the reference element in the list + $newPos = $this->delegate->getPosition($ref, $groupRestriction); + + if (!$before && $oldPos > $newPos) { + $newPos += 1; + } else if ($before && $oldPos < $newPos) { + $newPos -= 1; + } + } else { + // no, "move behind nothing" means "move to beginning", "move before nothing" means "move to the end" + $newPos = $before ? $this->delegate->getMaxPosition($subject, $groupRestriction) + 1 : 0; + } + + // actual move? + if ($oldPos != $newPos) { + // temporarily move the subject to a neutral position, so as to avoid any conflicts (e.g. SQL constraints) + $this->delegate->setPosition($subject, -1, $groupRestriction); + // shift remaining entries (possibly including reference element) + $this->delegate->shiftPosition($subject, $newPos, $oldPos, $groupRestriction); + // set final position on subject + $this->delegate->setPosition($subject, $newPos, $groupRestriction); + } + // that's all, folks! + } +} Modified: trunk/framework/Bee/Persistence/Doctrine/DaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine/DaoBase.php 2013-05-02 13:54:25 UTC (rev 28) +++ trunk/framework/Bee/Persistence/Doctrine/DaoBase.php 2013-05-07 07:25:49 UTC (rev 29) @@ -112,11 +112,12 @@ } } - /** - * @param Doctrine_Query $query - * @param array $params - * @param Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder - */ + /** + * @param Doctrine_Query $query + * @param array $params + * @param Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder + * @param array $defaultOrderMapping + */ protected final function applyOrderAndLimit(Doctrine_Query &$query, array &$params, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping = array()) { if (is_null($orderAndLimitHolder)) { $orderMapping = $defaultOrderMapping; Added: trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php (rev 0) +++ trunk/framework/Bee/Persistence/Doctrine2/DaoBase.php 2013-05-07 07:25:49 UTC (rev 29) @@ -0,0 +1,32 @@ +<?php +namespace Bee\Persistence\Doctrine2; + +use \Doctrine\ORM\EntityManager; + +/** + * User: mp + * Date: 05.05.13 + * Time: 17:26 + */ +class DaoBase { + + /** + * @var EntityManager + */ + private $em; + + /** + * @return EntityManager + */ + public function getEm() { + return $this->em; + } + + /** + * @param EntityManager $em + */ + public function setEm(EntityManager $em) { + $this->em = $em; + } + +} Added: trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php (rev 0) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/DelegateBase.php 2013-05-07 07:25:49 UTC (rev 29) @@ -0,0 +1,72 @@ +<?php +namespace Bee\Persistence\Pdo\Behaviors; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use \PDOStatement; + +/** + * User: mp + * Date: 05.05.13 + * Time: 23:52 + */ +abstract class DelegateBase { + + /** + * @var \PDO + */ + private $pdo; + + /** + * @var string + */ + private $queryDomain; + + /** + * @param string $queryDomain + * @param \PDO $pdo + */ + public function __construct($queryDomain, \PDO $pdo) { + \Bee_Utils_Assert::hasText($queryDomain, 'Query domain (table name / table joins) required, must not be empty'); + $this->queryDomain = $queryDomain; + $this->pdo = $pdo; + } + + /** + * @return \PDO + */ + public function getPdo() { + return $this->pdo; + } + + /** + * @return string + */ + public function getQueryDomain() { + return $this->queryDomain; + } + + /** + * @param PDOStatement $qry + * @param array $params + * @return mixed + */ + public static function fetchOne(PDOStatement $qry, array $params) { + $qry->execute($params); + $res = $qry->fetch(\PDO::FETCH_NUM); + return $res [0]; + } +} Added: trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php (rev 0) +++ trunk/framework/Bee/Persistence/Pdo/Behaviors/GenericOrderedDelegate.php 2013-05-07 07:25:49 UTC (rev 29) @@ -0,0 +1,187 @@ +<?php +namespace Bee\Persistence\Pdo\Behaviors; + +use Bee\Persistence\Behaviors\Ordered\IDelegate; + +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * User: mp + * Date: 05.05.13 + * Time: 23:23 + */ +class GenericOrderedDelegate extends DelegateBase implements IDelegate { + + const GET_POS_QUERY_TEMPLATE = 'SELECT %1$s FROM %2$s WHERE %3$s AND %4$s'; + const MAX_POS_QUERY_TEMPLATE = 'SELECT MAX(%1$s) FROM %2$s WHERE %3$s'; + const GROUP_QUERY_TEMPLATE = 'SELECT %1$s FROM %2$s WHERE %3$s'; + const SHIFT_UP_QUERY_TEMPLATE = 'UPDATE %2$s SET %1$s = %1$s + 1 WHERE %1$s >= :newPos AND %1$s < :oldPos AND %3$s'; + const SHIFT_DOWN_QUERY_TEMPLATE = 'UPDATE %2$s SET %1$s = %1$s - 1 WHERE %1$s <= :newPos AND %1$s > :oldPos AND %3$s'; + const SET_POS_QUERY_TEMPLATE = 'UPDATE %2$s SET %1$s = :newPos WHERE %3$s AND %4$s'; + + /** + * @var string + */ + private $posExpression = 'pos'; + + /** + * @var string + */ + private $idFieldName = 'id'; + + /** + * @var string + */ + private $groupFieldName; + + /** + * @param string $posFieldName + */ + public function setPosExpression($posFieldName) { + $this->posExpression = $posFieldName; + } + + /** + * @return string + */ + public function getPosExpression() { + return $this->posExpression; + } + + /** + * @param string $idFieldName + */ + public function setIdFieldName($idFieldName) { + $this->idFieldName = $idFieldName; + } + + /** + * @return string + */ + public function getIdFieldName() { + return $this->idFieldName; + } + + /** + * @param string $domainFieldName + */ + public function setGroupFieldName($domainFieldName) { + $this->groupFieldName = $domainFieldName; + } + + /** + * @return string + */ + public function getGroupFieldName() { + return $this->groupFieldName; + } + + /** + * @param $orderedEntity + * @param array $params + * @param bool $restriction + * @return string + */ + protected function getDomainRestrictionString($orderedEntity, array &$params, $restriction = false) { + $result = '1=1'; + if ($this->getGroupFieldName()) { + if ($restriction === false) { + // determine group value + $grpParams = array(); + $qryString = sprintf(self::GROUP_QUERY_TEMPLATE, $this->getGroupFieldName(), $this->getQueryDomain(), $this->getIdentityRestrictionString($orderedEntity, $params)); + $restriction = self::fetchOne($this->getPdo()->prepare($qryString), $grpParams); + } + $result = $this->doCreateRestrictionString($params, $restriction); + } + return $result; + } + + /** + * @param array $params + * @param $restriction + * @return string + */ + protected function doCreateRestrictionString(array &$params, $restriction) { + $params[':group_id'] = $restriction; + return $this->getGroupFieldName() . ' = :group_id'; + } + + /** + * @param $orderedEntity object representing the entity to be manipulated. Default implementation assumes that this + * is the actual id as stored in the database + * @param array $params + * @return string + */ + protected function getIdentityRestrictionString($orderedEntity, array &$params) { + $params[':id'] = $orderedEntity; + return $this->getIdFieldName() . ' = :id'; + } + + /** + * @param $orderedEntity + * @param $restriction + * @return mixed + */ + public function getPosition($orderedEntity, $restriction = false) { + $params = array(); + $qryString = sprintf(self::GET_POS_QUERY_TEMPLATE, $this->getPosExpression(), $this->getQueryDomain(), + $this->getIdentityRestrictionString($orderedEntity, $params), $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); + return self::fetchOne($this->getPdo()->prepare($qryString), $params); + } + + /** + * @param $orderedEntity + * @param $restriction + * @return mixed + */ + public function getMaxPosition($orderedEntity, $restriction = false) { + $params = array(); + $qryString = sprintf(self::MAX_POS_QUERY_TEMPLATE, $this->getPosExpression(), $this->getQueryDomain(), + $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); + return self::fetchOne($this->getPdo()->prepare($qryString), $params); + } + + /** + * @param $orderedEntity + * @param int $newPos + * @param int $oldPos + * @param mixed $restriction + */ + public function shiftPosition($orderedEntity, $newPos, $oldPos, $restriction = false) { + $params = array(':newPos' => $newPos, ':oldPos' => $oldPos); + $qryDomain = $this->getQueryDomain(); + $qryString = sprintf($newPos < $oldPos ? self::SHIFT_UP_QUERY_TEMPLATE : self::SHIFT_DOWN_QUERY_TEMPLATE, + $this->getPosExpression(), $qryDomain, $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); + // if this is a single table update, add ORDER clause to avoid unique constraint violation + if (stripos($qryDomain, ' JOIN ') === false) { + $qryString .= ' ORDER BY ' . $this->getPosExpression() . ($newPos < $oldPos ? ' DESC' : ' ASC'); + } + $this->getPdo()->prepare($qryString)->execute($params); + } + + /** + * @param mixed $orderedEntity + * @param int $newPos + * @param mixed $restriction + */ + public function setPosition($orderedEntity, $newPos, $restriction) { + $params = array(':newPos' => $newPos); + $qryString = sprintf(self::SET_POS_QUERY_TEMPLATE, $this->getPosExpression(), $this->getQueryDomain(), + $this->getIdentityRestrictionString($orderedEntity, $params), $this->getDomainRestrictionString($orderedEntity, $params, $restriction)); + $this->getPdo()->prepare($qryString)->execute($params); + } +} Modified: trunk/framework/Bee/Persistence/Pdo/Template.php =================================================================== --- trunk/framework/Bee/Persistence/Pdo/Template.php 2013-05-02 13:54:25 UTC (rev 28) +++ trunk/framework/Bee/Persistence/Pdo/Template.php 2013-05-07 07:25:49 UTC (rev 29) @@ -28,6 +28,11 @@ */ private $pdoConnection; + /** + * @var Logger + */ + private static $log; + /** * Gets the PdoConnection * @@ -47,6 +52,16 @@ $this->pdoConnection = $pdoConnection; } + /** + * @return \Logger + */ + public static function getLog() { + if(!self::$log) { + self::$log = Bee_Framework::getLoggerForClass(__CLASS__); + } + return self::$log; + } + public function __construct(PDO $pdoConnection) { $this->pdoConnection = $pdoConnection; } @@ -90,7 +105,7 @@ Bee_Persistence_Pdo_IResultSetExtractor $rse) { Bee_Utils_Assert::notNull($rse, 'ResultSetExtractor must not be null'); - Bee_Utils_Logger::debug('Executing prepared SQL query'); + self::getLog()->debug('Executing prepared SQL query'); return $this->execute($psc, new Bee_Persistence_Pdo_Template_QueryCallback($pss, $rse)); } @@ -104,7 +119,7 @@ } public function update(Bee_Persistence_Pdo_IStatementCreator $psc, Bee_Persistence_Pdo_IStatementSetter $pss) { - Bee_Utils_Logger::debug('Executing prepared SQL update'); + self::getLog()->debug('Executing prepared SQL update'); return $this->execute($psc, new Bee_Persistence_Pdo_Template_UpdateCallback($pss)); } @@ -113,7 +128,7 @@ } public function batchUpdate(Bee_Persistence_Pdo_IStatementCreator $psc, Bee_Persistence_Pdo_IBatchStatementSetter $bss) { - Bee_Utils_Logger::debug('Executing prepared SQL batch update'); + self::getLog()->debug('Executing prepared SQL batch update'); return $this->execute($psc, new Bee_Persistence_Pdo_Template_BatchUpdateCallback($bss)); } @@ -126,9 +141,9 @@ Bee_Utils_Assert::notNull($psc, 'PreparedStatementCreator must not be null'); Bee_Utils_Assert::notNull($action, 'Callback object must not be null'); - if (Bee_Utils_Logger::isDebugEnabled()) { + if (self::getLog()->isDebugEnabled()) { $sql = self::getSql($psc); - Bee_Utils_Logger::debug('Executing prepared SQL statement' . (!is_null($sql) ? " [" . $sql . "]" : "")); + self::getLog()->debug('Executing prepared SQL statement' . (!is_null($sql) ? " [" . $sql . "]" : "")); } $ps = null; @@ -197,18 +212,30 @@ */ private $pss; + /** + * @var Logger + */ + private static $log; + public function __construct(Bee_Persistence_Pdo_IStatementSetter $pss) { $this->pss = $pss; } + public static function getLog() { + if(!self::$log) { + self::$log = Bee_Framework::getLoggerForClass(__CLASS__); + } + return self::$log; + } + function doInPreparedStatement(PDOStatement $ps) { if ($this->pss != null) { $this->pss->setValues($ps); } if($ps->execute()) { $rows = $ps->rowCount(); - if(Bee_Utils_Logger::isDebugEnabled()) { - Bee_Utils_Logger::debug('SQL update affected '.$rows.' rows'); + if(self::getLog()->isDebugEnabled()) { + self::getLog()->debug('SQL update affected '.$rows.' rows'); } return $rows; } Modified: trunk/framework/composer.json =================================================================== --- trunk/framework/composer.json 2013-05-02 13:54:25 UTC (rev 28) +++ trunk/framework/composer.json 2013-05-07 07:25:49 UTC (rev 29) @@ -15,7 +15,7 @@ } ], "require": { - "php": ">=5.2.3", + "php": ">=5.3", "niktux/addendum": "0.4.1", "apache/log4php": "2.3.0" }, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |