Replace submodules with actual files

Submodules never were actually useful
This commit is contained in:
DarkPhoenix
2013-06-10 22:12:34 +04:00
parent 91513d7d95
commit fd36a0b172
2940 changed files with 105139 additions and 0 deletions

77
eos/db/__init__.py Executable file
View File

@@ -0,0 +1,77 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
import threading
from sqlalchemy import MetaData, create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import pool
from eos import config
import migration
class ReadOnlyException(Exception):
pass
gamedata_connectionstring = config.gamedata_connectionstring
if callable(gamedata_connectionstring):
gamedata_engine = create_engine("sqlite://", creator=gamedata_connectionstring, echo = config.debug)
else:
gamedata_engine = create_engine(gamedata_connectionstring, echo = config.debug)
gamedata_meta = MetaData()
gamedata_meta.bind = gamedata_engine
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
saveddata_connectionstring = config.saveddata_connectionstring
if saveddata_connectionstring is not None:
if callable(saveddata_connectionstring):
saveddata_engine = create_engine(creator=saveddata_connectionstring, echo=config.debug)
else:
saveddata_engine = create_engine(saveddata_connectionstring, echo=config.debug)
saveddata_meta = MetaData()
saveddata_meta.bind = saveddata_engine
migration.update(saveddata_engine)
saveddata_session = sessionmaker(bind=saveddata_engine, autoflush=False, expire_on_commit=False)()
# Lock controlling any changes introduced to session
sd_lock = threading.Lock()
#Import all the definitions for all our database stuff
from eos.db.gamedata import *
from eos.db.saveddata import *
#Import queries
from eos.db.gamedata.queries import getItem, searchItems, getVariations, getItemsByCategory, directAttributeRequest, \
getMarketGroup, getGroup, getCategory, getAttributeInfo, getMetaData, getMetaGroup
from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithShip, countFitsWithShip, searchFits, \
getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \
getFitList, getFleetList, getFleet, save, remove, commit, add, \
getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \
getSquad
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
if config.saveddata_connectionstring == "sqlite:///:memory:":
saveddata_meta.create_all()
def rollback():
with sd_lock:
saveddata_session.rollback()

2
eos/db/gamedata/__init__.py Executable file
View File

@@ -0,0 +1,2 @@
__all__ = ["attribute", "category", "effect", "group", "metaData",
"icon", "item", "marketGroup", "metaGroup", "unit"]

59
eos/db/gamedata/attribute.py Executable file
View File

@@ -0,0 +1,59 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, Float, Unicode, ForeignKey, String, Boolean
from sqlalchemy.orm import relation, mapper, synonym, deferred
from sqlalchemy.ext.associationproxy import association_proxy
from eos.types import Attribute, Icon, AttributeInfo, Unit
from eos.db import gamedata_meta
typeattributes_table = Table("dgmtypeattribs", gamedata_meta,
Column("value", Float),
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
Column("attributeID", ForeignKey("dgmattribs.attributeID"), primary_key=True))
attributes_table = Table("dgmattribs", gamedata_meta,
Column("attributeID", Integer, primary_key = True),
Column("attributeName", String),
Column("defaultValue", Float),
Column("description", Unicode),
Column("published", Boolean),
Column("displayName", String),
Column("highIsGood", Boolean),
Column("iconID", Integer, ForeignKey("icons.iconID")),
Column("unitID", Integer, ForeignKey("dgmunits.unitID")))
mapper(Attribute, typeattributes_table,
properties = {"info": relation(AttributeInfo, lazy=False)})
mapper(AttributeInfo, attributes_table,
properties = {"icon" : relation(Icon),
"unit": relation(Unit),
"ID": synonym("attributeID"),
"name": synonym("attributeName"),
"description" : deferred(attributes_table.c.description)})
Attribute.ID = association_proxy("info", "attributeID")
Attribute.name = association_proxy("info", "attributeName")
Attribute.description = association_proxy("info", "description")
Attribute.published = association_proxy("info", "published")
Attribute.displayName = association_proxy("info", "displayName")
Attribute.highIsGood = association_proxy("info", "highIsGood")
Attribute.iconID = association_proxy("info", "iconID")
Attribute.icon = association_proxy("info", "icon")
Attribute.unit = association_proxy("info", "unit")

37
eos/db/gamedata/category.py Executable file
View File

@@ -0,0 +1,37 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, ForeignKey, Boolean, Table
from sqlalchemy.orm import relation, mapper, synonym, deferred
from eos.db import gamedata_meta
from eos.types import Category, Icon
categories_table = Table("invcategories", gamedata_meta,
Column("categoryID", Integer, primary_key = True),
Column("categoryName", String),
Column("description", String),
Column("published", Boolean),
Column("iconID", Integer, ForeignKey("icons.iconID")))
mapper(Category, categories_table,
properties = {"icon" : relation(Icon),
"ID" : synonym("categoryID"),
"name" : synonym("categoryName"),
"description" : deferred(categories_table.c.description)})

