function commit_symbols($syms, $project, $no_purge) { echo "Looking up path IDs...\n"; $path_map = PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(ipull($syms, 'path')); $symbol = new PhabricatorRepositorySymbol(); $conn_w = $symbol->establishConnection('w'); echo "Preparing queries...\n"; $sql = array(); foreach ($syms as $dict) { $sql[] = qsprintf($conn_w, '(%d, %s, %s, %s, %s, %d, %d)', $project->getID(), $dict['ctxt'], $dict['name'], $dict['type'], $dict['lang'], $dict['line'], $path_map[$dict['path']]); } if (!$no_purge) { echo "Purging old syms...\n"; queryfx($conn_w, 'DELETE FROM %T WHERE arcanistProjectID = %d', $symbol->getTableName(), $project->getID()); } echo "Loading " . number_format(count($sql)) . " syms...\n"; foreach (array_chunk($sql, 128) as $chunk) { queryfx($conn_w, 'INSERT INTO %T (arcanistProjectID, symbolContext, symbolName, symbolType, symbolLanguage, lineNumber, pathID) VALUES %Q', $symbol->getTableName(), implode(', ', $chunk)); } }
function commit_symbols(array $symbols, PhabricatorRepository $repository, $no_purge) { echo pht('Looking up path IDs...'), "\n"; $path_map = PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(ipull($symbols, 'path')); $symbol = new PhabricatorRepositorySymbol(); $conn_w = $symbol->establishConnection('w'); echo pht('Preparing queries...'), "\n"; $sql = array(); foreach ($symbols as $dict) { $sql[] = qsprintf($conn_w, '(%s, %s, %s, %s, %s, %d, %d)', $repository->getPHID(), $dict['ctxt'], $dict['name'], $dict['type'], $dict['lang'], $dict['line'], $path_map[$dict['path']]); } if (!$no_purge) { echo pht('Purging old symbols...'), "\n"; queryfx($conn_w, 'DELETE FROM %T WHERE repositoryPHID = %s', $symbol->getTableName(), $repository->getPHID()); } echo pht('Loading %s symbols...', phutil_count($sql)), "\n"; foreach (array_chunk($sql, 128) as $chunk) { queryfx($conn_w, 'INSERT INTO %T (repositoryPHID, symbolContext, symbolName, symbolType, symbolLanguage, lineNumber, pathID) VALUES %Q', $symbol->getTableName(), implode(', ', $chunk)); } }
/** * Update the table which links Differential revisions to paths they affect, * so Diffusion can efficiently find pending revisions for a given file. */ private function updateAffectedPathTable(DifferentialRevision $revision, DifferentialDiff $diff) { $repository = $revision->getRepository(); if (!$repository) { // The repository where the code lives is untracked. return; } $path_prefix = null; $local_root = $diff->getSourceControlPath(); if ($local_root) { // We're in a working copy which supports subdirectory checkouts (e.g., // SVN) so we need to figure out what prefix we should add to each path // (e.g., trunk/projects/example/) to get the absolute path from the // root of the repository. DVCS systems like Git and Mercurial are not // affected. // Normalize both paths and check if the repository root is a prefix of // the local root. If so, throw it away. Note that this correctly handles // the case where the remote path is "/". $local_root = id(new PhutilURI($local_root))->getPath(); $local_root = rtrim($local_root, '/'); $repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath(); $repo_root = rtrim($repo_root, '/'); if (!strncmp($repo_root, $local_root, strlen($repo_root))) { $path_prefix = substr($local_root, strlen($repo_root)); } } $changesets = $diff->getChangesets(); $paths = array(); foreach ($changesets as $changeset) { $paths[] = $path_prefix . '/' . $changeset->getFilename(); } // Mark this as also touching all parent paths, so you can see all pending // changes to any file within a directory. $all_paths = array(); foreach ($paths as $local) { foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) { $all_paths[$path] = true; } } $all_paths = array_keys($all_paths); $path_ids = PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths($all_paths); $table = new DifferentialAffectedPath(); $conn_w = $table->establishConnection('w'); $sql = array(); foreach ($path_ids as $path_id) { $sql[] = qsprintf($conn_w, '(%d, %d, %d, %d)', $repository->getID(), $path_id, time(), $revision->getID()); } queryfx($conn_w, 'DELETE FROM %T WHERE revisionID = %d', $table->getTableName(), $revision->getID()); foreach (array_chunk($sql, 256) as $chunk) { queryfx($conn_w, 'INSERT INTO %T (repositoryID, pathID, epoch, revisionID) VALUES %Q', $table->getTableName(), implode(', ', $chunk)); } }
$args = new PhutilArgumentParser($argv); $args->setSynopsis(<<<EOSYNOPSIS **clear_repository_symbols.php** [__options__] __repository__ Clear repository symbols. EOSYNOPSIS ); $args->parseStandardArguments(); $args->parse(array(array('name' => 'repository', 'wildcard' => true))); $identifiers = $args->getArg('repository'); if (count($identifiers) !== 1) { $args->printHelpAndExit(); } $identifier = head($identifiers); $repository = id(new PhabricatorRepositoryQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withIdentifiers($identifiers)->executeOne(); if (!$repository) { echo tsprintf("%s\n", pht('Repository "%s" does not exist.', $identifier)); exit(1); } $input = file_get_contents('php://stdin'); $normalized = array(); foreach (explode("\n", trim($input)) as $path) { // Emulate the behavior of the symbol generation scripts. $normalized[] = '/' . ltrim($path, './'); } $paths = PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths($normalized); $symbol = new PhabricatorRepositorySymbol(); $conn_w = $symbol->establishConnection('w'); foreach (array_chunk(array_values($paths), 128) as $chunk) { queryfx($conn_w, 'DELETE FROM %T WHERE repositoryPHID = %s AND pathID IN (%Ld)', $symbol->getTableName(), $repository->getPHID(), $chunk); }
if (strlen($name) > 128) { throw new Exception("Symbol name '{$name}' defined on line #{$line_no} is too long, maximum " . "symbol name length is 128 characters."); } if (strlen($type) > 12) { throw new Exception("Symbol type '{$type}' defined on line #{$line_no} is too long, maximum " . "symbol type length is 12 characters."); } if (strlen($lang) > 32) { throw new Exception("Symbol language '{$lang}' defined on line #{$line_no} is too long, " . "maximum symbol language length is 32 characters."); } if (!strlen($path) || $path[0] != 0) { throw new Exception("Path '{$path}' defined on line #{$line_no} is invalid. Paths should be " . "begin with '/' and specify a path from the root of the project, like " . "'/src/utils/utils.php'."); } $symbols[] = array('name' => $name, 'type' => $type, 'lang' => $lang, 'line' => $line_number, 'path' => $path); } echo "Looking up path IDs...\n"; $path_map = PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(ipull($symbols, 'path')); $symbol = new PhabricatorRepositorySymbol(); $conn_w = $symbol->establishConnection('w'); echo "Preparing queries...\n"; $sql = array(); foreach ($symbols as $dict) { $sql[] = qsprintf($conn_w, '(%d, %s, %s, %s, %d, %d)', $project->getID(), $dict['name'], $dict['type'], $dict['lang'], $dict['line'], $path_map[$dict['path']]); } echo "Purging old symbols...\n"; queryfx($conn_w, 'DELETE FROM %T WHERE arcanistProjectID = %d', $symbol->getTableName(), $project->getID()); echo "Loading " . number_format(count($sql)) . " symbols...\n"; foreach (array_chunk($sql, 128) as $chunk) { queryfx($conn_w, 'INSERT INTO %T (arcanistProjectID, symbolName, symbolType, symbolLanguage, lineNumber, pathID) VALUES %Q', $symbol->getTableName(), implode(', ', $chunk)); }