Server is returning some shops selling unknown items, add support for it

Previously the code would just throw an exception and
quit (foreign key constraint violation). Add an empty
row with the missing id so it will work. When the item
list returns that item the next time, the empty row will
be filled.
This commit is contained in:
King_DuckZ 2020-08-16 22:29:46 +01:00
parent d66af7779d
commit a1aeb3c587

View file

@ -353,7 +353,7 @@ void OriginsDB::update (const Items& items, const oro::Timestamp& next_update) {
db.exec(std::string(g_create_items_a).append("items") + g_create_items_b);
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS items_item_id_idx ON items(item_id, removal_date)");
//see https://stackoverflow.com/questions/22699409/sqlite-null-and-unique
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS unique_active_item_constraint ON items(item_id, unique_name, ifnull(removal_date, 0))");
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS unique_active_item_constraint ON items(item_id, ifnull(removal_date, 0))");
SQLite::Statement query(db,
"INSERT INTO items_staging "
@ -375,15 +375,16 @@ void OriginsDB::update (const Items& items, const oro::Timestamp& next_update) {
"UPDATE items SET removal_date = CURRENT_TIMESTAMP WHERE "
"removal_date IS NULL AND item_id IN ("
"SELECT item_id FROM ("
"SELECT item_id, unique_name FROM items WHERE removal_date IS NULL EXCEPT "
"SELECT item_id, unique_name FROM items_staging"
"SELECT item_id FROM items WHERE removal_date IS NULL EXCEPT "
"SELECT item_id FROM items_staging"
")"
")"
);
db.exec(
"INSERT INTO items (item_id, unique_name, name, type, subtype, npc_price, slots) "
"SELECT item_id, unique_name, name, type, subtype, npc_price, slots FROM items_staging WHERE true "
"ON CONFLICT(item_id, unique_name, ifnull(removal_date, 0)) DO UPDATE SET "
"ON CONFLICT(item_id, ifnull(removal_date, 0)) DO UPDATE SET "
"unique_name=excluded.unique_name, "
"name=excluded.name, type=excluded.type, subtype=excluded.subtype, "
"npc_price=excluded.npc_price, slots=excluded.slots"
);
@ -406,11 +407,16 @@ void OriginsDB::update (const Icons& icons, const oro::Timestamp& next_update) {
db.exec(std::string(g_create_icons_a).append("icons_staging") + g_create_icons_b);
db.exec(std::string(g_create_icons_a).append("icons") + g_create_icons_b);
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS icons_item_id_idx ON icons(item_id)");
SQLite::Statement ins_empty_item(db, "INSERT OR IGNORE INTO items(item_id) VALUES(?)");
SQLite::Statement query(db, "INSERT INTO icons_staging(item_id, icon) VALUES(?, ?)");
ItemIdToTableId item_id_to_table_id(db, false);
SQLite::Transaction transaction(db);
for (const auto& ico : icons.icons) {
bind_all(ins_empty_item, ico.item_id);
ins_empty_item.exec();
ins_empty_item.reset();
bind_all(query, item_id_to_table_id(ico.item_id), no_copy(ico.icon));
query.exec();
query.reset();
@ -455,6 +461,7 @@ void OriginsDB::update (const Shops& shops, const oro::Timestamp& next_update) {
db.exec(g_create_slotted_cards);
SQLite::Statement ins_sshot(db, "INSERT OR IGNORE INTO shop_snapshots(shop_id, hash) VALUES(?, ?)");
SQLite::Statement ins_empty_item(db, "INSERT OR IGNORE INTO items(item_id) VALUES(?)");
SQLite::Statement sel_sshot(db, "SELECT id FROM shop_snapshots WHERE shop_id = ? AND hash = ?");
SQLite::Statement ins_item(db, "INSERT INTO shop_items(snapshot_id, item_id, amount, price, refine, star_crumbs, element, creator, beloved) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
SQLite::Statement ins_card(db, "INSERT INTO slotted_cards(shop_item_id, card_id) VALUES(?, ?)");
@ -488,6 +495,10 @@ void OriginsDB::update (const Shops& shops, const oro::Timestamp& next_update) {
//insert items relative to this snapshot and associated slotted cards
const auto sshot_id = db.getLastInsertRowid();
for (const auto& item : shop.items) {
bind_all(ins_empty_item, item.item_id);
ins_empty_item.exec();
ins_empty_item.reset();
bind_all(ins_item, sshot_id, item_id_to_table_id(item.item_id),
item.amount, item.price, item.refine, item.star_crumbs,
item.element, item.creator, cast<int>(item.beloved)