50
eos/db/gamedata/effect.py Executable file
View File

@@ -0,0 +1,50 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, Boolean, Table, ForeignKey
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import mapper, synonym, relation, deferred
from eos.types import Effect, EffectInfo
from eos.db import gamedata_meta
typeeffects_table = Table("dgmtypeeffects", gamedata_meta,
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key=True, index=True),
Column("effectID", Integer, ForeignKey("dgmeffects.effectID"), primary_key=True))
effects_table = Table("dgmeffects", gamedata_meta,
Column("effectID", Integer, primary_key = True),
Column("effectName", String),
Column("description", String),
Column("published", Boolean),
Column("isAssistance", Boolean),
Column("isOffensive", Boolean))
mapper(EffectInfo, effects_table,
properties = {"ID" : synonym("effectID"),
"name" : synonym("effectName"),
"description" : deferred(effects_table.c.description)})
mapper(Effect, typeeffects_table,
properties = {"ID": synonym("effectID"),
"info": relation(EffectInfo, lazy=False)})
Effect.name = association_proxy("info", "name")
Effect.description = association_proxy("info", "description")
Effect.published = association_proxy("info", "published")

39
eos/db/gamedata/group.py Executable file
View File

@@ -0,0 +1,39 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
from sqlalchemy.orm import relation, mapper, synonym, deferred
from eos.db import gamedata_meta
from eos.types import Group, Icon, Category
groups_table = Table("invgroups", gamedata_meta,
Column("groupID", Integer, primary_key = True),
Column("groupName", String),
Column("description", String),
Column("published", Boolean),
Column("categoryID", Integer, ForeignKey("invcategories.categoryID")),
Column("iconID", Integer, ForeignKey("icons.iconID")))
mapper(Group, groups_table,
properties = {"category" : relation(Category, backref = "groups"),
"icon" : relation(Icon),
"ID" : synonym("groupID"),
"name" : synonym("groupName"),
"description" : deferred(groups_table.c.description)})

33
eos/db/gamedata/icon.py Executable file
View File

@@ -0,0 +1,33 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, Table
from sqlalchemy.orm import mapper, synonym, deferred
from eos.db import gamedata_meta
from eos.types import Icon
icons_table = Table("icons", gamedata_meta,
Column("iconID", Integer, primary_key = True),
Column("description", String),
Column("iconFile", String))
mapper(Icon, icons_table,
properties = {"ID" : synonym("iconID"),
"description" : deferred(icons_table.c.description)})

57
eos/db/gamedata/item.py Executable file
View File

@@ -0,0 +1,57 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table, Float
from sqlalchemy.orm import relation, mapper, synonym, deferred
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from eos.db import gamedata_meta
from eos.types import Icon, Attribute, Item, Effect, MetaType, Group
items_table = Table("invtypes", gamedata_meta,
Column("typeID", Integer, primary_key = True),
Column("typeName", String, index=True),
Column("description", String),
Column("raceID", Integer),
Column("volume", Float),
Column("mass", Float),
Column("capacity", Float),
Column("published", Boolean),
Column("marketGroupID", Integer, ForeignKey("invmarketgroups.marketGroupID")),
Column("iconID", Integer, ForeignKey("icons.iconID")),
Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))
from .metaGroup import metatypes_table
mapper(Item, items_table,
properties = {"group" : relation(Group, backref = "items"),
"icon" : relation(Icon),
"_Item__attributes" : relation(Attribute, collection_class = attribute_mapped_collection('name')),
"effects" : relation(Effect, collection_class = attribute_mapped_collection('name')),
"metaGroup" : relation(MetaType,
primaryjoin = metatypes_table.c.typeID == items_table.c.typeID,
uselist = False),
"ID" : synonym("typeID"),
"name" : synonym("typeName"),
"description" : deferred(items_table.c.description)})
Item.category = association_proxy("group", "category")

40
eos/db/gamedata/marketGroup.py Executable file
View File

@@ -0,0 +1,40 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey, Table
from sqlalchemy.orm import relation, mapper, synonym, deferred
from eos.db import gamedata_meta
from eos.types import Item, MarketGroup, Icon
marketgroups_table = Table("invmarketgroups", gamedata_meta,
Column("marketGroupID", Integer, primary_key = True),
Column("marketGroupName", String),
Column("description", String),
Column("hasTypes", Boolean),
Column("parentGroupID", Integer, ForeignKey("invmarketgroups.marketGroupID", initially="DEFERRED", deferrable=True)),
Column("iconID", Integer, ForeignKey("icons.iconID")))
mapper(MarketGroup, marketgroups_table,
properties = {"items" : relation(Item, backref = "marketGroup"),
"parent" : relation(MarketGroup, backref = "children", remote_side = [marketgroups_table.c.marketGroupID]),
"icon" : relation(Icon),
"ID" : synonym("marketGroupID"),
"name" : synonym("marketGroupName"),
"description" : deferred(marketgroups_table.c.description)})

