launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #25345
[Merge] ~cjwatson/launchpad:stormify-worlddata into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:stormify-worlddata into launchpad:master.
Commit message:
Convert lp.services.worlddata to Storm
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/391112
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-worlddata into launchpad:master.
diff --git a/lib/lp/services/worlddata/model/country.py b/lib/lp/services/worlddata/model/country.py
index 387a84a..e46988f 100644
--- a/lib/lp/services/worlddata/model/country.py
+++ b/lib/lp/services/worlddata/model/country.py
@@ -6,18 +6,18 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = ['Country', 'CountrySet', 'Continent']
-import six
-from sqlobject import (
- ForeignKey,
- SQLRelatedJoin,
- StringCol,
+from storm.locals import (
+ Int,
+ Reference,
+ ReferenceSet,
+ Unicode,
)
from zope.interface import implementer
from lp.app.errors import NotFoundError
from lp.services.database.constants import DEFAULT
from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import SQLBase
+from lp.services.database.stormbase import StormBase
from lp.services.worlddata.interfaces.country import (
IContinent,
ICountry,
@@ -26,27 +26,25 @@ from lp.services.worlddata.interfaces.country import (
@implementer(ICountry)
-class Country(SQLBase):
+class Country(StormBase):
"""A country."""
- _table = 'Country'
+ __storm_table__ = 'Country'
# default to listing newest first
- _defaultOrder = 'name'
+ __storm_order__ = 'name'
# db field names
- name = StringCol(dbName='name', unique=True, notNull=True)
- iso3166code2 = StringCol(dbName='iso3166code2', unique=True,
- notNull=True)
- iso3166code3 = StringCol(dbName='iso3166code3', unique=True,
- notNull=True)
- title = StringCol(dbName='title', notNull=False, default=DEFAULT)
- description = StringCol(dbName='description')
- continent = ForeignKey(
- dbName='continent', foreignKey='Continent', default=None)
- languages = SQLRelatedJoin(
- six.ensure_str('Language'), joinColumn='country',
- otherColumn='language', intermediateTable='SpokenIn')
+ id = Int(primary=True)
+ name = Unicode(name='name', allow_none=False)
+ iso3166code2 = Unicode(name='iso3166code2', allow_none=False)
+ iso3166code3 = Unicode(name='iso3166code3', allow_none=False)
+ title = Unicode(name='title', allow_none=True, default=DEFAULT)
+ description = Unicode(name='description')
+ continent_id = Int(name='continent', default=None)
+ continent = Reference(continent_id, 'Continent.id')
+ languages = ReferenceSet(
+ id, 'SpokenIn.country_id', 'SpokenIn.language_id', 'Language.id')
@implementer(ICountrySet)
@@ -54,13 +52,14 @@ class CountrySet:
"""A set of countries"""
def __getitem__(self, iso3166code2):
- country = Country.selectOneBy(iso3166code2=iso3166code2)
+ country = IStore(Country).find(
+ Country, iso3166code2=iso3166code2).one()
if country is None:
raise NotFoundError(iso3166code2)
return country
def __iter__(self):
- for row in Country.select():
+ for row in IStore(Country).find(Country):
yield row
def getByName(self, name):
@@ -77,11 +76,12 @@ class CountrySet:
@implementer(IContinent)
-class Continent(SQLBase):
+class Continent(StormBase):
"""See IContinent."""
- _table = 'Continent'
- _defaultOrder = ['name', 'id']
+ __storm_table__ = 'Continent'
+ __storm_order__ = ['name', 'id']
- name = StringCol(unique=True, notNull=True)
- code = StringCol(unique=True, notNull=True)
+ id = Int(primary=True)
+ name = Unicode(allow_none=False)
+ code = Unicode(allow_none=False)
diff --git a/lib/lp/services/worlddata/model/language.py b/lib/lp/services/worlddata/model/language.py
index 9142207..105230e 100644
--- a/lib/lp/services/worlddata/model/language.py
+++ b/lib/lp/services/worlddata/model/language.py
@@ -11,13 +11,6 @@ __all__ = [
]
import six
-from sqlobject import (
- BoolCol,
- IntCol,
- SQLObjectNotFound,
- SQLRelatedJoin,
- StringCol,
- )
from storm.expr import (
And,
Count,
@@ -26,6 +19,12 @@ from storm.expr import (
LeftJoin,
Or,
)
+from storm.locals import (
+ Bool,
+ Int,
+ ReferenceSet,
+ Unicode,
+ )
from zope.interface import implementer
from lp.app.errors import NotFoundError
@@ -34,12 +33,13 @@ from lp.registry.model.karma import (
KarmaCategory,
)
from lp.services.database.decoratedresultset import DecoratedResultSet
-from lp.services.database.enumcol import EnumCol
+from lp.services.database.enumcol import DBEnum
from lp.services.database.interfaces import (
ISlaveStore,
IStore,
)
-from lp.services.database.sqlbase import SQLBase
+from lp.services.database.stormbase import StormBase
+from lp.services.database.stormexpr import IsTrue
from lp.services.helpers import ensure_unicode
from lp.services.propertycache import (
cachedproperty,
@@ -53,28 +53,46 @@ from lp.services.worlddata.interfaces.language import (
@implementer(ILanguage)
-class Language(SQLBase):
-
- _table = 'Language'
-
- code = StringCol(dbName='code', notNull=True, unique=True)
- uuid = StringCol(dbName='uuid', notNull=False, default=None)
- nativename = StringCol(dbName='nativename')
- englishname = StringCol(dbName='englishname')
- pluralforms = IntCol(dbName='pluralforms')
- pluralexpression = StringCol(dbName='pluralexpression')
- visible = BoolCol(dbName='visible', notNull=True)
- direction = EnumCol(
- dbName='direction', notNull=True, schema=TextDirection,
+class Language(StormBase):
+
+ __storm_table__ = 'Language'
+
+ id = Int(primary=True)
+ code = Unicode(name='code', allow_none=False)
+ uuid = Unicode(name='uuid', allow_none=True, default=None)
+ nativename = Unicode(name='nativename')
+ englishname = Unicode(name='englishname')
+ pluralforms = Int(name='pluralforms')
+ pluralexpression = Unicode(name='pluralexpression')
+ visible = Bool(name='visible', allow_none=False)
+ direction = DBEnum(
+ name='direction', allow_none=False, enum=TextDirection,
default=TextDirection.LTR)
- translation_teams = SQLRelatedJoin(
- six.ensure_str('Person'), joinColumn="language",
- intermediateTable='Translator', otherColumn='translator')
+ translation_teams = ReferenceSet(
+ id, 'Translator.languageID',
+ 'Translator.translatorID', 'Person.<primary key>')
+
+ _countries = ReferenceSet(
+ id, 'SpokenIn.language_id', 'SpokenIn.country_id', 'Country.id')
+
+ def __init__(self, code, nativename=None, englishname=None,
+ pluralforms=None, pluralexpression=None, visible=True,
+ direction=TextDirection.LTR):
+ super(Language, self).__init__()
+ self.code = code
+ self.nativename = nativename
+ self.englishname = englishname
+ self.pluralforms = pluralforms
+ self.pluralexpression = pluralexpression
+ self.visible = visible
+ self.direction = direction
- _countries = SQLRelatedJoin(
- six.ensure_str('Country'), joinColumn='language',
- otherColumn='country', intermediateTable='SpokenIn')
+ def addCountry(self, country):
+ self._countries.add(country)
+
+ def removeCountry(self, country):
+ self._countries.remove(country)
# Define a read/write property `countries` so it can be passed
# to language administration `LaunchpadFormView`.
@@ -200,9 +218,8 @@ class LanguageSet:
@property
def _visible_languages(self):
- return Language.select(
- 'visible IS TRUE',
- orderBy='englishname')
+ return IStore(Language).find(
+ Language, IsTrue(Language.visible)).order_by(Language.englishname)
@property
def common_languages(self):
@@ -220,9 +237,8 @@ class LanguageSet:
"""See `ILanguageSet`."""
result = IStore(Language).find(
Language,
- Language.visible == True if only_visible else True,
- ).order_by(
- Language.englishname)
+ IsTrue(Language.visible) if only_visible else True,
+ ).order_by(Language.englishname)
if want_translators_count:
def preload_translators_count(languages):
from lp.registry.model.person import PersonLanguage
@@ -245,7 +261,8 @@ class LanguageSet:
def __iter__(self):
"""See `ILanguageSet`."""
- return iter(Language.select(orderBy='englishname'))
+ return iter(
+ IStore(Language).find(Language).order_by(Language.englishname))
def __getitem__(self, code):
"""See `ILanguageSet`."""
@@ -258,14 +275,11 @@ class LanguageSet:
def get(self, language_id):
"""See `ILanguageSet`."""
- try:
- return Language.get(language_id)
- except SQLObjectNotFound:
- return None
+ return IStore(Language).get(Language, language_id)
def getLanguageByCode(self, code):
"""See `ILanguageSet`."""
- assert isinstance(code, six.string_types), (
+ assert isinstance(code, six.text_type), (
"%s is not a valid type for 'code'" % type(code))
return IStore(Language).find(Language, code=code).one()
@@ -300,10 +314,13 @@ class LanguageSet:
pluralforms=None, pluralexpression=None, visible=True,
direction=TextDirection.LTR):
"""See `ILanguageSet`."""
- return Language(
+ store = IStore(Language)
+ language = Language(
code=code, englishname=englishname, nativename=nativename,
pluralforms=pluralforms, pluralexpression=pluralexpression,
visible=visible, direction=direction)
+ store.add(language)
+ return language
def search(self, text):
"""See `ILanguageSet`."""
diff --git a/lib/lp/services/worlddata/model/spokenin.py b/lib/lp/services/worlddata/model/spokenin.py
index 6d2f06c..46d00f5 100644
--- a/lib/lp/services/worlddata/model/spokenin.py
+++ b/lib/lp/services/worlddata/model/spokenin.py
@@ -6,22 +6,27 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = ['SpokenIn']
-from sqlobject import ForeignKey
+from storm.locals import (
+ Int,
+ Reference,
+ )
from zope.interface import implementer
-from lp.services.database.sqlbase import SQLBase
+from lp.services.database.stormbase import StormBase
from lp.services.worlddata.interfaces.spokenin import ISpokenIn
@implementer(ISpokenIn)
-class SpokenIn(SQLBase):
+class SpokenIn(StormBase):
"""A way of telling which languages are spoken in which countries.
This table maps a language which is SpokenIn a country.
"""
- _table = 'SpokenIn'
+ __storm_table__ = 'SpokenIn'
- country = ForeignKey(dbName='country', notNull=True, foreignKey='Country')
- language = ForeignKey(dbName='language', notNull=True,
- foreignKey='Language')
+ id = Int(primary=True)
+ country_id = Int(name='country', allow_none=False)
+ country = Reference(country_id, 'Country.id')
+ language_id = Int(name='language', allow_none=False)
+ language = Reference(language_id, 'Language.id')
diff --git a/lib/lp/services/worlddata/vocabularies.py b/lib/lp/services/worlddata/vocabularies.py
index 6c96021..5634cbc 100644
--- a/lib/lp/services/worlddata/vocabularies.py
+++ b/lib/lp/services/worlddata/vocabularies.py
@@ -20,7 +20,10 @@ from zope.schema.vocabulary import (
SimpleVocabulary,
)
-from lp.services.webapp.vocabulary import SQLObjectVocabularyBase
+from lp.services.webapp.vocabulary import (
+ NamedStormVocabulary,
+ StormVocabularyBase,
+ )
from lp.services.worlddata.interfaces.language import (
ILanguage,
ILanguageSet,
@@ -43,24 +46,20 @@ def TimezoneNameVocabulary(context=None):
return _timezone_vocab
-# Country.name may have non-ASCII characters, so we can't use
-# NamedSQLObjectVocabulary here.
-
-class CountryNameVocabulary(SQLObjectVocabularyBase):
+class CountryNameVocabulary(NamedStormVocabulary):
"""A vocabulary for country names."""
_table = Country
- _orderBy = 'name'
def toTerm(self, obj):
return SimpleTerm(obj, obj.id, obj.name)
-class LanguageVocabulary(SQLObjectVocabularyBase):
+class LanguageVocabulary(StormVocabularyBase):
"""All the languages known by Launchpad."""
_table = Language
- _orderBy = 'englishname'
+ _order_by = 'englishname'
def __contains__(self, language):
"""See `IVocabulary`."""
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index b7dc38f..7759cd4 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -2619,13 +2619,13 @@ class BareLaunchpadObjectFactory(ObjectFactory):
plural_expression=None):
"""Makes a language given the language_code and name."""
if language_code is None:
- language_code = self.getUniqueString('lang')
+ language_code = self.getUniqueUnicode('lang')
if name is None:
name = "Language %s" % language_code
if plural_expression is None and pluralforms is not None:
# If the number of plural forms is known, the language
# should also have a plural expression and vice versa.
- plural_expression = 'n %% %d' % pluralforms
+ plural_expression = u'n %% %d' % pluralforms
language_set = getUtility(ILanguageSet)
return language_set.createLanguage(
diff --git a/lib/lp/translations/vocabularies.py b/lib/lp/translations/vocabularies.py
index 0da0c5f..79cef40 100644
--- a/lib/lp/translations/vocabularies.py
+++ b/lib/lp/translations/vocabularies.py
@@ -3,6 +3,8 @@
"""Translations vocabularies."""
+from __future__ import absolute_import, print_function, unicode_literals
+
__metaclass__ = type
__all__ = [
@@ -20,6 +22,7 @@ from zope.schema.vocabulary import SimpleTerm
from lp.registry.interfaces.distroseries import IDistroSeries
from lp.services.database.sqlbase import sqlvalues
+from lp.services.database.stormexpr import IsTrue
from lp.services.webapp.vocabulary import (
NamedSQLObjectVocabulary,
SQLObjectVocabularyBase,
@@ -59,9 +62,8 @@ class TranslatableLanguageVocabulary(LanguageVocabulary):
Iterate languages that are visible and not English.
"""
- languages = self._table.select(
- "Language.code != 'en' AND Language.visible = True",
- orderBy=self._orderBy)
+ languages = self._entries.find(
+ self._table.code != 'en', IsTrue(self._table.visible))
for language in languages:
yield self.toTerm(language)