diff --git a/d2warehouse/item.py b/d2warehouse/item.py index a4c8499..ceeb998 100644 --- a/d2warehouse/item.py +++ b/d2warehouse/item.py @@ -216,25 +216,18 @@ class Item: set_name = ( lookup_set_item(self.set_id)["set"] if self.quality == Quality.SET else None ) - prefix1 = self.prefixes[0] if self.prefixes and len(self.prefixes) > 0 else None - prefix2 = self.prefixes[1] if self.prefixes and len(self.prefixes) > 1 else None - prefix3 = self.prefixes[2] if self.prefixes and len(self.prefixes) > 2 else None - suffix1 = self.suffixes[0] if self.suffixes and len(self.suffixes) > 0 else None - suffix2 = self.suffixes[1] if self.suffixes and len(self.suffixes) > 1 else None - suffix3 = self.suffixes[2] if self.suffixes and len(self.suffixes) > 2 else None db = get_db() cur = db.cursor() cur.execute( """INSERT INTO item (itembase_name, item_name, set_name, socketed_into, raw_data, is_identified, is_socketed, - is_beginner, is_simple, is_ethereal, is_personalized, is_runeword, pos_x, - pos_y, code, uid, lvl, quality, graphic, implicit, low_quality, prefix1, - prefix2, prefix3, suffix1, suffix2, suffix3, set_id, unique_id, - nameword1, nameword2, runeword_id, personal_name, defense, durability, - max_durability, quantity) + is_beginner, is_simple, is_ethereal, is_personalized, is_runeword, + code, uid, lvl, quality, graphic, implicit, low_quality, set_id, + unique_id, nameword1, nameword2, runeword_id, personal_name, + defense, durability, max_durability, quantity) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + ?, ?, ?, ?, ?, ?, ?)""", ( lookup_basetype(self.code)["name"], name, @@ -248,8 +241,6 @@ class Item: self.is_ethereal, self.is_personalized, self.is_runeword, - self.pos_x, - self.pos_y, self.code, self.uid, self.lvl, @@ -257,12 +248,6 @@ class Item: self.graphic, self.implicit, int(self.low_quality) if self.low_quality else None, - prefix1, - prefix2, - prefix3, - suffix1, - suffix2, - suffix3, self.set_id, self.unique_id, self.nameword1, @@ -277,6 +262,15 @@ class Item: ) item_id = cur.lastrowid + if self.quality in [Quality.MAGIC, Quality.RARE, Quality.CRAFTED]: + for prefix, id in [(False, id) for id in self.suffixes] + [ + (True, id) for id in self.prefixes + ]: + db.execute( + "INSERT INTO item_affix (item_id, prefix, affix_id) VALUES (?, ?, ?)", + (item_id, prefix, id), + ) + if self.stats: for stat in self.stats: db.execute( @@ -306,26 +300,14 @@ class Item: db = get_db() row = db.execute( """SELECT raw_data, is_identified, is_socketed, - is_beginner, is_simple, is_ethereal, is_personalized, is_runeword, pos_x, - pos_y, code, uid, lvl, quality, graphic, implicit, low_quality, prefix1, - prefix2, prefix3, suffix1, suffix2, suffix3, set_id, unique_id, + is_beginner, is_simple, is_ethereal, is_personalized, is_runeword, code, + uid, lvl, quality, graphic, implicit, low_quality, set_id, unique_id, nameword1, nameword2, runeword_id, personal_name, defense, durability, max_durability, quantity FROM item WHERE id = ?""", (id,), ).fetchone() - quality = Quality(row["quality"]) if row["quality"] else None - prefixes = None - suffixes = None - if quality in [Quality.MAGIC, Quality.RARE, Quality.CRAFTED]: - prefixes = [ - x for x in [row["prefix1"], row["prefix2"], row["prefix3"]] if x - ] - suffixes = [ - x for x in [row["suffix1"], row["suffix2"], row["suffix3"]] if x - ] - item = Item( raw_data=row["raw_data"], is_identified=bool(row["is_identified"]), @@ -335,19 +317,17 @@ class Item: is_ethereal=bool(row["is_ethereal"]), is_personalized=bool(row["is_personalized"]), is_runeword=bool(row["is_runeword"]), - pos_x=row["pos_x"], - pos_y=row["pos_y"], + pos_x=0, + pos_y=0, code=row["code"], uid=row["uid"], lvl=row["lvl"], - quality=quality, + quality=Quality(row["quality"]) if row["quality"] else None, graphic=row["graphic"], implicit=row["implicit"], low_quality=LowQualityType(row["low_quality"]) if row["low_quality"] else None, - prefixes=prefixes, - suffixes=suffixes, set_id=row["set_id"], unique_id=row["unique_id"], nameword1=row["nameword1"], @@ -360,6 +340,18 @@ class Item: quantity=row["quantity"], ) + if item.quality in [Quality.MAGIC, Quality.RARE, Quality.CRAFTED]: + rows = db.execute( + "SELECT prefix, affix_id FROM item_affix WHERE item_id = ?", (id,) + ) + item.prefixes = [] + item.suffixes = [] + for row in rows: + if row["prefix"]: + item.prefixes.append(row["affix_id"]) + else: + item.suffixes.append(row["affix_id"]) + rows = db.execute( "SELECT id FROM item WHERE socketed_into = ?", (id,) ).fetchall() @@ -367,6 +359,7 @@ class Item: item.sockets = [] for row in rows: socket = Item.load_from_db(row["id"]) + socket.pos_x = len(item.sockets) item.sockets.append(socket) rows = db.execute( diff --git a/d2warehouse/schema.sql b/d2warehouse/schema.sql index a24f34b..4340183 100644 --- a/d2warehouse/schema.sql +++ b/d2warehouse/schema.sql @@ -1,10 +1,12 @@ -DROP TABLE IF EXISTS stat; +DROP TABLE IF EXISTS item_stat; +DROP TABLE IF EXISTS item_affix; DROP TABLE IF EXISTS item; CREATE TABLE item ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id INTEGER PRIMARY KEY, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - deletion TEXT DEFAULT NULL CHECK (deletion IN (NULL, "deleted", "nuked")), -- * + deleted TIMESTAMP DEFAULT NULL, + nuked BOOLEAN DEFAULT NULL, -- * itembase_name TEXT NOT NULL, item_name TEXT NOT NULL, set_name TEXT DEFAULT NULL, @@ -19,8 +21,6 @@ CREATE TABLE item ( is_ethereal BOOLEAN NOT NULL, is_personalized BOOLEAN NOT NULL, is_runeword BOOLEAN NOT NULL, - pos_x INTEGER NOT NULL, - pos_y INTEGER NOT NULL, code TEXT NOT NULL, uid INTEGER DEFAULT NULL, lvl INTEGER DEFAULT NULL, @@ -28,12 +28,6 @@ CREATE TABLE item ( graphic INTEGER DEFAULT NULL, implicit INTEGER DEFAULT NULL, low_quality INTEGER DEFAULT NULL CHECK(0 <= low_quality AND low_quality <= 3), - prefix1 INTEGER DEFAULT NULL, - prefix2 INTEGER DEFAULT NULL, - prefix3 INTEGER DEFAULT NULL, - suffix1 INTEGER DEFAULT NULL, - suffix2 INTEGER DEFAULT NULL, - suffix3 INTEGER DEFAULT NULL, set_id INTEGER DEFAULT NULL, unique_id INTEGER DEFAULT NULL, nameword1 INTEGER DEFAULT NULL, @@ -50,14 +44,12 @@ CREATE TABLE item ( FOREIGN KEY (socketed_into) REFERENCES item (item_id) ); -- Add an index for "... WHERE deletion IS NULL" -CREATE INDEX item_deletion_partial ON item (deletion) WHERE deletion IS NULL; --- *: NULL: if the item is currently stored, --- deleted: if the item has been removed from storage --- nuked: if the item has been removed from storage & user indicated he does not --- want to count it as potentially in his possession any longer +CREATE INDEX item_deletion_partial ON item (deleted) WHERE deleted IS NULL; +-- * nuked: if the item has been removed from storage & user indicated he does not +-- want to count it as potentially in his possession any longer CREATE TABLE item_stat ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id INTEGER PRIMARY KEY, item_id INTEGER NOT NULL, stat INTEGER NOT NULL, value1 INTEGER DEFAULT NULL, @@ -68,3 +60,12 @@ CREATE TABLE item_stat ( FOREIGN KEY (item_id) REFERENCES item (item_id) ); CREATE INDEX item_stat_stat ON item_stat (stat); + +CREATE TABLE item_affix ( + id INTEGER PRIMARY KEY, + item_id INTEGER NOT NULL, + prefix BOOLEAN NOT NULL, + affix_id INTEGER NOT NULL, + + FOREIGN KEY (item_id) REFERENCES item (item_id) +); diff --git a/d2warehouse/tests/test_db.py b/d2warehouse/tests/test_db.py index 5b2060e..3081ebf 100644 --- a/d2warehouse/tests/test_db.py +++ b/d2warehouse/tests/test_db.py @@ -22,7 +22,7 @@ class DbTest(unittest.TestCase): def test_runeword_lore(self): data = bytes.fromhex( - "1008800405c055c637f1073af4558697412981070881506049e87f005516fb134582ff1000a0003500e07cbb001000a0003504e07c9800" + "10088004050054c637f1073af4558697412981070881506049e87f005516fb134582ff1000a0003500e07cbb001000a0003504e07c9800" ) _, item = parse_item(data)