29
eos/db/gamedata/metaData.py Executable file
View File

@@ -0,0 +1,29 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, Table, String
from sqlalchemy.orm import mapper
from eos.types import MetaData
from eos.db import gamedata_meta
metadata_table = Table("metadata", gamedata_meta,
Column("fieldName", String, primary_key=True),
Column("fieldValue", String))
mapper(MetaData, metadata_table)

47
eos/db/gamedata/metaGroup.py Executable file
View File

@@ -0,0 +1,47 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import relation, mapper, synonym
from eos.db import gamedata_meta
from eos.db.gamedata.item import items_table
from eos.types import MetaGroup, Item, MetaType
from sqlalchemy.ext.associationproxy import association_proxy
metagroups_table = Table("invmetagroups", gamedata_meta,
Column("metaGroupID", Integer, primary_key = True),
Column("metaGroupName", String))
metatypes_table = Table("invmetatypes", gamedata_meta,
Column("typeID", Integer, ForeignKey("invtypes.typeID"), primary_key = True),
Column("parentTypeID", Integer, ForeignKey("invtypes.typeID")),
Column("metaGroupID", Integer, ForeignKey("invmetagroups.metaGroupID")))
mapper(MetaGroup, metagroups_table,
properties = {"ID" : synonym("metaGroupID"),
"name" : synonym("metaGroupName")})
mapper(MetaType, metatypes_table,
properties = {"ID" : synonym("metaGroupID"),
"parent" : relation(Item, primaryjoin = metatypes_table.c.parentTypeID == items_table.c.typeID),
"items" : relation(Item, primaryjoin = metatypes_table.c.typeID == items_table.c.typeID),
"info": relation(MetaGroup, lazy=False)})
MetaType.name = association_proxy("info", "name")

251
eos/db/gamedata/queries.py Executable file
View File

