@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow Almanac interfaces to be browsed

Summary:
Fixes T10205. Ref T10246. Previously, the issue was that the result set was not ordered, so "More Results" would not have been able to work in a reasonable way if there were more than 100 matching interfaces.

You would have seen 100 interfaces more or less at random, then clicked "more" and gotten 100 more random interfaces.

Now, you would see 100 "a" interfaces, then click more to get the next 100 alphabetical interfaces (say, "b" and "c" interfaces).

Test Plan:
- Clicked browse when binding an interface.
- Got a browse dialog.
- Artificially set query limit to 1, paged through "local" interfaces in an ordered, consistent way.

{F1121313}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10205, T10246

Differential Revision: https://secure.phabricator.com/D15320

+91 -34
+85 -26
src/applications/almanac/query/AlmanacInterfaceQuery.php
··· 34 34 return $this; 35 35 } 36 36 37 + public function newResultObject() { 38 + return new AlmanacInterface(); 39 + } 40 + 37 41 protected function loadPage() { 38 - $table = new AlmanacInterface(); 39 - $conn_r = $table->establishConnection('r'); 40 - 41 - $data = queryfx_all( 42 - $conn_r, 43 - 'SELECT * FROM %T %Q %Q %Q', 44 - $table->getTableName(), 45 - $this->buildWhereClause($conn_r), 46 - $this->buildOrderClause($conn_r), 47 - $this->buildLimitClause($conn_r)); 48 - 49 - return $table->loadAllFromArray($data); 42 + return $this->loadStandardPage($this->newResultObject()); 50 43 } 51 44 52 45 protected function willFilterPage(array $interfaces) { ··· 83 76 return $interfaces; 84 77 } 85 78 86 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 87 - $where = array(); 79 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 80 + $where = parent::buildWhereClauseParts($conn); 88 81 89 82 if ($this->ids !== null) { 90 83 $where[] = qsprintf( 91 - $conn_r, 92 - 'id IN (%Ld)', 84 + $conn, 85 + 'interface.id IN (%Ld)', 93 86 $this->ids); 94 87 } 95 88 96 89 if ($this->phids !== null) { 97 90 $where[] = qsprintf( 98 - $conn_r, 99 - 'phid IN (%Ls)', 91 + $conn, 92 + 'interface.phid IN (%Ls)', 100 93 $this->phids); 101 94 } 102 95 103 96 if ($this->networkPHIDs !== null) { 104 97 $where[] = qsprintf( 105 - $conn_r, 106 - 'networkPHID IN (%Ls)', 98 + $conn, 99 + 'interface.networkPHID IN (%Ls)', 107 100 $this->networkPHIDs); 108 101 } 109 102 110 103 if ($this->devicePHIDs !== null) { 111 104 $where[] = qsprintf( 112 - $conn_r, 113 - 'devicePHID IN (%Ls)', 105 + $conn, 106 + 'interface.devicePHID IN (%Ls)', 114 107 $this->devicePHIDs); 115 108 } 116 109 ··· 118 111 $parts = array(); 119 112 foreach ($this->addresses as $address) { 120 113 $parts[] = qsprintf( 121 - $conn_r, 122 - '(networkPHID = %s AND address = %s AND port = %d)', 114 + $conn, 115 + '(interface.networkPHID = %s '. 116 + 'AND interface.address = %s '. 117 + 'AND interface.port = %d)', 123 118 $address->getNetworkPHID(), 124 119 $address->getAddress(), 125 120 $address->getPort()); ··· 127 122 $where[] = implode(' OR ', $parts); 128 123 } 129 124 130 - $where[] = $this->buildPagingClause($conn_r); 125 + return $where; 126 + } 127 + 128 + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 129 + $joins = parent::buildJoinClauseParts($conn); 130 + 131 + if ($this->shouldJoinDeviceTable()) { 132 + $joins[] = qsprintf( 133 + $conn, 134 + 'JOIN %T device ON device.phid = interface.devicePHID', 135 + id(new AlmanacDevice())->getTableName()); 136 + } 137 + 138 + return $joins; 139 + } 131 140 132 - return $this->formatWhereClause($where); 141 + protected function shouldGroupQueryResultRows() { 142 + if ($this->shouldJoinDeviceTable()) { 143 + return true; 144 + } 145 + 146 + return parent::shouldGroupQueryResultRows(); 147 + } 148 + 149 + private function shouldJoinDeviceTable() { 150 + $vector = $this->getOrderVector(); 151 + 152 + if ($vector->containsKey('name')) { 153 + return true; 154 + } 155 + 156 + return false; 157 + } 158 + 159 + protected function getPrimaryTableAlias() { 160 + return 'interface'; 133 161 } 134 162 135 163 public function getQueryApplicationClass() { 136 164 return 'PhabricatorAlmanacApplication'; 165 + } 166 + 167 + public function getBuiltinOrders() { 168 + return array( 169 + 'name' => array( 170 + 'vector' => array('name', 'id'), 171 + 'name' => pht('Device Name'), 172 + ), 173 + ) + parent::getBuiltinOrders(); 174 + } 175 + 176 + public function getOrderableColumns() { 177 + return parent::getOrderableColumns() + array( 178 + 'name' => array( 179 + 'table' => 'device', 180 + 'column' => 'name', 181 + 'type' => 'string', 182 + 'reverse' => true, 183 + ), 184 + ); 185 + } 186 + 187 + protected function getPagingValueMap($cursor, array $keys) { 188 + $interface = $this->loadCursorObject($cursor); 189 + 190 + $map = array( 191 + 'id' => $interface->getID(), 192 + 'name' => $interface->getDevice()->getName(), 193 + ); 194 + 195 + return $map; 137 196 } 138 197 139 198 }
+4 -8
src/applications/almanac/typeahead/AlmanacInterfaceDatasource.php
··· 3 3 final class AlmanacInterfaceDatasource 4 4 extends PhabricatorTypeaheadDatasource { 5 5 6 - public function isBrowsable() { 7 - // TODO: We should make this browsable, but need to make the result set 8 - // orderable by device name. 9 - return false; 10 - } 11 - 12 6 public function getBrowseTitle() { 13 7 return pht('Browse Interfaces'); 14 8 } ··· 31 25 ->execute(); 32 26 33 27 if ($devices) { 34 - $interfaces = id(new AlmanacInterfaceQuery()) 28 + $interface_query = id(new AlmanacInterfaceQuery()) 35 29 ->setViewer($viewer) 36 30 ->withDevicePHIDs(mpull($devices, 'getPHID')) 37 - ->execute(); 31 + ->setOrder('name'); 32 + 33 + $interfaces = $this->executeQuery($interface_query); 38 34 } else { 39 35 $interfaces = array(); 40 36 }
+2
src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php
··· 107 107 if (($offset + (2 * $limit)) < $hard_limit) { 108 108 $next_uri = id(new PhutilURI($request->getRequestURI())) 109 109 ->setQueryParam('offset', $offset + $limit) 110 + ->setQueryParam('q', $query) 111 + ->setQueryParam('raw', $raw_query) 110 112 ->setQueryParam('format', 'html'); 111 113 112 114 $next_link = javelin_tag(