From 8a098691f8a2eb74fb07e4cd49517f0fcdd3739e Mon Sep 17 00:00:00 2001
From: Ghislain Loas <ghislo@sandbox.pergame.net>
Date: Thu, 28 Jan 2016 16:11:55 +0100
Subject: [PATCH] hotline #37385 improve delete record with out items

---
 VERSIONS_HOTLINE/37385                        |  1 +
 .../Cosmogramme/Integration/PhaseAbstract.php | 12 ++++++
 .../PhaseDeleteRecordWithoutItem.php          | 39 ++++++++-----------
 .../Integration/PhaseItemFacets.php           | 13 -------
 .../PhaseDeleteRecordWithoutItemTest.php      | 36 ++++++++++++++++-
 5 files changed, 64 insertions(+), 37 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/37385

diff --git a/VERSIONS_HOTLINE/37385 b/VERSIONS_HOTLINE/37385
new file mode 100644
index 00000000000..a2c8f94c0f8
--- /dev/null
+++ b/VERSIONS_HOTLINE/37385
@@ -0,0 +1 @@
+ - ticket #37385 : Réduction du temps de la phase de suppression des notices sans exemplaires
diff --git a/library/Class/Cosmogramme/Integration/PhaseAbstract.php b/library/Class/Cosmogramme/Integration/PhaseAbstract.php
index 844f79c062c..401a106d357 100644
--- a/library/Class/Cosmogramme/Integration/PhaseAbstract.php
+++ b/library/Class/Cosmogramme/Integration/PhaseAbstract.php
@@ -134,4 +134,16 @@ abstract class Class_Cosmogramme_Integration_PhaseAbstract {
     return !$this->_phase->isCron()
       && $this->_chrono->mainElapsed() > $this->_chrono->timeout();
   }
+
+
+  protected function _resetDbConnection() {
+    if (!$this->_db_reset)
+      return $this;
+
+    Storm_Model_Abstract::unsetLoaders();
+    Zend_Db_Table::getDefaultAdapter()->closeConnection();
+    setupDatabase(loadConfig());
+    gc_collect_cycles();
+    return $this;
+  }
 }
\ No newline at end of file
diff --git a/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItem.php b/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItem.php
index e37cf361e0c..fe482ec5d6d 100644
--- a/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItem.php
+++ b/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItem.php
@@ -26,46 +26,41 @@ class Class_Cosmogramme_Integration_PhaseDeleteRecordWithoutItem extends Class_C
   protected $_label = 'Suppression des notices sans exemplaire';
 
   public function _execute() {
-    if ($this->isTimeOut())
-      return $this->_phase;
-
     $this->_chrono->start();
-    $page_size = 1000;
-    $page = 1;
+    $page_size = 100;
+    $page = 0;
+
+    while($records_ids = Zend_Registry::get('sql')->fetchAll('SELECT notices.id_notice FROM notices WHERE notices.id_notice NOT IN (SELECT exemplaires.id_notice FROM exemplaires) LIMIT ' . $page . ', ' . $page_size)) {
 
-    while ($notices = Class_Notice::findAllBy(['order' => 'id_notice',
-                                               'limitPage' => [$page, $page_size]])) {
-      foreach ($notices as $notice) {
-        $this->_runOne($notice);
-      }
+      if ($this->isTimeOut())
+        return $this->_resetDbConnection()
+                    ->_phase;
 
+      foreach ($records_ids as $record_id)
+        $this->_runOne($record_id['id_notice']);
+
+      $this->_log->ecrire($this->_getData('deleted') . ' notices sans exemplaire supprimées<br/>');
       $this->_cleanMemory();
       $page++;
     }
 
-    if (0 == $this->_getData('deleted'))
+    if (0 == $this->_getData('deleted')) {
       $this->_log->ecrire('Aucune notice sans exemplaire');
+      return;
+    }
 
-    if (0 < $this->_getData('deleted'))
-      $this->_log->ecrire($this->_getData('deleted').' notices sans exemplaire supprimées');
-    $this->_log->ecrire('Temps de traitement: '.$this->_chrono->endMain().' ('.$this->_chrono->mainAverage($this->_getData('nombre'), 'notices').')' );
+    $this->_log->ecrire('Temps de traitement: '.$this->_chrono->endMain().' ('.$this->_chrono->mainAverage($this->_getData('deleted'), 'notices').')' );
   }
 
 
-  protected function _runOne($notice) {
-    $this->_incrementData('nombre');
-
-    if ($notice->hasExemplaires())
-      return;
-
-    $notice->delete();
+  protected function _runOne($record_id) {
+    Class_Notice::find($record_id)->delete();
     $this->_incrementData('deleted');
   }
 
   protected function _init($phase) {
     $phase
       ->resetDatas()
-      ->setData('nombre', 0)
       ->setData('deleted', 0);
   }
 }
diff --git a/library/Class/Cosmogramme/Integration/PhaseItemFacets.php b/library/Class/Cosmogramme/Integration/PhaseItemFacets.php
index 9fb699df84f..1c40d36af5d 100644
--- a/library/Class/Cosmogramme/Integration/PhaseItemFacets.php
+++ b/library/Class/Cosmogramme/Integration/PhaseItemFacets.php
@@ -128,18 +128,5 @@ class Class_Cosmogramme_Integration_PhaseItemFacets
     $this->_db_reset = false;
     return $this;
   }