@@ -0,0 +1,251 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from eos.db import gamedata_session
from eos.db.gamedata.metaGroup import metatypes_table, items_table
from sqlalchemy.sql import and_, or_, select, func
from sqlalchemy.orm import join, exc
from eos.types import Item, Category, Group, MarketGroup, AttributeInfo, MetaData, MetaGroup
from eos.db.util import processEager, processWhere
import eos.config
configVal = getattr(eos.config, "gamedataCache", None)
if configVal is True:
def cachedQuery(amount, *keywords):
def deco(function):
cache = {}
def checkAndReturn(*args, **kwargs):
useCache = kwargs.pop("useCache", True)
cacheKey = []
cacheKey.extend(args)
for keyword in keywords:
cacheKey.append(kwargs.get(keyword))
cacheKey = tuple(cacheKey)
handler = cache.get(cacheKey)
if handler is None or not useCache:
handler = cache[cacheKey] = function(*args, **kwargs)
return handler
return checkAndReturn
return deco
elif callable(configVal):
cachedQuery = eos.config.gamedataCache
else:
def cachedQuery(amount, *keywords):
def deco(function):
def checkAndReturn(*args, **kwargs):
return function(*args, **kwargs)
return checkAndReturn
return deco
def sqlizeString(line):
# Escape backslashes first, as they will be as escape symbol in queries
# Then escape percent and underscore signs
# Finally, replace generic wildcards with sql-style wildcards
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
return line
itemNameMap = {}
@cachedQuery(1, "lookfor")
def getItem(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
item = gamedata_session.query(Item).get(lookfor)
else:
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
elif isinstance(lookfor, basestring):
if lookfor in itemNameMap:
id = itemNameMap[lookfor]
if eager is None:
item = gamedata_session.query(Item).get(id)
else:
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == id).first()
else:
# Item names are unique, so we can use first() instead of one()
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.name == lookfor).first()
itemNameMap[lookfor] = item.ID
else:
raise TypeError("Need integer or string as argument")
return item
groupNameMap = {}
@cachedQuery(1, "lookfor")
def getGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
group = gamedata_session.query(Group).get(lookfor)
else:
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
elif isinstance(lookfor, basestring):
if lookfor in groupNameMap:
id = groupNameMap[lookfor]
if eager is None:
group = gamedata_session.query(Group).get(id)
else:
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == id).first()
else:
# Group names are unique, so we can use first() instead of one()
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.name == lookfor).first()
groupNameMap[lookfor] = group.ID
else:
raise TypeError("Need integer or string as argument")
return group
categoryNameMap = {}
@cachedQuery(1, "lookfor")
def getCategory(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
category = gamedata_session.query(Category).get(lookfor)
else:
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.ID == lookfor).first()
elif isinstance(lookfor, basestring):
if lookfor in categoryNameMap:
id = categoryNameMap[lookfor]
if eager is None:
category = gamedata_session.query(Category).get(id)
else:
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.ID == id).first()
else:
# Category names are unique, so we can use first() instead of one()
category = gamedata_session.query(Category).options(*processEager(eager)).filter(Category.name == lookfor).first()
categoryNameMap[lookfor] = category.ID
else:
raise TypeError("Need integer or string as argument")
return category
metaGroupNameMap = {}
@cachedQuery(1, "lookfor")
def getMetaGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
metaGroup = gamedata_session.query(MetaGroup).get(lookfor)
else:
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.ID == lookfor).first()
elif isinstance(lookfor, basestring):
if lookfor in metaGroupNameMap:
id = metaGroupNameMap[lookfor]
if eager is None:
metaGroup = gamedata_session.query(MetaGroup).get(id)
else:
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.ID == id).first()
else:
# MetaGroup names are unique, so we can use first() instead of one()
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(MetaGroup.name == lookfor).first()
metaGroupNameMap[lookfor] = metaGroup.ID
else:
raise TypeError("Need integer or string as argument")
return metaGroup
@cachedQuery(1, "lookfor")
def getMarketGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
marketGroup = gamedata_session.query(MarketGroup).get(lookfor)
else:
marketGroup = gamedata_session.query(MarketGroup).options(*processEager(eager)).filter(MarketGroup.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
return marketGroup
@cachedQuery(2, "where", "filter")
def getItemsByCategory(filter, where=None, eager=None):
if isinstance(filter, int):
filter = Category.ID == filter
elif isinstance(filter, basestring):
filter = Category.name == filter
else:
raise TypeError("Need integer or string as argument")
filter = processWhere(filter, where)
return gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category).filter(filter).all()
@cachedQuery(3, "where", "nameLike", "join")
def searchItems(nameLike, where=None, join=None, eager=None):
if not isinstance(nameLike, basestring):
raise TypeError("Need string as argument")
# Prepare our string for request
nameLike = u"%{0}%".format(sqlizeString(nameLike))
if join is None:
join = tuple()
if not hasattr(join, "__iter__"):
join = (join,)
filter = processWhere(Item.name.like(nameLike, escape="\\"), where)
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join).filter(filter).all()
return items
@cachedQuery(2, "where", "itemids")
def getVariations(itemids, where=None, eager=None):
for itemid in itemids:
if not isinstance(itemid, int):
raise TypeError("All passed item IDs must be integers")
# Get out if list of provided IDs is empty
if len(itemids) == 0:
return []
itemfilter = or_(*(metatypes_table.c.parentTypeID == itemid for itemid in itemids))
filter = processWhere(itemfilter, where)
joinon = items_table.c.typeID == metatypes_table.c.typeID
vars = gamedata_session.query(Item).options(*processEager(eager)).join((metatypes_table, joinon)).filter(filter).all()
return vars
@cachedQuery(1, "attr")
def getAttributeInfo(attr, eager=None):
if isinstance(attr, basestring):
filter = AttributeInfo.name == attr
elif isinstance(attr, int):
filter = AttributeInfo.ID == attr
else:
raise TypeError("Need integer or string as argument")
try:
result = gamedata_session.query(AttributeInfo).options(*processEager(eager)).filter(filter).one()
except exc.NoResultFound:
result = None
return result
@cachedQuery(1, "field")
def getMetaData(field):
if isinstance(field, basestring):
data = gamedata_session.query(MetaData).get(field)
else:
raise TypeError("Need string as argument")
return data
@cachedQuery(2, "itemIDs", "attributeID")
def directAttributeRequest(itemIDs, attrIDs):
for itemID in itemIDs:
if not isinstance(itemID, int):
raise TypeError("All attrIDs must be integer")
for itemID in itemIDs:
if not isinstance(itemID, int):
raise TypeError("All itemIDs must be integer")
q = select((eos.types.Item.typeID, eos.types.Attribute.attributeID, eos.types.Attribute.value),
and_(eos.types.Attribute.attributeID.in_(attrIDs), eos.types.Item.typeID.in_(itemIDs)),
from_obj=[join(eos.types.Attribute, eos.types.Item)])
result = gamedata_session.execute(q).fetchall()
return result

33
eos/db/gamedata/unit.py Executable file
View File

@@ -0,0 +1,33 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, Table, Integer, String
from sqlalchemy.orm import mapper, synonym
from eos.db import gamedata_meta
from eos.types import Unit
groups_table = Table("dgmunits", gamedata_meta,
Column("unitID", Integer, primary_key = True),
Column("unitName", String),
Column("displayName", String))
mapper(Unit, groups_table,
properties = {"ID" : synonym("unitID"),
"name" : synonym("unitName")})

20
eos/db/migration.py Executable file
View File

