#include "MySQLDatabase.h" #include "UgcLookupSql.h" namespace { IUgcLookup::UgcEntry ReadEntry(PreparedStmtResultSet& result, IUgcLookup::eUgcKind kind) { IUgcLookup::UgcEntry entry; entry.kind = kind; entry.id = result->getInt64("id"); entry.characterId = result->getInt64("character_id"); entry.characterName = std::string(result->getString("character_name").c_str()); entry.accountId = static_cast(result->getInt64("account_id")); entry.accountName = std::string(result->getString("account_name").c_str()); entry.state = static_cast(result->getInt("is_optimized")); entry.error = std::string(result->getString("process_error").c_str()); entry.detail = std::string(result->getString("detail").c_str()); entry.attempts = static_cast(result->getInt("process_attempts")); entry.processedAt = result->getInt64("processed_at"); entry.processAfter = result->getInt64("process_after"); entry.bakeAo = result->getInt("bake_ao") != 0; entry.bricks = static_cast(result->getInt64("brick_count")); entry.triangles = static_cast(result->getInt64("triangle_count")); entry.processMs = static_cast(result->getInt64("process_ms")); entry.processCpuMs = static_cast(result->getInt64("process_cpu_ms")); entry.processMemoryKb = static_cast(result->getInt64("process_memory_kb")); entry.modelName = result->getString("model_name").c_str(); entry.trianglesBefore = static_cast(result->getInt64("triangle_count_before")); return entry; } } std::vector MySQLDatabase::SearchUgc(const UgcSearch& search, const uint32_t limit) { std::vector entries; const std::string pattern = "%" + search.text + "%"; for (const bool modular : { false, true }) { const auto order = modular ? "ORDER BY b.ugc_id DESC LIMIT ?;" : "ORDER BY u.id DESC LIMIT ?;"; auto result = ExecuteSelect(UgcLookupSql::Select(modular) + UgcLookupSql::Where(search, modular) + order, pattern, pattern, pattern, pattern, pattern, pattern, limit); while (result->next()) entries.push_back(ReadEntry(result, modular ? eUgcKind::MODULAR : eUgcKind::MODEL)); } return entries; } std::vector MySQLDatabase::GetUgcEntries(const std::vector& ids) { std::vector entries; if (ids.empty()) return entries; const auto list = UgcLookupSql::IdList(ids); for (const bool modular : { false, true }) { auto result = ExecuteSelect(UgcLookupSql::Select(modular) + (modular ? "WHERE b.ugc_id IN (" : "WHERE u.id IN (") + list + ");"); while (result->next()) entries.push_back(ReadEntry(result, modular ? eUgcKind::MODULAR : eUgcKind::MODEL)); } return entries; } std::vector MySQLDatabase::GetUgcPlacements(const std::vector& ugcIds) { std::vector placements; if (ugcIds.empty()) return placements; auto result = ExecuteSelect(UgcLookupSql::Placements(ugcIds)); while (result->next()) { auto& placement = placements.emplace_back(); placement.ugcId = result->getInt64("ugc_id"); placement.modelId = result->getInt64("id"); placement.lot = result->getInt("lot"); placement.propertyId = result->getInt64("property_id"); placement.propertyName = std::string(result->getString("property_name").c_str()); placement.ownerId = result->getInt64("owner_id"); placement.ownerName = std::string(result->getString("owner_name").c_str()); placement.zoneId = static_cast(result->getInt("zone_id")); placement.modelName = std::string(result->getString("model_name").c_str()); placement.modelDescription = std::string(result->getString("model_description").c_str()); } return placements; } std::vector MySQLDatabase::GetUgcMail(const std::vector& subkeys, const LOT modelItemLot) { std::vector mail; auto result = ExecuteSelect(UgcLookupSql::Mail(subkeys, modelItemLot)); while (result->next()) { auto& entry = mail.emplace_back(); entry.id = static_cast(result->getInt64("id")); entry.receiverId = result->getInt64("receiver_id"); entry.receiverName = std::string(result->getString("receiver_name").c_str()); entry.lot = result->getInt("attachment_lot"); entry.subkey = result->getInt64("attachment_subkey"); entry.config = std::string(result->getString("attachment_config").c_str()); } return mail; } std::pair, uint64_t> MySQLDatabase::ListUgc(const eUgcKind kind, const UgcListQuery& query) { const bool modular = kind == eUgcKind::MODULAR; const std::string pattern = "%" + query.search.text + "%"; const bool searching = UgcLookupSql::Searching(query.search); const auto where = (searching ? UgcLookupSql::Where(query.search, modular) : std::string("WHERE 1=1 ")) + UgcLookupSql::ListFilter(query, modular); std::vector entries; uint64_t total = 0; const auto page = UgcLookupSql::Select(modular) + where + UgcLookupSql::ListOrder(query, modular) + "LIMIT ? OFFSET ?;"; const auto count = "SELECT COUNT(*) AS n " + UgcLookupSql::From(modular) + where + ";"; if (searching) { auto result = ExecuteSelect(page, pattern, pattern, pattern, pattern, pattern, pattern, query.limit, query.offset); while (result->next()) entries.push_back(ReadEntry(result, kind)); auto counted = ExecuteSelect(count, pattern, pattern, pattern, pattern, pattern, pattern); if (counted->next()) total = static_cast(counted->getInt64("n")); } else { auto result = ExecuteSelect(page, query.limit, query.offset); while (result->next()) entries.push_back(ReadEntry(result, kind)); auto counted = ExecuteSelect(count); if (counted->next()) total = static_cast(counted->getInt64("n")); } return { entries, total }; }