launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #30465
[Merge] ~cjwatson/launchpad:stormify-person into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:stormify-person into launchpad:master.
Commit message:
Convert Person to Storm
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/451654
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-person into launchpad:master.
diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py
index 8de8c55..08fe8dc 100644
--- a/lib/lp/bugs/model/bugtasksearch.py
+++ b/lib/lp/bugs/model/bugtasksearch.py
@@ -29,8 +29,9 @@ from storm.expr import (
Row,
Select,
Union,
+ With,
)
-from storm.info import ClassAlias
+from storm.info import ClassAlias, get_cls_info
from storm.references import Reference
from zope.component import getUtility
from zope.security.proxy import isinstance as zope_isinstance
@@ -77,10 +78,6 @@ from lp.registry.model.teammembership import TeamParticipation
from lp.services.database.bulk import load
from lp.services.database.decoratedresultset import DecoratedResultSet
from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import (
- convert_storm_clause_to_string,
- sqlvalues,
-)
from lp.services.database.stormexpr import (
ArrayAgg,
ArrayIntersects,
@@ -224,10 +221,10 @@ def search_bugs(pre_iter_hook, alternatives, just_bug_ids=False):
clauseTables,
bugtask_decorator,
join_tables,
- with_clause,
+ with_clauses,
] = _build_query(alternatives[0])
- if with_clause:
- store = store.with_(with_clause)
+ if with_clauses:
+ store = store.with_(with_clauses)
decorators.append(bugtask_decorator)
origin = _build_origin(
join_tables + orderby_joins, clauseTables, start
@@ -242,12 +239,12 @@ def search_bugs(pre_iter_hook, alternatives, just_bug_ids=False):
clauseTables,
decorator,
join_tables,
- with_clause,
+ with_clauses,
] = _build_query(params)
origin = _build_origin(join_tables, clauseTables, start)
localstore = store
- if with_clause:
- localstore = store.with_(with_clause)
+ if with_clauses:
+ localstore = store.with_(with_clauses)
next_result = localstore.using(*origin).find(BugTaskFlat, query)
results.append(next_result)
# NB: assumes the decorators are all compatible.
@@ -492,9 +489,16 @@ def _build_query(params):
if params.structural_subscriber is not None:
with_clauses.append(
- """ss as (SELECT * from StructuralSubscription
- WHERE StructuralSubscription.subscriber = %s)"""
- % sqlvalues(params.structural_subscriber)
+ With(
+ "ss",
+ Select(
+ get_cls_info(StructuralSubscription).columns,
+ where=(
+ StructuralSubscription.subscriber
+ == params.structural_subscriber
+ ),
+ ),
+ )
)
class StructuralSubscriptionCTE(StructuralSubscription):
@@ -761,27 +765,23 @@ def _build_query(params):
)
store = IStore(Bug)
with_clauses.append(
- convert_storm_clause_to_string(
- WithMaterialized(
- "commented_bug_ids",
- store,
- Union(commented_messages, commented_activities),
- )
+ WithMaterialized(
+ "commented_bug_ids",
+ store,
+ Union(commented_messages, commented_activities),
)
)
with_clauses.append(
- convert_storm_clause_to_string(
- WithMaterialized(
- "commented_bugtask_ids",
- store,
- Select(
- BugTaskFlat.bugtask_id,
- tables=[BugTaskFlat],
- where=BugTaskFlat.bug_id.is_in(
- Select(Column("bug", "commented_bug_ids"))
- ),
+ WithMaterialized(
+ "commented_bugtask_ids",
+ store,
+ Select(
+ BugTaskFlat.bugtask_id,
+ tables=[BugTaskFlat],
+ where=BugTaskFlat.bug_id.is_in(
+ Select(Column("bug", "commented_bug_ids"))
),
- )
+ ),
)
)
extra_clauses.append(
@@ -921,11 +921,7 @@ def _build_query(params):
obj = decor(obj)
return obj
- if with_clauses:
- with_clause = SQL(", ".join(with_clauses))
- else:
- with_clause = None
- return (query, clauseTables, decorator, join_tables, with_clause)
+ return (query, clauseTables, decorator, join_tables, with_clauses)
def _process_order_by(params):
diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
index d14004b..4b4e920 100644
--- a/lib/lp/registry/browser/person.py
+++ b/lib/lp/registry/browser/person.py
@@ -2099,7 +2099,7 @@ class PersonParticipationView(LaunchpadView):
# The member is a direct member; use the membership data.
datejoined = membership.datejoined
dateexpires = membership.dateexpires
- if membership.person_id == team.teamownerID:
+ if membership.person_id == team.teamowner_id:
role = "Owner"
elif membership.status == TeamMembershipStatus.ADMIN:
role = "Admin"
diff --git a/lib/lp/registry/doc/person-merge.rst b/lib/lp/registry/doc/person-merge.rst
index f50b89c..65d98e4 100644
--- a/lib/lp/registry/doc/person-merge.rst
+++ b/lib/lp/registry/doc/person-merge.rst
@@ -278,6 +278,7 @@ create, and then delete, the needed two people.
>>> from lp.registry.model.person import PersonSet, Person
>>> from lp.registry.interfaces.person import PersonCreationRationale
+ >>> from lp.services.database.interfaces import IStore
>>> personset = PersonSet()
>>> skip = []
@@ -312,11 +313,14 @@ create, and then delete, the needed two people.
... display_name="Merge Winner",
... creation_rationale=lp,
... )
+ ... IStore(Person).add(winner)
... loser = Person(
... name=name + ".loser",
... display_name="Merge Loser",
... creation_rationale=lp,
... )
+ ... IStore(Person).add(loser)
+ ... IStore(Person).flush()
... yield winner, loser
...
>>> endless_supply_of_players = new_players()
diff --git a/lib/lp/registry/doc/vocabularies.rst b/lib/lp/registry/doc/vocabularies.rst
index ad6bf4b..ab7f5c5 100644
--- a/lib/lp/registry/doc/vocabularies.rst
+++ b/lib/lp/registry/doc/vocabularies.rst
@@ -611,7 +611,6 @@ Any person that's already merged is not part of this vocabulary:
>>> naked_cprov = removeSecurityProxy(cprov)
>>> naked_cprov.merged = 1
- >>> naked_cprov.syncUpdate()
>>> cprov in vocab
False
diff --git a/lib/lp/registry/interfaces/person.py b/lib/lp/registry/interfaces/person.py
index fe77d12..4e66cfd 100644
--- a/lib/lp/registry/interfaces/person.py
+++ b/lib/lp/registry/interfaces/person.py
@@ -220,7 +220,7 @@ def validate_membership_policy(obj, attr, value):
return None
# If we are just creating a new team, it can have any membership policy.
- if getattr(obj, "_SO_creating", True):
+ if getattr(obj, "_creating", True):
return value
team = obj
@@ -792,7 +792,7 @@ class IPersonLimitedView(IHasIcon, IHasLogo):
"in listings of bugs or on a person's membership table."
),
)
- iconID = Int(title=_("Icon ID"), required=True, readonly=True)
+ icon_id = Int(title=_("Icon ID"), required=True, readonly=True)
logo = exported(
LogoImageUpload(
title=_("Logo"),
@@ -806,7 +806,7 @@ class IPersonLimitedView(IHasIcon, IHasLogo):
),
)
)
- logoID = Int(title=_("Logo ID"), required=True, readonly=True)
+ logo_id = Int(title=_("Logo ID"), required=True, readonly=True)
# title is required for the Launchpad Page Layout main template
title = Attribute("Person Page Title")
is_probationary = exported(
@@ -890,7 +890,7 @@ class IPersonViewRestricted(
),
)
)
- mugshotID = Int(title=_("Mugshot ID"), required=True, readonly=True)
+ mugshot_id = Int(title=_("Mugshot ID"), required=True, readonly=True)
languages = exported(
CollectionField(
@@ -1111,7 +1111,7 @@ class IPersonViewRestricted(
),
exported_as="team_owner",
)
- teamownerID = Int(
+ teamowner_id = Int(
title=_("The Team Owner's ID or None"), required=False, readonly=True
)
preferredemail = exported(
diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
index 22d2895..4119824 100644
--- a/lib/lp/registry/model/distroseries.py
+++ b/lib/lp/registry/model/distroseries.py
@@ -1580,7 +1580,7 @@ class DistroSeries(
POTemplate.distroseries == self,
POTemplate.iscurrent == True,
)
- contributors = contributors.order_by(*Person._storm_sortingColumns)
+ contributors = contributors.order_by(*Person._sortingColumns)
contributors = contributors.config(distinct=True)
return contributors
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index 81f4187..dcf118e 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -62,7 +62,7 @@ from storm.expr import (
With,
)
from storm.info import ClassAlias
-from storm.locals import Int, Reference, ReferenceSet, Unicode
+from storm.locals import Bool, DateTime, Int, Reference, ReferenceSet, Unicode
from storm.store import EmptyResultSet, Store
from twisted.conch.ssh.common import getNS
from twisted.conch.ssh.keys import Key
@@ -193,24 +193,16 @@ from lp.registry.model.teammembership import (
)
from lp.services.config import config
from lp.services.database import bulk, postgresql
-from lp.services.database.constants import UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
+from lp.services.database.constants import DEFAULT, UTC_NOW
from lp.services.database.decoratedresultset import DecoratedResultSet
from lp.services.database.enumcol import DBEnum
from lp.services.database.interfaces import IStore
from lp.services.database.policy import PrimaryDatabasePolicy
from lp.services.database.sqlbase import (
- SQLBase,
convert_storm_clause_to_string,
cursor,
sqlvalues,
)
-from lp.services.database.sqlobject import (
- BoolCol,
- ForeignKey,
- IntCol,
- StringCol,
-)
from lp.services.database.stormbase import StormBase
from lp.services.database.stormexpr import WithMaterialized, fti_search
from lp.services.helpers import backslashreplace, shortlist
@@ -282,7 +274,7 @@ class TeamInvitationEvent:
self.team = team
-class ValidPersonCache(SQLBase):
+class ValidPersonCache(StormBase):
"""Flags if a Person is active and usable in Launchpad.
This is readonly, as this is a view in the database.
@@ -294,6 +286,10 @@ class ValidPersonCache(SQLBase):
corroborating information.
"""
+ __storm_table__ = "ValidPersonCache"
+
+ id = Int(primary=True)
+
def validate_person_visibility(person, attr, value):
"""Validate changes in visibility.
@@ -355,14 +351,14 @@ class PersonSettings(StormBase):
__storm_table__ = "PersonSettings"
- personID = Int("person", default=None, primary=True)
- person = Reference(personID, "Person.id")
+ person_id = Int("person", default=None, primary=True)
+ person = Reference(person_id, "Person.id")
- selfgenerated_bugnotifications = BoolCol(notNull=True, default=False)
+ selfgenerated_bugnotifications = Bool(allow_none=False, default=False)
- expanded_notification_footers = BoolCol(notNull=False, default=False)
+ expanded_notification_footers = Bool(allow_none=True, default=False)
- require_strong_email_authentication = BoolCol(notNull=False, default=False)
+ require_strong_email_authentication = Bool(allow_none=True, default=False)
def readonly_settings(message, interface):
@@ -420,7 +416,7 @@ _readonly_person_settings = readonly_settings(
@implementer(IPerson)
@delegate_to(IPersonSettings, context="_person_settings")
class Person(
- SQLBase,
+ StormBase,
HasBugsBase,
HasSpecificationsMixin,
HasTranslationImportsMixin,
@@ -431,14 +427,54 @@ class Person(
):
"""A Person."""
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- # Initialize our PersonSettings object/record.
+ __storm_table__ = "Person"
+
+ id = Int(primary=True)
+
+ _creating = False
+
+ def __init__(
+ self,
+ name,
+ display_name,
+ account=None,
+ teamowner=None,
+ description=None,
+ membership_policy=DEFAULT,
+ defaultrenewalperiod=None,
+ defaultmembershipperiod=None,
+ creation_rationale=None,
+ creation_comment=None,
+ registrant=None,
+ hide_email_addresses=False,
+ ):
+ super().__init__()
+ self._creating = True
+ self.name = name
+ self.display_name = display_name
+ self.account = account
+ self.teamowner = teamowner
+ self.description = description
+ self.membership_policy = membership_policy
+ self.defaultrenewalperiod = defaultrenewalperiod
+ self.defaultmembershipperiod = defaultmembershipperiod
+ self.creation_rationale = creation_rationale
+ self.creation_comment = creation_comment
+ self.registrant = registrant
+ self.hide_email_addresses = hide_email_addresses
if not self.is_team:
- # This is a Person, not a team. Teams may want a TeamSettings
- # in the future.
+ # Initialize our PersonSettings object/record. This is a
+ # Person, not a team. Teams may want a TeamSettings in the
+ # future.
settings = PersonSettings()
settings.person = self
+ self.__storm_loaded__()
+ del self._creating
+
+ def __storm_loaded__(self):
+ """Mark the person as a team when created or fetched from database."""
+ if self.is_team:
+ alsoProvides(self, ITeam)
@cachedproperty
def _person_settings(self):
@@ -462,13 +498,11 @@ class Person(
return self.id
sortingColumns = SQL("person_sort_key(Person.displayname, Person.name)")
- # Redefine the default ordering into Storm syntax.
- _storm_sortingColumns = ("Person.displayname", "Person.name")
# When doing any sort of set operations (union, intersect, except_) with
- # SQLObject we can't use sortingColumns because the table name Person is
- # not available in that context, so we use this one.
+ # Storm we can't use sortingColumns because the table name Person is not
+ # available in that context, so we use this one.
_sortingColumnsForSetOperations = SQL("person_sort_key(displayname, name)")
- _defaultOrder = sortingColumns
+ __storm_order__ = sortingColumns
_visibility_warning_cache_key = None
_visibility_warning_cache = None
@@ -490,7 +524,7 @@ class Person(
else:
mailing_list = getUtility(IMailingListSet).get(self.name)
can_rename = (
- self._SO_creating
+ self._creating
or not self.is_team
or mailing_list is None
or mailing_list.status == MailingListStatus.PURGED
@@ -499,35 +533,27 @@ class Person(
# Everything's okay, so let SQLObject do the normal thing.
return value
- name = StringCol(
- dbName="name",
- alternateID=True,
- notNull=True,
- storm_validator=_validate_name,
- )
+ name = Unicode(name="name", allow_none=False, validator=_validate_name)
def __repr__(self):
displayname = backslashreplace(self.displayname)
return "<Person %s (%s)>" % (self.name, displayname)
- display_name = StringCol(dbName="displayname", notNull=True)
+ display_name = Unicode(name="displayname", allow_none=False)
@property
def displayname(self):
return self.display_name
- teamdescription = StringCol(dbName="teamdescription", default=None)
- homepage_content = StringCol(default=None)
- _description = StringCol(dbName="description", default=None)
- icon = ForeignKey(
- dbName="icon", foreignKey="LibraryFileAlias", default=None
- )
- logo = ForeignKey(
- dbName="logo", foreignKey="LibraryFileAlias", default=None
- )
- mugshot = ForeignKey(
- dbName="mugshot", foreignKey="LibraryFileAlias", default=None
- )
+ teamdescription = Unicode(name="teamdescription", default=None)
+ homepage_content = Unicode(default=None)
+ _description = Unicode(name="description", default=None)
+ icon_id = Int(name="icon", allow_none=True, default=None)
+ icon = Reference(icon_id, "LibraryFileAlias.id")
+ logo_id = Int(name="logo", allow_none=True, default=None)
+ logo = Reference(logo_id, "LibraryFileAlias.id")
+ mugshot_id = Int(name="mugshot", allow_none=True, default=None)
+ mugshot = Reference(mugshot_id, "LibraryFileAlias.id")
@property
def account_status(self):
@@ -546,12 +572,13 @@ class Person(
raise NoAccountError()
self.account.setStatus(status, user, comment)
- teamowner = ForeignKey(
- dbName="teamowner",
- foreignKey="Person",
+ teamowner_id = Int(
+ name="teamowner",
+ validator=validate_public_person,
+ allow_none=True,
default=None,
- storm_validator=validate_public_person,
)
+ teamowner = Reference(teamowner_id, "Person.id")
sshkeys = ReferenceSet("id", "SSHKey.person_id")
@@ -565,30 +592,32 @@ class Person(
default=TeamMembershipPolicy.RESTRICTED,
validator=validate_membership_policy,
)
- defaultrenewalperiod = IntCol(dbName="defaultrenewalperiod", default=None)
- defaultmembershipperiod = IntCol(
- dbName="defaultmembershipperiod", default=None
- )
+ defaultrenewalperiod = Int(name="defaultrenewalperiod", default=None)
+ defaultmembershipperiod = Int(name="defaultmembershipperiod", default=None)
mailing_list_auto_subscribe_policy = DBEnum(
enum=MailingListAutoSubscribePolicy,
default=MailingListAutoSubscribePolicy.ON_REGISTRATION,
)
- merged = ForeignKey(dbName="merged", foreignKey="Person", default=None)
+ merged_id = Int(name="merged", allow_none=True, default=None)
+ merged = Reference(merged_id, "Person.id")
- datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW)
+ datecreated = DateTime(
+ allow_none=False, default=UTC_NOW, tzinfo=timezone.utc
+ )
creation_rationale = DBEnum(enum=PersonCreationRationale, default=None)
- creation_comment = StringCol(default=None)
- registrant = ForeignKey(
- dbName="registrant",
- foreignKey="Person",
+ creation_comment = Unicode(default=None)
+ registrant_id = Int(
+ name="registrant",
+ validator=validate_public_person,
+ allow_none=True,
default=None,
- storm_validator=validate_public_person,
)
- hide_email_addresses = BoolCol(notNull=True, default=False)
- verbose_bugnotifications = BoolCol(notNull=True, default=True)
+ registrant = Reference(registrant_id, "Person.id")
+ hide_email_addresses = Bool(allow_none=False, default=False)
+ verbose_bugnotifications = Bool(allow_none=False, default=True)
- signedcocs = ReferenceSet("<primary key>", "SignedCodeOfConduct.owner_id")
+ signedcocs = ReferenceSet("id", "SignedCodeOfConduct.owner_id")
_ircnicknames = ReferenceSet("id", "IrcID.person_id")
jabberids = ReferenceSet("id", "JabberID.person_id")
@@ -604,7 +633,7 @@ class Person(
allow_none=False,
)
- personal_standing_reason = StringCol(default=None)
+ personal_standing_reason = Unicode(default=None)
@property
def description(self):
@@ -703,12 +732,6 @@ class Person(
person_language.delete()
self.deleteLanguagesCache()
- def _init(self, *args, **kw):
- """Mark the person as a team when created or fetched from database."""
- SQLBase._init(self, *args, **kw)
- if self.teamownerID is not None:
- alsoProvides(self, ITeam)
-
def convertToTeam(self, team_owner):
"""See `IPerson`."""
if self.is_team:
@@ -1009,7 +1032,7 @@ class Person(
@property
def is_team(self):
"""See `IPerson`."""
- return self.teamownerID is not None
+ return self.teamowner_id is not None
@property
def mailing_list(self):
@@ -1117,7 +1140,7 @@ class Person(
OR product.bug_supervisor = %(person)s
)
""" % sqlvalues(
- person=self
+ person=self.id
)
return "%s AND (%s)" % (
@@ -1157,7 +1180,7 @@ class Person(
) _pillar
ON PillarName.name = _pillar.name
"""
- % sqlvalues(person=self)
+ % sqlvalues(person=self.id)
)
results = IStore(self).using(SQL(origin)).find(find_spec)
@@ -1260,7 +1283,6 @@ class Person(
CommercialSubscription,
)
from lp.registry.model.distribution import Distribution
- from lp.registry.model.person import Person
from lp.registry.model.product import Product
from lp.registry.model.teammembership import TeamParticipation
@@ -1599,7 +1621,6 @@ class Person(
def getAssignedSpecificationWorkItemsDueBefore(self, date, user):
"""See `IPerson`."""
from lp.registry.model.distribution import Distribution
- from lp.registry.model.person import Person
from lp.registry.model.product import Product
store = Store.of(self)
@@ -1811,7 +1832,7 @@ class Person(
And(
TeamParticipation.team_id == self.id,
TeamParticipation.person_id != self.id,
- Person.teamownerID != None,
+ IsNot(Person.teamowner_id, None),
),
need_api=True,
)
@@ -2061,7 +2082,7 @@ class Person(
Select(
Person.id,
tables=[Person],
- where=Person.teamownerID.is_in(team_select),
+ where=Person.teamowner_id.is_in(team_select),
),
Select(
TeamMembership.team_id,
@@ -2942,7 +2963,7 @@ class Person(
Person,
Person.id == TeamParticipation.team_id,
TeamParticipation.person == self,
- IsNot(Person.teamownerID, None),
+ IsNot(Person.teamowner_id, None),
)
.order_by(Person.sortingColumns)
)
@@ -2950,11 +2971,10 @@ class Person(
@property
def teams_indirectly_participated_in(self):
"""See `IPerson`."""
- Team = ClassAlias(Person, "Team")
store = Store.of(self)
origin = [
- Team,
- Join(TeamParticipation, Team.id == TeamParticipation.team_id),
+ Person,
+ Join(TeamParticipation, Person.id == TeamParticipation.team_id),
LeftJoin(
TeamMembership,
And(
@@ -2969,9 +2989,8 @@ class Person(
),
),
]
- find_objects = Team
return store.using(*origin).find(
- find_objects,
+ Person,
And(
TeamParticipation.person == self.id,
TeamParticipation.person != TeamParticipation.team_id,
@@ -2988,8 +3007,8 @@ class Person(
Person,
Person.id == TeamParticipation.team_id,
TeamParticipation.person == self,
- IsNot(Person.teamownerID, None),
- IsNot(Person.iconID, None),
+ IsNot(Person.teamowner_id, None),
+ IsNot(Person.icon_id, None),
TeamParticipation.team != self,
)
.order_by(Person.sortingColumns)
@@ -4155,6 +4174,9 @@ class PersonSet:
defaultrenewalperiod=defaultrenewalperiod,
membership_policy=membership_policy,
)
+ store = IStore(Person)
+ store.add(team)
+ store.flush()
notify(ObjectCreatedEvent(team))
# Here we add the owner as a team admin manually because we know what
# we're doing (so we don't need to do any sanity checks) and we don't
@@ -4267,19 +4289,18 @@ class PersonSet:
if not displayname:
displayname = name.capitalize()
- if account is None:
- account_id = None
- else:
- account_id = account.id
person = Person(
name=name,
display_name=displayname,
- account_id=account_id,
+ account=account,
creation_rationale=rationale,
creation_comment=comment,
hide_email_addresses=hide_email_addresses,
registrant=registrant,
)
+ store = IStore(Person)
+ store.add(person)
+ store.flush()
return person
def ensurePerson(
@@ -4309,7 +4330,7 @@ class PersonSet:
"""See `IPersonSet`."""
clauses = [Person.name == name]
if ignore_merged:
- clauses.append(Is(Person.mergedID, None))
+ clauses.append(Is(Person.merged_id, None))
return IStore(Person).find(Person, *clauses).one()
def getByAccount(self, account):
@@ -4323,8 +4344,8 @@ class PersonSet:
IStore(Person)
.find(
Person,
- Is(Person.teamownerID, None),
- Is(Person.mergedID, None),
+ Is(Person.teamowner_id, None),
+ Is(Person.merged_id, None),
)
.count()
)
@@ -4334,8 +4355,8 @@ class PersonSet:
IStore(Person)
.find(
Person,
- IsNot(Person.teamownerID, None),
- Is(Person.mergedID, None),
+ IsNot(Person.teamowner_id, None),
+ Is(Person.merged_id, None),
)
.count()
)
@@ -4601,15 +4622,15 @@ class PersonSet:
"""See `IPersonSet`."""
aliases = []
aliases.extend(
- person.iconID for person in people if person.iconID is not None
+ person.icon_id for person in people if person.icon_id is not None
)
aliases.extend(
- person.logoID for person in people if person.logoID is not None
+ person.logo_id for person in people if person.logo_id is not None
)
aliases.extend(
- person.mugshotID
+ person.mugshot_id
for person in people
- if person.mugshotID is not None
+ if person.mugshot_id is not None
)
if not aliases:
return
@@ -4805,7 +4826,7 @@ class PersonSet:
def preload_for_people(rows):
if need_teamowner or need_api:
- bulk.load(Person, [row[0].teamownerID for row in rows])
+ bulk.load(Person, [row[0].teamowner_id for row in rows])
def prepopulate_person(row):
result = row[0]
@@ -5559,7 +5580,7 @@ def _get_recipients_for_team(team):
EmailAddress.person != None,
Account.status == AccountStatus.ACTIVE,
),
- Person.teamownerID != None,
+ IsNot(Person.teamowner_id, None),
),
).config(distinct=True)
next_ids = []
diff --git a/lib/lp/registry/personmerge.py b/lib/lp/registry/personmerge.py
index cec406c..2787bc2 100644
--- a/lib/lp/registry/personmerge.py
+++ b/lib/lp/registry/personmerge.py
@@ -1230,8 +1230,7 @@ def merge_people(from_person, to_person, reviewer, delete=False):
cur.execute("SELECT id FROM Person WHERE name = %s" % sqlvalues(name))
i += 1
cur.execute(
- "UPDATE Person SET name = %s WHERE id = %s"
- % sqlvalues(name, from_person)
+ "UPDATE Person SET name = %s WHERE id = %s" % sqlvalues(name, from_id)
)
# Since we've updated the database behind Storm's back,
diff --git a/lib/lp/registry/scripts/closeaccount.py b/lib/lp/registry/scripts/closeaccount.py
index c7d4c55..7df78d0 100644
--- a/lib/lp/registry/scripts/closeaccount.py
+++ b/lib/lp/registry/scripts/closeaccount.py
@@ -236,7 +236,7 @@ def close_account(username, log):
# Keep the corresponding PersonSettings row, but reset everything to the
# defaults.
table_notification("PersonSettings")
- store.find(PersonSettings, PersonSettings.personID == person.id).set(
+ store.find(PersonSettings, PersonSettings.person == person).set(
selfgenerated_bugnotifications=DEFAULT,
# XXX cjwatson 2018-11-29: These two columns have NULL defaults, but
# perhaps shouldn't?
diff --git a/lib/lp/registry/vocabularies.py b/lib/lp/registry/vocabularies.py
index 56453ca..0104a33 100644
--- a/lib/lp/registry/vocabularies.py
+++ b/lib/lp/registry/vocabularies.py
@@ -71,6 +71,8 @@ from storm.expr import (
And,
Column,
Desc,
+ Is,
+ IsNot,
Join,
LeftJoin,
Not,
@@ -176,7 +178,6 @@ from lp.services.webapp.vocabulary import (
IHugeVocabulary,
NamedStormHugeVocabulary,
NamedStormVocabulary,
- SQLObjectVocabularyBase,
StormVocabularyBase,
VocabularyFilter,
)
@@ -208,7 +209,6 @@ class BasePersonVocabulary:
If the token contains an '@', treat it like an email. Otherwise,
treat it like a name.
"""
- token = six.ensure_text(token)
if "@" in token:
# This looks like an email token, so let's do an object
# lookup based on that.
@@ -369,11 +369,11 @@ def project_products_vocabulary_factory(context):
)
-class UserTeamsParticipationVocabulary(SQLObjectVocabularyBase):
+class UserTeamsParticipationVocabulary(StormVocabularyBase):
"""Describes the public teams in which the current user participates."""
_table = Person
- _orderBy = "display_name"
+ _order_by = "display_name"
INCLUDE_PRIVATE_TEAM = False
@@ -401,7 +401,7 @@ class UserTeamsParticipationVocabulary(SQLObjectVocabularyBase):
teams = list(
IStore(Person)
.find(Person, *clauses)
- .order_by(Person._storm_sortingColumns)
+ .order_by(Person._sortingColumns)
)
# Users can view all the teams they belong to.
precache_permission_for_objects(
@@ -428,7 +428,7 @@ class UserTeamsParticipationVocabulary(SQLObjectVocabularyBase):
@implementer(IHugeVocabulary)
class NonMergedPeopleAndTeamsVocabulary(
- BasePersonVocabulary, SQLObjectVocabularyBase
+ BasePersonVocabulary, StormVocabularyBase
):
"""The set of all non-merged people and teams.
@@ -437,7 +437,7 @@ class NonMergedPeopleAndTeamsVocabulary(
a preferred email address, that is, unvalidated person profiles.
"""
- _orderBy = ["display_name"]
+ _order_by = ["display_name"]
displayname = "Select a Person or Team"
step_title = "Search"
@@ -449,7 +449,7 @@ class NonMergedPeopleAndTeamsVocabulary(
return getUtility(IPersonSet).find(text)
def search(self, text, vocab_filter=None):
- """See `SQLObjectVocabularyBase`.
+ """See `StormVocabularyBase`.
Return people/teams whose fti or email address match :text.
"""
@@ -461,7 +461,7 @@ class NonMergedPeopleAndTeamsVocabulary(
@implementer(IHugeVocabulary)
class PersonAccountToMergeVocabulary(
- BasePersonVocabulary, SQLObjectVocabularyBase
+ BasePersonVocabulary, StormVocabularyBase
):
"""The set of all non-merged people with at least one email address.
@@ -469,7 +469,7 @@ class PersonAccountToMergeVocabulary(
accounts to merge. You *don't* want to use it.
"""
- _orderBy = ["display_name"]
+ _order_by = ["display_name"]
displayname = "Select a Person to Merge"
step_title = "Search"
must_have_email = True
@@ -486,7 +486,7 @@ class PersonAccountToMergeVocabulary(
)
def search(self, text, vocab_filter=None):
- """See `SQLObjectVocabularyBase`.
+ """See `StormVocabularyBase`.
Return people whose fti or email address match :text.
"""
@@ -516,7 +516,7 @@ class VocabularyFilterPerson(VocabularyFilter):
@property
def filter_terms(self):
- return [Person.teamownerID == None]
+ return [Is(Person.teamowner_id, None)]
class VocabularyFilterTeam(VocabularyFilter):
@@ -529,13 +529,11 @@ class VocabularyFilterTeam(VocabularyFilter):
@property
def filter_terms(self):
- return [Person.teamownerID != None]
+ return [IsNot(Person.teamowner_id, None)]
@implementer(IHugeVocabulary)
-class ValidPersonOrTeamVocabulary(
- BasePersonVocabulary, SQLObjectVocabularyBase
-):
+class ValidPersonOrTeamVocabulary(BasePersonVocabulary, StormVocabularyBase):
"""The set of valid, viewable Persons/Teams in Launchpad.
A Person is considered valid if they have a preferred email address, and
diff --git a/lib/lp/translations/model/poexportrequest.py b/lib/lp/translations/model/poexportrequest.py
index 3313457..9dd9ec5 100644
--- a/lib/lp/translations/model/poexportrequest.py
+++ b/lib/lp/translations/model/poexportrequest.py
@@ -92,7 +92,7 @@ class POExportRequestSet:
)
query_params = {
- "person": quote(person),
+ "person": quote(person.id),
"format": quote(format),
"templates": potemplate_ids,
"pofiles": pofile_ids,
diff --git a/lib/lp/translations/model/pofile.py b/lib/lp/translations/model/pofile.py
index 14626b1..623fb69 100644
--- a/lib/lp/translations/model/pofile.py
+++ b/lib/lp/translations/model/pofile.py
@@ -456,7 +456,7 @@ class POFile(StormBase, POFileMixIn):
)
.config(distinct=True)
)
- contributors = contributors.order_by(*Person._storm_sortingColumns)
+ contributors = contributors.order_by(*Person._sortingColumns)
contributors = contributors.config(distinct=True)
return contributors
diff --git a/lib/lp/translations/model/translationgroup.py b/lib/lp/translations/model/translationgroup.py
index 943b38e..c8dc2dd 100644
--- a/lib/lp/translations/model/translationgroup.py
+++ b/lib/lp/translations/model/translationgroup.py
@@ -175,7 +175,7 @@ class TranslationGroup(StormBase):
Translator,
Language,
Person,
- LeftJoin(LibraryFileAlias, LibraryFileAlias.id == Person.iconID),
+ LeftJoin(LibraryFileAlias, LibraryFileAlias.id == Person.icon_id),
LeftJoin(
LibraryFileContent,
LibraryFileContent.id == LibraryFileAlias.contentID,
diff --git a/lib/lp/translations/scripts/remove_translations.py b/lib/lp/translations/scripts/remove_translations.py
index c042b8a..e854640 100644
--- a/lib/lp/translations/scripts/remove_translations.py
+++ b/lib/lp/translations/scripts/remove_translations.py
@@ -444,11 +444,11 @@ def remove_translations(
conditions = set()
if submitter is not None:
conditions.add(
- "TranslationMessage.submitter = %s" % sqlvalues(submitter)
+ "TranslationMessage.submitter = %s" % sqlvalues(submitter.id)
)
if reviewer is not None:
conditions.add(
- "TranslationMessage.reviewer = %s" % sqlvalues(reviewer)
+ "TranslationMessage.reviewer = %s" % sqlvalues(reviewer.id)
)
if date_created is not None:
conditions.add(