@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3$table = new PhabricatorRepositoryRefPosition();
4$conn = $table->establishConnection('w');
5$key_name = 'key_position';
6
7try {
8 queryfx(
9 $conn,
10 'ALTER TABLE %T DROP KEY %T',
11 $table->getTableName(),
12 $key_name);
13} catch (AphrontQueryException $ex) {
14 // This key may or may not exist, depending on exactly when the install
15 // ran previous migrations and adjustments. We're just dropping it if it
16 // does exist.
17
18 // We're doing this first (outside of the lock) because the MySQL
19 // documentation says "if you ALTER TABLE a locked table, it may become
20 // unlocked".
21}
22
23queryfx(
24 $conn,
25 'LOCK TABLES %T WRITE',
26 $table->getTableName());
27
28$seen = array();
29foreach (new LiskMigrationIterator($table) as $position) {
30 $cursor_id = $position->getCursorID();
31 $hash = $position->getCommitIdentifier();
32
33 // If this is the first copy of this row we've seen, mark it as seen and
34 // move on.
35 if (empty($seen[$cursor_id][$hash])) {
36 $seen[$cursor_id][$hash] = true;
37 continue;
38 }
39
40 // Otherwise, get rid of this row as it duplicates a row we saw previously.
41 $position->delete();
42}
43
44queryfx(
45 $conn,
46 'ALTER TABLE %T ADD UNIQUE KEY %T (cursorID, commitIdentifier)',
47 $table->getTableName(),
48 $key_name);
49
50queryfx(
51 $conn,
52 'UNLOCK TABLES');