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

Add test coverage for "%R" in qsprintf() and convert LiskDAO to support it

Summary:
Ref T13210. Ref T11908. Add some basic test coverage for the new "%R" introduced in D19764, then convert LiskDAO to implement the "Database + Table Ref" interface.

To move forward, we need to convert all of these (where `%T` is not a table alias):

```counterexample
qsprintf($conn, '... %T ...', $thing->getTableName());
```

...to these:

```
qsprintf($conn, '... %R ...', $thing);
```

The new code is a little simpler (no `->getTableName()` call) which is sort of nice. But we also have a //lot// of `%T` so this is probably going to take a while.

(I'll hold this until after the release cut.)

Test Plan:
- Ran unit tests.
- Browsed around and edited some objects without issues. This change causes a reasonably large percentage of our total queries to use the new code since the LiskDAO builtin queries are some of the most commonly-constructed queries, although there are still ~700 callsites which need to be examined for possible conversion.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13210, T11908

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

+57 -25
+4 -1
src/__phutil_library_map__.php
··· 7131 7131 'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 7132 7132 'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView', 7133 7133 'LiskChunkTestCase' => 'PhabricatorTestCase', 7134 - 'LiskDAO' => 'Phobject', 7134 + 'LiskDAO' => array( 7135 + 'Phobject', 7136 + 'AphrontDatabaseTableRefInterface', 7137 + ), 7135 7138 'LiskDAOSet' => 'Phobject', 7136 7139 'LiskDAOTestCase' => 'PhabricatorTestCase', 7137 7140 'LiskEphemeralObjectException' => 'Exception',
+24 -11
src/infrastructure/storage/__tests__/QueryFormattingTestCase.php
··· 3 3 final class QueryFormattingTestCase extends PhabricatorTestCase { 4 4 5 5 public function testQueryFormatting() { 6 - $conn_r = id(new PhabricatorUser())->establishConnection('r'); 6 + $conn = id(new PhabricatorUser())->establishConnection('r'); 7 7 8 8 $this->assertEqual( 9 9 'NULL', 10 - qsprintf($conn_r, '%nd', null)); 10 + qsprintf($conn, '%nd', null)); 11 11 12 12 $this->assertEqual( 13 13 '0', 14 - qsprintf($conn_r, '%nd', 0)); 14 + qsprintf($conn, '%nd', 0)); 15 15 16 16 $this->assertEqual( 17 17 '0', 18 - qsprintf($conn_r, '%d', 0)); 18 + qsprintf($conn, '%d', 0)); 19 19 20 20 $raised = null; 21 21 try { 22 - qsprintf($conn_r, '%d', 'derp'); 22 + qsprintf($conn, '%d', 'derp'); 23 23 } catch (Exception $ex) { 24 24 $raised = $ex; 25 25 } ··· 29 29 30 30 $this->assertEqual( 31 31 "'<S>'", 32 - qsprintf($conn_r, '%s', null)); 32 + qsprintf($conn, '%s', null)); 33 33 34 34 $this->assertEqual( 35 35 'NULL', 36 - qsprintf($conn_r, '%ns', null)); 36 + qsprintf($conn, '%ns', null)); 37 37 38 38 $this->assertEqual( 39 39 "'<S>', '<S>'", 40 - qsprintf($conn_r, '%Ls', array('x', 'y'))); 40 + qsprintf($conn, '%Ls', array('x', 'y'))); 41 41 42 42 $this->assertEqual( 43 43 "'<B>'", 44 - qsprintf($conn_r, '%B', null)); 44 + qsprintf($conn, '%B', null)); 45 45 46 46 $this->assertEqual( 47 47 'NULL', 48 - qsprintf($conn_r, '%nB', null)); 48 + qsprintf($conn, '%nB', null)); 49 49 50 50 $this->assertEqual( 51 51 "'<B>', '<B>'", 52 - qsprintf($conn_r, '%LB', array('x', 'y'))); 52 + qsprintf($conn, '%LB', array('x', 'y'))); 53 + 54 + $this->assertEqual( 55 + '<C>', 56 + qsprintf($conn, '%T', 'x')); 57 + 58 + $this->assertEqual( 59 + '<C>', 60 + qsprintf($conn, '%C', 'y')); 61 + 62 + $this->assertEqual( 63 + '<C>.<C>', 64 + qsprintf($conn, '%R', new AphrontDatabaseTableRef('x', 'y'))); 65 + 53 66 } 54 67 55 68
+27 -10
src/infrastructure/storage/lisk/LiskDAO.php
··· 162 162 * @task xaction Managing Transactions 163 163 * @task isolate Isolation for Unit Testing 164 164 */ 165 - abstract class LiskDAO extends Phobject { 165 + abstract class LiskDAO extends Phobject 166 + implements AphrontDatabaseTableRefInterface { 166 167 167 168 const CONFIG_IDS = 'id-mechanism'; 168 169 const CONFIG_TIMESTAMPS = 'timestamps'; ··· 235 236 * @return string Connection namespace for cache 236 237 * @task conn 237 238 */ 238 - abstract protected function getConnectionNamespace(); 239 + protected function getConnectionNamespace() { 240 + return $this->getDatabaseName(); 241 + } 239 242 243 + abstract protected function getDatabaseName(); 240 244 241 245 /** 242 246 * Get an existing, cached connection for this object. ··· 525 529 $args = func_get_args(); 526 530 $args = array_slice($args, 1); 527 531 528 - $pattern = 'SELECT * FROM %T WHERE '.$pattern.' %Q'; 529 - array_unshift($args, $this->getTableName()); 532 + $pattern = 'SELECT * FROM %R WHERE '.$pattern.' %Q'; 533 + array_unshift($args, $this); 530 534 array_push($args, $lock_clause); 531 535 array_unshift($args, $pattern); 532 536 ··· 1150 1154 1151 1155 $id = $this->getID(); 1152 1156 $conn->query( 1153 - 'UPDATE %T SET %Q WHERE %C = '.(is_int($id) ? '%d' : '%s'), 1154 - $this->getTableName(), 1157 + 'UPDATE %R SET %Q WHERE %C = '.(is_int($id) ? '%d' : '%s'), 1158 + $this, 1155 1159 $map, 1156 1160 $this->getIDKeyForUse(), 1157 1161 $id); ··· 1178 1182 1179 1183 $conn = $this->establishConnection('w'); 1180 1184 $conn->query( 1181 - 'DELETE FROM %T WHERE %C = %d', 1182 - $this->getTableName(), 1185 + 'DELETE FROM %R WHERE %C = %d', 1186 + $this, 1183 1187 $this->getIDKeyForUse(), 1184 1188 $this->getID()); 1185 1189 ··· 1255 1259 $data = implode(', ', $data); 1256 1260 1257 1261 $conn->query( 1258 - '%Q INTO %T (%LC) VALUES (%Q)', 1262 + '%Q INTO %R (%LC) VALUES (%Q)', 1259 1263 $mode, 1260 - $this->getTableName(), 1264 + $this, 1261 1265 $columns, 1262 1266 $data); 1263 1267 ··· 2018 2022 return id(new PhabricatorStorageSchemaSpec()) 2019 2023 ->getMaximumByteLengthForDataType($data_type); 2020 2024 } 2025 + 2026 + 2027 + /* -( AphrontDatabaseTableRefInterface )----------------------------------- */ 2028 + 2029 + 2030 + public function getAphrontRefDatabaseName() { 2031 + return $this->getDatabaseName(); 2032 + } 2033 + 2034 + public function getAphrontRefTableName() { 2035 + return $this->getTableName(); 2036 + } 2037 + 2021 2038 2022 2039 }
+1 -2
src/infrastructure/storage/lisk/PhabricatorLiskDAO.php
··· 187 187 */ 188 188 abstract public function getApplicationName(); 189 189 190 - protected function getConnectionNamespace() { 190 + protected function getDatabaseName() { 191 191 return self::getStorageNamespace().'_'.$this->getApplicationName(); 192 192 } 193 - 194 193 195 194 /** 196 195 * Break a list of escaped SQL statement fragments (e.g., VALUES lists for
+1 -1
src/infrastructure/storage/lisk/__tests__/LiskIsolationTestDAO.php
··· 22 22 'resource!')); 23 23 } 24 24 25 - protected function getConnectionNamespace() { 25 + protected function getDatabaseName() { 26 26 return 'test'; 27 27 } 28 28