/**
  * Performs the actual task of table population.
  */
 public static function populate_cache_table($db, $table, $last_run_date)
 {
     $queries = kohana::config("cache_builder.{$table}");
     try {
         $count = cache_builder::get_changelist($db, $table, $queries, $last_run_date);
         if ($count > 0) {
             cache_builder::do_delete($db, $table, $queries);
             // preprocess some of the tags in the queries
             if (is_array($queries['update'])) {
                 foreach ($queries['update'] as $key => &$sql) {
                     $sql = str_replace('#join_needs_update#', $queries['join_needs_update'], $sql);
                 }
             } else {
                 $queries['update'] = str_replace('#join_needs_update#', $queries['join_needs_update'], $queries['update']);
             }
             cache_builder::run_statement($db, $table, $queries['update'], 'update');
             // preprocess some of the tags in the queries
             if (is_array($queries['insert'])) {
                 foreach ($queries['insert'] as $key => &$sql) {
                     $sql = str_replace('#join_needs_update#', $queries['join_needs_update'] . ' and (nu.deleted=false or nu.deleted is null)', $sql);
                 }
             } else {
                 $queries['insert'] = str_replace('#join_needs_update#', $queries['join_needs_update'] . ' and (nu.deleted=false or nu.deleted is null)', $queries['insert']);
             }
             cache_builder::run_statement($db, $table, $queries['insert'], 'insert');
             if (isset($queries['extra_multi_record_updates'])) {
                 cache_builder::run_statement($db, $table, $queries['extra_multi_record_updates'], 'final update');
             }
             if (!variable::get("populated-{$table}")) {
                 $cacheQuery = $db->query("select count(*) from cache_{$table}")->result_array(false);
                 if (isset($queries['count'])) {
                     $totalQuery = $db->query($queries['count'])->result_array(false);
                 } else {
                     $totalQuery = $db->query("select count(*) from {$table} where deleted='f'")->result_array(false);
                 }
                 $percent = round($cacheQuery[0]['count'] * 100 / $totalQuery[0]['count']);
                 echo "{$table} population in progress - {$percent}% done";
             }
             echo '<br/>';
         }
         $db->query("drop table needs_update_{$table}");
     } catch (Exception $e) {
         error::log_error('Building cache', $e);
         echo $e->getMessage();
         $db->query("drop table needs_update_{$table}");
     }
 }
/**
 * Hook into the task scheduler. This uses the queries defined in the cache_builder.php
 * file to create and populate cache tables. The tables are not always up to date as they
 * are only updated when the scheduler runs, but they have the advantage of simplifying
 * the data model for reporting as well as reducing the need to join in queries, therefore
 * significantly improving report performance.
 * @param string $last_run_date Date last run, or null if never run
 * @param object $db Database object.
 */
