pyircbot/pyircbot/modules/AttributeStorage.py

168 lines
5.8 KiB
Python
Raw Normal View History

2013-12-28 09:58:20 -08:00
#!/usr/bin/env python
2014-10-02 18:14:42 -07:00
"""
.. module:: AttributeStorage
2015-11-01 18:03:11 -08:00
:synopsis: An item key->value storage engine based on mysql
2014-10-02 18:14:42 -07:00
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
"""
2017-01-01 14:59:01 -08:00
from pyircbot.modulebase import ModuleBase
2013-12-28 09:58:20 -08:00
class AttributeStorage(ModuleBase):
2015-11-01 18:03:11 -08:00
def __init__(self, bot, moduleName):
2017-01-01 14:59:01 -08:00
ModuleBase.__init__(self, bot, moduleName)
self.services = ["attributes"]
2015-11-01 18:03:11 -08:00
self.db = None
serviceProviders = self.bot.getmodulesbyservice("mysql")
2017-01-01 14:59:01 -08:00
if len(serviceProviders) == 0:
2015-11-01 18:03:11 -08:00
self.log.error("AttributeStorage: Could not find a valid mysql service provider")
else:
self.log.info("AttributeStorage: Selecting mysql service provider: %s" % serviceProviders[0])
self.db = serviceProviders[0]
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if not self.db.connection.tableExists("attribute"):
self.log.info("AttributeStorage: Creating table: attribute")
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `attribute` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`attribute` varchar(128) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `attribute` (`attribute`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
c.close()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if not self.db.connection.tableExists("items"):
self.log.info("AttributeStorage: Creating table: items")
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item` varchar(512) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
c.close()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if not self.db.connection.tableExists("values"):
self.log.info("AttributeStorage: Creating table: values")
c = self.db.connection.query("""CREATE TABLE IF NOT EXISTS `values` (
`itemid` int(11) NOT NULL,
`attributeid` int(11) NOT NULL,
`value` varchar(512) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`itemid`,`attributeid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;""")
c.close()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
def getItem(self, name):
"""Get all values for a item
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
:param name: the item
:type name: str
:returns: dict -- the item's values expressed as a dict"""
2017-01-01 14:59:01 -08:00
c = self.db.connection.query("""SELECT
2015-11-01 18:03:11 -08:00
`i`.`id`,
`i`.`item`,
`a`.`attribute`,
`v`.`value`
FROM
`items` `i`
INNER JOIN `values` `v`
on `v`.`itemid`=`i`.`id`
INNER JOIN `attribute` `a`
on `a`.`id`=`v`.`attributeid`
2017-01-01 14:59:01 -08:00
WHERE
`i`.`item`=%s;""", (name,))
2015-11-01 18:03:11 -08:00
item = {}
while True:
row = c.fetchone()
2017-01-01 14:59:01 -08:00
if row is None:
2015-11-01 18:03:11 -08:00
break
2017-01-01 14:59:01 -08:00
item[row["attribute"]] = row["value"]
2015-11-01 18:03:11 -08:00
c.close()
2017-01-01 14:59:01 -08:00
if len(item) == 0:
2015-11-01 18:03:11 -08:00
return {}
return item
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
def get(self, item, key):
return self.getKey(item, key)
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
def getKey(self, item, key):
"""Get the value of an key on an item
2017-01-01 14:59:01 -08:00
:param item: the item to fetch a key from
2015-11-01 18:03:11 -08:00
:type item: str
:param key: they key who's value to return
:type key: str
:returns: str -- the item from the database or **None**"""
2017-01-01 14:59:01 -08:00
c = self.db.connection.query("""SELECT
2015-11-01 18:03:11 -08:00
`i`.`id`,
`i`.`item`,
`a`.`attribute`,
`v`.`value`
FROM
`items` `i`
INNER JOIN `values` `v`
on `v`.`itemid`=`i`.`id`
INNER JOIN `attribute` `a`
on `a`.`id`=`v`.`attributeid`
2017-01-01 14:59:01 -08:00
WHERE
2015-11-01 18:03:11 -08:00
`i`.`item`=%s
AND
2017-01-01 14:59:01 -08:00
`a`.`attribute`=%s;""", (item, key))
2015-11-01 18:03:11 -08:00
row = c.fetchone()
c.close()
2017-01-01 14:59:01 -08:00
if row is None:
2015-11-01 18:03:11 -08:00
return None
return row["value"]
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
def set(self, item, key, value):
return self.setKey(item, key, value)
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
def setKey(self, item, key, value):
"""Set the key on an item
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
:param item: the item name to set the key on
:type item: str
:param key: the key to set
:type key: tuple
:param value: the value to set
:type value: str"""
item = item.lower()
attribute = key.lower()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# Check attribute exists
c = self.db.connection.query("SELECT `id` FROM `attribute` WHERE `attribute`=%s;", (attribute))
row = c.fetchone()
attributeId = -1
2017-01-01 14:59:01 -08:00
if row is None:
2015-11-01 18:03:11 -08:00
c = self.db.connection.query("INSERT INTO `attribute` (`attribute`) VALUES (%s);", (attribute))
attributeId = c.lastrowid
else:
attributeId = row["id"]
c.close()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# check item exists
c = self.db.connection.query("SELECT `id` FROM `items` WHERE `item`=%s;", (item))
row = c.fetchone()
itemId = -1
2017-01-01 14:59:01 -08:00
if row is None:
2015-11-01 18:03:11 -08:00
c = self.db.connection.query("INSERT INTO `items` (`item`) VALUES (%s);", (item))
itemId = c.lastrowid
else:
itemId = row["id"]
c.close()
2017-01-01 14:59:01 -08:00
if value is None:
2015-11-01 18:03:11 -08:00
# delete it
2017-01-01 14:59:01 -08:00
c = self.db.connection.query("DELETE FROM `values` WHERE `itemid`=%s AND `attributeid`=%s ;",
(itemId, attributeId))
self.log.info("AttributeStorage: Stored item %s attribute %s value: %s (Deleted)" %
(itemId, attributeId, value))
2015-11-01 18:03:11 -08:00
else:
# add attribute
2017-01-01 14:59:01 -08:00
c = self.db.connection.query("REPLACE INTO `values` (`itemid`, `attributeid`, `value`) "
"VALUES (%s, %s, %s);", (itemId, attributeId, value))
2016-11-06 15:00:15 -08:00
self.log.info("AttributeStorage: Stored item %s attribute %s value: %s" % (itemId, attributeId, value))
2015-11-01 18:03:11 -08:00
c.close()