eqemu-server/common/repositories/buyer_buy_lines_repository.h

361 lines
10 KiB
C++

#ifndef EQEMU_BUYER_BUY_LINES_REPOSITORY_H
#define EQEMU_BUYER_BUY_LINES_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_buyer_buy_lines_repository.h"
#include "buyer_trade_items_repository.h"
#include "character_data_repository.h"
#include "buyer_repository.h"
#include "../eq_packet_structs.h"
class BuyerBuyLinesRepository: public BaseBuyerBuyLinesRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* BuyerBuyLinesRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* BuyerBuyLinesRepository::GetWhereNeverExpires()
* BuyerBuyLinesRepository::GetWhereXAndY()
* BuyerBuyLinesRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
struct WelcomeData_Struct {
uint32 count_of_buyers;
uint32 count_of_items;
};
static int CreateBuyLine(Database& db, const BuyerLineItems_Struct b, uint32 char_id)
{
auto buyer = BuyerRepository::GetWhere(db, fmt::format("`char_id` = '{}' LIMIT 1", char_id));
if (buyer.empty()){
return 0;
}
BuyerBuyLinesRepository::BuyerBuyLines buy_lines{};
buy_lines.id = 0;
buy_lines.buyer_id = buyer.front().id;
buy_lines.char_id = char_id;
buy_lines.buy_slot_id = b.slot;
buy_lines.item_id = b.item_id;
buy_lines.item_name = b.item_name;
buy_lines.item_icon = b.item_icon;
buy_lines.item_qty = b.item_quantity;
buy_lines.item_price = b.item_cost;
auto e = InsertOne(db, buy_lines);
std::vector<BuyerTradeItemsRepository::BuyerTradeItems> queue;
for (auto const &r: b.trade_items) {
BuyerTradeItemsRepository::BuyerTradeItems bti{};
bti.id = 0;
bti.buyer_buy_lines_id = e.id;
bti.item_id = r.item_id;
bti.item_qty = r.item_quantity;
bti.item_icon = r.item_icon;
bti.item_name = r.item_name;
if (bti.item_id) {
queue.push_back(bti);
}
}
if (!queue.empty()) {
BuyerTradeItemsRepository::InsertMany(db, queue);
}
return e.id;
}
static int ModifyBuyLine(Database& db, const BuyerLineItems_Struct b, uint32 char_id)
{
auto b_lines = GetWhere(db, fmt::format("`char_id` = '{}' AND `buy_slot_id` = '{}';", char_id, b.slot));
if (b_lines.empty() || b_lines.size() > 1){
return 0;
}
auto b_line = b_lines.front();
b_line.item_qty = b.item_quantity;
b_line.item_price = b.item_cost;
b_line.item_icon = b.item_icon;
auto e = UpdateOne(db, b_line);
std::vector<BuyerTradeItemsRepository::BuyerTradeItems> queue;
BuyerTradeItemsRepository::DeleteWhere(db, fmt::format("`buyer_buy_lines_id` = '{}';", b_line.id));
for (auto const &r: b.trade_items) {
BuyerTradeItemsRepository::BuyerTradeItems bti{};
bti.id = 0;
bti.buyer_buy_lines_id = b_line.id;
bti.item_id = r.item_id;
bti.item_qty = r.item_quantity;
bti.item_icon = r.item_icon;
bti.item_name = r.item_name;
if (bti.item_id) {
queue.push_back(bti);
}
}
if (!queue.empty()) {
BuyerTradeItemsRepository::InsertMany(db, queue);
}
return 1;
}
static bool DeleteBuyLine(Database &db, uint32 char_id, int32 slot_id = 0xffffffff)
{
std::vector<BuyerBuyLines> buylines{};
if (slot_id == 0xffffffff) {
auto buylines = GetWhere(db, fmt::format("`char_id` = '{}'", char_id));
DeleteWhere(db, fmt::format("`char_id` = '{}'", char_id));
}
else {
auto buylines = GetWhere(db, fmt::format("`char_id` = '{}' AND `buy_slot_id` = '{}'", char_id, slot_id));
DeleteWhere(db, fmt::format("`char_id` = '{}' AND `buy_slot_id` = '{}'", char_id, slot_id));
}
if (buylines.empty()) {
return 0;
}
std::vector<std::string> buyline_ids{};
for (auto const &bl: buylines) {
buyline_ids.push_back((std::to_string(bl.id)));
}
if (!buyline_ids.empty()) {
BuyerTradeItemsRepository::DeleteWhere(
db,
fmt::format(
"`buyer_buy_lines_id` IN({})",
Strings::Implode(", ", buyline_ids)
)
);
}
return 1;
}
static std::vector<BuyerLineItems_Struct> GetBuyLines(Database &db, uint32 char_id)
{
std::vector<BuyerLineItems_Struct> all_entries{};
auto buy_line = GetWhere(db, fmt::format("`char_id` = '{}';", char_id));
if (buy_line.empty()){
return all_entries;
}
auto buy_line_trade_items = BuyerTradeItemsRepository::GetWhere(
db,
fmt::format(
"`buyer_buy_lines_id` IN (SELECT b.id FROM buyer_buy_lines AS b WHERE b.char_id = '{}')",
char_id
)
);
all_entries.reserve(buy_line.size());
for (auto const &l: buy_line) {
BuyerLineItems_Struct bli{};
bli.item_id = l.item_id;
bli.item_cost = l.item_price;
bli.item_quantity = l.item_qty;
bli.slot = l.buy_slot_id;
bli.item_name = l.item_name;
for (auto const &i: GetSubIDs(buy_line_trade_items, l.id)) {
BuyerLineTradeItems_Struct blti{};
blti.item_id = i.item_id;
blti.item_icon = i.item_icon;
blti.item_quantity = i.item_qty;
blti.item_id = i.item_id;
blti.item_name = i.item_name;
bli.trade_items.push_back(blti);
}
all_entries.push_back(bli);
}
return all_entries;
}
static BuyerLineSearch_Struct SearchBuyLines(
Database &db,
std::string &search_string,
uint32 char_id = 0,
uint32 zone_id = 0,
uint32 zone_instance_id = 0
)
{
BuyerLineSearch_Struct all_entries{};
std::string where_clause(fmt::format("`item_name` LIKE \"%{}%\" ", search_string));
if (char_id) {
where_clause += fmt::format("AND `char_id` = '{}' ", char_id);
}
if (zone_id) {
auto buyers = BuyerRepository::GetWhere(
db,
fmt::format(
"`char_zone_id` = '{}' AND char_zone_instance_id = '{}'",
zone_id,
zone_instance_id
)
);
if (buyers.empty()) {
return all_entries;
}
std::vector<std::string> char_ids{};
for (auto const &bl : buyers) {
char_ids.push_back((std::to_string(bl.char_id)));
}
where_clause += fmt::format("AND `char_id` IN ({}) ", Strings::Implode(", ", char_ids));
}
auto buy_line = GetWhere(db, where_clause);
if (buy_line.empty()){
return all_entries;
}
std::vector<std::string> ids{};
std::vector<std::string> char_ids{};
for (auto const &bl : buy_line) {
if (std::find(ids.begin(), ids.end(), std::to_string(bl.id)) == std::end(ids)) {
ids.push_back(std::to_string(bl.id));
}
if (std::find(char_ids.begin(), char_ids.end(), std::to_string(bl.char_id)) == std::end(char_ids)) {
char_ids.push_back((std::to_string(bl.char_id)));
}
}
auto buy_line_trade_items = BuyerTradeItemsRepository::GetWhere(
db,
fmt::format(
"`buyer_buy_lines_id` IN ({});",
Strings::Implode(", ", ids)
)
);
auto char_names = BuyerRepository::GetWhere(
db,
fmt::format(
"`char_id` IN ({});",
Strings::Implode(", ", char_ids)
)
);
all_entries.no_items = buy_line.size();
for (auto const &l: buy_line) {
BuyerLineItemsSearch_Struct blis{};
blis.slot = l.buy_slot_id;
blis.item_id = l.item_id;
blis.item_cost = l.item_price;
blis.item_icon = l.item_icon;
blis.item_quantity = l.item_qty;
blis.buyer_id = l.char_id;
auto it = std::find_if(
char_names.cbegin(),
char_names.cend(),
[&](BuyerRepository::Buyer e) { return e.char_id == l.char_id; }
);
blis.buyer_name = it != char_names.end() ? it->char_name : std::string("");
blis.buyer_entity_id = it != char_names.end() ? it->char_entity_id : 0;
blis.buyer_zone_id = it != char_names.end() ? it->char_zone_id : 0;
blis.buyer_zone_instance_id = it != char_names.end() ? it->char_zone_instance_id : 0;
strn0cpy(blis.item_name, l.item_name.c_str(), sizeof(blis.item_name));
for (auto const &i: GetSubIDs(buy_line_trade_items, l.id)) {
BuyerLineTradeItems_Struct e{};
e.item_id = i.item_id;
e.item_icon = i.item_icon;
e.item_quantity = i.item_qty;
e.item_id = i.item_id;
e.item_name = i.item_name;
blis.trade_items.push_back(e);
}
all_entries.buy_line.push_back(blis);
}
return all_entries;
}
static std::vector<BuyerTradeItemsRepository::BuyerTradeItems>
GetSubIDs(std::vector<BuyerTradeItemsRepository::BuyerTradeItems> &in, uint64 id)
{
std::vector<BuyerTradeItemsRepository::BuyerTradeItems> results{};
std::vector<uint64> indices{};
auto it = in.begin();
while ((it = std::find_if(
it,
in.end(),
[&](BuyerTradeItemsRepository::BuyerTradeItems const &e) {
return e.buyer_buy_lines_id == id;
}
))
!= in.end()
) {
indices.push_back(std::distance(in.begin(), it));
results.push_back(*it);
it++;
}
return results;
}
static WelcomeData_Struct GetWelcomeData(Database &db)
{
WelcomeData_Struct e{};
auto results = db.QueryDatabase("SELECT COUNT(DISTINCT char_id), COUNT(char_id) FROM buyer;");
if (!results.RowCount()) {
return e;
}
auto r = results.begin();
e.count_of_buyers = Strings::ToInt(r[0]);
e.count_of_items = Strings::ToInt(r[1]);
return e;
}
};
#endif //EQEMU_BUYER_BUY_LINES_REPOSITORY_H