From: Eevee Date: Tue, 22 Mar 2011 00:54:28 +0000 (-0700) Subject: Sigh! Remove support for strings as keys; use Language objects. X-Git-Tag: veekun-promotions/2011041101~33^2~9 X-Git-Url: http://git.veekun.com/zzz-pokedex.git/commitdiff_plain/0069207e4e6fc2c68d0f9c2eb8ad9fc818349b38 Sigh! Remove support for strings as keys; use Language objects. --- diff --git a/pokedex/db/tables.py b/pokedex/db/tables.py index f40583e..20fcbea 100644 --- a/pokedex/db/tables.py +++ b/pokedex/db/tables.py @@ -570,24 +570,6 @@ class Language(TableBase): name = TextColumn(Unicode(16), nullable=False, index=True, plural='names', 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): u"""A place in the Pokémon world """ @@ -1965,34 +1947,9 @@ TODO remove this requirement # Add full-table relations to the original class # 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, primaryjoin=foreign_class.id == Translations.object_id, - #collection_class=attribute_mapped_collection('_language_identifier'), - collection_class=partial(LanguageMapping, - lambda obj: obj._language_identifier), + collection_class=attribute_mapped_collection('language'), # TODO lazy='select', )) @@ -2014,8 +1971,6 @@ TODO remove this requirement # Add per-column proxies to the original class for name, column in kwitems: - # TODO should these proxies be mutable? - # Class.(column) -- accessor for the default language's value setattr(foreign_class, name, association_proxy(local_relation_name, name)) @@ -2023,8 +1978,9 @@ TODO remove this requirement # Class.(column)_map -- accessor for the language dict # Need a custom creator since Translations doesn't have an init, and # these are passed as *args anyway - def creator(language_code, value): + def creator(language, value): row = Translations() + row.language = language setattr(row, name, value) return row setattr(foreign_class, name + '_map', diff --git a/pokedex/tests/test_schema.py b/pokedex/tests/test_schema.py index 63f48ce..9aa3943 100644 --- a/pokedex/tests/test_schema.py +++ b/pokedex/tests/test_schema.py @@ -7,6 +7,8 @@ from sqlalchemy.orm.session import Session from sqlalchemy.ext.declarative import declarative_base 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(): """We want pokedex.db.tables to export tables using the class name""" @@ -46,7 +48,7 @@ def test_i18n_table_creation(): __singlename__ = 'foo' 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, name = Column(String(100)), ) @@ -97,15 +99,22 @@ def test_i18n_table_creation(): foo = sess.query(Foo).params(_default_language='en').one() # Dictionary of language identifiers => names - assert foo.name_map['en'] == 'english' - assert foo.name_map['jp'] == 'nihongo' + assert foo.name_map[lang_en] == 'english' + assert foo.name_map[lang_jp] == 'nihongo' # Default language, currently English assert foo.name == 'english' 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 # .options(joinedload(Foo.name)) \ foo = sess.query(Foo) \ @@ -116,28 +125,28 @@ def test_i18n_table_creation(): 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 # .options(joinedload(Foo.name_map)) \ foo = sess.query(Foo) \ .options(joinedload(Foo.foo_text)) \ .one() - assert foo.name_map['en'] == 'english' - assert foo.name_map['jp'] == 'nihongo' + assert foo.name_map[lang_en] == 'english' + assert foo.name_map[lang_jp] == 'nihongo' 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.name_map['en'] = 'different english' - foo.name_map['ru'] = 'new russian' + foo.name_map[lang_en] = 'different english' + foo.name_map[lang_ru] = 'new russian' sess.commit() - assert foo.name_map['en'] == 'different english' - assert foo.name_map['ru'] == 'new russian' + assert foo.name_map[lang_en] == 'different english' + assert foo.name_map[lang_ru] == 'new russian' def test_texts(): """Check DB schema for integrity of text columns & translations.