1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-08 22:01:03 +01:00

Provide read and overwrite for Lisk counters

Summary:
Ref T6881. This is part 1 of my 35-step plan to support subscriptions that bill monthly.

Expanding the capabilities of counters will let me use them to create a logical clock on time-based event updates, build a daemon on top of that, and eventually get time-based triggers.

Test Plan: Added and executed unit tests.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: chad, epriestley

Maniphest Tasks: T6881

Differential Revision: https://secure.phabricator.com/D11395
This commit is contained in:
epriestley 2015-01-14 12:15:47 -08:00
parent 2297a43d44
commit 7ab5d108a4
3 changed files with 72 additions and 14 deletions

View file

@ -2231,7 +2231,6 @@ phutil_register_library_map(array(
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
'PhabricatorProjectWikiExplainController' => 'applications/project/controller/PhabricatorProjectWikiExplainController.php',
'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
@ -5459,7 +5458,6 @@ phutil_register_library_map(array(
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
'PhabricatorProjectWikiExplainController' => 'PhabricatorProjectController',
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',

View file

@ -1173,7 +1173,7 @@ abstract class LiskDAO {
$id_key = $this->getIDKeyForUse();
if (empty($data[$id_key])) {
$counter_name = $this->getTableName();
$id = self::loadNextCounterID($conn, $counter_name);
$id = self::loadNextCounterValue($conn, $counter_name);
$this->setID($id);
$data[$id_key] = $id;
}
@ -1688,6 +1688,7 @@ abstract class LiskDAO {
$this->$name = $value;
}
/**
* Increments a named counter and returns the next value.
*
@ -1697,7 +1698,7 @@ abstract class LiskDAO {
*
* @task util
*/
public static function loadNextCounterID(
public static function loadNextCounterValue(
AphrontDatabaseConnection $conn_w,
$counter_name) {
@ -1721,6 +1722,58 @@ abstract class LiskDAO {
return $conn_w->getInsertID();
}
/**
* Returns the current value of a named counter.
*
* @param AphrontDatabaseConnection Database where the counter resides.
* @param string Counter name to read.
* @return int|null Current value, or `null` if the counter does not exist.
*
* @task util
*/
public static function loadCurrentCounterValue(
AphrontDatabaseConnection $conn_r,
$counter_name) {
$row = queryfx_one(
$conn_r,
'SELECT counterValue FROM %T WHERE counterName = %s',
self::COUNTER_TABLE_NAME,
$counter_name);
if (!$row) {
return null;
}
return (int)$row['counterValue'];
}
/**
* Overwrite a named counter, forcing it to a specific value.
*
* If the counter does not exist, it is created.
*
* @param AphrontDatabaseConnection Database where the counter resides.
* @param string Counter name to create or overwrite.
* @return void
*
* @task util
*/
public static function overwriteCounterValue(
AphrontDatabaseConnection $conn_w,
$counter_name,
$counter_value) {
queryfx(
$conn_w,
'INSERT INTO %T (counterName, counterValue) VALUES (%s, %d)
ON DUPLICATE KEY UPDATE counterValue = VALUES(counterValue)',
self::COUNTER_TABLE_NAME,
$counter_name,
$counter_value);
}
private function getBinaryColumns() {
return $this->getConfigOption(self::CONFIG_BINARY);
}

View file

@ -99,14 +99,21 @@ final class LiskFixtureTestCase extends PhabricatorTestCase {
$conn_w = $obj->establishConnection('w');
// Test that the counter bascially behaves as expected.
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'a'));
$this->assertEqual(2, LiskDAO::loadNextCounterID($conn_w, 'a'));
$this->assertEqual(3, LiskDAO::loadNextCounterID($conn_w, 'a'));
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_w, 'a'));
$this->assertEqual(2, LiskDAO::loadNextCounterValue($conn_w, 'a'));
$this->assertEqual(3, LiskDAO::loadNextCounterValue($conn_w, 'a'));
// This first insert is primarily a test that the previous LAST_INSERT_ID()
// value does not bleed into the creation of a new counter.
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'b'));
$this->assertEqual(2, LiskDAO::loadNextCounterID($conn_w, 'b'));
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_w, 'b'));
$this->assertEqual(2, LiskDAO::loadNextCounterValue($conn_w, 'b'));
// Test alternate access/overwrite methods.
$this->assertEqual(3, LiskDAO::loadCurrentCounterValue($conn_w, 'a'));
LiskDAO::overwriteCounterValue($conn_w, 'a', 42);
$this->assertEqual(42, LiskDAO::loadCurrentCounterValue($conn_w, 'a'));
$this->assertEqual(43, LiskDAO::loadNextCounterValue($conn_w, 'a'));
// These inserts alternate database connections. Since unit tests are
// transactional by default, we need to break out of them or we'll deadlock
@ -117,11 +124,11 @@ final class LiskFixtureTestCase extends PhabricatorTestCase {
$conn_1 = $obj->establishConnection('w', $force_new = true);
$conn_2 = $obj->establishConnection('w', $force_new = true);
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_1, 'z'));
$this->assertEqual(2, LiskDAO::loadNextCounterID($conn_2, 'z'));
$this->assertEqual(3, LiskDAO::loadNextCounterID($conn_1, 'z'));
$this->assertEqual(4, LiskDAO::loadNextCounterID($conn_2, 'z'));
$this->assertEqual(5, LiskDAO::loadNextCounterID($conn_1, 'z'));
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_1, 'z'));
$this->assertEqual(2, LiskDAO::loadNextCounterValue($conn_2, 'z'));
$this->assertEqual(3, LiskDAO::loadNextCounterValue($conn_1, 'z'));
$this->assertEqual(4, LiskDAO::loadNextCounterValue($conn_2, 'z'));
$this->assertEqual(5, LiskDAO::loadNextCounterValue($conn_1, 'z'));
LiskDAO::beginIsolateAllLiskEffectsToTransactions();
} catch (Exception $ex) {