diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index cd3ab4b682..c1a9526ea2 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -401,6 +401,7 @@ phutil_register_library_map(array( 'JavelinViewExample' => 'applications/uiexample/examples/client', 'JavelinViewExampleServerView' => 'applications/uiexample/examples/client', 'LiskDAO' => 'storage/lisk/dao', + 'LiskEphemeralObjectException' => 'storage/lisk/dao', 'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__', 'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__', 'LiskIsolationTestDAOException' => 'storage/lisk/dao/__tests__', diff --git a/src/storage/lisk/dao/LiskDAO.php b/src/storage/lisk/dao/LiskDAO.php index cae002ea45..0e501542c5 100644 --- a/src/storage/lisk/dao/LiskDAO.php +++ b/src/storage/lisk/dao/LiskDAO.php @@ -193,6 +193,8 @@ abstract class LiskDAO { private static $processIsolationLevel = 0; private static $__checkedClasses = array(); + private $__ephemeral = false; + /** * Build an empty object. * @@ -778,6 +780,24 @@ abstract class LiskDAO { /* -( Writing Objects )---------------------------------------------------- */ + /** + * Make an object read-only. + * + * Making an object ephemeral indicates that you will be changing state in + * such a way that you would never ever want it to be written to back to the + * storage. + */ + public function makeEphemeral() { + $this->__ephemeral = true; + return $this; + } + + private function isEphemeralCheck() { + if ($this->__ephemeral) { + throw new LiskEphemeralObjectException(); + } + } + /** * Persist this object to the database. In most cases, this is the only * method you need to call to do writes. If the object has not yet been @@ -805,6 +825,7 @@ abstract class LiskDAO { * @task save */ public function replace() { + $this->isEphemeralCheck(); return $this->insertRecordIntoDatabase('REPLACE'); } @@ -818,6 +839,7 @@ abstract class LiskDAO { * @task save */ public function insert() { + $this->isEphemeralCheck(); return $this->insertRecordIntoDatabase('INSERT'); } @@ -831,6 +853,7 @@ abstract class LiskDAO { * @task save */ public function update() { + $this->isEphemeralCheck(); $use_locks = $this->getConfigOption(self::CONFIG_OPTIMISTIC_LOCKS); $this->willSaveObject(); @@ -899,6 +922,7 @@ abstract class LiskDAO { * @task save */ public function delete() { + $this->isEphemeralCheck(); $this->willDelete(); $conn = $this->establishConnection('w'); diff --git a/src/storage/lisk/dao/LiskEphemeralObjectException.php b/src/storage/lisk/dao/LiskEphemeralObjectException.php new file mode 100644 index 0000000000..588c3fafe7 --- /dev/null +++ b/src/storage/lisk/dao/LiskEphemeralObjectException.php @@ -0,0 +1,19 @@ +assertEqual($phid, $dao->getPHID(), 'Expect PHID unchanged.'); } + public function testEphemeral() { + $dao = new LiskIsolationTestDAO(); + $dao->save(); + $dao->makeEphemeral(); + + $this->assertException( + 'LiskEphemeralObjectException', + function() use ($dao) { + $dao->save(); + } + ); + } + public function testIsolationContainment() { $dao = new LiskIsolationTestDAO();