[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/kernel/classes/ -> ezdbgarbagecollector.php (source)

   1  <?php
   2  //
   3  // Definition of eZDBGarbageCollector class
   4  //
   5  // Created on: <09-Jun-2005 08:42:13 amos>
   6  //
   7  // SOFTWARE NAME: eZ publish
   8  // SOFTWARE RELEASE: 3.9.0
   9  // BUILD VERSION: 17785
  10  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
  11  // SOFTWARE LICENSE: GNU General Public License v2.0
  12  // NOTICE: >
  13  //   This program is free software; you can redistribute it and/or
  14  //   modify it under the terms of version 2.0  of the GNU General
  15  //   Public License as published by the Free Software Foundation.
  16  //
  17  //   This program is distributed in the hope that it will be useful,
  18  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20  //   GNU General Public License for more details.
  21  //
  22  //   You should have received a copy of version 2.0 of the GNU General
  23  //   Public License along with this program; if not, write to the Free
  24  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25  //   MA 02110-1301, USA.
  26  //
  27  //
  28  
  29  /*! \file ezdbgarbagecollector.php
  30  */
  31  
  32  /*!
  33    \class eZDBGrbageCollector ezdbgarbagecollector.php
  34    \brief Handles garbage collection in the database.
  35  
  36    Cleans up garbage (leaks) in the database which can be left behind by
  37    bugs or crashes in the system.
  38  
  39    Garbage collection is divided into several static functions which performs
  40    cleanup of one or more tables. What is common for all functions are the
  41    \a $maxTime and \a $sleepTime parameters which controls how long a GC
  42    operation can go on and how long it should sleep between batch operations.
  43  
  44    \code
  45    eZDBGarbageCollector::collectBaskets();
  46    // or
  47    // Perform GC for 5 minutes with 2 second sleep intervals
  48    eZDBGarbageCollector::collectBaskets( 5*60, 2 );
  49    \endcode
  50  
  51  */
  52  
  53  include_once ( 'kernel/classes/ezpersistentobject.php' );
  54  
  55  /*!
  56   Controls the default value for how many items are cleaned in one batch operation.
  57  */
  58  define( "EZ_DB_GC_ITEM_LIMIT", 3000 );
  59  
  60  class eZDBGarbageCollector
  61  {
  62      /*!
  63       \static
  64       Removes all baskets which are missing a session entry.
  65       This usually means the basket was not cleaned up when the session was removed.
  66  
  67       \param $maxTime The maximum number of seconds the collector should run.
  68                       If set to \c false or \c true it will continue until all garbage is collected,
  69                       \c false means to try the fastest way possible (may use lots of resources).
  70       \param $sleepTime Controls how many seconds it will sleep between each batch of cleanup,
  71                         setting it to \c false means that it should never sleep.
  72       \param $limit Controls how many items are cleaned in one batch operation,
  73                     a value of \c false means to use default value.
  74  
  75       \note The function will most likely use a little more time than \a $maxTime so
  76             don't depend on it to be accurate.
  77  
  78       \note This will also remove the product collection the basket is using.
  79  
  80       \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
  81       the calls within a db transaction; thus within db->begin and db->commit.
  82      */
  83      function collectBaskets( $maxTime = false, $sleepTime = false, $limit = false )
  84      {
  85          $db =& eZDB::instance();
  86  
  87          if ( $maxTime === false and $db->hasRequiredServerVersion( '4.0', 'mysql' ) )
  88          {
  89              $sql = "DELETE FROM ezbasket, ezproductcollection, ezproductcollection_item, ezproductcollection_item_opt
  90  USING ezsession
  91        RIGHT JOIN ezbasket
  92          ON ezsession.session_key = ezbasket.session_id
  93        LEFT JOIN ezproductcollection
  94          ON ezbasket.productcollection_id = ezproductcollection.id
  95        LEFT JOIN ezproductcollection_item
  96          ON ezproductcollection.id = ezproductcollection_item.productcollection_id
  97        LEFT JOIN ezproductcollection_item_opt
  98          ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id
  99  WHERE ezsession.session_key IS NULL";
 100              $db->query( $sql );
 101              return;
 102          }
 103  
 104          // Find all baskets which are lacking a session (db leaks)
 105          if ( $db->hasRequiredServerVersion( '8', 'oracle' ) )
 106          {
 107              $sql = "SELECT id, productcollection_id
 108  FROM ezsession, ezbasket
 109  WHERE ezbasket.session_id = ezsession.session_key (+) AND
 110        ezsession.session_key IS NULL";
 111          }
 112          else
 113          {
 114              $sql = "SELECT id, productcollection_id
 115  FROM ezsession
 116       RIGHT JOIN ezbasket
 117         ON ezbasket.session_id = ezsession.session_key
 118  WHERE ezsession.session_key IS NULL";
 119          }
 120          if ( $limit === false )
 121              $limit = EZ_DB_GC_ITEM_LIMIT;
 122          $end = false;
 123          if ( is_numeric( $maxTime ) )
 124              $end = time() + $maxTime;
 125  
 126          include_once ( 'kernel/classes/ezproductcollection.php' );
 127  
 128          do
 129          {
 130              $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) );
 131              if ( count( $rows ) == 0 )
 132                  break;
 133  
 134              $productCollectionIDList = array();
 135              $idList = array();
 136              foreach ( $rows as $row )
 137              {
 138                  $idList[] = (int)$row['id'];
 139                  $productCollectionIDList[] = (int)$row['productcollection_id'];
 140              }
 141              eZProductCollection::cleanupList( $productCollectionIDList );
 142  
 143              $ids = implode( ', ', $idList );
 144              $db->query( "DELETE FROM ezbasket WHERE id IN ( $ids )" );
 145  
 146              // Stop when we used up our time
 147              if ( $end !== false and time() > $end )
 148                  break;
 149  
 150              // Sleep a little if required, reduces load on server
 151              if ( $sleepTime !== false )
 152                  sleep( $sleepTime );
 153  
 154          } while ( true );
 155      }
 156  
 157      /*!
 158       Removes entries from ezproductcollection which is missing relations to other tables.
 159  
 160       \param $maxTime The maximum number of seconds the collector should run.
 161                       If set to \c false or \c true it will continue until all garbage is collected,
 162                       \c false means to try the fastest way possible (may use lots of resources).
 163       \param $sleepTime Controls how many seconds it will sleep between each batch of cleanup,
 164                         setting it to \c false means that it should never sleep.
 165       \param $limit Controls how many items are cleaned in one batch operation,
 166                     a value of \c false means to use default value.
 167  
 168       \note The function will most likely use a little more time than \a $maxTime so
 169             don't depend on it to be accurate.
 170  
 171       \note The current code hardcodes the related tables.
 172  
 173       \warning This code may be very slow on large sites.
 174  
 175       \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
 176       the calls within a db transaction; thus within db->begin and db->commit.
 177      */
 178      function collectProductCollections( $maxTime = false, $sleepTime = false, $limit = false )
 179      {
 180          $db =& eZDB::instance();
 181  
 182          // Create a temporary table for filling in collection ids
 183          // that are in use
 184          if ( $db->databaseName() == 'mysql' )
 185              $db->query( "DROP TABLE IF EXISTS ezproductcollection_used" );
 186          $db->query( "CREATE TABLE ezproductcollection_used ( id int )" );
 187  
 188          // Fill in collections used by orders
 189          $db->query( "INSERT INTO ezproductcollection_used (id) SELECT productcollection_id FROM ezorder" );
 190  
 191          // Fill in collections used by wish lists
 192          $db->query( "INSERT INTO ezproductcollection_used (id) SELECT productcollection_id FROM ezwishlist" );
 193  
 194          // Fill in collections used by baskets
 195          $db->query( "INSERT INTO ezproductcollection_used (id) SELECT productcollection_id FROM ezbasket" );
 196  
 197          // Create the index for faster selects
 198          $db->query( "CREATE INDEX ezproductcollection_used_id on ezproductcollection_used( id )" );
 199  
 200          if ( $maxTime === false and $db->hasRequiredServerVersion( '4.0', 'mysql' ) )
 201          {
 202              // Delete entries which are not in ezproductcollection_used
 203              $db->query( "DELETE FROM ezproductcollection, ezproductcollection_item, ezproductcollection_item_opt
 204  USING ezproductcollection_used
 205        RIGHT JOIN ezproductcollection
 206          ON ezproductcollection_used.id = ezproductcollection.id
 207        LEFT JOIN ezproductcollection_item
 208          ON ezproductcollection.id = ezproductcollection_item.productcollection_id
 209        LEFT JOIN ezproductcollection_item_opt
 210          ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id
 211  WHERE ezproductcollection_used.id IS NULL" );
 212              $db->query( $sql );
 213  
 214              // Remove the temporary table
 215              $db->query( "DROP TABLE ezproductcollection_used" );
 216  
 217              return;
 218          }
 219  
 220          // Find all product collections which are not in use
 221          if ( $db->hasRequiredServerVersion( '8', 'oracle' ) )
 222          {
 223              $sql = "SELECT ezproductcollection.id
 224  FROM ezproductcollection_used, ezproductcollection
 225  WHERE ezproductcollection_used.id = ezproductcollection.id (+) AND
 226        ezproductcollection_used.id IS NULL";
 227          }
 228          else
 229          {
 230              $sql = "SELECT ezproductcollection.id
 231  FROM ezproductcollection_used
 232       RIGHT JOIN ezproductcollection
 233         ON ezproductcollection_used.id = ezproductcollection.id
 234  WHERE ezproductcollection_used.id IS NULL";
 235          }
 236          if ( $limit === false )
 237              $limit = EZ_DB_GC_ITEM_LIMIT;
 238          $end = false;
 239          if ( is_numeric( $maxTime ) )
 240              $end = time() + $maxTime;
 241  
 242          include_once ( 'kernel/classes/ezproductcollectionitem.php' );
 243  
 244          do
 245          {
 246              $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) );
 247              if ( count( $rows ) == 0 )
 248                  break;
 249  
 250              $idList = array();
 251              foreach ( $rows as $row )
 252              {
 253                  $idList[] = (int)$row['id'];
 254              }
 255              eZProductCollectionItem::cleanupList( $idList );
 256  
 257              $ids = implode( ', ', $idList );
 258              $db->query( "DELETE FROM ezproductcollection WHERE id IN ( $ids )" );
 259              $db->query( "DELETE FROM ezproductcollection_used WHERE id IN ( $ids )" );
 260  
 261              // Stop when we used up our time
 262              if ( $end !== false and time() > $end )
 263                  break;
 264  
 265              // Sleep a little if required, reduces load on server
 266              if ( $sleepTime !== false )
 267                  sleep( $sleepTime );
 268  
 269          } while ( true );
 270  
 271          // Remove the temporary table
 272          $db->query( "DROP TABLE ezproductcollection_used" );
 273      }
 274  
 275      /*!
 276       \static
 277       Removes all product collection items which are missing a product collection.
 278  
 279       \param $maxTime The maximum number of seconds the collector should run.
 280                       If set to \c false or \c true it will continue until all garbage is collected,
 281                       \c false means to try the fastest way possible (may use lots of resources).
 282       \param $sleepTime Controls how many seconds it will sleep between each batch of cleanup,
 283                         setting it to \c false means that it should never sleep.
 284       \param $limit Controls how many items are cleaned in one batch operation,
 285                     a value of \c false means to use default value.
 286  
 287       \note The function will most likely use a little more time than \a $maxTime so
 288             don't depend on it to be accurate.
 289  
 290       \note This will also remove the product collection item option the item is using.
 291  
 292       \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
 293       the calls within a db transaction; thus within db->begin and db->commit.
 294      */
 295      function collectProductCollectionItems( $maxTime = false, $sleepTime = false, $limit = false )
 296      {
 297          $db =& eZDB::instance();
 298  
 299          if ( $maxTime === false and $db->hasRequiredServerVersion( '4.0', 'mysql' ) )
 300          {
 301              $sql = "DELETE FROM ezproductcollection_item, ezproductcollection_item_opt
 302  USING ezproductcollection
 303        LEFT JOIN ezproductcollection_item
 304          ON ezproductcollection.id = ezproductcollection_item.productcollection_id
 305        LEFT JOIN ezproductcollection_item_opt
 306          ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id
 307  WHERE ezproductcollection.id IS NULL";
 308              $db->query( $sql );
 309  
 310              return;
 311          }
 312  
 313          // Find all items which are lacking a collection (db leaks)
 314          if ( $db->hasRequiredServerVersion( '8', 'oracle' ) )
 315          {
 316              $sql = "SELECT ezproductcollection_item.productcollection_id
 317  FROM ezproductcollection, ezproductcollection_item
 318  WHERE ezproductcollection.id = ezproductcollection_item.productcollection_id (+) AND
 319        ezproductcollection.id IS NULL";
 320          }
 321          else
 322          {
 323              $sql = "SELECT ezproductcollection_item.productcollection_id
 324  FROM ezproductcollection
 325       RIGHT JOIN ezproductcollection_item
 326         ON ezproductcollection.id = ezproductcollection_item.productcollection_id
 327  WHERE ezproductcollection.id IS NULL";
 328          }
 329          if ( $limit === false )
 330              $limit = EZ_DB_GC_ITEM_LIMIT;
 331          $end = false;
 332          if ( is_numeric( $maxTime ) )
 333              $end = time() + $maxTime;
 334  
 335          include_once ( 'kernel/classes/ezproductcollectionitemoption.php' );
 336  
 337          do
 338          {
 339              $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) );
 340              if ( count( $rows ) == 0 )
 341                  break;
 342  
 343              $idList = array();
 344              foreach ( $rows as $row )
 345              {
 346                  $idList[] = (int)$row['productcollection_id'];
 347              }
 348              eZProductCollectionItemOption::cleanupList( $idList );
 349  
 350              $ids = implode( ', ', $idList );
 351              $db->query( "DELETE FROM ezproductcollection_item WHERE productcollection_id IN ( $ids )" );
 352  
 353              // Stop when we used up our time
 354              if ( $end !== false and time() > $end )
 355                  break;
 356  
 357              // Sleep a little if required, reduces load on server
 358              if ( $sleepTime !== false )
 359                  sleep( $sleepTime );
 360  
 361          } while ( true );
 362      }
 363  
 364      /*!
 365       \static
 366       Removes all product collection item options which are missing a product collection item.
 367  
 368       \param $maxTime The maximum number of seconds the collector should run.
 369                       If set to \c false or \c true it will continue until all garbage is collected,
 370                       \c false means to try the fastest way possible (may use lots of resources).
 371       \param $sleepTime Controls how many seconds it will sleep between each batch of cleanup,
 372                         setting it to \c false means that it should never sleep.
 373       \param $limit Controls how many items are cleaned in one batch operation,
 374                     a value of \c false means to use default value.
 375  
 376       \note The function will most likely use a little more time than \a $maxTime so
 377             don't depend on it to be accurate.
 378  
 379       \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
 380       the calls within a db transaction; thus within db->begin and db->commit.
 381      */
 382      function collectProductCollectionItemOptions( $maxTime = false, $sleepTime = false, $limit = false )
 383      {
 384          $db =& eZDB::instance();
 385  
 386          if ( $maxTime === false and $db->hasRequiredServerVersion( '4.0', 'mysql' ) )
 387          {
 388              $sql = "DELETE FROM ezproductcollection_item_opt
 389  USING ezproductcollection_item
 390        LEFT JOIN ezproductcollection_item_opt
 391          ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id
 392  WHERE ezproductcollection_item.id IS NULL";
 393              $db->query( $sql );
 394  
 395              return;
 396          }
 397  
 398          // Find all items which are lacking a collection (db leaks)
 399          if ( $db->hasRequiredServerVersion( '8', 'oracle' ) )
 400          {
 401              $sql = "SELECT ezproductcollection_item_opt.item_id
 402  FROM ezproductcollection_item, ezproductcollection_item_opt
 403  WHERE ezproductcollection_item.id = ezproductcollection_item_opt.item_id (+) AND
 404        ezproductcollection_item.id IS NULL";
 405          }
 406          else
 407          {
 408              $sql = "SELECT ezproductcollection_item_opt.item_id
 409  FROM ezproductcollection_item
 410       RIGHT JOIN ezproductcollection_item_opt
 411         ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id
 412  WHERE ezproductcollection_item.id IS NULL";
 413          }
 414          if ( $limit === false )
 415              $limit = EZ_DB_GC_ITEM_LIMIT;
 416          $end = false;
 417          if ( is_numeric( $maxTime ) )
 418              $end = time() + $maxTime;
 419  
 420          do
 421          {
 422              $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) );
 423              if ( count( $rows ) == 0 )
 424                  break;
 425  
 426              $idList = array();
 427              foreach ( $rows as $row )
 428              {
 429                  $idList[] = (int)$row['item_id'];
 430              }
 431  
 432              $ids = implode( ', ', $idList );
 433              $db->query( "DELETE FROM ezproductcollection_item_opt WHERE item_id IN ( $ids )" );
 434  
 435              // Stop when we used up our time
 436              if ( $end !== false and time() > $end )
 437                  break;
 438  
 439              // Sleep a little if required, reduces load on server
 440              if ( $sleepTime !== false )
 441                  sleep( $sleepTime );
 442  
 443          } while ( true );
 444      }
 445  }
 446  
 447  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7