@@ -0,0 +1,20 @@
import sqlalchemy
def update(saveddata_engine):
checkPriceFailures(saveddata_engine)
def checkPriceFailures(saveddata_engine):
# Check if we have 'failed' column
try:
saveddata_engine.execute("SELECT failed FROM prices")
except sqlalchemy.exc.DatabaseError:
# As we don't have any important data there, let's just drop
# and recreate whole table
from eos.db.saveddata.price import prices_table
# Attempt to drop/create table only if it's already there
try:
prices_table.drop(saveddata_engine)
prices_table.create(saveddata_engine)
except sqlalchemy.exc.DatabaseError:
pass

3
eos/db/saveddata/__init__.py Executable file
View File

@@ -0,0 +1,3 @@
__all__ = ["character", "fit", "module", "user", "skill", "price",
"booster", "drone", "implant", "fleet", "damagePattern",
"miscData"]

47
eos/db/saveddata/booster.py Executable file
View File

@@ -0,0 +1,47 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, ForeignKey, Integer, UniqueConstraint, Boolean
from sqlalchemy.orm import mapper, relation
from sqlalchemy.ext.associationproxy import association_proxy
from eos.db import saveddata_meta
from eos.types import Booster
boosters_table = Table("boosters", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("itemID", Integer),
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False),
Column("active", Boolean),
UniqueConstraint("itemID", "fitID"))
activeSideEffects_table = Table("boostersActiveSideEffects", saveddata_meta,
Column("boosterID", ForeignKey("boosters.ID"), primary_key = True),
Column("effectID", Integer, primary_key = True))
class ActiveSideEffectsDummy(object):
def __init__(self, effectID):
self.effectID = effectID
mapper(ActiveSideEffectsDummy, activeSideEffects_table)
mapper(Booster, boosters_table,
properties = {"_Booster__activeSideEffectDummies" : relation(ActiveSideEffectsDummy)})
Booster._Booster__activeSideEffectIDs = association_proxy("_Booster__activeSideEffectDummies", "effectID")

42
eos/db/saveddata/character.py Executable file
View File

@@ -0,0 +1,42 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import relation, mapper
from eos.db import saveddata_meta
from eos.db.saveddata.implant import charImplants_table
from eos.types import Character, User, Skill, Implant
from eos.effectHandlerHelpers import HandledImplantBoosterList
characters_table = Table("characters", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("name", String, nullable = False),
Column("apiID", Integer),
Column("apiKey", String),
Column("defaultLevel", Integer, nullable=True),
Column("ownerID", ForeignKey("users.ID"), nullable = True))
mapper(Character, characters_table,
properties = {"_Character__owner" : relation(User, backref = "characters"),
"_Character__skills" : relation(Skill, backref="character", cascade = "all,delete-orphan"),
"_Character__implants" : relation(Implant, collection_class = HandledImplantBoosterList, cascade='all,delete-orphan', single_parent=True,
primaryjoin = charImplants_table.c.charID == characters_table.c.ID,
secondaryjoin = charImplants_table.c.implantID == Implant.ID,
secondary = charImplants_table),})

View File

@@ -0,0 +1,35 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import DamagePattern
damagePatterns_table = Table("damagePatterns", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("name", String),
Column("emAmount", Integer),
Column("thermalAmount", Integer),
Column("kineticAmount", Integer),
Column("explosiveAmount", Integer),
Column("ownerID", ForeignKey("users.ID"), nullable=True))
mapper(DamagePattern, damagePatterns_table)

33
eos/db/saveddata/drone.py Executable file
View File

@@ -0,0 +1,33 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Drone
drones_table = Table("drones", saveddata_meta,
Column("groupID", Integer, primary_key=True),
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
Column("itemID", Integer, nullable = False),
Column("amount", Integer, nullable = False),
Column("amountActive", Integer, nullable = False),
Column("projected", Boolean, default = False))
mapper(Drone, drones_table)

68
eos/db/saveddata/fit.py Executable file
View File

@@ -0,0 +1,68 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import relation, mapper
from sqlalchemy.sql import and_
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.implant import fitImplants_table
from eos.types import Fit, Module, User, Booster, Drone, Implant, Character, DamagePattern
from eos.effectHandlerHelpers import HandledModuleList, HandledDroneList, \
HandledImplantBoosterList, HandledProjectedModList, HandledProjectedDroneList, \
HandledProjectedFitList
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))
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))
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"),
"_Fit__boosters" : relation(Booster, collection_class = HandledImplantBoosterList, cascade='all, delete, delete-orphan', single_parent=True),
"_Fit__drones" : relation(Drone, collection_class = HandledDroneList, cascade='all, delete, delete-orphan', single_parent=True,
primaryjoin = and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == False)),
"_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', 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__projectedFits" : relation(Fit,
primaryjoin = projectedFits_table.c.victimID == fits_table.c.ID,
secondaryjoin = fits_table.c.ID == projectedFits_table.c.sourceID,
secondary = projectedFits_table,
collection_class = HandledProjectedFitList)
})

