3 final class PhabricatorRepositoryWorkingCopyVersion
4 extends PhabricatorRepositoryDAO
{
6 protected $repositoryPHID;
8 protected $repositoryVersion;
11 protected $writeProperties;
13 protected function getConfiguration() {
15 self
::CONFIG_TIMESTAMPS
=> false,
16 self
::CONFIG_COLUMN_SCHEMA
=> array(
17 'repositoryVersion' => 'uint32',
18 'isWriting' => 'bool',
19 'writeProperties' => 'text?',
20 'lockOwner' => 'text255?',
22 self
::CONFIG_KEY_SCHEMA
=> array(
23 'key_workingcopy' => array(
24 'columns' => array('repositoryPHID', 'devicePHID'),
28 ) + parent
::getConfiguration();
31 public function getWriteProperty($key, $default = null) {
32 // The "writeProperties" don't currently get automatically serialized or
33 // deserialized. Perhaps they should.
35 $properties = phutil_json_decode($this->writeProperties
);
36 return idx($properties, $key, $default);
37 } catch (Exception
$ex) {
42 public static function loadVersions($repository_phid) {
43 $version = new self();
44 $conn_w = $version->establishConnection('w');
45 $table = $version->getTableName();
47 // This is a normal read, but force it to come from the master.
50 'SELECT * FROM %T WHERE repositoryPHID = %s',
54 return $version->loadAllFromArray($rows);
57 public static function loadWriter($repository_phid) {
58 $version = new self();
59 $conn_w = $version->establishConnection('w');
60 $table = $version->getTableName();
62 // We're forcing this read to go to the master.
65 'SELECT * FROM %T WHERE repositoryPHID = %s AND isWriting = 1
74 return $version->loadFromArray($row);
78 public static function getReadLock($repository_phid, $device_phid) {
80 'repositoryPHID' => $repository_phid,
81 'devicePHID' => $device_phid,
84 return PhabricatorGlobalLock
::newLock('repo.read', $parameters);
87 public static function getWriteLock($repository_phid) {
89 'repositoryPHID' => $repository_phid,
92 return PhabricatorGlobalLock
::newLock('repo.write', $parameters);
97 * Before a write, set the "isWriting" flag.
99 * This allows us to detect when we lose a node partway through a write and
100 * may have committed and acknowledged a write on a node that lost the lock
101 * partway through the write and is no longer reachable.
103 * In particular, if a node loses its connection to the database the global
104 * lock is released by default. This is a durable lock which stays locked
107 public static function willWrite(
108 AphrontDatabaseConnection
$locked_connection,
111 array $write_properties,
114 $version = new self();
115 $table = $version->getTableName();
120 (repositoryPHID, devicePHID, repositoryVersion, isWriting,
121 writeProperties, lockOwner)
123 (%s, %s, %d, %d, %s, %s)
124 ON DUPLICATE KEY UPDATE
125 isWriting = VALUES(isWriting),
126 writeProperties = VALUES(writeProperties),
127 lockOwner = VALUES(lockOwner)',
133 phutil_json_encode($write_properties),
139 * After a write, update the version and release the "isWriting" lock.
141 public static function didWrite(
148 $version = new self();
149 $conn_w = $version->establishConnection('w');
150 $table = $version->getTableName();
155 repositoryVersion = %d,
159 repositoryPHID = %s AND
161 repositoryVersion = %d AND
174 * After a fetch, set the local version to the fetched version.
176 public static function updateVersion(
181 $version = new self();
182 $conn_w = $version->establishConnection('w');
183 $table = $version->getTableName();
188 (repositoryPHID, devicePHID, repositoryVersion, isWriting)
191 ON DUPLICATE KEY UPDATE
192 repositoryVersion = VALUES(repositoryVersion)',
202 * Explicitly demote a device.
204 public static function demoteDevice(
208 $version = new self();
209 $conn_w = $version->establishConnection('w');
210 $table = $version->getTableName();
214 'DELETE FROM %T WHERE repositoryPHID = %s AND devicePHID = %s',