protected function recordCommit($commit_identifier, $epoch)
 {
     $repository = $this->getRepository();
     $commit = new PhabricatorRepositoryCommit();
     $commit->setRepositoryID($repository->getID());
     $commit->setCommitIdentifier($commit_identifier);
     $commit->setEpoch($epoch);
     try {
         $commit->save();
         $event = new PhabricatorTimelineEvent('cmit', array('id' => $commit->getID()));
         $event->recordEvent();
         queryfx($repository->establishConnection('w'), 'INSERT INTO %T (repositoryID, size, lastCommitID, epoch)
       VALUES (%d, 1, %d, %d)
       ON DUPLICATE KEY UPDATE
         size = size + 1,
         lastCommitID =
           IF(VALUES(epoch) > epoch, VALUES(lastCommitID), lastCommitID),
         epoch = IF(VALUES(epoch) > epoch, VALUES(epoch), epoch)', PhabricatorRepository::TABLE_SUMMARY, $repository->getID(), $commit->getID(), $epoch);
         $this->commitCache[$commit_identifier] = true;
     } catch (AphrontQueryDuplicateKeyException $ex) {
         // Ignore. This can happen because we discover the same new commit
         // more than once when looking at history, or because of races or
         // data inconsistency or cosmic radiation; in any case, we're still
         // in a good state if we ignore the failure.
         $this->commitCache[$commit_identifier] = true;
     }
     $this->stillWorking();
 }
 public function processRequest()
 {
     $timeline_table = new PhabricatorTimelineEvent('NULL');
     $events = queryfx_all($timeline_table->establishConnection('r'), 'SELECT id, type FROM %T ORDER BY id DESC LIMIT 100', $timeline_table->getTableName());
     $rows = array();
     foreach ($events as $event) {
         $rows[] = array(phutil_render_tag('a', array('href' => '/daemon/timeline/' . $event['id'] . '/'), $event['id']), phutil_escape_html($event['type']));
     }
     $event_table = new AphrontTableView($rows);
     $event_table->setHeaders(array('ID', 'Type'));
     $event_table->setColumnClasses(array(null, 'wide'));
     $event_panel = new AphrontPanelView();
     $event_panel->setHeader('Timeline Events');
     $event_panel->appendChild($event_table);
     return $this->buildStandardPageResponse(array($event_panel), array('title' => 'Timeline', 'tab' => 'timeline'));
 }
 protected function loadEvents()
 {
     if (!$this->cursor) {
         $this->cursor = id(new PhabricatorTimelineCursor())->loadOneWhere('name = %s', $this->cursorName);
         if (!$this->cursor) {
             $cursor = new PhabricatorTimelineCursor();
             $cursor->setName($this->cursorName);
             $cursor->setPosition(0);
             $cursor->save();
             $this->cursor = $cursor;
         }
     }
     $event = new PhabricatorTimelineEvent('NULL');
     $event_data = new PhabricatorTimelineEventData();
     $raw_data = queryfx_all($event->establishConnection('r'), 'SELECT event.*, event_data.eventData eventData
     FROM %T event
     LEFT JOIN %T event_data ON event_data.id = event.dataID
     WHERE event.id > %d AND event.type in (%Ls)
     ORDER BY event.id ASC LIMIT %d', $event->getTableName(), $event_data->getTableName(), $this->cursor->getPosition(), $this->eventTypes, self::LOAD_CHUNK_SIZE);
     $events = $event->loadAllFromArray($raw_data);
     $events = mpull($events, null, 'getID');
     $raw_data = ipull($raw_data, 'eventData', 'id');
     foreach ($raw_data as $id => $data) {
         if ($data) {
             $decoded = json_decode($data, true);
             $events[$id]->setData($decoded);
         }
     }
     $this->events = $events;
     if ($this->events) {
         $this->events = array_values($this->events);
         $this->index = 0;
     } else {
         $this->cursor = null;
     }
 }
 private function recordCommit(PhabricatorRepository $repository, $commit_identifier, $epoch, $branch = null)
 {
     $commit = new PhabricatorRepositoryCommit();
     $commit->setRepositoryID($repository->getID());
     $commit->setCommitIdentifier($commit_identifier);
     $commit->setEpoch($epoch);
     $data = new PhabricatorRepositoryCommitData();
     if ($branch) {
         $data->setCommitDetail('seenOnBranches', array($branch));
     }
     try {
         $commit->openTransaction();
         $commit->save();
         $data->setCommitID($commit->getID());
         $data->save();
         $commit->saveTransaction();
         $event = new PhabricatorTimelineEvent('cmit', array('id' => $commit->getID()));
         $event->recordEvent();
         $this->insertTask($repository, $commit);
         queryfx($repository->establishConnection('w'), 'INSERT INTO %T (repositoryID, size, lastCommitID, epoch)
       VALUES (%d, 1, %d, %d)
       ON DUPLICATE KEY UPDATE
         size = size + 1,
         lastCommitID =
           IF(VALUES(epoch) > epoch, VALUES(lastCommitID), lastCommitID),
         epoch = IF(VALUES(epoch) > epoch, VALUES(epoch), epoch)', PhabricatorRepository::TABLE_SUMMARY, $repository->getID(), $commit->getID(), $epoch);
         if ($this->repair) {
             // Normally, the query should throw a duplicate key exception. If we
             // reach this in repair mode, we've actually performed a repair.
             $this->log("Repaired commit '{$commit_identifier}'.");
         }
         $this->setCache($repository, $commit_identifier);
         PhutilEventEngine::dispatchEvent(new PhabricatorEvent(PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT, array('repository' => $repository, 'commit' => $commit)));
     } catch (AphrontQueryDuplicateKeyException $ex) {
         $commit->killTransaction();
         // Ignore. This can happen because we discover the same new commit
         // more than once when looking at history, or because of races or
         // data inconsistency or cosmic radiation; in any case, we're still
         // in a good state if we ignore the failure.
         $this->setCache($repository, $commit_identifier);
     }
 }