66
eos/db/saveddata/fleet.py Executable file
View File

@@ -0,0 +1,66 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, String
from sqlalchemy.orm import mapper, relation
from eos.db import saveddata_meta
from eos.types import Fleet, Wing, Squad, Fit
from eos.db.saveddata.fit import fits_table
gangs_table = Table("gangs", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("leaderID", ForeignKey("fits.ID")),
Column("boosterID", ForeignKey("fits.ID")),
Column("name", String))
wings_table = Table("wings", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("gangID", ForeignKey("gangs.ID")),
Column("boosterID", ForeignKey("fits.ID")),
Column("leaderID", ForeignKey("fits.ID")))
squads_table = Table("squads", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("wingID", ForeignKey("wings.ID")),
Column("leaderID", ForeignKey("fits.ID")),
Column("boosterID", ForeignKey("fits.ID")))
squadmembers_table = Table("squadmembers", saveddata_meta,
Column("squadID", ForeignKey("squads.ID"), primary_key = True),
Column("memberID", ForeignKey("fits.ID"), primary_key = True))
mapper(Fleet, gangs_table,
properties = {"wings" : relation(Wing, backref="gang"),
"leader" : relation(Fit, primaryjoin = gangs_table.c.leaderID == fits_table.c.ID),
"booster": relation(Fit, primaryjoin = gangs_table.c.boosterID == fits_table.c.ID)})
mapper(Wing, wings_table,
properties = {"squads" : relation(Squad, backref="wing"),
"leader" : relation(Fit, primaryjoin = wings_table.c.leaderID == fits_table.c.ID),
"booster": relation(Fit, primaryjoin = wings_table.c.boosterID == fits_table.c.ID)})
mapper(Squad, squads_table,
properties = {"leader" : relation(Fit, primaryjoin = squads_table.c.leaderID == fits_table.c.ID),
"booster" : relation(Fit, primaryjoin = squads_table.c.boosterID == fits_table.c.ID),
"members" : relation(Fit,
primaryjoin = squads_table.c.ID == squadmembers_table.c.squadID,
secondaryjoin = squadmembers_table.c.memberID == fits_table.c.ID,
secondary = squadmembers_table)})

39
eos/db/saveddata/implant.py Executable file
View File

