Skip to content

Commit

Permalink
[Database] Consolidate Starting Items Table (#3723)
Browse files Browse the repository at this point in the history
* [Database] Consolidate Starting Items Table

# Notes
- Convert `class`, `deityId`, `race`, and `zoneid` columns to `|` separated columns.
- Consolidates up to 15 rows per item down to a singular row.
- Allows ease of use for operators.
- Entire process is automated and creates a backup of pre-existing table.

* Update shareddb.cpp

* Unnecessary.
  • Loading branch information
Kinglykrab committed Nov 30, 2023
1 parent e75c31d commit 33b40e8
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 90 deletions.
67 changes: 61 additions & 6 deletions common/database/database_update_manifest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5019,17 +5019,72 @@ ALTER TABLE `spawn2` DROP COLUMN `enabled`;
)"
},
ManifestEntry{
.version = 9242,
.description = "2023_11_7_mintime_maxtime_spawnentry.sql",
.check = "SHOW COLUMNS FROM `spawnentry` LIKE 'min_time'",
.condition = "empty",
.match = "",
.sql = R"(
.version = 9242,
.description = "2023_11_7_mintime_maxtime_spawnentry.sql",
.check = "SHOW COLUMNS FROM `spawnentry` LIKE 'min_time'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `spawnentry`
ADD COLUMN `min_time` smallint(4) NOT NULL DEFAULT 0 AFTER `condition_value_filter`,
ADD COLUMN `max_time` smallint(4) NOT NULL DEFAULT 0 AFTER `min_time`;
)"
},
ManifestEntry{
.version = 9243,
.description = "2023_11_27_starting_items_revamp.sql",
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'race_list'",
.condition = "empty",
.match = "",
.sql = R"(
CREATE TABLE `starting_items_backup_9243` LIKE `starting_items`;
INSERT INTO `starting_items_backup_9243` SELECT * FROM `starting_items`;
CREATE TABLE `starting_items_new` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`race_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`deity_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`zone_id_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
`gm` mediumint(3) UNSIGNED NOT NULL DEFAULT 0,
`slot` mediumint(9) NOT NULL DEFAULT -1,
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
`content_flags` varchar(100) NULL,
`content_flags_disabled` varchar(100) NULL,
PRIMARY KEY (`id`)
);
INSERT INTO
`starting_items_new`
(
SELECT
0 AS `id`,
GROUP_CONCAT(DISTINCT `class` ORDER BY class ASC SEPARATOR '|') AS `class_list`,
GROUP_CONCAT(DISTINCT `race` ORDER BY race ASC SEPARATOR '|') AS `race_list`,
GROUP_CONCAT(DISTINCT `deityid` ORDER BY deityid ASC SEPARATOR '|') AS `deity_list`,
GROUP_CONCAT(DISTINCT `zoneid` ORDER BY zoneid ASC SEPARATOR '|') AS `zone_list`,
`itemid`,
`item_charges`,
`gm`,
`slot`,
`min_expansion`,
`max_expansion`,
`content_flags`,
`content_flags_disabled `
FROM
`starting_items`
GROUP BY
`itemid`
);
DROP TABLE `starting_items`;
RENAME TABLE `starting_items_new` TO `starting_items`;
)"

}
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
// .version = 9228,
Expand Down
112 changes: 57 additions & 55 deletions common/repositories/base/base_starting_items_repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@
#include "../../strings.h"
#include <ctime>


class BaseStartingItemsRepository {
public:
struct StartingItems {
uint32_t id;
int32_t race;
int32_t class_;
int32_t deityid;
int32_t zoneid;
int32_t itemid;
std::string race_list;
std::string class_list;
std::string deity_list;
std::string zone_id_list;
uint32_t item_id;
uint8_t item_charges;
int8_t gm;
uint8_t gm;
int32_t slot;
int8_t min_expansion;
int8_t max_expansion;
Expand All @@ -43,11 +44,11 @@ class BaseStartingItemsRepository {
{
return {
"id",
"race",
"`class`",
"deityid",
"zoneid",
"itemid",
"race_list",
"class_list",
"deity_list",
"zone_id_list",
"item_id",
"item_charges",
"gm",
"slot",
Expand All @@ -62,11 +63,11 @@ class BaseStartingItemsRepository {
{
return {
"id",
"race",
"`class`",
"deityid",
"zoneid",
"itemid",
"race_list",
"class_list",
"deity_list",
"zone_id_list",
"item_id",
"item_charges",
"gm",
"slot",
Expand Down Expand Up @@ -115,11 +116,11 @@ class BaseStartingItemsRepository {
StartingItems e{};

e.id = 0;
e.race = 0;
e.class_ = 0;
e.deityid = 0;
e.zoneid = 0;
e.itemid = 0;
e.race_list = "";
e.class_list = "";
e.deity_list = "";
e.zone_id_list = "";
e.item_id = 0;
e.item_charges = 1;
e.gm = 0;
e.slot = -1;
Expand Down Expand Up @@ -152,8 +153,9 @@ class BaseStartingItemsRepository {
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
starting_items_id
)
);
Expand All @@ -163,13 +165,13 @@ class BaseStartingItemsRepository {
StartingItems e{};

e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race = static_cast<int32_t>(atoi(row[1]));
e.class_ = static_cast<int32_t>(atoi(row[2]));
e.deityid = static_cast<int32_t>(atoi(row[3]));
e.zoneid = static_cast<int32_t>(atoi(row[4]));
e.itemid = static_cast<int32_t>(atoi(row[5]));
e.race_list = row[1] ? row[1] : "";
e.class_list = row[2] ? row[2] : "";
e.deity_list = row[3] ? row[3] : "";
e.zone_id_list = row[4] ? row[4] : "";
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.gm = static_cast<int8_t>(atoi(row[7]));
e.gm = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.slot = static_cast<int32_t>(atoi(row[8]));
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
Expand Down Expand Up @@ -208,11 +210,11 @@ class BaseStartingItemsRepository {

auto columns = Columns();

v.push_back(columns[1] + " = " + std::to_string(e.race));
v.push_back(columns[2] + " = " + std::to_string(e.class_));
v.push_back(columns[3] + " = " + std::to_string(e.deityid));
v.push_back(columns[4] + " = " + std::to_string(e.zoneid));
v.push_back(columns[5] + " = " + std::to_string(e.itemid));
v.push_back(columns[1] + " = '" + Strings::Escape(e.race_list) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.class_list) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.deity_list) + "'");
v.push_back(columns[4] + " = '" + Strings::Escape(e.zone_id_list) + "'");
v.push_back(columns[5] + " = " + std::to_string(e.item_id));
v.push_back(columns[6] + " = " + std::to_string(e.item_charges));
v.push_back(columns[7] + " = " + std::to_string(e.gm));
v.push_back(columns[8] + " = " + std::to_string(e.slot));
Expand Down Expand Up @@ -242,11 +244,11 @@ class BaseStartingItemsRepository {
std::vector<std::string> v;

v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.race));
v.push_back(std::to_string(e.class_));
v.push_back(std::to_string(e.deityid));
v.push_back(std::to_string(e.zoneid));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.race_list) + "'");
v.push_back("'" + Strings::Escape(e.class_list) + "'");
v.push_back("'" + Strings::Escape(e.deity_list) + "'");
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_charges));
v.push_back(std::to_string(e.gm));
v.push_back(std::to_string(e.slot));
Expand Down Expand Up @@ -284,11 +286,11 @@ class BaseStartingItemsRepository {
std::vector<std::string> v;

v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.race));
v.push_back(std::to_string(e.class_));
v.push_back(std::to_string(e.deityid));
v.push_back(std::to_string(e.zoneid));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.race_list) + "'");
v.push_back("'" + Strings::Escape(e.class_list) + "'");
v.push_back("'" + Strings::Escape(e.deity_list) + "'");
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_charges));
v.push_back(std::to_string(e.gm));
v.push_back(std::to_string(e.slot));
Expand Down Expand Up @@ -330,13 +332,13 @@ class BaseStartingItemsRepository {
StartingItems e{};

e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race = static_cast<int32_t>(atoi(row[1]));
e.class_ = static_cast<int32_t>(atoi(row[2]));
e.deityid = static_cast<int32_t>(atoi(row[3]));
e.zoneid = static_cast<int32_t>(atoi(row[4]));
e.itemid = static_cast<int32_t>(atoi(row[5]));
e.race_list = row[1] ? row[1] : "";
e.class_list = row[2] ? row[2] : "";
e.deity_list = row[3] ? row[3] : "";
e.zone_id_list = row[4] ? row[4] : "";
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.gm = static_cast<int8_t>(atoi(row[7]));
e.gm = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.slot = static_cast<int32_t>(atoi(row[8]));
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
Expand Down Expand Up @@ -367,13 +369,13 @@ class BaseStartingItemsRepository {
StartingItems e{};

e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.race = static_cast<int32_t>(atoi(row[1]));
e.class_ = static_cast<int32_t>(atoi(row[2]));
e.deityid = static_cast<int32_t>(atoi(row[3]));
e.zoneid = static_cast<int32_t>(atoi(row[4]));
e.itemid = static_cast<int32_t>(atoi(row[5]));
e.race_list = row[1] ? row[1] : "";
e.class_list = row[2] ? row[2] : "";
e.deity_list = row[3] ? row[3] : "";
e.zone_id_list = row[4] ? row[4] : "";
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
e.gm = static_cast<int8_t>(atoi(row[7]));
e.gm = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
e.slot = static_cast<int32_t>(atoi(row[8]));
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
Expand Down
93 changes: 65 additions & 28 deletions common/shareddb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "repositories/criteria/content_filter_criteria.h"
#include "repositories/account_repository.h"
#include "repositories/faction_association_repository.h"
#include "repositories/starting_items_repository.h"
#include "path_manager.h"
#include "repositories/loottable_repository.h"

Expand Down Expand Up @@ -446,45 +447,81 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
return true;
}

bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQ::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {

const EQ::ItemData *myitem;
bool SharedDatabase::SetStartingItems(
PlayerProfile_Struct *pp,
EQ::InventoryProfile *inv,
uint32 si_race,
uint32 si_class,
uint32 si_deity,
uint32 si_current_zone,
char *si_name,
int admin_level
)
{
const EQ::ItemData *item_data;

const std::string query = StringFormat(
"SELECT itemid, item_charges, slot FROM starting_items "
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
"(deityid = %i or deityid = 0) AND (zoneid = %i or zoneid = 0) AND "
"gm <= %i %s ORDER BY id",
si_race,
si_class,
si_deity,
si_current_zone,
admin_level,
ContentFilterCriteria::apply().c_str()
);
const auto &l = StartingItemsRepository::All(*this);

auto results = QueryDatabase(query);
if (!results.Success()) {
if (l.empty()) {
return false;
}

std::vector<StartingItemsRepository::StartingItems> v;

for (auto& row = results.begin(); row != results.end(); ++row) {
const int32 itemid = Strings::ToInt(row[0]);
const int32 charges = Strings::ToInt(row[1]);
int32 slot = Strings::ToInt(row[2]);
myitem = GetItem(itemid);
for (const auto &e : l) {
const auto &classes = Strings::Split(e.class_list, "|");
const auto &deities = Strings::Split(e.deity_list, "|");
const auto &races = Strings::Split(e.race_list, "|");
const auto &zones = Strings::Split(e.zone_id_list, "|");

const std::string &all = std::to_string(0);

if (classes[0] != all) {
if (!Strings::Contains(classes, std::to_string(si_class))) {
continue;
}
}

if (deities[0] != all) {
if (!Strings::Contains(deities, std::to_string(si_deity))) {
continue;
}
}

if(!myitem)
if (races[0] != all) {
if (!Strings::Contains(races, std::to_string(si_race))) {
continue;
}
}

if (zones[0] != all) {
if (!Strings::Contains(zones, std::to_string(si_current_zone))) {
continue;
}
}

v.emplace_back(e);
}

for (const auto &e : v) {
const uint32 item_id = e.item_id;
const uint8 item_charges = e.item_charges;
int32 slot = e.slot;

item_data = GetItem(item_id);

if (!item_data) {
continue;
}

const EQ::ItemInstance* myinst = CreateBaseItem(myitem, charges);
const auto *inst = CreateBaseItem(item_data, item_charges);

if(slot < 0)
slot = inv->FindFreeSlot(0, 0);
if (slot < EQ::invslot::slotCharm) {
slot = inv->FindFreeSlot(false, false);
}

inv->PutItem(slot, *myinst);
safe_delete(myinst);
inv->PutItem(slot, *inst);
safe_delete(inst);
}

return true;
Expand Down
Loading

0 comments on commit 33b40e8

Please sign in to comment.