Exemplo n.º 1
0
 public function purgeOutdatedArchives()
 {
     $archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
     foreach ($archiveTables as $table) {
         $date = ArchiveTableCreator::getDateFromTableName($table);
         list($year, $month) = explode('_', $date);
         // Somehow we may have archive tables created with older dates, prevent exception from being thrown
         if ($year > 1990) {
             ArchiveSelector::purgeOutdatedArchives(Date::factory("{$year}-{$month}-15"));
         }
     }
 }
Exemplo n.º 2
0
 /**
  * Gets the IDs of the archives we're querying for and stores them in $this->archives.
  * This function will not launch the archiving process (and is thus much, much faster
  * than cacheArchiveIdsAfterLaunching).
  *
  * @param array $plugins List of plugin names from which data is being requested.
  */
 private function cacheArchiveIdsWithoutLaunching($plugins)
 {
     $idarchivesByReport = ArchiveSelector::getArchiveIds($this->params->getIdSites(), $this->params->getPeriods(), $this->params->getSegment(), $plugins, $this->params->isSkipAggregationOfSubTables());
     // initialize archive ID cache for each report
     foreach ($plugins as $plugin) {
         $doneFlag = $this->getDoneStringForPlugin($plugin);
         $this->initializeArchiveIdCache($doneFlag);
     }
     foreach ($idarchivesByReport as $doneFlag => $idarchivesByDate) {
         foreach ($idarchivesByDate as $dateRange => $idarchives) {
             foreach ($idarchives as $idarchive) {
                 $this->idarchives[$doneFlag][$dateRange][] = $idarchive;
             }
         }
     }
 }
Exemplo n.º 3
0
 /**
  * Returns the idArchive if the archive is available in the database for the requested plugin.
  * Returns false if the archive needs to be processed.
  *
  * @return array
  */
 protected function loadExistingArchiveIdFromDb()
 {
     $noArchiveFound = array(false, false, false);
     // see isArchiveTemporary()
     $minDatetimeArchiveProcessedUTC = $this->getMinTimeArchiveProcessed();
     if ($this->isArchivingForcedToTrigger()) {
         return $noArchiveFound;
     }
     $idAndVisits = ArchiveSelector::getArchiveIdAndVisits($this->params, $minDatetimeArchiveProcessedUTC);
     if (!$idAndVisits) {
         return $noArchiveFound;
     }
     return $idAndVisits;
 }
Exemplo n.º 4
0
 /**
  * Returns the idArchive if the archive is available in the database for the requested plugin.
  * Returns false if the archive needs to be processed.
  *
  * @return array
  */
 protected function loadExistingArchiveIdFromDb()
 {
     $noArchiveFound = array(false, false, false);
     // see isArchiveTemporary()
     $minDatetimeArchiveProcessedUTC = $this->getMinTimeArchiveProcessed();
     if ($this->isArchivingForcedToTrigger()) {
         return $noArchiveFound;
     }
     $site = $this->params->getSite();
     $period = $this->params->getPeriod();
     $segment = $this->params->getSegment();
     $requestedPlugin = $this->params->getRequestedPlugin();
     $idAndVisits = ArchiveSelector::getArchiveIdAndVisits($site, $period, $segment, $minDatetimeArchiveProcessedUTC, $requestedPlugin);
     if (!$idAndVisits) {
         return $noArchiveFound;
     }
     return $idAndVisits;
 }