function cache_builder_scheduled_task($last_run_date, $db)
{
    if (isset($_GET['force_cache_rebuild'])) {
        $last_run_date = date('Y-m-d', time() - 60 * 60 * 24 * 365 * 200);
    } elseif ($last_run_date === null) {
        // first run, so get all records changed in last day. Query will automatically gradually pick up the rest.
        $last_run_date = date('Y-m-d', time() - 60 * 60 * 24);
    }
    try {
        foreach (kohana::config('cache_builder') as $table => $queries) {
            cache_builder::populate_cache_table($db, $table, $last_run_date);
            if (!variable::get("populated-{$table}")) {
                // don't bother populating the next table, as there can be dependencies.
                break;
            }
        }
    } catch (Exception $e) {
        echo $e->getMessage();
    }
}
Example #3
0
 /**
  * Handles any index rebuild requirements as a result of new or updated records, e.g. in
  * samples or occurrences. Also handles joining of occurrence_associations to the
  * correct records
  */
 private function postProcess()
 {
     if (class_exists('cache_builder')) {
         if (!empty(self::$changedRecords['insert']['occurrence'])) {
             cache_builder::insert($this->db, 'occurrences', self::$changedRecords['insert']['occurrence']);
         }
         if (!empty(self::$changedRecords['update']['occurrence'])) {
             cache_builder::update($this->db, 'occurrences', self::$changedRecords['update']['occurrence']);
         }
         if (!empty(self::$changedRecords['delete']['occurrence'])) {
             cache_builder::delete($this->db, 'occurrences', self::$changedRecords['delete']['occurrence']);
         }
         $samples = array();
         if (!empty(self::$changedRecords['insert']['sample'])) {
             $samples = self::$changedRecords['insert']['sample'];
         }
         if (!empty(self::$changedRecords['update']['sample'])) {
             $samples += self::$changedRecords['update']['sample'];
         }
         if (!empty($samples)) {
             postgreSQL::insertMapSquaresForSamples($samples, 1000, $this->db);
             postgreSQL::insertMapSquaresForSamples($samples, 2000, $this->db);
             postgreSQL::insertMapSquaresForSamples($samples, 10000, $this->db);
         } else {
             // might be directly inserting an occurrence. No need to do this if inserting a sample, as the above code does the
             // occurrences in bulk.
             $occurrences = array();
             if (!empty(self::$changedRecords['insert']['occurrence'])) {
                 $occurrences = self::$changedRecords['insert']['occurrence'];
             }
             if (!empty(self::$changedRecords['update']['occurrence'])) {
                 $occurrences += self::$changedRecords['update']['occurrence'];
             }
             if (!empty($occurrences)) {
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 1000, $this->db);
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 2000, $this->db);
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 10000, $this->db);
             }
         }
     }
     if (!empty(self::$changedRecords['insert']['occurrence_association'])) {
         // We've got some associations between occurrences that could not have the to_occurrence_id
         // foreign key filled in yet, since the occurrence referred to did not exist at the time of
         // saving
         foreach (Occurrence_association_Model::$to_occurrence_id_pointers as $associationId => $pointer) {
             if (!empty($this->dynamicRowIdReferences["occurrence:{$pointer}"])) {
                 $this->db->from('occurrence_associations')->set('to_occurrence_id', $this->dynamicRowIdReferences["occurrence:{$pointer}"])->where('id', $associationId)->update();
             }
         }
     }
 }
Example #4
0
 /**
  * Handles any index rebuild requirements as a result of new or updated records, e.g. in 
  * samples or occurrences.
  */
 private function postProcess()
 {
     if (class_exists('cache_builder')) {
         if (!empty(self::$changedRecords['insert']['occurrence'])) {
             cache_builder::insert($this->db, 'occurrences', self::$changedRecords['insert']['occurrence']);
         }
         if (!empty(self::$changedRecords['update']['occurrence'])) {
             cache_builder::update($this->db, 'occurrences', self::$changedRecords['update']['occurrence']);
         }
         if (!empty(self::$changedRecords['delete']['occurrence'])) {
             cache_builder::delete($this->db, 'occurrences', self::$changedRecords['delete']['occurrence']);
         }
         $samples = array();
         if (!empty(self::$changedRecords['insert']['sample'])) {
             $samples = self::$changedRecords['insert']['sample'];
         }
         if (!empty(self::$changedRecords['update']['sample'])) {
             $samples += self::$changedRecords['update']['sample'];
         }
         if (!empty($samples)) {
             postgreSQL::insertMapSquaresForSamples($samples, 1000, $this->db);
             postgreSQL::insertMapSquaresForSamples($samples, 2000, $this->db);
             postgreSQL::insertMapSquaresForSamples($samples, 10000, $this->db);
         } else {
             // might be directly inserting an occurrence. No need to do this if inserting a sample, as the above code does the
             // occurrences in bulk.
             $occurrences = array();
             if (!empty(self::$changedRecords['insert']['occurrence'])) {
                 $occurrences = self::$changedRecords['insert']['occurrence'];
             }
             if (!empty(self::$changedRecords['update']['occurrence'])) {
                 $occurrences += self::$changedRecords['update']['occurrence'];
             }
             if (!empty($occurrences)) {
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 1000, $this->db);
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 2000, $this->db);
                 postgreSQL::insertMapSquaresForOccurrences($occurrences, 10000, $this->db);
             }
         }
     }
 }