launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #30297
[Merge] ~cjwatson/launchpad:stormify-branch into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:stormify-branch into launchpad:master.
Commit message:
Convert Branch to Storm
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/447535
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-branch into launchpad:master.
diff --git a/lib/lp/app/doc/tales.rst b/lib/lp/app/doc/tales.rst
index e872cff..662c1ff 100644
--- a/lib/lp/app/doc/tales.rst
+++ b/lib/lp/app/doc/tales.rst
@@ -597,7 +597,7 @@ For branches, fmt:link links to the branch page.
>>> eric = factory.makePerson(name="eric")
>>> fooix = factory.makeProduct(name="fooix")
>>> branch = factory.makeProductBranch(
- ... owner=eric, product=fooix, name="bar", title="The branch title"
+ ... owner=eric, product=fooix, name="bar"
... )
>>> print(test_tales("branch/fmt:link", branch=branch))
<a href=".../~eric/fooix/bar"
@@ -680,7 +680,7 @@ Branch subscriptions show the person and branch name. For users without
adequate permissions, a link is not generated.
>>> branch = factory.makeProductBranch(
- ... owner=eric, product=fooix, name="my-branch", title="My Branch"
+ ... owner=eric, product=fooix, name="my-branch"
... )
>>> michael = factory.makePerson(
... name="michael", displayname="Michael the Viking"
diff --git a/lib/lp/code/doc/branch.rst b/lib/lp/code/doc/branch.rst
index 7984f04..1b92425 100644
--- a/lib/lp/code/doc/branch.rst
+++ b/lib/lp/code/doc/branch.rst
@@ -273,7 +273,7 @@ Branch names
Branches have a display name that is the bzr_identity.
- >>> untitled_branch = factory.makeAnyBranch(title=None)
+ >>> untitled_branch = factory.makeAnyBranch()
>>> untitled_branch.displayname == untitled_branch.bzr_identity
True
diff --git a/lib/lp/code/interfaces/branchnamespace.py b/lib/lp/code/interfaces/branchnamespace.py
index 345f36d..24c6ffb 100644
--- a/lib/lp/code/interfaces/branchnamespace.py
+++ b/lib/lp/code/interfaces/branchnamespace.py
@@ -32,9 +32,8 @@ class IBranchNamespace(Interface):
name,
registrant,
url=None,
- title=None,
lifecycle_status=BranchLifecycleStatus.DEVELOPMENT,
- summary=None,
+ description=None,
whiteboard=None,
):
"""Create and return an `IBranch` in this namespace."""
diff --git a/lib/lp/code/mail/tests/test_branch.py b/lib/lp/code/mail/tests/test_branch.py
index e1faf88..c9285fc 100644
--- a/lib/lp/code/mail/tests/test_branch.py
+++ b/lib/lp/code/mail/tests/test_branch.py
@@ -149,9 +149,9 @@ class TestRecipientReasonBzr(TestRecipientReasonMixin, TestCaseWithFactory):
"""Test fixture."""
if subscriber is None:
subscriber = self.factory.makePerson()
- source_branch = self.factory.makeProductBranch(title="foo")
+ source_branch = self.factory.makeProductBranch()
target_branch = self.factory.makeProductBranch(
- product=source_branch.product, title="bar"
+ product=source_branch.product
)
merge_proposal = source_branch.addLandingTarget(
source_branch.owner, target_branch
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index b9f9b5f..48fd5fc 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -16,7 +16,14 @@ from breezy.revision import NULL_REVISION
from breezy.url_policy_open import open_only_scheme
from lazr.lifecycle.event import ObjectCreatedEvent
from storm.expr import SQL, And, Coalesce, Desc, Join, Not, Or, Select
-from storm.locals import AutoReload, ReferenceSet
+from storm.locals import (
+ AutoReload,
+ DateTime,
+ Int,
+ Reference,
+ ReferenceSet,
+ Unicode,
+)
from storm.store import Store
from zope.component import getUtility
from zope.event import notify
@@ -130,12 +137,10 @@ from lp.registry.model.teammembership import TeamParticipation
from lp.services.config import config
from lp.services.database import bulk
from lp.services.database.constants import DEFAULT, UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
from lp.services.database.decoratedresultset import DecoratedResultSet
from lp.services.database.enumcol import DBEnum
from lp.services.database.interfaces import IPrimaryStore, IStore
-from lp.services.database.sqlbase import SQLBase
-from lp.services.database.sqlobject import ForeignKey, IntCol, StringCol
+from lp.services.database.stormbase import StormBase
from lp.services.database.stormexpr import Array, ArrayAgg, ArrayIntersects
from lp.services.helpers import shortlist
from lp.services.job.interfaces.job import JobStatus
@@ -151,27 +156,68 @@ from lp.snappy.interfaces.snap import ISnapSet
@implementer(IBranch, IInformationType)
-class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
+class Branch(StormBase, WebhookTargetMixin, BzrIdentityMixin):
"""A sequence of ordered revisions in Bazaar."""
- _table = "Branch"
+ __storm_table__ = "Branch"
+
+ id = Int(primary=True)
branch_type = DBEnum(enum=BranchType, allow_none=False)
- name = StringCol(notNull=False)
- url = StringCol(dbName="url")
- description = StringCol(dbName="summary")
+ name = Unicode(allow_none=False)
+ url = Unicode(name="url")
+ description = Unicode(name="summary")
branch_format = DBEnum(enum=BranchFormat)
repository_format = DBEnum(enum=RepositoryFormat)
# XXX: Aaron Bentley 2008-06-13
# Rename the metadir_format in the database, see bug 239746
control_format = DBEnum(enum=ControlFormat, name="metadir_format")
- whiteboard = StringCol(default=None)
- mirror_status_message = StringCol(default=None)
+ whiteboard = Unicode(default=None)
+ mirror_status_message = Unicode(default=None)
information_type = DBEnum(
- enum=InformationType, default=InformationType.PUBLIC
+ enum=InformationType, allow_none=False, default=InformationType.PUBLIC
)
+ def __init__(
+ self,
+ branch_type,
+ name,
+ registrant,
+ owner,
+ url=None,
+ description=None,
+ branch_format=None,
+ repository_format=None,
+ control_format=None,
+ whiteboard=None,
+ information_type=InformationType.PUBLIC,
+ product=None,
+ sourcepackage=None,
+ lifecycle_status=BranchLifecycleStatus.DEVELOPMENT,
+ date_created=DEFAULT,
+ date_last_modified=DEFAULT,
+ ):
+ super().__init__()
+ self.branch_type = branch_type
+ self.name = name
+ self.registrant = registrant
+ self.owner = owner
+ self.url = url
+ self.description = description
+ self.branch_format = branch_format
+ self.repository_format = repository_format
+ self.control_format = control_format
+ self.whiteboard = whiteboard
+ self.information_type = information_type
+ self.product = product
+ if sourcepackage is not None:
+ self.distroseries = sourcepackage.distroseries
+ self.sourcepackagename = sourcepackage.sourcepackagename
+ self.lifecycle_status = lifecycle_status
+ self.date_created = date_created
+ self.date_last_modified = date_last_modified
+
@property
def valid_webhook_event_types(self):
return ["bzr:push:0.1", "merge-proposal:0.1"]
@@ -278,41 +324,28 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
# such subscriptions.
getUtility(IRemoveArtifactSubscriptionsJobSource).create(who, [self])
- registrant = ForeignKey(
- dbName="registrant",
- foreignKey="Person",
- storm_validator=validate_public_person,
- notNull=True,
- )
- owner = ForeignKey(
- dbName="owner",
- foreignKey="Person",
- storm_validator=validate_person,
- notNull=True,
+ registrant_id = Int(
+ name="registrant", validator=validate_public_person, allow_none=False
)
+ registrant = Reference(registrant_id, "Person.id")
+ owner_id = Int(name="owner", validator=validate_person, allow_none=False)
+ owner = Reference(owner_id, "Person.id")
def setOwner(self, new_owner, user):
"""See `IBranch`."""
new_namespace = self.target.getNamespace(new_owner)
new_namespace.moveBranch(self, user, rename_if_necessary=True)
- reviewer = ForeignKey(
- dbName="reviewer",
- foreignKey="Person",
- storm_validator=validate_person,
- default=None,
- )
+ reviewer_id = Int(name="reviewer", validator=validate_person, default=None)
+ reviewer = Reference(reviewer_id, "Person.id")
- product = ForeignKey(dbName="product", foreignKey="Product", default=None)
+ product_id = Int(name="product", default=None)
+ product = Reference(product_id, "Product.id")
- distroseries = ForeignKey(
- dbName="distroseries", foreignKey="DistroSeries", default=None
- )
- sourcepackagename = ForeignKey(
- dbName="sourcepackagename",
- foreignKey="SourcePackageName",
- default=None,
- )
+ distroseries_id = Int(name="distroseries", default=None)
+ distroseries = Reference(distroseries_id, "DistroSeries.id")
+ sourcepackagename_id = Int(name="sourcepackagename", default=None)
+ sourcepackagename = Reference(sourcepackagename_id, "SourcePackageName.id")
lifecycle_status = DBEnum(
enum=BranchLifecycleStatus,
@@ -320,24 +353,23 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
default=BranchLifecycleStatus.DEVELOPMENT,
)
- last_mirrored = UtcDateTimeCol(default=None)
- last_mirrored_id = StringCol(default=None)
- last_mirror_attempt = UtcDateTimeCol(default=None)
- mirror_failures = IntCol(default=0, notNull=True)
- next_mirror_time = UtcDateTimeCol(default=None)
-
- last_scanned = UtcDateTimeCol(default=None)
- last_scanned_id = StringCol(default=None)
- revision_count = IntCol(default=DEFAULT, notNull=True)
- stacked_on = ForeignKey(
- dbName="stacked_on", foreignKey="Branch", default=None
- )
+ last_mirrored = DateTime(default=None, tzinfo=timezone.utc)
+ last_mirrored_id = Unicode(default=None)
+ last_mirror_attempt = DateTime(default=None, tzinfo=timezone.utc)
+ mirror_failures = Int(default=0, allow_none=False)
+ next_mirror_time = DateTime(default=None, tzinfo=timezone.utc)
+
+ last_scanned = DateTime(default=None, tzinfo=timezone.utc)
+ last_scanned_id = Unicode(default=None)
+ revision_count = Int(default=DEFAULT, allow_none=False)
+ stacked_on_id = Int(name="stacked_on", default=None)
+ stacked_on = Reference(stacked_on_id, "Branch.id")
# The unique_name is maintined by a SQL trigger.
- unique_name = StringCol()
+ unique_name = Unicode()
# Denormalised columns used primarily for sorting.
- owner_name = StringCol()
- target_suffix = StringCol()
+ owner_name = Unicode()
+ target_suffix = Unicode()
def __repr__(self):
return "<Branch %r (%d)>" % (self.unique_name, self.id)
@@ -500,8 +532,12 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
"""See `IBranch`."""
return spec.unlinkBranch(self, user)
- date_created = UtcDateTimeCol(notNull=True, default=DEFAULT)
- date_last_modified = UtcDateTimeCol(notNull=True, default=DEFAULT)
+ date_created = DateTime(
+ allow_none=False, default=DEFAULT, tzinfo=timezone.utc
+ )
+ date_last_modified = DateTime(
+ allow_none=False, default=DEFAULT, tzinfo=timezone.utc
+ )
@property
def landing_targets(self):
@@ -1642,7 +1678,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
# Now destroy the branch.
branch_id = self.id
- SQLBase.destroySelf(self)
+ Store.of(self).remove(self)
# And now create a job to remove the branch from disk when it's done.
job = getUtility(IReclaimBranchSpaceJobSource).create(branch_id)
job.celeryRunOnCommit()
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 55cbb0c..fd5677d 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -127,7 +127,7 @@ class GenericBranchCollection:
def ownerCounts(self):
"""See `IBranchCollection`."""
is_team = Person.teamowner != None
- branch_owners = self._getBranchSelect((Branch.ownerID,))
+ branch_owners = self._getBranchSelect((Branch.owner_id,))
counts = dict(
self.store.find(
(is_team, Count(Person.id)), Person.id.is_in(branch_owners)
@@ -245,9 +245,9 @@ class GenericBranchCollection:
def preloadDataForBranches(branches):
"""Preload branches' cached associated targets, product series, and
suite source packages."""
- load_related(SourcePackageName, branches, ["sourcepackagenameID"])
- load_related(DistroSeries, branches, ["distroseriesID"])
- load_related(Product, branches, ["productID"])
+ load_related(SourcePackageName, branches, ["sourcepackagename_id"])
+ load_related(DistroSeries, branches, ["distroseries_id"])
+ load_related(Product, branches, ["product_id"])
caches = {branch.id: get_property_cache(branch) for branch in branches}
branch_ids = caches.keys()
for cache in caches.values():
@@ -259,9 +259,9 @@ class GenericBranchCollection:
from lp.registry.model.productseries import ProductSeries
for productseries in IStore(ProductSeries).find(
- ProductSeries, ProductSeries.branchID.is_in(branch_ids)
+ ProductSeries, ProductSeries.branch_id.is_in(branch_ids)
):
- cache = caches[productseries.branchID]
+ cache = caches[productseries.branch_id]
cache._associatedProductSeries.append(productseries)
# associatedSuiteSourcePackages
series_set = getUtility(IFindOfficialBranchLinks)
@@ -346,7 +346,7 @@ class GenericBranchCollection:
# So far have only needed the persons for their canonical_url - no
# need for validity etc in the /branches API call.
load_related(
- Person, rows, ["ownerID", "registrantID", "reviewerID"]
+ Person, rows, ["owner_id", "registrant_id", "reviewer_id"]
)
load_referencing(BugBranch, rows, ["branch_id"])
@@ -667,7 +667,7 @@ class GenericBranchCollection:
# BranchCollection conceptual model, but we're not quite sure how to
# fix it just yet. Perhaps when bug 337494 is fixed, we'd be able to
# sensibly be able to move this method to another utility class.
- branch_query = self._getBranchSelect((Branch.ownerID,))
+ branch_query = self._getBranchSelect((Branch.owner_id,))
return self.store.find(
Person,
Person.id == TeamParticipation.teamID,
@@ -754,7 +754,7 @@ class GenericBranchCollection:
return self._filterBy(
[Person.membership_policy.is_in(EXCLUSIVE_TEAM_POLICY)],
table=Person,
- join=Join(Person, Branch.ownerID == Person.id),
+ join=Join(Person, Branch.owner_id == Person.id),
)
def isSeries(self):
@@ -763,9 +763,9 @@ class GenericBranchCollection:
from lp.registry.model.productseries import ProductSeries
return self._filterBy(
- [Branch.id == ProductSeries.branchID],
+ [Branch.id == ProductSeries.branch_id],
table=ProductSeries,
- join=Join(ProductSeries, Branch.id == ProductSeries.branchID),
+ join=Join(ProductSeries, Branch.id == ProductSeries.branch_id),
)
def ownedBy(self, person):
@@ -778,7 +778,7 @@ class GenericBranchCollection:
TeamParticipation.teamID,
where=TeamParticipation.personID == person.id,
)
- return self._filterBy([In(Branch.ownerID, subquery)], symmetric=False)
+ return self._filterBy([In(Branch.owner_id, subquery)], symmetric=False)
def registeredBy(self, person):
"""See `IBranchCollection`."""
diff --git a/lib/lp/code/model/branchlistingqueryoptimiser.py b/lib/lp/code/model/branchlistingqueryoptimiser.py
index a108d14..6dc8ee2 100644
--- a/lib/lp/code/model/branchlistingqueryoptimiser.py
+++ b/lib/lp/code/model/branchlistingqueryoptimiser.py
@@ -38,7 +38,7 @@ class BranchListingQueryOptimiser:
for product, series in IStore(Product)
.find(
(Product, ProductSeries),
- ProductSeries.branchID.is_in(branch_ids),
+ ProductSeries.branch_id.is_in(branch_ids),
ProductSeries.product == Product.id,
)
.order_by(ProductSeries.name)
diff --git a/lib/lp/code/model/branchlookup.py b/lib/lp/code/model/branchlookup.py
index 5c40120..5abf549 100644
--- a/lib/lp/code/model/branchlookup.py
+++ b/lib/lp/code/model/branchlookup.py
@@ -50,7 +50,6 @@ from lp.registry.model.product import Product
from lp.registry.model.sourcepackagename import SourcePackageName
from lp.services.config import config
from lp.services.database.interfaces import IStore
-from lp.services.database.sqlobject import SQLObjectNotFound
from lp.services.webapp.authorization import check_permission
@@ -189,10 +188,10 @@ class BranchLookup:
def get(self, branch_id, default=None):
"""See `IBranchLookup`."""
- try:
- return Branch.get(branch_id)
- except SQLObjectNotFound:
+ branch = IStore(Branch).get(Branch, branch_id)
+ if branch is None:
return default
+ return branch
@staticmethod
def uriToHostingPath(uri):
@@ -233,7 +232,7 @@ class BranchLookup:
return None
return self.getByPath(uri.path.lstrip("/"))
- return Branch.selectOneBy(url=url)
+ return IStore(Branch).find(Branch, url=url).one()
def performLookup(self, lookup):
if lookup["type"] == "id":
@@ -365,7 +364,7 @@ class BranchLookup:
.find(
Branch,
Person.name == owner,
- Branch.distroseriesID
+ Branch.distroseries_id
== Select(
DistroSeries.id,
And(
diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
index 04b28b3..924658c 100644
--- a/lib/lp/code/model/branchmergeproposal.py
+++ b/lib/lp/code/model/branchmergeproposal.py
@@ -1630,7 +1630,7 @@ class BranchMergeProposal(StormBase, BugLinkTargetMixin):
# persons. We need the target repository owner as well; unlike
# branches, repository unique names aren't trigger-maintained.
person_ids.update(
- branch.ownerID
+ branch.owner_id
for branch in branches
if branch.id in source_branch_ids
)
diff --git a/lib/lp/code/model/branchnamespace.py b/lib/lp/code/model/branchnamespace.py
index ca997a5..f441c41 100644
--- a/lib/lp/code/model/branchnamespace.py
+++ b/lib/lp/code/model/branchnamespace.py
@@ -62,7 +62,7 @@ from lp.registry.interfaces.product import IProduct, IProductSet, NoSuchProduct
from lp.registry.interfaces.projectgroup import IProjectGroup
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
from lp.registry.model.sourcepackage import SourcePackage
-from lp.services.database.constants import UTC_NOW
+from lp.services.database.constants import DEFAULT
from lp.services.database.interfaces import IStore
BRANCH_POLICY_ALLOWED_TYPES = {
@@ -107,11 +107,10 @@ class _BaseBranchNamespace:
name,
registrant,
url=None,
- title=None,
lifecycle_status=BranchLifecycleStatus.DEVELOPMENT,
- summary=None,
+ description=None,
whiteboard=None,
- date_created=None,
+ date_created=DEFAULT,
branch_format=None,
repository_format=None,
control_format=None,
@@ -121,21 +120,12 @@ class _BaseBranchNamespace:
self.validateRegistrant(registrant)
self.validateBranchName(name)
- if date_created is None:
- date_created = UTC_NOW
-
# Run any necessary data massage on the branch URL.
if url is not None:
url = IBranch["url"].normalize(url)
product = getattr(self, "product", None)
sourcepackage = getattr(self, "sourcepackage", None)
- if sourcepackage is None:
- distroseries = None
- sourcepackagename = None
- else:
- distroseries = sourcepackage.distroseries
- sourcepackagename = sourcepackage.sourcepackagename
information_type = self.getDefaultInformationType(registrant)
if information_type is None:
@@ -146,10 +136,10 @@ class _BaseBranchNamespace:
name=name,
owner=self.owner,
product=product,
+ sourcepackage=sourcepackage,
url=url,
- title=title,
lifecycle_status=lifecycle_status,
- summary=summary,
+ description=description,
whiteboard=whiteboard,
information_type=information_type,
date_created=date_created,
@@ -158,8 +148,6 @@ class _BaseBranchNamespace:
branch_format=branch_format,
repository_format=repository_format,
control_format=control_format,
- distroseries=distroseries,
- sourcepackagename=sourcepackagename,
)
branch._reconcileAccess()
diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py
index 8b3f793..c3416db 100644
--- a/lib/lp/code/model/revision.py
+++ b/lib/lp/code/model/revision.py
@@ -184,7 +184,7 @@ class Revision(StormBase):
result_set.order_by(Asc(BranchRevision.sequence))
else:
result_set.order_by(
- Branch.ownerID != self.revision_author.person_id,
+ Branch.owner_id != self.revision_author.person_id,
Asc(BranchRevision.sequence),
)
@@ -639,8 +639,8 @@ class RevisionSet:
insert_columns.append("NULL")
subselect_clauses.append("product IS NULL")
else:
- insert_columns.append(str(naked_branch.productID))
- subselect_clauses.append("product = %s" % naked_branch.productID)
+ insert_columns.append(str(naked_branch.product_id))
+ subselect_clauses.append("product = %s" % naked_branch.product_id)
if branch.distroseries is None:
insert_columns.extend(["NULL", "NULL"])
@@ -650,15 +650,15 @@ class RevisionSet:
else:
insert_columns.extend(
[
- str(naked_branch.distroseriesID),
- str(naked_branch.sourcepackagenameID),
+ str(naked_branch.distroseries_id),
+ str(naked_branch.sourcepackagename_id),
]
)
subselect_clauses.extend(
[
- "distroseries = %s" % naked_branch.distroseriesID,
+ "distroseries = %s" % naked_branch.distroseries_id,
"sourcepackagename = %s"
- % naked_branch.sourcepackagenameID,
+ % naked_branch.sourcepackagename_id,
]
)
diff --git a/lib/lp/code/model/tests/test_branchnamespace.py b/lib/lp/code/model/tests/test_branchnamespace.py
index 1e6f3e6..20bbf32 100644
--- a/lib/lp/code/model/tests/test_branchnamespace.py
+++ b/lib/lp/code/model/tests/test_branchnamespace.py
@@ -94,17 +94,15 @@ class NamespaceMixin:
namespace = self.getNamespace()
branch_name = self.factory.getUniqueString()
registrant = removeSecurityProxy(namespace).owner
- title = self.factory.getUniqueString()
- summary = self.factory.getUniqueString()
+ description = self.factory.getUniqueString()
whiteboard = self.factory.getUniqueString()
branch = namespace.createBranch(
BranchType.HOSTED,
branch_name,
registrant,
url=None,
- title=title,
lifecycle_status=BranchLifecycleStatus.EXPERIMENTAL,
- summary=summary,
+ description=description,
whiteboard=whiteboard,
)
self.assertEqual(BranchType.HOSTED, branch.branch_type)
diff --git a/lib/lp/code/model/tests/test_codereviewcomment.py b/lib/lp/code/model/tests/test_codereviewcomment.py
index 823e4f5..3c01ea9 100644
--- a/lib/lp/code/model/tests/test_codereviewcomment.py
+++ b/lib/lp/code/model/tests/test_codereviewcomment.py
@@ -20,10 +20,8 @@ class TestCodeReviewComment(TestCaseWithFactory):
def setUp(self):
TestCaseWithFactory.setUp(self, "admin@xxxxxxxxxxxxx")
- source = self.factory.makeProductBranch(title="source-branch")
- target = self.factory.makeProductBranch(
- product=source.product, title="target-branch"
- )
+ source = self.factory.makeProductBranch()
+ target = self.factory.makeProductBranch(product=source.product)
self.bmp = source.addLandingTarget(source.owner, target)
self.submitter = self.factory.makePerson()
self.reviewer = self.factory.makePerson()
diff --git a/lib/lp/code/stories/branches/xx-branch-index.rst b/lib/lp/code/stories/branches/xx-branch-index.rst
index e2946b1..bdab297 100644
--- a/lib/lp/code/stories/branches/xx-branch-index.rst
+++ b/lib/lp/code/stories/branches/xx-branch-index.rst
@@ -235,7 +235,6 @@ it has been mirrored:
... name="mirrored",
... owner=no_priv,
... url="http://example.com/mirrored",
- ... title="Disabled branch",
... )
>>> branch.last_mirrored = datetime(
... year=2007, month=10, day=1, tzinfo=timezone.utc
@@ -289,7 +288,6 @@ If next_mirror_time is NULL, then mirroring of the branch is disabled.
... name="mirror-disabled",
... owner=no_priv,
... url="http://example.com/disabled",
- ... title="Disabled branch",
... )
>>> branch.next_mirror_time = None
>>> flush_database_updates()
diff --git a/lib/lp/code/stories/webservice/xx-branch.rst b/lib/lp/code/stories/webservice/xx-branch.rst
index 6d27ce6..3417ecc 100644
--- a/lib/lp/code/stories/webservice/xx-branch.rst
+++ b/lib/lp/code/stories/webservice/xx-branch.rst
@@ -84,7 +84,6 @@ time goes on.
... owner=eric,
... product=fooix,
... name="trunk",
- ... title="The Fooix Trunk",
... date_created=datetime(2009, 1, 1, tzinfo=timezone.utc),
... )
>>> feature_branch = factory.makeAnyBranch(
diff --git a/lib/lp/code/vocabularies/branch.py b/lib/lp/code/vocabularies/branch.py
index 1e35f6c..620d9ba 100644
--- a/lib/lp/code/vocabularies/branch.py
+++ b/lib/lp/code/vocabularies/branch.py
@@ -24,16 +24,16 @@ from lp.services.webapp.interfaces import ILaunchBag
from lp.services.webapp.vocabulary import (
CountableIterator,
IHugeVocabulary,
- SQLObjectVocabularyBase,
+ StormVocabularyBase,
)
@implementer(IHugeVocabulary)
-class BranchVocabulary(SQLObjectVocabularyBase):
+class BranchVocabulary(StormVocabularyBase):
"""A vocabulary for searching branches."""
_table = Branch
- _orderBy = ["name", "id"]
+ _order_by = ["name", "id"]
displayname = "Select a branch"
step_title = "Search"
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index cf764f9..6427a0f 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -1085,7 +1085,7 @@ class Distribution(
IStore(self)
.using(
Branch,
- Join(DistroSeries, DistroSeries.id == Branch.distroseriesID),
+ Join(DistroSeries, DistroSeries.id == Branch.distroseries_id),
LeftJoin(
Join(
SeriesSourcePackageBranch,
diff --git a/lib/lp/registry/model/productseries.py b/lib/lp/registry/model/productseries.py
index 0bd1479..dc347e1 100644
--- a/lib/lp/registry/model/productseries.py
+++ b/lib/lp/registry/model/productseries.py
@@ -14,7 +14,7 @@ from operator import itemgetter
from lazr.delegates import delegate_to
from storm.expr import Max, Sum
-from storm.locals import And, Desc
+from storm.locals import And, Desc, Int, Reference
from storm.store import Store
from zope.component import getUtility
from zope.interface import implementer
@@ -130,7 +130,8 @@ class ProductSeries(
notNull=False,
default=None,
)
- branch = ForeignKey(foreignKey="Branch", dbName="branch", default=None)
+ branch_id = Int(name="branch", default=None)
+ branch = Reference(branch_id, "Branch.id")
def validate_autoimport_mode(self, attr, value):
# Perform the normal validation for None
@@ -152,12 +153,10 @@ class ProductSeries(
default=TranslationsBranchImportMode.NO_IMPORT,
validator=validate_autoimport_mode,
)
- translations_branch = ForeignKey(
- dbName="translations_branch",
- foreignKey="Branch",
- notNull=False,
- default=None,
+ translations_branch_id = Int(
+ name="translations_branch", allow_none=True, default=None
)
+ translations_branch = Reference(translations_branch_id, "Branch.id")
# where are the tarballs released from this branch placed?
releasefileglob = StringCol(default=None)
releaseverstyle = StringCol(default=None)
diff --git a/lib/lp/snappy/model/snap.py b/lib/lp/snappy/model/snap.py
index 5730bff..c55f435 100644
--- a/lib/lp/snappy/model/snap.py
+++ b/lib/lp/snappy/model/snap.py
@@ -1851,7 +1851,7 @@ class SnapSet:
# Add branch/repository owners to the list of pre-loaded persons.
# We need the target repository owner as well; unlike branches,
# repository unique names aren't trigger-maintained.
- person_ids.update(branch.ownerID for branch in branches)
+ person_ids.update(branch.owner_id for branch in branches)
person_ids.update(repository.owner_id for repository in repositories)
list(