mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-24 05:28:18 +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:
parent
2297a43d44
commit
7ab5d108a4
3 changed files with 72 additions and 14 deletions
|
@ -2231,7 +2231,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
|
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
|
||||||
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
|
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
|
||||||
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
|
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
|
||||||
'PhabricatorProjectWikiExplainController' => 'applications/project/controller/PhabricatorProjectWikiExplainController.php',
|
|
||||||
'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
|
'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
|
||||||
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
|
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
|
||||||
'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
|
'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
|
||||||
|
@ -5459,7 +5458,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
|
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
|
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
|
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
|
||||||
'PhabricatorProjectWikiExplainController' => 'PhabricatorProjectController',
|
|
||||||
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
|
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
|
||||||
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ abstract class LiskDAO {
|
||||||
$id_key = $this->getIDKeyForUse();
|
$id_key = $this->getIDKeyForUse();
|
||||||
if (empty($data[$id_key])) {
|
if (empty($data[$id_key])) {
|
||||||
$counter_name = $this->getTableName();
|
$counter_name = $this->getTableName();
|
||||||
$id = self::loadNextCounterID($conn, $counter_name);
|
$id = self::loadNextCounterValue($conn, $counter_name);
|
||||||
$this->setID($id);
|
$this->setID($id);
|
||||||
$data[$id_key] = $id;
|
$data[$id_key] = $id;
|
||||||
}
|
}
|
||||||
|
@ -1688,6 +1688,7 @@ abstract class LiskDAO {
|
||||||
$this->$name = $value;
|
$this->$name = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments a named counter and returns the next value.
|
* Increments a named counter and returns the next value.
|
||||||
*
|
*
|
||||||
|
@ -1697,7 +1698,7 @@ abstract class LiskDAO {
|
||||||
*
|
*
|
||||||
* @task util
|
* @task util
|
||||||
*/
|
*/
|
||||||
public static function loadNextCounterID(
|
public static function loadNextCounterValue(
|
||||||
AphrontDatabaseConnection $conn_w,
|
AphrontDatabaseConnection $conn_w,
|
||||||
$counter_name) {
|
$counter_name) {
|
||||||
|
|
||||||
|
@ -1721,6 +1722,58 @@ abstract class LiskDAO {
|
||||||
return $conn_w->getInsertID();
|
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() {
|
private function getBinaryColumns() {
|
||||||
return $this->getConfigOption(self::CONFIG_BINARY);
|
return $this->getConfigOption(self::CONFIG_BINARY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,14 +99,21 @@ final class LiskFixtureTestCase extends PhabricatorTestCase {
|
||||||
$conn_w = $obj->establishConnection('w');
|
$conn_w = $obj->establishConnection('w');
|
||||||
|
|
||||||
// Test that the counter bascially behaves as expected.
|
// Test that the counter bascially behaves as expected.
|
||||||
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'a'));
|
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_w, 'a'));
|
||||||
$this->assertEqual(2, LiskDAO::loadNextCounterID($conn_w, 'a'));
|
$this->assertEqual(2, LiskDAO::loadNextCounterValue($conn_w, 'a'));
|
||||||
$this->assertEqual(3, LiskDAO::loadNextCounterID($conn_w, 'a'));
|
$this->assertEqual(3, LiskDAO::loadNextCounterValue($conn_w, 'a'));
|
||||||
|
|
||||||
// This first insert is primarily a test that the previous LAST_INSERT_ID()
|
// This first insert is primarily a test that the previous LAST_INSERT_ID()
|
||||||
// value does not bleed into the creation of a new counter.
|
// value does not bleed into the creation of a new counter.
|
||||||
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_w, 'b'));
|
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_w, 'b'));
|
||||||
$this->assertEqual(2, LiskDAO::loadNextCounterID($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
|
// These inserts alternate database connections. Since unit tests are
|
||||||
// transactional by default, we need to break out of them or we'll deadlock
|
// 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_1 = $obj->establishConnection('w', $force_new = true);
|
||||||
$conn_2 = $obj->establishConnection('w', $force_new = true);
|
$conn_2 = $obj->establishConnection('w', $force_new = true);
|
||||||
|
|
||||||
$this->assertEqual(1, LiskDAO::loadNextCounterID($conn_1, 'z'));
|
$this->assertEqual(1, LiskDAO::loadNextCounterValue($conn_1, 'z'));
|
||||||
$this->assertEqual(2, LiskDAO::loadNextCounterID($conn_2, 'z'));
|
$this->assertEqual(2, LiskDAO::loadNextCounterValue($conn_2, 'z'));
|
||||||
$this->assertEqual(3, LiskDAO::loadNextCounterID($conn_1, 'z'));
|
$this->assertEqual(3, LiskDAO::loadNextCounterValue($conn_1, 'z'));
|
||||||
$this->assertEqual(4, LiskDAO::loadNextCounterID($conn_2, 'z'));
|
$this->assertEqual(4, LiskDAO::loadNextCounterValue($conn_2, 'z'));
|
||||||
$this->assertEqual(5, LiskDAO::loadNextCounterID($conn_1, 'z'));
|
$this->assertEqual(5, LiskDAO::loadNextCounterValue($conn_1, 'z'));
|
||||||
|
|
||||||
LiskDAO::beginIsolateAllLiskEffectsToTransactions();
|
LiskDAO::beginIsolateAllLiskEffectsToTransactions();
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue