Factor out logic for finding the default db/index. #180
[zzz-pokedex.git] / pokedex / db / tables.py
index f2a31ee..39a2948 100644 (file)
@@ -3,7 +3,8 @@
 from sqlalchemy import Column, ForeignKey, MetaData, Table
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.ext.associationproxy import association_proxy
-from sqlalchemy.orm import backref, relation
+from sqlalchemy.orm import backref, eagerload_all, relation
+from sqlalchemy.orm.session import Session
 from sqlalchemy.sql import and_
 from sqlalchemy.types import *
 
@@ -17,8 +18,15 @@ class Ability(TableBase):
     __singlename__ = 'ability'
     id = Column(Integer, primary_key=True, nullable=False)
     name = Column(Unicode(24), nullable=False)
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
+    effect = Column(rst.RstTextColumn(5120), nullable=False)
+    short_effect = Column(rst.RstTextColumn(255), nullable=False)
+
+class AbilityFlavorText(TableBase):
+    __tablename__ = 'ability_flavor_text'
+    ability_id = Column(Integer, ForeignKey('abilities.id'), primary_key=True, nullable=False, autoincrement=False)
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
     flavor_text = Column(Unicode(64), nullable=False)
-    effect = Column(Unicode(255), nullable=False)
 
 class Berry(TableBase):
     __tablename__ = 'berries'
@@ -201,13 +209,11 @@ class Item(TableBase):
     cost = Column(Integer, nullable=False)
     fling_power = Column(Integer, nullable=True)
     fling_effect_id = Column(Integer, ForeignKey('item_fling_effects.id'), nullable=True)
-    flavor_text = Column(Unicode(255), nullable=False)
-    effect = Column(Unicode(5120), nullable=False)
-    is_underground = Column(Boolean, nullable=False)
-    can_hold = Column(Boolean, nullable=False)
-    is_battle_item = Column(Boolean, nullable=False)
-    can_use_automatically = Column(Boolean, nullable=False)
-    can_reuse = Column(Boolean, nullable=False)
+    effect = Column(rst.RstTextColumn(5120), nullable=False)
+
+    @property
+    def appears_underground(self):
+        return any(flag.identifier == u'underground' for flag in self.flags)
 
 class ItemCategory(TableBase):
     __tablename__ = 'item_categories'
@@ -215,11 +221,34 @@ class ItemCategory(TableBase):
     pocket_id = Column(Integer, ForeignKey('item_pockets.id'), nullable=False)
     name = Column(Unicode(16), nullable=False)
 
+class ItemFlag(TableBase):
+    __tablename__ = 'item_flags'
+    id = Column(Integer, primary_key=True, nullable=False)
+    identifier = Column(Unicode(24), nullable=False)
+    name = Column(Unicode(64), nullable=False)
+
+class ItemFlagMap(TableBase):
+    __tablename__ = 'item_flag_map'
+    item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
+    item_flag_id = Column(Integer, ForeignKey('item_flags.id'), primary_key=True, autoincrement=False, nullable=False)
+
+class ItemFlavorText(TableBase):
+    __tablename__ = 'item_flavor_text'
+    item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, autoincrement=False, nullable=False)
+    flavor_text = Column(Unicode(255), nullable=False)
+
 class ItemFlingEffect(TableBase):
     __tablename__ = 'item_fling_effects'
     id = Column(Integer, primary_key=True, nullable=False)
     effect = Column(Unicode(255), nullable=False)
 
+class ItemInternalID(TableBase):
+    __tablename__ = 'item_internal_ids'
+    item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
+    generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, autoincrement=False, nullable=False)
+    internal_id = Column(Integer, nullable=False)
+
 class ItemPocket(TableBase):
     __tablename__ = 'item_pockets'
     id = Column(Integer, primary_key=True, nullable=False)
@@ -258,8 +287,13 @@ class Machine(TableBase):
     __tablename__ = 'machines'
     machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
+    item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
     move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
 
+    @property
+    def is_hm(self):
+        return self.machine_number >= 100
+
 class MoveBattleStyle(TableBase):
     __tablename__ = 'move_battle_styles'
     id = Column(Integer, primary_key=True, nullable=False)
@@ -607,6 +641,11 @@ class Version(TableBase):
 
 
 ### Relations down here, to avoid ordering problems
+Ability.flavor_text = relation(AbilityFlavorText, order_by=AbilityFlavorText.version_group_id, backref='abilities')
+Ability.generation = relation(Generation, backref='abilities')
+
+AbilityFlavorText.version_group = relation(VersionGroup)
+
 Berry.berry_firmness = relation(BerryFirmness, backref='berries')
 Berry.firmness = association_proxy('berry_firmness', 'name')
 Berry.flavors = relation(BerryFlavor, order_by=BerryFlavor.contest_type_id, backref='berry')
@@ -646,20 +685,29 @@ Generation.canonical_pokedex = relation(Pokedex, backref='canonical_for_generati
 Generation.versions = relation(Version, secondary=VersionGroup.__table__)
 Generation.main_region = relation(Region)
 
+GrowthRate.max_experience_obj = relation(Experience, primaryjoin=and_(Experience.growth_rate_id == GrowthRate.id, Experience.level == 100), uselist=False)
+GrowthRate.max_experience = association_proxy('max_experience_obj', 'experience')
+
 Item.berry = relation(Berry, uselist=False, backref='item')
+Item.flags = relation(ItemFlag, secondary=ItemFlagMap.__table__)
+Item.flavor_text = relation(ItemFlavorText, order_by=ItemFlavorText.version_group_id.asc(), backref='item')
 Item.fling_effect = relation(ItemFlingEffect, backref='items')
+Item.machines = relation(Machine, order_by=Machine.version_group_id.asc())
 Item.category = relation(ItemCategory)
 Item.pocket = association_proxy('category', 'pocket')
 
 ItemCategory.items = relation(Item, order_by=Item.name)
 ItemCategory.pocket = relation(ItemPocket)
 
+ItemFlavorText.version_group = relation(VersionGroup)
+
 ItemPocket.categories = relation(ItemCategory, order_by=ItemCategory.name)
 
 Location.region = relation(Region, backref='locations')
 
 LocationArea.location = relation(Location, backref='areas')
 
+Machine.item = relation(Item)
 Machine.version_group = relation(VersionGroup)
 
 Move.contest_effect = relation(ContestEffect, backref='moves')
@@ -737,7 +785,7 @@ Pokemon.evolution_method = relation(EvolutionMethod)
 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
                                                backref=backref('evolution_parent',
                                                                remote_side=[Pokemon.id]))
-Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.pokemon_id, backref='pokemon')
+Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.version_id.asc(), backref='pokemon')
 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
@@ -745,7 +793,7 @@ Pokemon.items = relation(PokemonItem, backref='pokemon')
 Pokemon.generation = relation(Generation, backref='pokemon')
 Pokemon.shape = relation(PokemonShape, backref='pokemon')
 Pokemon.stats = relation(PokemonStat, backref='pokemon')
-Pokemon.types = relation(Type, secondary=PokemonType.__table__)
+Pokemon.types = relation(Type, secondary=PokemonType.__table__, order_by=PokemonType.slot.asc())
 
 PokemonDexNumber.pokedex = relation(Pokedex)