#=============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of eos. # # eos is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # eos is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with eos. If not, see . #=============================================================================== from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.sql import and_ from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm.collections import attribute_mapped_collection from eos.db import saveddata_meta from eos.db.saveddata.module import modules_table from eos.db.saveddata.drone import drones_table from eos.db.saveddata.cargo import cargo_table from eos.db.saveddata.implant import fitImplants_table from eos.types import Fit, Module, User, Booster, Drone, Cargo, Implant, Character, DamagePattern, TargetResists from eos.effectHandlerHelpers import * fits_table = Table("fits", saveddata_meta, Column("ID", Integer, primary_key = True), Column("ownerID", ForeignKey("users.ID"), nullable = True, index = True), Column("shipID", Integer, nullable = False, index = True), Column("name", String, nullable = False), Column("timestamp", Integer, nullable = False), Column("characterID", ForeignKey("characters.ID"), nullable = True), Column("damagePatternID", ForeignKey("damagePatterns.ID"), nullable=True), Column("booster", Boolean, nullable = False, index = True, default = 0), Column("targetResistsID", ForeignKey("targetResists.ID"), nullable=True), Column("modeID", Integer, nullable=True), ) projectedFits_table = Table("projectedFits", saveddata_meta, Column("sourceID", ForeignKey("fits.ID"), primary_key = True), Column("victimID", ForeignKey("fits.ID"), primary_key = True), Column("amount", Integer, nullable = False, default = 1), Column("active", Boolean, nullable = False, default = 1), ) class ProjectedFit(object): def __init__(self, sourceID, source_fit, amount=1, active=True): self.sourceID = sourceID self.source_fit = source_fit self.active = active self.__amount = amount @reconstructor def init(self): if self.source_fit.isInvalid: # Very rare for this to happen, but be prepared for it eos.db.saveddata_session.delete(self.source_fit) eos.db.saveddata_session.flush() eos.db.saveddata_session.refresh(self.victim_fit) # We have a series of setters and getters here just in case someone # downgrades and screws up the table with NULL values @property def amount(self): return self.__amount or 1 @amount.setter def amount(self, amount): self.__amount = amount def __repr__(self): return "ProjectedFit(sourceID={}, victimID={}, amount={}, active={}) at {}".format( self.sourceID, self.victimID, self.amount, self.active, hex(id(self)) ) Fit._Fit__projectedFits = association_proxy( "victimOf", # look at the victimOf association... "source_fit", # .. and return the source fits creator=lambda sourceID, source_fit: ProjectedFit(sourceID, source_fit) ) mapper(Fit, fits_table, properties = { "_Fit__modules": relation( Module, collection_class=HandledModuleList, primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == False), order_by=modules_table.c.position, cascade='all, delete, delete-orphan'), "_Fit__projectedModules": relation( Module, collection_class=HandledProjectedModList, cascade='all, delete, delete-orphan', single_parent=True, primaryjoin=and_(modules_table.c.fitID == fits_table.c.ID, modules_table.c.projected == True)), "owner": relation( User, backref="fits"), "itemID": fits_table.c.shipID, "shipID": fits_table.c.shipID, "_Fit__boosters": relation( Booster, collection_class=HandledImplantBoosterList, cascade='all, delete, delete-orphan', single_parent=True), "_Fit__drones": relation( Drone, collection_class=HandledDroneCargoList, cascade='all, delete, delete-orphan', single_parent=True, primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)), "_Fit__cargo": relation( Cargo, collection_class=HandledDroneCargoList, cascade='all, delete, delete-orphan', single_parent=True, primaryjoin=and_(cargo_table.c.fitID == fits_table.c.ID)), "_Fit__projectedDrones": relation( Drone, collection_class=HandledProjectedDroneList, cascade='all, delete, delete-orphan', single_parent=True, primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)), "_Fit__implants": relation( Implant, collection_class=HandledImplantBoosterList, cascade='all, delete, delete-orphan', backref='fit', single_parent=True, primaryjoin=fitImplants_table.c.fitID == fits_table.c.ID, secondaryjoin=fitImplants_table.c.implantID == Implant.ID, secondary=fitImplants_table), "_Fit__character": relation( Character, backref="fits"), "_Fit__damagePattern": relation(DamagePattern), "_Fit__targetResists": relation(TargetResists), "projectedOnto": relationship( ProjectedFit, primaryjoin=projectedFits_table.c.sourceID == fits_table.c.ID, backref='source_fit', collection_class=attribute_mapped_collection('victimID'), cascade='all, delete, delete-orphan'), "victimOf": relationship( ProjectedFit, primaryjoin=fits_table.c.ID == projectedFits_table.c.victimID, backref='victim_fit', collection_class=attribute_mapped_collection('sourceID'), cascade='all, delete, delete-orphan'), } ) mapper(ProjectedFit, projectedFits_table, properties = { "_ProjectedFit__amount": projectedFits_table.c.amount, } )