diff --git a/resources/sql/autopatches/20180306.opath.01.digest.sql b/resources/sql/autopatches/20180306.opath.01.digest.sql new file mode 100644 index 0000000000..2418366fc5 --- /dev/null +++ b/resources/sql/autopatches/20180306.opath.01.digest.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_owners.owners_path + ADD pathIndex BINARY(12) NOT NULL; diff --git a/resources/sql/autopatches/20180306.opath.02.digestpopulate.php b/resources/sql/autopatches/20180306.opath.02.digestpopulate.php new file mode 100644 index 0000000000..a6b817fc46 --- /dev/null +++ b/resources/sql/autopatches/20180306.opath.02.digestpopulate.php @@ -0,0 +1,19 @@ +establishConnection('w'); + +foreach (new LiskMigrationIterator($table) as $path) { + $index = PhabricatorHash::digestForIndex($path->getPath()); + + if ($index === $path->getPathIndex()) { + continue; + } + + queryfx( + $conn, + 'UPDATE %T SET pathIndex = %s WHERE id = %d', + $table->getTableName(), + $index, + $path->getID()); +} diff --git a/src/applications/owners/storage/PhabricatorOwnersPath.php b/src/applications/owners/storage/PhabricatorOwnersPath.php index f240db2851..47f7faa2b3 100644 --- a/src/applications/owners/storage/PhabricatorOwnersPath.php +++ b/src/applications/owners/storage/PhabricatorOwnersPath.php @@ -1,110 +1,117 @@ false, self::CONFIG_COLUMN_SCHEMA => array( 'path' => 'text255', + 'pathIndex' => 'bytes12', 'excluded' => 'bool', ), self::CONFIG_KEY_SCHEMA => array( 'packageID' => array( 'columns' => array('packageID'), ), ), ) + parent::getConfiguration(); } - public static function newFromRef(array $ref) { $path = new PhabricatorOwnersPath(); $path->repositoryPHID = $ref['repositoryPHID']; - $path->path = $ref['path']; + + $raw_path = $ref['path']; + + $path->pathIndex = PhabricatorHash::digestForIndex($raw_path); + $path->path = $raw_path; + $path->excluded = $ref['excluded']; + return $path; } public function getRef() { return array( 'repositoryPHID' => $this->getRepositoryPHID(), 'path' => $this->getPath(), 'excluded' => (int)$this->getExcluded(), ); } public static function getTransactionValueChanges(array $old, array $new) { return array( self::getTransactionValueDiff($old, $new), self::getTransactionValueDiff($new, $old), ); } private static function getTransactionValueDiff(array $u, array $v) { $set = self::getSetFromTransactionValue($v); foreach ($u as $key => $ref) { if (self::isRefInSet($ref, $set)) { unset($u[$key]); } } return $u; } public static function getSetFromTransactionValue(array $v) { $set = array(); foreach ($v as $ref) { $set[$ref['repositoryPHID']][$ref['path']][$ref['excluded']] = true; } return $set; } public static function isRefInSet(array $ref, array $set) { return isset($set[$ref['repositoryPHID']][$ref['path']][$ref['excluded']]); } /** * Get the number of directory matches between this path specification and * some real path. */ public function getPathMatchStrength($path_fragments, $path_count) { $this_path = $this->path; if ($this_path === '/') { // The root path "/" just matches everything with strength 1. return 1; } if ($this->fragments === null) { $this->fragments = PhabricatorOwnersPackage::splitPath($this_path); $this->fragmentCount = count($this->fragments); } $self_fragments = $this->fragments; $self_count = $this->fragmentCount; if ($self_count > $path_count) { // If this path is longer (and therefore more specific) than the target // path, we don't match it at all. return 0; } for ($ii = 0; $ii < $self_count; $ii++) { if ($self_fragments[$ii] != $path_fragments[$ii]) { return 0; } } return $self_count; } }