-
-
-  protected function _resetDbConnection() {
-    if (!$this->_db_reset)
-      return $this;
-
-    Storm_Model_Abstract::unsetLoaders();
-    Zend_Db_Table::getDefaultAdapter()->closeConnection();
-    setupDatabase(loadConfig());
-    gc_collect_cycles();
-    return $this;
-  }
 }
-
 ?>
\ No newline at end of file
diff --git a/tests/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItemTest.php b/tests/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItemTest.php
index 28c71ca79d3..5f42eac3861 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItemTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhaseDeleteRecordWithoutItemTest.php
@@ -21,11 +21,10 @@
 
 
 abstract class PhaseDeleteRecordWithoutItemTestCase extends Class_Cosmogramme_Integration_PhaseTestCase {
-  protected $_phase;
+  protected $_phase, $_mock_sql;
 
   public function setUp() {
     parent::setUp();
-
     $this->_phase = $this->_buildPhase('DeleteRecordWithoutItem')
                          ->setMemoryCleaner(function() {})
                          ->run();
@@ -67,10 +66,30 @@ abstract class PhaseDeleteRecordWithoutItemTestCase extends Class_Cosmogramme_In
 
 class PhaseDeleteRecordWithoutItemSimpleTest extends PhaseDeleteRecordWithoutItemTestCase {
 
+  public function setUp() {
+    parent::setup();
+  }
+
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
     $this->fixture('Class_Notice', ['id' => 34]);
     $this->fixture('Class_Notice', ['id' => 35]);
+
+    $this->_mock_sql = Storm_Test_ObjectWrapper::mock();
+    Zend_Registry::set('sql', $this->_mock_sql);
+
+    $this->_mock_sql
+      ->whenCalled('fetchAll')
+      ->with('SELECT notices.id_notice FROM notices WHERE notices.id_notice NOT IN (SELECT exemplaires.id_notice FROM exemplaires) LIMIT 0, 100')
+      ->answers([0 => ['id_notice' => 34],
+                 1 => ['id_notice' => 35]])
+
+      ->whenCalled('fetchAll')
+      ->with('SELECT notices.id_notice FROM notices WHERE notices.id_notice NOT IN (SELECT exemplaires.id_notice FROM exemplaires) LIMIT 1, 100')
+      ->answers([])
+
+      ->beStrict();
   }
 
 
@@ -90,6 +109,19 @@ class PhaseDeleteRecordWithoutItemSimpleTest extends PhaseDeleteRecordWithoutIte
 
 
 class PhaseDeleteRecordWithoutItemNothingToDeleteTest extends PhaseDeleteRecordWithoutItemTestCase {
+  protected function _prepareFixtures() {
+    parent::_prepareFixtures();
+    $this->_mock_sql = Storm_Test_ObjectWrapper::mock();
+    Zend_Registry::set('sql', $this->_mock_sql);
+
+    $this->_mock_sql
+      ->whenCalled('fetchAll')
+      ->with('SELECT notices.id_notice FROM notices WHERE notices.id_notice NOT IN (SELECT exemplaires.id_notice FROM exemplaires) LIMIT 0, 100')
+      ->answers([])
+
+      ->beStrict();
+  }
+
 
   /** @test */
   public function totalNumberOfRecordsShouldBe3() {
-- 
GitLab