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, "ad...@canonical.com") - 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(
_______________________________________________ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp