mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 04:42:40 +01:00
Prepare Projects schema for subprojects
Summary: Ref T10010. This does some cleanups on the schema: - `viewPolicy`, `editPolicy` and `joinPolicy` were nullable, but should never be `null`. Set them to defaults if they're null, then make the column non-nullable. - Rename `phrictionSlug` to `primarySlug` and stop adding and removing trailing slashes from it. - Add new columns to support milestones and non-milestone subprojects. - Drop very old subprojectPHIDs column. This hasn't done anything in the UI for years and years, and isn't particularly realistic to migrate forward. The new columns aren't reachable from the UI. Test Plan: - Applied patches. - Grepped for `phrictionSlug`. - Grepped for `subprojectPHIDs`. - Created tasks. - Edited tasks. - Verified existing tasks still had primary slugs. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10010 Differential Revision: https://secure.phabricator.com/D14825
This commit is contained in:
parent
3f8e5c9620
commit
aeae0e7028
13 changed files with 105 additions and 40 deletions
2
resources/sql/autopatches/20151219.proj.01.prislug.sql
Normal file
2
resources/sql/autopatches/20151219.proj.01.prislug.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD COLUMN primarySlug VARCHAR(128) COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD UNIQUE KEY `key_primaryslug` (primarySlug);
|
2
resources/sql/autopatches/20151219.proj.03.copyslug.sql
Normal file
2
resources/sql/autopatches/20151219.proj.03.copyslug.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
UPDATE {$NAMESPACE}_project.project
|
||||||
|
SET primarySlug = TRIM(TRAILING "/" FROM phrictionSlug);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
DROP KEY `phrictionSlug`;
|
2
resources/sql/autopatches/20151219.proj.05.dropslug.sql
Normal file
2
resources/sql/autopatches/20151219.proj.05.dropslug.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
DROP COLUMN phrictionSlug;
|
28
resources/sql/autopatches/20151219.proj.06.defaultpolicy.php
Normal file
28
resources/sql/autopatches/20151219.proj.06.defaultpolicy.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$app = PhabricatorApplication::getByClass('PhabricatorProjectApplication');
|
||||||
|
|
||||||
|
$view_policy = $app->getPolicy(ProjectDefaultViewCapability::CAPABILITY);
|
||||||
|
$edit_policy = $app->getPolicy(ProjectDefaultEditCapability::CAPABILITY);
|
||||||
|
$join_policy = $app->getPolicy(ProjectDefaultJoinCapability::CAPABILITY);
|
||||||
|
|
||||||
|
$table = new PhabricatorProject();
|
||||||
|
$conn_w = $table->establishConnection('w');
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'UPDATE %T SET viewPolicy = %s WHERE viewPolicy IS NULL',
|
||||||
|
$table->getTableName(),
|
||||||
|
$view_policy);
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'UPDATE %T SET editPolicy = %s WHERE editPolicy IS NULL',
|
||||||
|
$table->getTableName(),
|
||||||
|
$edit_policy);
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'UPDATE %T SET joinPolicy = %s WHERE joinPolicy IS NULL',
|
||||||
|
$table->getTableName(),
|
||||||
|
$join_policy);
|
2
resources/sql/autopatches/20151219.proj.07.viewnull.sql
Normal file
2
resources/sql/autopatches/20151219.proj.07.viewnull.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
CHANGE viewPolicy viewPolicy VARBINARY(64) NOT NULL;
|
2
resources/sql/autopatches/20151219.proj.08.editnull.sql
Normal file
2
resources/sql/autopatches/20151219.proj.08.editnull.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
CHANGE editPolicy editPolicy VARBINARY(64) NOT NULL;
|
2
resources/sql/autopatches/20151219.proj.09.joinnull.sql
Normal file
2
resources/sql/autopatches/20151219.proj.09.joinnull.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
CHANGE joinPolicy joinPolicy VARBINARY(64) NOT NULL;
|
17
resources/sql/autopatches/20151219.proj.10.subcolumns.sql
Normal file
17
resources/sql/autopatches/20151219.proj.10.subcolumns.sql
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD parentProjectPHID VARBINARY(64);
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD hasWorkboard BOOL NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD hasMilestones BOOL NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD hasSubprojects BOOL NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD milestoneNumber INT UNSIGNED;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
ADD UNIQUE KEY `key_milestone` (parentProjectPHID, milestoneNumber);
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_project.project
|
||||||
|
DROP subprojectPHIDs;
|
|
@ -11,19 +11,11 @@ final class PhabricatorPolicyDataTestCase extends PhabricatorTestCase {
|
||||||
public function testProjectPolicyMembership() {
|
public function testProjectPolicyMembership() {
|
||||||
$author = $this->generateNewTestUser();
|
$author = $this->generateNewTestUser();
|
||||||
|
|
||||||
$proj_a = id(new PhabricatorProject())
|
$proj_a = PhabricatorProject::initializeNewProject($author)
|
||||||
->setName('A')
|
->setName('A')
|
||||||
->setAuthorPHID($author->getPHID())
|
|
||||||
->setIcon(PhabricatorProject::DEFAULT_ICON)
|
|
||||||
->setColor(PhabricatorProject::DEFAULT_COLOR)
|
|
||||||
->setIsMembershipLocked(0)
|
|
||||||
->save();
|
->save();
|
||||||
$proj_b = id(new PhabricatorProject())
|
$proj_b = PhabricatorProject::initializeNewProject($author)
|
||||||
->setName('B')
|
->setName('B')
|
||||||
->setAuthorPHID($author->getPHID())
|
|
||||||
->setIcon(PhabricatorProject::DEFAULT_ICON)
|
|
||||||
->setColor(PhabricatorProject::DEFAULT_COLOR)
|
|
||||||
->setIsMembershipLocked(0)
|
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
$proj_a->setViewPolicy($proj_b->getPHID())->save();
|
$proj_a->setViewPolicy($proj_b->getPHID())->save();
|
||||||
|
|
|
@ -12,8 +12,7 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
protected $name;
|
protected $name;
|
||||||
protected $status = PhabricatorProjectStatus::STATUS_ACTIVE;
|
protected $status = PhabricatorProjectStatus::STATUS_ACTIVE;
|
||||||
protected $authorPHID;
|
protected $authorPHID;
|
||||||
protected $subprojectPHIDs = array();
|
protected $primarySlug;
|
||||||
protected $phrictionSlug;
|
|
||||||
protected $profileImagePHID;
|
protected $profileImagePHID;
|
||||||
protected $icon;
|
protected $icon;
|
||||||
protected $color;
|
protected $color;
|
||||||
|
@ -24,6 +23,12 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
protected $joinPolicy;
|
protected $joinPolicy;
|
||||||
protected $isMembershipLocked;
|
protected $isMembershipLocked;
|
||||||
|
|
||||||
|
protected $parentProjectPHID;
|
||||||
|
protected $hasWorkboard;
|
||||||
|
protected $hasMilestones;
|
||||||
|
protected $hasSubprojects;
|
||||||
|
protected $milestoneNumber;
|
||||||
|
|
||||||
private $memberPHIDs = self::ATTACHABLE;
|
private $memberPHIDs = self::ATTACHABLE;
|
||||||
private $watcherPHIDs = self::ATTACHABLE;
|
private $watcherPHIDs = self::ATTACHABLE;
|
||||||
private $sparseWatchers = self::ATTACHABLE;
|
private $sparseWatchers = self::ATTACHABLE;
|
||||||
|
@ -31,6 +36,7 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
private $customFields = self::ATTACHABLE;
|
private $customFields = self::ATTACHABLE;
|
||||||
private $profileImageFile = self::ATTACHABLE;
|
private $profileImageFile = self::ATTACHABLE;
|
||||||
private $slugs = self::ATTACHABLE;
|
private $slugs = self::ATTACHABLE;
|
||||||
|
private $parentProject = self::ATTACHABLE;
|
||||||
|
|
||||||
const DEFAULT_ICON = 'fa-briefcase';
|
const DEFAULT_ICON = 'fa-briefcase';
|
||||||
const DEFAULT_COLOR = 'blue';
|
const DEFAULT_COLOR = 'blue';
|
||||||
|
@ -59,7 +65,10 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
->setJoinPolicy($join_policy)
|
->setJoinPolicy($join_policy)
|
||||||
->setIsMembershipLocked(0)
|
->setIsMembershipLocked(0)
|
||||||
->attachMemberPHIDs(array())
|
->attachMemberPHIDs(array())
|
||||||
->attachSlugs(array());
|
->attachSlugs(array())
|
||||||
|
->setHasWorkboard(0)
|
||||||
|
->setHasMilestones(0)
|
||||||
|
->setHasSubprojects(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCapabilities() {
|
public function getCapabilities() {
|
||||||
|
@ -132,24 +141,21 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
self::CONFIG_SERIALIZATION => array(
|
|
||||||
'subprojectPHIDs' => self::SERIALIZATION_JSON,
|
|
||||||
),
|
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
'name' => 'sort128',
|
'name' => 'sort128',
|
||||||
'status' => 'text32',
|
'status' => 'text32',
|
||||||
'phrictionSlug' => 'text128?',
|
'primarySlug' => 'text128?',
|
||||||
'isMembershipLocked' => 'bool',
|
'isMembershipLocked' => 'bool',
|
||||||
'profileImagePHID' => 'phid?',
|
'profileImagePHID' => 'phid?',
|
||||||
'icon' => 'text32',
|
'icon' => 'text32',
|
||||||
'color' => 'text32',
|
'color' => 'text32',
|
||||||
'mailKey' => 'bytes20',
|
'mailKey' => 'bytes20',
|
||||||
|
'joinPolicy' => 'policy',
|
||||||
// T6203/NULLABILITY
|
'parentProjectPHID' => 'phid?',
|
||||||
// These are definitely wrong and should always exist.
|
'hasWorkboard' => 'bool',
|
||||||
'editPolicy' => 'policy?',
|
'hasMilestones' => 'bool',
|
||||||
'viewPolicy' => 'policy?',
|
'hasSubprojects' => 'bool',
|
||||||
'joinPolicy' => 'policy?',
|
'milestoneNumber' => 'uint32?',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
'key_phid' => null,
|
'key_phid' => null,
|
||||||
|
@ -163,14 +169,18 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
'key_color' => array(
|
'key_color' => array(
|
||||||
'columns' => array('color'),
|
'columns' => array('color'),
|
||||||
),
|
),
|
||||||
'phrictionSlug' => array(
|
|
||||||
'columns' => array('phrictionSlug'),
|
|
||||||
'unique' => true,
|
|
||||||
),
|
|
||||||
'name' => array(
|
'name' => array(
|
||||||
'columns' => array('name'),
|
'columns' => array('name'),
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
),
|
),
|
||||||
|
'key_milestone' => array(
|
||||||
|
'columns' => array('parentProjectPHID', 'milestoneNumber'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
'key_primaryslug' => array(
|
||||||
|
'columns' => array('primarySlug'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
@ -189,19 +199,6 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
return $this->assertAttached($this->memberPHIDs);
|
return $this->assertAttached($this->memberPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPrimarySlug($slug) {
|
|
||||||
$this->phrictionSlug = $slug.'/';
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - once we sever project => phriction automagicalness,
|
|
||||||
// migrate getPhrictionSlug to have no trailing slash and be called
|
|
||||||
// getPrimarySlug
|
|
||||||
public function getPrimarySlug() {
|
|
||||||
$slug = $this->getPhrictionSlug();
|
|
||||||
return rtrim($slug, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isArchived() {
|
public function isArchived() {
|
||||||
return ($this->getStatus() == PhabricatorProjectStatus::STATUS_ARCHIVED);
|
return ($this->getStatus() == PhabricatorProjectStatus::STATUS_ARCHIVED);
|
||||||
}
|
}
|
||||||
|
@ -313,6 +310,19 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isMilestone() {
|
||||||
|
return ($this->getMilestoneNumber() !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParentProject() {
|
||||||
|
return $this->assertAttached($this->parentProject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachParentProject(PhabricatorProject $project) {
|
||||||
|
$this->parentProject = $project;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue