Support for Abyssal module loading base item attributes

This commit is contained in:
blitzmann
2018-05-27 14:58:14 -04:00
parent 154ac6b045
commit 3944545721
4 changed files with 54 additions and 2 deletions

View File

@@ -17,8 +17,9 @@
# along with eos. If not, see <http://www.gnu.org/licenses/>.
# ===============================================================================
from sqlalchemy.orm import join, exc, aliased
from sqlalchemy.orm import join, exc, aliased, joinedload, subqueryload
from sqlalchemy.sql import and_, or_, select
from sqlalchemy.inspection import inspect
import eos.config
from eos.db import gamedata_session
@@ -97,6 +98,27 @@ def getItem(lookfor, eager=None):
return item
def getItemWithBaseItemAttribute(lookfor, baseItemID, eager=None):
# A lot of this is described in more detail in #1597
item = gamedata_session.query(Item).get(lookfor)
base = getItem(baseItemID)
# we have to load all attributes for this object, otherwise we'll lose access to them when we expunge.
# todo: figure out a way to eagerly load all these via the query...
for x in inspect(Item).relationships.keys():
getattr(item, x)
# Copy over the attributes from the base, but ise the items attributes when there's an overlap
# WARNING: the attribute object still has the old typeID. I don't believe we access this typeID anywhere in the code,
# but should keep this in mind for now.
item._Item__attributes = {**base.attributes, **item.attributes}
# Expunge the item form the session. This is required to have different Abyssal / Base combinations loaded in memory.
# Without expunging it, once one Abyssal Web is created, SQLAlchmey will use it for all others. We don't want this,
# we want to generate a completely new object to work with
gamedata_session.expunge(item)
return item
@cachedQuery(1, "lookfor")
def getItems(lookfor, eager=None):
"""

View File

@@ -0,0 +1,18 @@
"""
Migration 28
- adds baseItemID and mutaplasmidID to modules table
"""
import sqlalchemy
def upgrade(saveddata_engine):
try:
saveddata_engine.execute("SELECT baseItemID FROM modules LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN baseItemID INT;")
try:
saveddata_engine.execute("SELECT mutaplasmidID FROM modules LIMIT 1")
except sqlalchemy.exc.DatabaseError:
saveddata_engine.execute("ALTER TABLE modules ADD COLUMN mutaplasmidID INT;")

View File

@@ -30,6 +30,8 @@ modules_table = Table("modules", saveddata_meta,
Column("ID", Integer, primary_key=True),
Column("fitID", Integer, ForeignKey("fits.ID"), nullable=False, index=True),
Column("itemID", Integer, nullable=True),
Column("baseItemID", Integer, nullable=True),
Column("mutaplasmidID", Integer, nullable=True),
Column("dummySlot", Integer, nullable=True, default=None),
Column("chargeID", Integer),
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),

View File

@@ -76,6 +76,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def __init__(self, item):
"""Initialize a module from the program"""
self.__item = item
self.__baseItem = None
if item is not None and self.isInvalid:
raise ValueError("Passed item is not a Module")
@@ -90,6 +91,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def init(self):
"""Initialize a module from the database and validate"""
self.__item = None
self.__baseItem = None
self.__charge = None
# we need this early if module is invalid and returns early
@@ -101,6 +103,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
pyfalog.error("Item (id: {0}) does not exist", self.itemID)
return
if self.baseItemID:
self.__item = eos.db.getItemWithBaseItemAttribute(self.itemID, self.baseItemID)
self.__baseItem = eos.db.getItem(self.baseItemID)
if self.__baseItem is None:
pyfalog.error("Base Item (id: {0}) does not exist", self.itemID)
return
if self.isInvalid:
pyfalog.error("Item (id: {0}) is not a Module", self.itemID)
return
@@ -128,10 +137,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if self.__item:
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.mutators = self.mutators
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__hardpoint = self.__calculateHardpoint(self.__item)
self.__slot = self.__calculateSlot(self.__item)
self.__itemModifiedAttributes.mutators = self.mutators
if self.__charge:
self.__chargeModifiedAttributes.original = self.__charge.attributes
self.__chargeModifiedAttributes.overrides = self.__charge.overrides