/** * Rebuild stack_trace table * CAUTION!!!! If you have a lot of records, this could take hours or days do get done! */ public static function rebuild() { Status::calculationStarted(); Status::setCalculationStatus('Initializing'); Status::setCalculationStatus('Reseting stack_trace_ids to NULL'); Db::query('UPDATE crash_archive SET stack_trace_id = NULL'); Status::setCalculationStatus('Emptying stack_trace table'); Db::query('TRUNCATE TABLE stack_trace'); $stacks = array(); // foreach (Stack\Trace::all() as $r) { // $stacks[$r['hash']] = (int) $r['id']; // } $total = \Crash\Archive::count(); $index = 0; $start = 0; do { $query = new Select('crash_archive'); $query->field('id')->where('id', '>', $start)->where('id', '<=', $start + 100000); Status::setCalculationStatus("Taking IDs from {$start} to " . ($start + 100000)); $records = $query->fetchAll(); $sizeofIds = count($records); foreach ($records as $r) { $id = (int) $r['id']; $crash = new \Crash\Archive(array('id' => $id)); $stackTrace = $crash->getMeta('stack_trace'); if ($stackTrace !== null) { $summary = static::getSummary($stackTrace); $md5 = md5($summary); if (isset($stacks[$md5])) { $stackTraceId = $stacks[$md5]; } else { $tmp = \Stack\Trace::create(array('hash' => $md5, 'summary' => $summary, 'created_at' => $crash->created_at)); $stackTraceId = (int) $tmp->id; $stacks[$md5] = $stackTraceId; } $crash->stack_trace_id = $stackTraceId; $crash->save(); Log::info("Updated #{$id} with stack={$stackTraceId}"); } else { Log::info("Crash report #{$id} is skipped because stack_trace is missing in meta table"); } if ($index % 25 == 0) { $percent = round($index / $total * 100, 2); Status::setCalculationStatus("Working on {$index}/{$sizeofIds} {$percent}%"); } $index++; } $start += 100000; } while (sizeof($records) > 0); Status::setCalculationStatus('Started stack trace recalculation!'); Log::info('Started recalculation of stack_trace counts'); static::recalculate(); Status::calculationFinished('all'); }