@@ -0,0 +1,39 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Implant
implants_table = Table("implants", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("itemID", Integer),
Column("active", Boolean))
fitImplants_table = Table("fitImplants", saveddata_meta,
Column("fitID", ForeignKey("fits.ID"), index = True),
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
charImplants_table = Table("charImplants", saveddata_meta,
Column("charID", ForeignKey("characters.ID"), index = True),
Column("implantID", ForeignKey("implants.ID"), primary_key = True))
mapper(Implant, implants_table)

29
eos/db/saveddata/miscData.py Executable file
View File

@@ -0,0 +1,29 @@
#===============================================================================
# Copyright (C) 2011 Anton Vorobyov
#
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Column, Table, String
from sqlalchemy.orm import mapper
from eos.types import MiscData
from eos.db import saveddata_meta
miscdata_table = Table("miscdata", saveddata_meta,
Column("fieldName", String, primary_key=True),
Column("fieldValue", String))
mapper(MiscData, miscdata_table)

39
eos/db/saveddata/module.py Executable file
View File

@@ -0,0 +1,39 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey, CheckConstraint, Boolean
from sqlalchemy.orm import relation, mapper
from eos.db import saveddata_meta
from eos.types import Module, Fit
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("dummySlot", Integer, nullable = True, default = None),
Column("chargeID", Integer),
Column("state", Integer, CheckConstraint("state >= -1"), CheckConstraint("state <= 2")),
Column("projected", Boolean, default = False, nullable = False),
Column("position", Integer),
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
mapper(Module, modules_table,
properties = {"owner" : relation(Fit)})

31
eos/db/saveddata/price.py Executable file
View File

@@ -0,0 +1,31 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Float, Integer
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Price
prices_table = Table("prices", saveddata_meta,
Column("typeID", Integer, primary_key=True),
Column("price", Float),
Column("time", Integer, nullable = False),
Column("failed", Integer))
mapper(Price, prices_table)

365
eos/db/saveddata/queries.py Executable file
View File

@@ -0,0 +1,365 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from eos.db.util import processEager, processWhere
from eos.db import saveddata_session, sd_lock
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad
from eos.db.saveddata.fleet import squadmembers_table
from sqlalchemy.sql import and_
import eos.config
configVal = getattr(eos.config, "saveddataCache", None)
if configVal is True:
import weakref
itemCache = {}
queryCache = {}
def cachedQuery(type, amount, *keywords):
itemCache[type] = localItemCache = weakref.WeakValueDictionary()
queryCache[type] = typeQueryCache = {}
def deco(function):
localQueryCache = typeQueryCache[function] = {}
def setCache(cacheKey, args, kwargs):
items = function(*args, **kwargs)
IDs = set()
localQueryCache[cacheKey] = (isinstance(items, list), IDs)
stuff = items if isinstance(items, list) else (items,)
for item in stuff:
ID = getattr(item, "ID", None)
if ID is None:
#Some uncachable data, don't cache this query
del localQueryCache[cacheKey]
break
localItemCache[ID] = item
IDs.add(ID)
return items
def checkAndReturn(*args, **kwargs):
useCache = kwargs.pop("useCache", True)
cacheKey = []
cacheKey.extend(args)
for keyword in keywords:
cacheKey.append(kwargs.get(keyword))
cacheKey = tuple(cacheKey)
info = localQueryCache.get(cacheKey)
if info is None or not useCache:
items = setCache(cacheKey, args, kwargs)
else:
l, IDs = info
if l:
items = []
for ID in IDs:
data = localItemCache.get(ID)
if data is None:
#Fuck, some of our stuff isn't cached it seems.
items = setCache(cacheKey, args, kwargs)
break
items.append(data)
else:
for ID in IDs:
items = localItemCache.get(ID)
if items is None:
items = setCache(cacheKey, args, kwargs)
break
return items
return checkAndReturn
return deco
def removeCachedEntry(type, ID):
if not type in queryCache:
return
functionCache = queryCache[type]
for _, localCache in functionCache.iteritems():
toDelete = set()
for cacheKey, info in localCache.iteritems():
IDs = info[1]
if ID in IDs:
toDelete.add(cacheKey)
for cacheKey in toDelete:
del localCache[cacheKey]
if ID in itemCache[type]:
del itemCache[type][ID]
elif callable(configVal):
cachedQuery, removeCachedEntry = eos.config.gamedataCache
else:
def cachedQuery(amount, *keywords):
def deco(function):
def checkAndReturn(*args, **kwargs):
return function(*args, **kwargs)
return checkAndReturn
return deco
def removeCachedEntry(*args, **kwargs):
return
def sqlizeString(line):
# Escape backslashes first, as they will be as escape symbol in queries
# Then escape percent and underscore signs
# Finally, replace generic wildcards with sql-style wildcards
line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%")
return line
@cachedQuery(User, 1, "lookfor")
def getUser(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
user = saveddata_session.query(User).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
user = saveddata_session.query(User).options(*eager).filter(User.ID == lookfor).first()
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
user = saveddata_session.query(User).options(*eager).filter(User.username == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return user
@cachedQuery(Character, 1, "lookfor")
def getCharacter(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
character = saveddata_session.query(Character).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(Character).options(*eager).filter(Character.ID == lookfor).first()
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(Character).options(*eager).filter(Character.name == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return character
def getCharacterList(eager=None):
eager = processEager(eager)
with sd_lock:
characters = saveddata_session.query(Character).options(*eager).all()
return characters
def getCharactersForUser(lookfor, eager=None):
if isinstance(lookfor, int):
eager = processEager(eager)
with sd_lock:
characters = saveddata_session.query(Character).options(*eager).filter(Character.ownerID == lookfor).all()
else:
raise TypeError("Need integer as argument")
return characters
@cachedQuery(Fit, 1, "lookfor")
def getFit(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
fit = saveddata_session.query(Fit).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == fitID).first()
else:
raise TypeError("Need integer as argument")
return fit
@cachedQuery(Fleet, 1, "fleetID")
def getFleet(fleetID, eager=None):
if isinstance(fleetID, int):
if eager is None:
with sd_lock:
fleet = saveddata_session.query(Fleet).get(fleetID)
else:
eager = processEager(eager)
with sd_lock:
fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first()
else:
raise TypeError("Need integer as argument")
return fleet
@cachedQuery(Wing, 1, "wingID")
def getWing(wingID, eager=None):
if isinstance(wingID, int):
if eager is None:
with sd_lock:
wing = saveddata_session.query(Wing).get(wingID)
else:
eager = processEager(eager)
with sd_lock:
wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first()
else:
raise TypeError("Need integer as argument")
return wing
@cachedQuery(Squad, 1, "squadID")
def getSquad(squadID, eager=None):
if isinstance(squadID, int):
if eager is None:
with sd_lock:
squad = saveddata_session.query(Squad).get(squadID)
else:
eager = processEager(eager)
with sd_lock:
squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first()
else:
raise TypeError("Need integer as argument")
return squad
def getFitsWithShip(shipID, ownerID=None, where=None, eager=None):
"""
Get all the fits using a certain ship.
If no user is passed, do this for all users.
"""
if isinstance(shipID, int):
if ownerID is not None and not isinstance(ownerID, int):
raise TypeError("OwnerID must be integer")
filter = Fit.shipID == shipID
if ownerID is not None:
filter = and_(filter, Fit.ownerID == ownerID)
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
else:
raise TypeError("ShipID must be integer")
return fits
def countFitsWithShip(shipID, ownerID=None, where=None, eager=None):
"""
Get all the fits using a certain ship.
If no user is passed, do this for all users.
"""
if isinstance(shipID, int):
if ownerID is not None and not isinstance(ownerID, int):
raise TypeError("OwnerID must be integer")
filter = Fit.shipID == shipID
if ownerID is not None:
filter = and_(filter, Fit.ownerID == ownerID)
filter = processWhere(filter, where)
eager = processEager(eager)
with sd_lock:
count = saveddata_session.query(Fit).options(*eager).filter(filter).count()
else:
raise TypeError("ShipID must be integer")
return count
def getFitList(eager=None):
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).all()
return fits
def getFleetList(eager=None):
eager = processEager(eager)
with sd_lock:
fleets = saveddata_session.query(Fleet).options(*eager).all()
return fleets
@cachedQuery(Price, 1, "typeID")
def getPrice(typeID):
if isinstance(typeID, int):
with sd_lock:
price = saveddata_session.query(Price).get(typeID)
else:
raise TypeError("Need integer as argument")
return price
def getMiscData(field):
if isinstance(field, basestring):
with sd_lock:
data = saveddata_session.query(MiscData).get(field)
else:
raise TypeError("Need string as argument")
return data
def getDamagePatternList(eager=None):
eager = processEager(eager)
with sd_lock:
patterns = saveddata_session.query(DamagePattern).options(*eager).all()
return patterns
@cachedQuery(DamagePattern, 1, "lookfor")
def getDamagePattern(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
pattern = saveddata_session.query(DamagePattern).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.ID == lookfor).first()
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.name == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return pattern
def searchFits(nameLike, where=None, eager=None):
if not isinstance(nameLike, basestring):
raise TypeError("Need string as argument")
# Prepare our string for request
nameLike = u"%{0}%".format(sqlizeString(nameLike))
#Add any extra components to the search to our where clause
filter = processWhere(Fit.name.like(nameLike, escape="\\"), where)
eager = processEager(eager)
with sd_lock:
fits = saveddata_session.query(Fit).options(*eager).filter(filter).all()
return fits
def getSquadsIDsWithFitID(fitID):
if isinstance(fitID, int):
with sd_lock:
squads = saveddata_session.query(squadmembers_table.c.squadID).filter(squadmembers_table.c.memberID == fitID).all()
squads = tuple(entry[0] for entry in squads)
return squads
else:
raise TypeError("Need integer as argument")
def add(stuff):
with sd_lock:
saveddata_session.add(stuff)
def save(stuff):
add(stuff)
commit()
def remove(stuff):
removeCachedEntry(type(stuff), stuff.ID)
with sd_lock:
saveddata_session.delete(stuff)
commit()
def commit():
with sd_lock:
saveddata_session.commit()
saveddata_session.flush()

31
eos/db/saveddata/skill.py Executable file
View File

@@ -0,0 +1,31 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Skill
skills_table = Table("characterSkills", saveddata_meta,
Column("characterID", ForeignKey("characters.ID"), primary_key = True, index = True),
Column("itemID", Integer, primary_key = True),
Column("_Skill__level", Integer, nullable = True))
mapper(Skill, skills_table)

32
eos/db/saveddata/user.py Executable file
View File

@@ -0,0 +1,32 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy import Table, Column, Integer, String, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import User
users_table = Table("users", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("username", String, nullable = False, unique = True),
Column("password", String, nullable = False),
Column("admin", Boolean, nullable = False))
mapper(User, users_table)

68
eos/db/util.py Executable file
View File

@@ -0,0 +1,68 @@
#===============================================================================
# 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 <http://www.gnu.org/licenses/>.
#===============================================================================
from sqlalchemy.orm import eagerload
from sqlalchemy.sql import and_
replace = {"attributes": "_Item__attributes",
"modules": "_Fit__modules",
"projectedModules": "_Fit__projectedModules",
"boosters": "_Fit__boosters",
"drones": "_Fit__drones",
"projectedDrones": "_Fit__projectedDrones",
"implants": "_Fit__implants",
"character": "_Fit__character",
"damagePattern": "_Fit__damagePattern",
"projectedFits": "_Fit__projectedFits"}
def processEager(eager):
if eager == None:
return tuple()
else:
l = []
if isinstance(eager, basestring):
eager = (eager,)
for e in eager:
l.append(eagerload(_replacements(e)))
return l
def _replacements(eagerString):
splitEager = eagerString.split(".")
for i in xrange(len(splitEager)):
part = splitEager[i]
replacement = replace.get(part)
if replacement:
splitEager[i] = replacement
return ".".join(splitEager)
def processWhere(clause, where):
if where is not None:
if not hasattr(where, "__iter__"):
where = (where,)
try:
for extraClause in where:
clause = and_(clause, extraClause)
except NotImplementedError:
clause = and_(clause, where)
return clause