Populate shop_items table

This commit is contained in:
King_DuckZ 2020-08-10 23:17:17 +01:00
parent bf055b5b87
commit b76a2f22a4
4 changed files with 107 additions and 9 deletions

View file

@ -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<int>(value); }
ItemSubtype value {ItemSubtype::Unknown};
};

View file

@ -23,7 +23,10 @@
#include "oro/items.hpp"
#include "oro/icons.hpp"
#include "oro/shops.hpp"
#include "oro/dateconv.hpp"
#include <mutex>
#include <optional>
#include <type_traits>
namespace oro {
@ -36,6 +39,64 @@ namespace {
{
}
};
template <typename CastT=void, typename T=void>
void bind (SQLite::Statement& st, int idx, const boost::optional<T>& val) {
if (val) {
if constexpr (std::is_same_v<T, CastT> or std::is_same_v<void, CastT>) {
st.bind(idx, *val);
}
else {
st.bind(idx, static_cast<CastT>(*val));
}
}
else {
st.bind(idx, nullptr);
}
}
std::optional<oro::Shop> 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<int>(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<int>(item.type.value));
if (item.subtype)
query.bind(5, static_cast<int>(item.subtype->value));
else
query.bind(5, nullptr);
bind<int>(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<oro::Shop> 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<int>(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<int>(ins_item, 9, item.beloved);
ins_item.exec();
ins_item.reset();
}
}
transaction.commit();
}

View file

@ -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<int>(ShopType::Vending) == val)
value = ShopType::Vending;
else if (static_cast<int>(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;

View file

@ -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};