Exemplo n.º 5
0
 /**
  * Queries and returns archive data using a set of archive IDs.
  *
  * @param array $archiveIds The IDs of the archives to get data from.
  * @param array $recordNames The names of the data to retrieve (ie, nb_visits, nb_actions, etc.)
  * @param string $archiveDataType The archive data type (either, 'blob' or 'numeric').
  * @param int|null|string $idSubtable  null if the root blob should be loaded, an integer if a subtable should be
  *                                     loaded and 'all' if all subtables should be loaded.
  * @throws Exception
  * @return array
  */
 public function getArchiveData($archiveIds, $recordNames, $archiveDataType, $idSubtable)
 {
     $chunk = new Chunk();
     // create the SQL to select archive data
     $loadAllSubtables = $idSubtable == Archive::ID_SUBTABLE_LOAD_ALL_SUBTABLES;
     if ($loadAllSubtables) {
         $name = reset($recordNames);
         // select blobs w/ name like "$name_[0-9]+" w/o using RLIKE
         $nameEnd = strlen($name) + 1;
         $nameEndAppendix = $nameEnd + 1;
         $appendix = $chunk->getAppendix();
         $lenAppendix = strlen($appendix);
         $checkForChunkBlob = "SUBSTRING(name FROM {$nameEnd} FOR {$lenAppendix}) = '{$appendix}'";
         $checkForSubtableId = "(SUBSTRING(name FROM {$nameEndAppendix} FOR 1) >= '0'\n                                    AND SUBSTRING(name FROM {$nameEndAppendix} FOR 1) <= '9')";
         $whereNameIs = "(name = ? OR (name LIKE ? AND ( {$checkForChunkBlob} OR {$checkForSubtableId} ) ))";
         $bind = array($name, $name . '%');
     } else {
         if ($idSubtable === null) {
             // select root table or specific record names
             $bind = array_values($recordNames);
         } else {
             // select a subtable id
             $bind = array();
             foreach ($recordNames as $recordName) {
                 // to be backwards compatibe we need to look for the exact idSubtable blob and for the chunk
                 // that stores the subtables (a chunk stores many blobs in one blob)
                 $bind[] = $chunk->getRecordNameForTableId($recordName, $idSubtable);
                 $bind[] = ArchiveSelector::appendIdSubtable($recordName, $idSubtable);
             }
         }
         $inNames = Common::getSqlStringFieldsArray($bind);
         $whereNameIs = "name IN ({$inNames})";
     }
     $getValuesSql = "SELECT %s, name, idsite, date1, date2, ts_archived\n                         FROM %s\n                         WHERE idarchive IN (%s)\n                           AND " . $whereNameIs;
     // get data from every table we're querying
     $rows = array();
     foreach ($archiveIds as $period => $ids) {
         if (empty($ids)) {
             throw new Exception("Unexpected: id archive not found for period '{$period}' '");
         }
         // $period = "2009-01-04,2009-01-04",
         $date = Date::factory(substr($period, 0, 10));
         $isNumeric = $archiveDataType == 'numeric';
         if ($isNumeric) {
             $table = ArchiveTableCreator::getNumericTable($date);
         } else {
             $table = ArchiveTableCreator::getBlobTable($date);
         }
         $valueCol = $this->prepareForBinary($table);
         $sql = sprintf($getValuesSql, $valueCol, $table, implode(',', $ids));
         $dataRows = $this->db->fetchAll($sql, $bind);
         $dataRows = $this->binaryOutput($dataRows, true);
         foreach ($dataRows as $row) {
             if ($isNumeric) {
                 $rows[] = $row;
             } else {
                 $row['value'] = $this->uncompress($row['value']);
                 if ($chunk->isRecordNameAChunk($row['name'])) {
                     $this->moveChunkRowToRows($rows, $row, $chunk, $loadAllSubtables, $idSubtable);
                 } else {
                     $rows[] = $row;
                 }
             }
         }
     }
     return $rows;
 }
Exemplo n.º 6
0
 protected function moveChunkRowToRows(&$rows, $row, Chunk $chunk, $loadAllSubtables, $idSubtable)
 {
     // $blobs = array([subtableID] = [blob of subtableId])
     $blobs = unserialize($row['value']);
     if (!is_array($blobs)) {
         return;
     }
     // $rawName = eg 'PluginName_ArchiveName'
     $rawName = $chunk->getRecordNameWithoutChunkAppendix($row['name']);
     if ($loadAllSubtables) {
         foreach ($blobs as $subtableId => $blob) {
             $row['value'] = $blob;
             $row['name'] = ArchiveSelector::appendIdSubtable($rawName, $subtableId);
             $rows[] = $row;
         }
     } elseif (array_key_exists($idSubtable, $blobs)) {
         $row['value'] = $blobs[$idSubtable];
         $row['name'] = ArchiveSelector::appendIdSubtable($rawName, $idSubtable);
         $rows[] = $row;
     }
 }