Revision: 270
http://sourceforge.net/p/beeframework/code/270
Author: m_plomer
Date: 2014-10-31 07:35:38 +0000 (Fri, 31 Oct 2014)
Log Message:
-----------
- backport of proper Doctrine2 pagination from trunk
Modified Paths:
--------------
branches/0.9-dev/framework/Bee/Persistence/Doctrine/DaoBase.php
branches/0.9-dev/framework/Bee/Persistence/Doctrine2/DaoBase.php
branches/0.9-dev/framework/Bee/Persistence/Doctrine2/EntityManagerHolder.php
branches/0.9-dev/framework/Bee/Persistence/IOrderAndLimitHolder.php
Added Paths:
-----------
branches/0.9-dev/framework/Bee/Persistence/PaginationBase.php
Modified: branches/0.9-dev/framework/Bee/Persistence/Doctrine/DaoBase.php
===================================================================
--- branches/0.9-dev/framework/Bee/Persistence/Doctrine/DaoBase.php 2014-10-31 07:15:22 UTC (rev 269)
+++ branches/0.9-dev/framework/Bee/Persistence/Doctrine/DaoBase.php 2014-10-31 07:35:38 UTC (rev 270)
@@ -1,6 +1,6 @@
<?php
/*
- * Copyright 2008-2010 the original author or authors.
+ * Copyright 2008-2014 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.
@@ -141,7 +141,6 @@
}
foreach ($orderMapping as $orderField => $orderDir) {
-// $query->orderBy($orderField.' '.$orderDir);
$query->addOrderBy($orderField . ' ' . $orderDir);
}
@@ -151,13 +150,7 @@
if ($orderAndLimitHolder->getPageSize() > 0) {
$query->limit($orderAndLimitHolder->getPageSize());
-
- $pageCount = ceil($query->count($params) / $orderAndLimitHolder->getPageSize());
- $orderAndLimitHolder->setPageCount($pageCount);
-
- if ($orderAndLimitHolder->getCurrentPage() > $pageCount) {
- $orderAndLimitHolder->setCurrentPage($pageCount);
- }
+ $orderAndLimitHolder->setResultCount($query->count($params));
$query->offset($orderAndLimitHolder->getCurrentPage() * $orderAndLimitHolder->getPageSize());
}
}
Modified: branches/0.9-dev/framework/Bee/Persistence/Doctrine2/DaoBase.php
===================================================================
--- branches/0.9-dev/framework/Bee/Persistence/Doctrine2/DaoBase.php 2014-10-31 07:15:22 UTC (rev 269)
+++ branches/0.9-dev/framework/Bee/Persistence/Doctrine2/DaoBase.php 2014-10-31 07:35:38 UTC (rev 270)
@@ -1,12 +1,28 @@
<?php
namespace Bee\Persistence\Doctrine2;
+
+/*
+ * Copyright 2008-2014 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 Bee_Persistence_IOrderAndLimitHolder;
use Bee_Persistence_IRestrictionHolder;
use Bee_Utils_Strings;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
+use Doctrine\ORM\Tools\Pagination\Paginator;
use Exception;
-use Logger;
/**
* User: mp
@@ -16,21 +32,6 @@
class DaoBase extends EntityManagerHolder {
/**
- * @var Logger
- */
- protected $log;
-
- /**
- * @return Logger
- */
- protected function getLog() {
- if (!$this->log) {
- $this->log = Logger::getLogger(get_class($this));
- }
- return $this->log;
- }
-
- /**
* @param QueryBuilder $queryBuilder
* @param Bee_Persistence_IRestrictionHolder $restrictionHolder
* @param Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder
@@ -38,11 +39,15 @@
* @param null $hydrationMode
* @return array
*/
- public function executeListQuery(QueryBuilder $queryBuilder, Bee_Persistence_IRestrictionHolder $restrictionHolder = null, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping, $hydrationMode = null) {
- $this->applyFilterRestrictions($queryBuilder, $restrictionHolder);
- $this->applyOrderAndLimit($queryBuilder, $orderAndLimitHolder, $defaultOrderMapping);
- return $this->getQueryFromBuilder($queryBuilder)->execute(null, $hydrationMode);
- }
+ public function executeListQuery(QueryBuilder $queryBuilder, Bee_Persistence_IRestrictionHolder $restrictionHolder = null, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping, $hydrationMode = null) {
+ $this->applyFilterRestrictions($queryBuilder, $restrictionHolder);
+ $this->applyOrderMapping($queryBuilder, $orderAndLimitHolder, $defaultOrderMapping);
+ $q = $this->getQueryFromBuilder($queryBuilder);
+ if(!is_null($hydrationMode)) {
+ $q->setHydrationMode($hydrationMode);
+ }
+ return $this->getPaginatedOrderedResultFromQuery($q, $orderAndLimitHolder);
+ }
/**
* @param QueryBuilder $qb
@@ -57,81 +62,68 @@
* @param Bee_Persistence_IRestrictionHolder $restrictionHolder
* @internal param QueryBuilder $query
*/
- protected final function applyFilterRestrictions(QueryBuilder &$queryBuilder, Bee_Persistence_IRestrictionHolder $restrictionHolder = null) {
- if (is_null($restrictionHolder)) {
- return;
- }
+ protected final function applyFilterRestrictions(QueryBuilder &$queryBuilder, Bee_Persistence_IRestrictionHolder $restrictionHolder = null) {
+ if (is_null($restrictionHolder)) {
+ return;
+ }
- if (!Bee_Utils_Strings::hasText($restrictionHolder->getFilterString())) {
- return;
- }
+ if (!Bee_Utils_Strings::hasText($restrictionHolder->getFilterString())) {
+ return;
+ }
- $filterTokens = Bee_Utils_Strings::tokenizeToArray($restrictionHolder->getFilterString(), ' ');
- foreach ($filterTokens as $no => $token) {
- $andWhereString = '';
- $params = array();
+ $filterTokens = Bee_Utils_Strings::tokenizeToArray($restrictionHolder->getFilterString(), ' ');
+ foreach ($filterTokens as $no => $token) {
+ $andWhereString = '';
+ $params = array();
- $tokenName = 'filtertoken'.$no;
- $params[$tokenName] = '%'.$token.'%';
+ $tokenName = 'filtertoken' . $no;
+ $params[$tokenName] = '%' . $token . '%';
- foreach ($restrictionHolder->getFilterableFields() as $fieldName) {
- // $fieldName MUST BE A DOCTRINE NAME
- if (Bee_Utils_Strings::hasText($andWhereString)) {
- $andWhereString .= ' OR ';
- }
+ foreach ($restrictionHolder->getFilterableFields() as $fieldName) {
+ // $fieldName MUST BE A DOCTRINE NAME
+ if (Bee_Utils_Strings::hasText($andWhereString)) {
+ $andWhereString .= ' OR ';
+ }
- $andWhereString .= $fieldName.' LIKE :'.$tokenName;
- }
+ $andWhereString .= $fieldName . ' LIKE :' . $tokenName;
+ }
- if (Bee_Utils_Strings::hasText($andWhereString)) {
- $queryBuilder->andWhere($andWhereString);
+ if (Bee_Utils_Strings::hasText($andWhereString)) {
+ $queryBuilder->andWhere($andWhereString);
- foreach ($params as $key => $value) {
- $queryBuilder->setParameter($key, $value);
- }
- }
- }
- }
+ foreach ($params as $key => $value) {
+ $queryBuilder->setParameter($key, $value);
+ }
+ }
+ }
+ }
/**
* @param QueryBuilder $queryBuilder
* @param Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder
* @param array $defaultOrderMapping
*/
- protected final function applyOrderAndLimit(QueryBuilder &$queryBuilder, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping = array()) {
- if (is_null($orderAndLimitHolder)) {
- $orderMapping = $defaultOrderMapping;
- } else {
- $orderMapping = count($orderAndLimitHolder->getOrderMapping()) > 0 ? $orderAndLimitHolder->getOrderMapping() : $defaultOrderMapping;
- }
+ protected final function applyOrderMapping(QueryBuilder &$queryBuilder, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null, array $defaultOrderMapping = null) {
+ if (is_null($defaultOrderMapping)) {
+ $defaultOrderMapping = array();
+ }
+ if (is_null($orderAndLimitHolder)) {
+ $orderMapping = $defaultOrderMapping;
+ } else {
+ $orderMapping = count($orderAndLimitHolder->getOrderMapping()) > 0 ? $orderAndLimitHolder->getOrderMapping() : $defaultOrderMapping;
+ }
- foreach ($orderMapping as $orderField => $orderDir) {
- $queryBuilder->addOrderBy($orderField, $orderDir);
- }
+ foreach ($orderMapping as $orderField => $orderDir) {
+ $queryBuilder->addOrderBy($orderField, $orderDir);
+ }
+ }
- if (is_null($orderAndLimitHolder)) {
- return;
- }
-
- if ($orderAndLimitHolder->getPageSize() > 0) {
- $queryBuilder->setMaxResults($orderAndLimitHolder->getPageSize());
-
- // TODO: build a performant count-query! This is simply bullshit!
- $pageCount = ceil(count($this->getQueryFromBuilder($queryBuilder)->execute()) / $orderAndLimitHolder->getPageSize());
- $orderAndLimitHolder->setPageCount($pageCount);
-
- if ($orderAndLimitHolder->getCurrentPage() > $pageCount) {
- $orderAndLimitHolder->setCurrentPage($pageCount);
- }
- $queryBuilder->setFirstResult($orderAndLimitHolder->getCurrentPage() * $orderAndLimitHolder->getPageSize());
- $queryBuilder->setMaxResults($orderAndLimitHolder->getPageSize());
- }
- }
-
/**
* @param callback $func
* @throws Exception
* @return mixed
+ *
+ * @deprecated use EntityManagerHolder::transactional() instead
*/
public function doInTransaction($func) {
$this->getLog()->info('Begin transaction.');
@@ -152,4 +144,29 @@
throw $e;
}
}
+
+ /**
+ * @param Query $q
+ * @param Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder
+ * @return array|Paginator
+ */
+ protected function getPaginatedOrderedResultFromQuery(Query $q, Bee_Persistence_IOrderAndLimitHolder $orderAndLimitHolder = null) {
+ if (!is_null($orderAndLimitHolder) && $orderAndLimitHolder->getPageSize() > 0) {
+ $q->setFirstResult($orderAndLimitHolder->getCurrentPage() * $orderAndLimitHolder->getPageSize());
+ $q->setMaxResults($orderAndLimitHolder->getPageSize());
+ $paginator = new Paginator($q, $this->useWhereInPagination());
+ $paginator->setUseOutputWalkers(false);
+ $orderAndLimitHolder->setResultCount(count($paginator));
+ return $paginator;
+ } else {
+ return $q->getResult($q->getHydrationMode());
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ protected function useWhereInPagination() {
+ return true;
+ }
}
Modified: branches/0.9-dev/framework/Bee/Persistence/Doctrine2/EntityManagerHolder.php
===================================================================
--- branches/0.9-dev/framework/Bee/Persistence/Doctrine2/EntityManagerHolder.php 2014-10-31 07:15:22 UTC (rev 269)
+++ branches/0.9-dev/framework/Bee/Persistence/Doctrine2/EntityManagerHolder.php 2014-10-31 07:35:38 UTC (rev 270)
@@ -1,7 +1,7 @@
<?php
namespace Bee\Persistence\Doctrine2;
/*
- * Copyright 2008-2010 the original author or authors.
+ * Copyright 2008-2014 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.
@@ -16,6 +16,7 @@
* limitations under the License.
*/
use \Doctrine\ORM\EntityManager;
+use Logger;
/**
* User: mp
@@ -26,6 +27,21 @@
class EntityManagerHolder {
/**
+ * @var Logger
+ */
+ protected $log;
+
+ /**
+ * @return Logger
+ */
+ public function getLog() {
+ if (!$this->log) {
+ $this->log = Logger::getLogger(get_class($this));
+ }
+ return $this->log;
+ }
+
+ /**
* @var EntityManager
*/
private $entityManager;
@@ -43,4 +59,16 @@
public function setEntityManager(EntityManager $entityManager) {
$this->entityManager = $entityManager;
}
+
+ /**
+ * Convenience wrapper around EntityManager::transactional()
+ * @param $callback
+ * @return mixed
+ */
+ public function transactional($callback) {
+ $that = $this;
+ return $this->getEntityManager()->transactional(function (EntityManager $em) use ($callback, $that) {
+ return $callback($that);
+ });
+ }
}
Modified: branches/0.9-dev/framework/Bee/Persistence/IOrderAndLimitHolder.php
===================================================================
--- branches/0.9-dev/framework/Bee/Persistence/IOrderAndLimitHolder.php 2014-10-31 07:15:22 UTC (rev 269)
+++ branches/0.9-dev/framework/Bee/Persistence/IOrderAndLimitHolder.php 2014-10-31 07:35:38 UTC (rev 270)
@@ -1,5 +1,23 @@
<?php
+/*
+ * Copyright 2008-2014 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.
+ */
+/**
+ * Interface Bee_Persistence_IOrderAndLimitHolder
+ */
interface Bee_Persistence_IOrderAndLimitHolder {
/**
@@ -18,11 +36,6 @@
public function getPageCount();
/**
- * @param $pageCount
- */
- public function setPageCount($pageCount);
-
- /**
* @return int
*/
public function getCurrentPage();
@@ -32,6 +45,8 @@
*/
public function setCurrentPage($currentPage);
+ /**
+ * @param int $resultCount
+ */
+ public function setResultCount($resultCount);
}
-
-?>
\ No newline at end of file
Added: branches/0.9-dev/framework/Bee/Persistence/PaginationBase.php
===================================================================
--- branches/0.9-dev/framework/Bee/Persistence/PaginationBase.php (rev 0)
+++ branches/0.9-dev/framework/Bee/Persistence/PaginationBase.php 2014-10-31 07:35:38 UTC (rev 270)
@@ -0,0 +1,103 @@
+<?php
+namespace Bee\Persistence;
+/*
+ * Copyright 2008-2014 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 Bee_Persistence_IOrderAndLimitHolder;
+
+/**
+ * Class BasicListStateHolder
+ *
+ * Implements the pagination aspect of the IOrderAndLimitHolder and embodies generic logic for
+ * @package Bee\Persistence
+ */
+abstract class PaginationBase implements Bee_Persistence_IOrderAndLimitHolder {
+
+ /**
+ * @var int
+ */
+ private $pageSize = 50;
+
+ /**
+ * @var int
+ */
+ private $currentPage = 0;
+
+ /**
+ * @var int
+ */
+ private $resultCount;
+
+ /**
+ * @return int
+ */
+ public function getPageSize() {
+ return $this->pageSize;
+ }
+
+ /**
+ * @param int $pageSize
+ */
+ public function setPageSize($pageSize) {
+ $this->pageSize = $pageSize;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPageCount() {
+ return ceil($this->getResultCount() / $this->getPageSize());
+ }
+
+ /**
+ * @return int
+ */
+ public function getCurrentPage() {
+ return $this->currentPage;
+ }
+
+ /**
+ * @param $currentPage
+ */
+ public function setCurrentPage($currentPage) {
+ $currentPage = $currentPage < 0 ? 0 : $currentPage;
+ $this->currentPage = $currentPage;
+ }
+
+ /**
+ * @param int $resultCount
+ */
+ public function setResultCount($resultCount) {
+ $this->resultCount = $resultCount;
+ if($this->getCurrentPage() >= $this->getPageCount()) {
+ $this->setCurrentPage($this->getPageCount() - 1);
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function getResultCount() {
+ return $this->resultCount;
+ }
+
+ /**
+ * Implements the default behavior in case the current page is beyond the acceptable limit. By default, sets the
+ * current page to the last page.
+ */
+ protected function adjustCurrentPageOnOverflow() {
+ $this->setCurrentPage($this->getPageCount() - 1);
+ }
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|