diff --git a/resources/sql/autopatches/20180904.commit.01.unreachable.sql b/resources/sql/autopatches/20180904.commit.01.unreachable.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20180904.commit.01.unreachable.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_repository.repository_commit + ADD isUnreachable BOOL NOT NULL; diff --git a/resources/sql/autopatches/20180904.commit.02.reachability.sql b/resources/sql/autopatches/20180904.commit.02.reachability.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20180904.commit.02.reachability.sql @@ -0,0 +1,2 @@ +UPDATE {$NAMESPACE}_repository.repository_commit + SET isUnreachable = IF((importStatus & 2048) = 2048, 1, 0); diff --git a/scripts/repository/rebuild_summaries.php b/scripts/repository/rebuild_summaries.php deleted file mode 100755 --- a/scripts/repository/rebuild_summaries.php +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env php -establishConnection('w'); -$sizes = queryfx_all( - $conn_w, - 'SELECT repositoryID, count(*) N FROM %T GROUP BY repositoryID', - $commit->getTableName()); -$sizes = ipull($sizes, 'N', 'repositoryID'); - -$maxes = queryfx_all( - $conn_w, - 'SELECT repositoryID, max(epoch) maxEpoch FROM %T GROUP BY repositoryID', - $commit->getTableName()); -$maxes = ipull($maxes, 'maxEpoch', 'repositoryID'); - - -$repository_ids = array_keys($sizes + $maxes); - -echo pht('Updating %d repositories', count($repository_ids)); - -foreach ($repository_ids as $repository_id) { - $last_commit = queryfx_one( - $conn_w, - 'SELECT id FROM %T WHERE repositoryID = %d AND epoch = %d LIMIT 1', - $commit->getTableName(), - $repository_id, - idx($maxes, $repository_id, 0)); - if ($last_commit) { - $last_commit = $last_commit['id']; - } else { - $last_commit = 0; - } - queryfx( - $conn_w, - 'INSERT INTO %T (repositoryID, lastCommitID, size, epoch) - VALUES (%d, %d, %d, %d) ON DUPLICATE KEY UPDATE - lastCommitID = VALUES(lastCommitID), - size = VALUES(size), - epoch = VALUES(epoch)', - PhabricatorRepository::TABLE_SUMMARY, - $repository_id, - $last_commit, - idx($sizes, $repository_id, 0), - idx($maxes, $repository_id, 0)); - echo '.'; -} -echo "\n".pht('Done.')."\n"; diff --git a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php --- a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php @@ -912,14 +912,31 @@ private function rebuildSummaryTable(PhabricatorRepository $repository) { $conn_w = $repository->establishConnection('w'); - $data = queryfx_one( + // See PHI842. This awkward construction allows us to hit keys on both + // parts of the query. + + $repository_table = id(new PhabricatorRepositoryCommit())->getTableName(); + $repository_id = $repository->getID(); + + $data = queryfx_all( $conn_w, - 'SELECT COUNT(*) N, MAX(id) id, MAX(epoch) epoch - FROM %T WHERE repositoryID = %d AND (importStatus & %d) != %d', - id(new PhabricatorRepositoryCommit())->getTableName(), - $repository->getID(), - PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE, - PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE); + '(SELECT %s Label, COUNT(*) N, MAX(id) Max + FROM %T WHERE repositoryID = %d AND isUnreachable = 0) + UNION ALL + (SELECT %s Label, 0 N, MAX(epoch) + FROM %T WHERE repositoryID = %d AND isUnreachable = 0)', + 'size', + $repository_table, + $repository_id, + 'epoch', + $repository_table, + $repository_id); + + $data = ipull($data, null, 'Label'); + + $repository_size = (int)$data['size']['N']; + $repository_max = (int)$data['size']['Max']; + $repository_epoch = (int)$data['epoch']['Max']; queryfx( $conn_w, @@ -930,10 +947,10 @@ lastCommitID = VALUES(lastCommitID), epoch = VALUES(epoch)', PhabricatorRepository::TABLE_SUMMARY, - $repository->getID(), - $data['N'], - $data['id'], - $data['epoch']); + $repository_id, + $repository_size, + $repository_max, + $repository_epoch); } } diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -30,6 +30,7 @@ protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE; protected $summary = ''; protected $importStatus = 0; + protected $isUnreachable = 0; const IMPORTED_MESSAGE = 1; const IMPORTED_CHANGE = 2; @@ -87,26 +88,40 @@ $table_name = $this->getTableName(); $id = $this->getID(); + if ($set) { + $new_flags = ($this->getImportStatus() | $flag); + } else { + $new_flags = ($this->getImportStatus() & ~$flag); + } + + $is_unreachable = (bool)($new_flags & self::IMPORTED_UNREACHABLE); + if ($set) { queryfx( $conn_w, - 'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d', + 'UPDATE %T SET + importStatus = (importStatus | %d), + isUnreachable = %d + WHERE id = %d', $table_name, $flag, + (int)$is_unreachable, $id); - - $this->setImportStatus($this->getImportStatus() | $flag); } else { queryfx( $conn_w, - 'UPDATE %T SET importStatus = (importStatus & ~%d) WHERE id = %d', + 'UPDATE %T SET + importStatus = (importStatus & ~%d), + isUnreachable = %d + WHERE id = %d', $table_name, $flag, + (int)$is_unreachable, $id); - - $this->setImportStatus($this->getImportStatus() & ~$flag); } + $this->setImportStatus($new_flags); + return $this; } @@ -123,6 +138,7 @@ 'auditStatus' => 'uint32', 'summary' => 'text255', 'importStatus' => 'uint32', + 'isUnreachable' => 'bool', ), self::CONFIG_KEY_SCHEMA => array( 'key_phid' => null, @@ -149,6 +165,12 @@ 'key_author' => array( 'columns' => array('authorPHID', 'epoch'), ), + 'key_epoch_summary' => array( + 'columns' => array('repositoryID', 'isUnreachable', 'epoch'), + ), + 'key_count_summary' => array( + 'columns' => array('repositoryID', 'isUnreachable', 'id'), + ), ), self::CONFIG_NO_MUTATE => array( 'importStatus',