From b76a2f22a4365f4359c02885cd40f433a6d45ffe Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 10 Aug 2020 23:17:17 +0100 Subject: [PATCH] Populate shop_items table --- src/oro/items.hpp | 1 + src/oro/originsdb.cpp | 99 +++++++++++++++++++++++++++++++++++++++---- src/oro/shops.cpp | 14 ++++++ src/oro/shops.hpp | 2 + 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/oro/items.hpp b/src/oro/items.hpp index 675d52d..1229f9d 100644 --- a/src/oro/items.hpp +++ b/src/oro/items.hpp @@ -93,6 +93,7 @@ namespace oro { ItemSubtypeWrapper (const std::string& str); ItemSubtypeWrapper& operator= (const std::string& str); operator ItemSubtype() const {return value;} + operator int() const { return static_cast(value); } ItemSubtype value {ItemSubtype::Unknown}; }; diff --git a/src/oro/originsdb.cpp b/src/oro/originsdb.cpp index 0dec524..3bbc9ce 100644 --- a/src/oro/originsdb.cpp +++ b/src/oro/originsdb.cpp @@ -23,7 +23,10 @@ #include "oro/items.hpp" #include "oro/icons.hpp" #include "oro/shops.hpp" +#include "oro/dateconv.hpp" #include +#include +#include namespace oro { @@ -36,6 +39,64 @@ namespace { { } }; + + template + void bind (SQLite::Statement& st, int idx, const boost::optional& val) { + if (val) { + if constexpr (std::is_same_v or std::is_same_v) { + st.bind(idx, *val); + } + else { + st.bind(idx, static_cast(*val)); + } + } + else { + st.bind(idx, nullptr); + } + } + + std::optional fetch_shop ( + SQLite::Database& db, + const std::string& owner, + const oro::Timestamp& creation_timestamp + ) { + SQLite::Statement query_shop(db, "SELECT title, owner, creation_date, loc_map, loc_x, loc_y, type, id FROM shops where owner = ? AND creation_date = ?"); + query_shop.bind(1, owner); + query_shop.bind(2, to_sqlite_string(creation_timestamp)); + if (not query_shop.executeStep()) + return {}; + + + oro::Shop shop; + shop.title = query_shop.getColumn(0).getString(); + shop.owner = query_shop.getColumn(1).getString(); + shop.creation_date = from_sqlite_timestamp(query_shop.getColumn(2)); + shop.location.map = query_shop.getColumn(3).getString(); + shop.location.x = query_shop.getColumn(4); + shop.location.y = query_shop.getColumn(5); + shop.type = static_cast(query_shop.getColumn(6)); + + SQLite::Statement query_items(db, "SELECT item_id, amount, price, refine, star_crumbs, element, creator, beloved FROM shop_items WHERE shop_id = ?"); + query_items.bind(1, query_shop.getColumn(7).getInt64()); + while (query_items.executeStep()) { + oro::ShopItem item; + item.item_id = query_items.getColumn(0); + item.amount = query_items.getColumn(1); + item.price = query_items.getColumn(2); + item.refine = query_items.getColumn(3); + item.star_crumbs = query_items.getColumn(4); + if (not query_items.getColumn(5).isNull()) + item.element = query_items.getColumn(5).getString(); + if (not query_items.getColumn(6).isNull()) + item.creator = query_items.getColumn(6).getUInt(); + if (not query_items.getColumn(7).isNull()) + item.beloved = (query_items.getColumn(7).getInt() != 0); + + shop.items.push_back(item); + } + + return shop; + } } //unnamed namespace OriginsDB::OriginsDB (std::string_view path) : @@ -61,7 +122,7 @@ void OriginsDB::update (const Items& items) { db.exec( "CREATE TABLE items (" "item_id INTEGER PRIMARY KEY NOT NULL" - ", unique_name TEXT" + ", unique_name TEXT UNIQUE" ", name TEXT" ", type TINYINT" ", subtype TINYINT" @@ -76,15 +137,9 @@ void OriginsDB::update (const Items& items) { query.bind(2, item.unique_name); query.bind(3, item.name); query.bind(4, static_cast(item.type.value)); - if (item.subtype) - query.bind(5, static_cast(item.subtype->value)); - else - query.bind(5, nullptr); + bind(query, 5, item.subtype); query.bind(6, item.npc_price); - if (item.slots) - query.bind(7, *item.slots); - else - query.bind(7, nullptr); + bind(query, 7, item.slots); query.exec(); query.reset(); @@ -153,13 +208,24 @@ void OriginsDB::update (const Shops& shops) { ", item_id INTEGER NOT NULL" ", amount INTEGER NOT NULL" ", price INTEGER NOT NULL" + ", refine INTEGER NOT NULL" + ", star_crumbs INTEGER NOT NULL" + ", element TEXT" + ", creator INTEGER" + ", beloved TINYINT" ", FOREIGN KEY(shop_id) REFERENCES shops(id)" ")" ); SQLite::Statement ins_shop(db, "INSERT INTO shops(title, owner, creation_date, loc_map, loc_x, loc_y, type) VALUES(?, ?, ?, ?, ?, ?, ?)"); + SQLite::Statement ins_item(db, "INSERT INTO shop_items(shop_id, item_id, amount, price, refine, star_crumbs, element, creator, beloved) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"); SQLite::Transaction transaction(db); for (const auto& shop : shops.shops) { + std::optional old_shop = fetch_shop(db, shop.owner, shop.creation_date); + + if ( old_shop) + continue; + ins_shop.bind(1, shop.title); ins_shop.bind(2, shop.owner); ins_shop.bind(3, to_sqlite_string(shop.creation_date)); @@ -169,6 +235,21 @@ void OriginsDB::update (const Shops& shops) { ins_shop.bind(7, static_cast(shop.type.value)); ins_shop.exec(); ins_shop.reset(); + + const auto shop_id = db.getLastInsertRowid(); + for (const auto& item : shop.items) { + ins_item.bind(1, shop_id); + ins_item.bind(2, item.item_id); + ins_item.bind(3, item.amount); + ins_item.bind(4, item.price); + ins_item.bind(5, item.refine); + ins_item.bind(6, item.star_crumbs); + bind(ins_item, 7, item.element); + bind(ins_item, 8, item.creator); + bind(ins_item, 9, item.beloved); + ins_item.exec(); + ins_item.reset(); + } } transaction.commit(); } diff --git a/src/oro/shops.cpp b/src/oro/shops.cpp index f3bfe84..4288060 100644 --- a/src/oro/shops.cpp +++ b/src/oro/shops.cpp @@ -20,10 +20,24 @@ namespace oro { +ShopTypeWrapper::ShopTypeWrapper (int val) { + *this = val; +} + ShopTypeWrapper::ShopTypeWrapper (const std::string& str) { *this = str; } +ShopTypeWrapper& ShopTypeWrapper::operator= (int val) { + if (static_cast(ShopType::Vending) == val) + value = ShopType::Vending; + else if (static_cast(ShopType::Buying) == val) + value = ShopType::Buying; + else + value = ShopType::Unknown; + return *this; +} + ShopTypeWrapper& ShopTypeWrapper::operator= (const std::string& str) { if ("V" == str) value = ShopType::Vending; diff --git a/src/oro/shops.hpp b/src/oro/shops.hpp index 1ec7cde..417363d 100644 --- a/src/oro/shops.hpp +++ b/src/oro/shops.hpp @@ -31,7 +31,9 @@ namespace oro { struct ShopTypeWrapper { ShopTypeWrapper() = default; + ShopTypeWrapper (int val); ShopTypeWrapper (const std::string& str); + ShopTypeWrapper& operator= (int val); ShopTypeWrapper& operator= (const std::string& str); operator ShopType() const {return value;} ShopType value {ShopType::Unknown};