mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Sigh! Remove support for strings as keys; use Language objects.
This commit is contained in:
parent
1da816af4b
commit
6a9172151a
2 changed files with 24 additions and 59 deletions
|
@ -570,24 +570,6 @@ class Language(TableBase):
|
||||||
name = TextColumn(Unicode(16), nullable=False, index=True, plural='names',
|
name = TextColumn(Unicode(16), nullable=False, index=True, plural='names',
|
||||||
info=dict(description="The name", format='plaintext', official=True))
|
info=dict(description="The name", format='plaintext', official=True))
|
||||||
|
|
||||||
# Languages compare equal to its identifier, so a dictionary of
|
|
||||||
# translations, with a Language as the key, can be indexed by the identifier
|
|
||||||
def __eq__(self, other):
|
|
||||||
try:
|
|
||||||
return (
|
|
||||||
self is other or
|
|
||||||
self.identifier == other or
|
|
||||||
self.identifier == other.identifier
|
|
||||||
)
|
|
||||||
except AttributeError:
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not (self == other)
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash(self.identifier)
|
|
||||||
|
|
||||||
class Location(TableBase):
|
class Location(TableBase):
|
||||||
u"""A place in the Pokémon world
|
u"""A place in the Pokémon world
|
||||||
"""
|
"""
|
||||||
|
@ -1965,34 +1947,9 @@ TODO remove this requirement
|
||||||
|
|
||||||
# Add full-table relations to the original class
|
# Add full-table relations to the original class
|
||||||
# Class.foo_bars
|
# Class.foo_bars
|
||||||
class LanguageMapping(MappedCollection):
|
|
||||||
"""Baby class that converts a language identifier key into an actual
|
|
||||||
language object, allowing for `foo.bars['en'] = Translations(...)`.
|
|
||||||
|
|
||||||
Needed for per-column association proxies to function as setters.
|
|
||||||
"""
|
|
||||||
@collection.internally_instrumented
|
|
||||||
def __setitem__(self, key, value, _sa_initiator=None):
|
|
||||||
if key in self:
|
|
||||||
raise NotImplementedError("Can't replace the whole row, sorry!")
|
|
||||||
|
|
||||||
# Only do this nonsense if the value is a dangling object; if it's
|
|
||||||
# in the db it already has its language_id
|
|
||||||
if not object_session(value):
|
|
||||||
# This took quite some source-diving to find, but it oughta be
|
|
||||||
# the object that actually owns this collection.
|
|
||||||
obj = collection_adapter(self).owner_state.obj()
|
|
||||||
session = object_session(obj)
|
|
||||||
value.language = session.query(_language_class) \
|
|
||||||
.filter_by(identifier=key).one()
|
|
||||||
|
|
||||||
super(LanguageMapping, self).__setitem__(key, value, _sa_initiator)
|
|
||||||
|
|
||||||
setattr(foreign_class, _table_name, relation(Translations,
|
setattr(foreign_class, _table_name, relation(Translations,
|
||||||
primaryjoin=foreign_class.id == Translations.object_id,
|
primaryjoin=foreign_class.id == Translations.object_id,
|
||||||
#collection_class=attribute_mapped_collection('_language_identifier'),
|
collection_class=attribute_mapped_collection('language'),
|
||||||
collection_class=partial(LanguageMapping,
|
|
||||||
lambda obj: obj._language_identifier),
|
|
||||||
# TODO
|
# TODO
|
||||||
lazy='select',
|
lazy='select',
|
||||||
))
|
))
|
||||||
|
@ -2014,8 +1971,6 @@ TODO remove this requirement
|
||||||
|
|
||||||
# Add per-column proxies to the original class
|
# Add per-column proxies to the original class
|
||||||
for name, column in kwitems:
|
for name, column in kwitems:
|
||||||
# TODO should these proxies be mutable?
|
|
||||||
|
|
||||||
# Class.(column) -- accessor for the default language's value
|
# Class.(column) -- accessor for the default language's value
|
||||||
setattr(foreign_class, name,
|
setattr(foreign_class, name,
|
||||||
association_proxy(local_relation_name, name))
|
association_proxy(local_relation_name, name))
|
||||||
|
@ -2023,8 +1978,9 @@ TODO remove this requirement
|
||||||
# Class.(column)_map -- accessor for the language dict
|
# Class.(column)_map -- accessor for the language dict
|
||||||
# Need a custom creator since Translations doesn't have an init, and
|
# Need a custom creator since Translations doesn't have an init, and
|
||||||
# these are passed as *args anyway
|
# these are passed as *args anyway
|
||||||
def creator(language_code, value):
|
def creator(language, value):
|
||||||
row = Translations()
|
row = Translations()
|
||||||
|
row.language = language
|
||||||
setattr(row, name, value)
|
setattr(row, name, value)
|
||||||
return row
|
return row
|
||||||
setattr(foreign_class, name + '_map',
|
setattr(foreign_class, name + '_map',
|
||||||
|
|
|
@ -7,6 +7,8 @@ from sqlalchemy.orm.session import Session
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
from pokedex.db import tables, markdown
|
from pokedex.db import tables, markdown
|
||||||
|
from pokedex.db.multilang import create_translation_table
|
||||||
|
from pokedex.db.tables import create_translation_table
|
||||||
|
|
||||||
def test_variable_names():
|
def test_variable_names():
|
||||||
"""We want pokedex.db.tables to export tables using the class name"""
|
"""We want pokedex.db.tables to export tables using the class name"""
|
||||||
|
@ -46,7 +48,7 @@ def test_i18n_table_creation():
|
||||||
__singlename__ = 'foo'
|
__singlename__ = 'foo'
|
||||||
id = Column(Integer, primary_key=True, nullable=False)
|
id = Column(Integer, primary_key=True, nullable=False)
|
||||||
|
|
||||||
FooText = tables.create_translation_table('foo_text', Foo,
|
FooText = create_translation_table('foo_text', Foo,
|
||||||
_language_class=Language,
|
_language_class=Language,
|
||||||
name = Column(String(100)),
|
name = Column(String(100)),
|
||||||
)
|
)
|
||||||
|
@ -97,15 +99,22 @@ def test_i18n_table_creation():
|
||||||
foo = sess.query(Foo).params(_default_language='en').one()
|
foo = sess.query(Foo).params(_default_language='en').one()
|
||||||
|
|
||||||
# Dictionary of language identifiers => names
|
# Dictionary of language identifiers => names
|
||||||
assert foo.name_map['en'] == 'english'
|
assert foo.name_map[lang_en] == 'english'
|
||||||
assert foo.name_map['jp'] == 'nihongo'
|
assert foo.name_map[lang_jp] == 'nihongo'
|
||||||
|
|
||||||
# Default language, currently English
|
# Default language, currently English
|
||||||
assert foo.name == 'english'
|
assert foo.name == 'english'
|
||||||
|
|
||||||
sess.expire_all()
|
sess.expire_all()
|
||||||
|
|
||||||
### Test 2: joinedload on the default name should appear to work
|
### Test 2: querying by default language name should work
|
||||||
|
foo = sess.query(Foo).filter_by(name='english').one()
|
||||||
|
|
||||||
|
assert foo.name == 'english'
|
||||||
|
|
||||||
|
sess.expire_all()
|
||||||
|
|
||||||
|
### Test 3: joinedload on the default name should appear to work
|
||||||
# THIS SHOULD WORK SOMEDAY
|
# THIS SHOULD WORK SOMEDAY
|
||||||
# .options(joinedload(Foo.name)) \
|
# .options(joinedload(Foo.name)) \
|
||||||
foo = sess.query(Foo) \
|
foo = sess.query(Foo) \
|
||||||
|
@ -116,28 +125,28 @@ def test_i18n_table_creation():
|
||||||
|
|
||||||
sess.expire_all()
|
sess.expire_all()
|
||||||
|
|
||||||
### Test 3: joinedload on all the names should appear to work
|
### Test 4: joinedload on all the names should appear to work
|
||||||
# THIS SHOULD ALSO WORK SOMEDAY
|
# THIS SHOULD ALSO WORK SOMEDAY
|
||||||
# .options(joinedload(Foo.name_map)) \
|
# .options(joinedload(Foo.name_map)) \
|
||||||
foo = sess.query(Foo) \
|
foo = sess.query(Foo) \
|
||||||
.options(joinedload(Foo.foo_text)) \
|
.options(joinedload(Foo.foo_text)) \
|
||||||
.one()
|
.one()
|
||||||
|
|
||||||
assert foo.name_map['en'] == 'english'
|
assert foo.name_map[lang_en] == 'english'
|
||||||
assert foo.name_map['jp'] == 'nihongo'
|
assert foo.name_map[lang_jp] == 'nihongo'
|
||||||
|
|
||||||
sess.expire_all()
|
sess.expire_all()
|
||||||
|
|
||||||
### Test 4: Mutating the dict collection should work
|
### Test 5: Mutating the dict collection should work
|
||||||
foo = sess.query(Foo).one()
|
foo = sess.query(Foo).one()
|
||||||
|
|
||||||
foo.name_map['en'] = 'different english'
|
foo.name_map[lang_en] = 'different english'
|
||||||
foo.name_map['ru'] = 'new russian'
|
foo.name_map[lang_ru] = 'new russian'
|
||||||
|
|
||||||
sess.commit()
|
sess.commit()
|
||||||
|
|
||||||
assert foo.name_map['en'] == 'different english'
|
assert foo.name_map[lang_en] == 'different english'
|
||||||
assert foo.name_map['ru'] == 'new russian'
|
assert foo.name_map[lang_ru] == 'new russian'
|
||||||
|
|
||||||
def test_texts():
|
def test_texts():
|
||||||
"""Check DB schema for integrity of text columns & translations.
|
"""Check DB schema for integrity of text columns & translations.
|
||||||
|
|
Loading…
Reference in a new issue