From ee20577c6887c6af894aefad641d7069d02a3520 Mon Sep 17 00:00:00 2001 From: Rein Baarsma Date: Fri, 29 Jun 2018 12:27:16 +0200 Subject: [PATCH] added expirimental feature to conserve memory --- Util/Factory/Query/DoctrineBuilder.php | 62 +++++++++++++++++++++++--- Util/Formatter/Renderer.php | 2 +- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/Util/Factory/Query/DoctrineBuilder.php b/Util/Factory/Query/DoctrineBuilder.php index e0d402f..4bd35e9 100644 --- a/Util/Factory/Query/DoctrineBuilder.php +++ b/Util/Factory/Query/DoctrineBuilder.php @@ -406,7 +406,16 @@ public function getData(array $filter_fields=[]) { $query->setMaxResults($iDisplayLength)->setFirstResult($request->get('iDisplayStart')); } - $objects = $query->getResult(Query::HYDRATE_OBJECT); + + // we can conserve memory by iterating, also see below + if (true === $this->getConserveMemory()) + { + $iterable_result = $query->iterate($query->getParameters(), Query::HYDRATE_OBJECT); + } + else + { + $objects = $query->getResult(Query::HYDRATE_OBJECT); + } $data = array(); $entity_alias = $this->entity_alias; $joins = $this->joins; @@ -497,18 +506,59 @@ public function getData(array $filter_fields=[]) $property->setAccessible(true); return $property->getValue($object); }; - foreach ($objects as $object) + + // we can conserve memory by both detaching the entities and not returning them + if (true === $this->getConserveMemory()) { - $item = array(); - foreach ($this->fields as $_field) + $objects = []; // leave empty on purpose + while ((list($obj) = $iterable_result->next()) !== false) { - $item[] = $__getValue($__getKey($_field), $object, $has_add_select, $_field); + $item = array(); + foreach ($this->fields as $_field) + { + $item[] = $__getValue($__getKey($_field), $obj, $has_add_select, $_field); + } + $data[] = $item; + + $this->em->detach($has_add_select ? $obj[0] : $obj); } - $data[] = $item; } + else + { + foreach ($objects as $object) + { + $item = array(); + foreach ($this->fields as $_field) + { + $item[] = $__getValue($__getKey($_field), $object, $has_add_select, $_field); + } + $data[] = $item; + } + } + return array($data, $objects); } + /** + * Experimental feature to conserve memory usage. Will use an iterator and + * detach the entities from the EntityManager. Also does not give the + * entities back to the renderer. Might lead to problems for some datatables. + * + * @param boolean $conserve_memory + */ + public function setConserveMemory($conserve_memory) + { + $this->conserve_memory = $conserve_memory; + } + + /** + * @return bool + */ + public function getConserveMemory() + { + return $this->conserve_memory; + } + /** * get entity name * diff --git a/Util/Formatter/Renderer.php b/Util/Formatter/Renderer.php index b0443ac..c48c75c 100644 --- a/Util/Formatter/Renderer.php +++ b/Util/Formatter/Renderer.php @@ -87,7 +87,7 @@ public function applyTo(array &$data, array $objects) $view = 'AliDatatableBundle:Renderers:_default.html.twig'; } $params = array_merge($params, array( - 'dt_obj' => $objects[$row_index], + 'dt_obj' => isset($objects[$row_index]) ? $objects[$row_index] : null, 'dt_item' => $data[$row_index][$column_index], 'dt_id' => $identifier_raw )