CharDB Schema/Cleanup: cleanup character_tutorial table:

* rename table to account_tutorial, because it holds account specific data;
* rename column account to accountId;
* introduce prepared statements for table.
This commit is contained in:
Azazel
2011-02-24 23:57:43 +06:00
parent 20ab3e4bda
commit bcd7e45e12
10 changed files with 102 additions and 88 deletions

View File

@@ -65,6 +65,36 @@ LOCK TABLES `account_instance_times` WRITE;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
--
-- Table structure for table `account_tutorial`
--
DROP TABLE IF EXISTS `account_tutorial`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `account_tutorial` (
`accountId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Account Identifier',
`tut0` int(10) unsigned NOT NULL DEFAULT '0',
`tut1` int(10) unsigned NOT NULL DEFAULT '0',
`tut2` int(10) unsigned NOT NULL DEFAULT '0',
`tut3` int(10) unsigned NOT NULL DEFAULT '0',
`tut4` int(10) unsigned NOT NULL DEFAULT '0',
`tut5` int(10) unsigned NOT NULL DEFAULT '0',
`tut6` int(10) unsigned NOT NULL DEFAULT '0',
`tut7` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`accountId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `account_tutorial`
--
LOCK TABLES `account_tutorial` WRITE;
/*!40000 ALTER TABLE `account_tutorial` DISABLE KEYS */;
/*!40000 ALTER TABLE `account_tutorial` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `addons`
--
@@ -1085,36 +1115,6 @@ LOCK TABLES `character_talent` WRITE;
/*!40000 ALTER TABLE `character_talent` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `character_tutorial`
--
DROP TABLE IF EXISTS `character_tutorial`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `character_tutorial` (
`account` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Account Identifier',
`tut0` int(10) unsigned NOT NULL DEFAULT '0',
`tut1` int(10) unsigned NOT NULL DEFAULT '0',
`tut2` int(10) unsigned NOT NULL DEFAULT '0',
`tut3` int(10) unsigned NOT NULL DEFAULT '0',
`tut4` int(10) unsigned NOT NULL DEFAULT '0',
`tut5` int(10) unsigned NOT NULL DEFAULT '0',
`tut6` int(10) unsigned NOT NULL DEFAULT '0',
`tut7` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `character_tutorial`
--
LOCK TABLES `character_tutorial` WRITE;
/*!40000 ALTER TABLE `character_tutorial` DISABLE KEYS */;
/*!40000 ALTER TABLE `character_tutorial` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `characters`
--

View File

@@ -0,0 +1,21 @@
--
-- Table structure for table `account_tutorial`
--
DROP TABLE IF EXISTS `account_tutorial`;
CREATE TABLE `account_tutorial` (
`accountId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Account Identifier',
`tut0` int(10) unsigned NOT NULL DEFAULT '0',
`tut1` int(10) unsigned NOT NULL DEFAULT '0',
`tut2` int(10) unsigned NOT NULL DEFAULT '0',
`tut3` int(10) unsigned NOT NULL DEFAULT '0',
`tut4` int(10) unsigned NOT NULL DEFAULT '0',
`tut5` int(10) unsigned NOT NULL DEFAULT '0',
`tut6` int(10) unsigned NOT NULL DEFAULT '0',
`tut7` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`accountId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
INSERT INTO `account_tutorial`(`accountId`,`tut0`,`tut1`,`tut2`,`tut3`,`tut4`,`tut5`,`tut6`,`tut7`)
SELECT `account`,`tut0`,`tut1`,`tut2`,`tut3`,`tut4`,`tut5`,`tut6`,`tut7` FROM `character_tutorial`;
DROP TABLE `character_tutorial`;

View File

@@ -74,8 +74,10 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
}
// table realm specific but common for all characters of account for realm
CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS);
stmt->setUInt32(0, accid);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA);
stmt->setUInt32(0, accid);
CharacterDatabase.Execute(stmt);

View File

@@ -947,33 +947,29 @@ void WorldSession::HandleMeetingStoneInfo(WorldPacket & /*recv_data*/)
void WorldSession::HandleTutorialFlag(WorldPacket & recv_data)
{
uint32 iFlag;
recv_data >> iFlag;
uint32 data;
recv_data >> data;
uint32 wInt = (iFlag / 32);
if (wInt >= 8)
{
//sLog->outError("CHEATER? Account:[%d] Guid[%u] tried to send wrong CMSG_TUTORIAL_FLAG", GetAccountId(),GetGUID());
uint8 index = uint8(data / 32);
if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
return;
}
uint32 rInt = (iFlag % 32);
uint32 tutflag = GetTutorialInt(wInt);
tutflag |= (1 << rInt);
SetTutorialInt(wInt, tutflag);
uint32 value = (data % 32);
//sLog->outDebug("Received Tutorial Flag Set {%u}.", iFlag);
uint32 flag = GetTutorialInt(index);
flag |= (1 << value);
SetTutorialInt(index, flag);
}
void WorldSession::HandleTutorialClear(WorldPacket & /*recv_data*/)
{
for (int i = 0; i < MAX_CHARACTER_TUTORIAL_VALUES; ++i)
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
SetTutorialInt(i, 0xFFFFFFFF);
}
void WorldSession::HandleTutorialReset(WorldPacket & /*recv_data*/)
{
for (int i = 0; i < MAX_CHARACTER_TUTORIAL_VALUES; ++i)
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
SetTutorialInt(i, 0x00000000);
}

View File

@@ -676,30 +676,21 @@ void WorldSession::SendAccountDataTimes(uint32 mask)
void WorldSession::LoadTutorialsData()
{
for (int aX = 0; aX < MAX_CHARACTER_TUTORIAL_VALUES; ++aX)
m_Tutorials[ aX ] = 0;
memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
// is there a good reason why this isn't a prepared statement?
QueryResult result = CharacterDatabase.PQuery("SELECT tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7 FROM character_tutorial WHERE account = '%u'", GetAccountId());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_TUTORIALS);
stmt->setUInt32(0, GetAccountId());
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
m_Tutorials[i] = (*result)[i].GetUInt32();
if (result)
{
do
{
Field *fields = result->Fetch();
for (int iI = 0; iI < MAX_CHARACTER_TUTORIAL_VALUES; ++iI)
m_Tutorials[iI] = fields[iI].GetUInt32();
}
while (result->NextRow());
}
m_TutorialsChanged = false;
}
void WorldSession::SendTutorialsData()
{
WorldPacket data(SMSG_TUTORIAL_FLAGS, 4 * MAX_CHARACTER_TUTORIAL_VALUES);
for (uint32 i = 0; i < MAX_CHARACTER_TUTORIAL_VALUES; ++i)
WorldPacket data(SMSG_TUTORIAL_FLAGS, 4 * MAX_ACCOUNT_TUTORIAL_VALUES);
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
data << m_Tutorials[i];
SendPacket(&data);
}
@@ -709,19 +700,15 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
if (!m_TutorialsChanged)
return;
// should these be prepared as well?
uint32 Rows = 0;
// it's better than rebuilding indexes multiple times
QueryResult result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u'", GetAccountId());
if (result)
Rows = result->Fetch()[0].GetUInt32();
if (Rows)
trans->PAppend("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'",
m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetAccountId());
else
trans->PAppend("INSERT INTO character_tutorial (account, tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_HAS_TUTORIALS);
stmt->setUInt32(0, GetAccountId());
bool hasTutorials = (CharacterDatabase.Query(stmt) != NULL);
// Modify data in DB
stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_SET_TUTORIALS : CHAR_ADD_TUTORIALS);
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
stmt->setUInt32(i, m_Tutorials[i]);
stmt->setUInt32(MAX_ACCOUNT_TUTORIAL_VALUES, GetAccountId());
trans->Append(stmt);
m_TutorialsChanged = false;
}

View File

@@ -286,16 +286,12 @@ class WorldSession
void LoadTutorialsData();
void SendTutorialsData();
void SaveTutorialsData(SQLTransaction& trans);
uint32 GetTutorialInt(uint32 intId)
uint32 GetTutorialInt(uint8 index) { return m_Tutorials[index]; }
void SetTutorialInt(uint8 index, uint32 value)
{
return m_Tutorials[intId];
}
void SetTutorialInt(uint32 intId, uint32 value)
{
if (m_Tutorials[intId] != value)
if (m_Tutorials[index] != value)
{
m_Tutorials[intId] = value;
m_Tutorials[index] = value;
m_TutorialsChanged = true;
}
}
@@ -905,7 +901,7 @@ class WorldSession
LocaleConstant m_sessionDbLocaleIndex;
uint32 m_latency;
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 m_Tutorials[MAX_CHARACTER_TUTORIAL_VALUES];
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
bool m_TutorialsChanged;
AddonsList m_addonsList;
uint32 recruiterId;

View File

@@ -30,8 +30,7 @@ enum DumpTableType
DTT_CHAR_TABLE, // // character_achievement, character_achievement_progress,
// character_action, character_aura, character_homebind,
// character_queststatus, character_queststatus_rewarded, character_reputation,
// character_spell, character_spell_cooldown, character_ticket, character_talent,
// character_tutorial
// character_spell, character_spell_cooldown, character_ticket, character_talent
DTT_EQSET_TABLE, // <- guid // character_equipmentsets

View File

@@ -180,7 +180,7 @@ const uint8 TOTAL_LOCALES = 9;
const LocaleConstant DEFAULT_LOCALE = LOCALE_enUS;
#define MAX_LOCALES 8
#define MAX_CHARACTER_TUTORIAL_VALUES 8
#define MAX_ACCOUNT_TUTORIAL_VALUES 8
extern char const* localeNames[TOTAL_LOCALES];

View File

@@ -265,6 +265,13 @@ bool CharacterDatabaseConnection::Open()
PREPARE_STATEMENT(CHAR_SET_PLAYER_ACCOUNT_DATA, "REPLACE INTO character_account_data(guid, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_PLAYER_ACCOUNT_DATA, "DELETE FROM character_account_data WHERE guid = ?", CONNECTION_ASYNC)
// Tutorials
PREPARE_STATEMENT(CHAR_LOAD_TUTORIALS, "SELECT tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7 FROM account_tutorial WHERE accountId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_GET_HAS_TUTORIALS, "SELECT 1 FROM account_tutorial WHERE accountId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_ADD_TUTORIALS, "INSERT INTO account_tutorial(tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7, accountId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SET_TUTORIALS, "UPDATE account_tutorial SET tut0 = ?, tut1 = ?, tut2 = ?, tut3 = ?, tut4 = ?, tut5 = ?, tut6 = ?, tut7 = ? WHERE accountId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_TUTORIALS, "DELETE FROM account_tutorial WHERE accountId = ?", CONNECTION_ASYNC)
// Instance saves
PREPARE_STATEMENT(CHAR_ADD_INSTANCE_SAVE, "INSERT INTO instance (id,map,resettime,difficulty,completedEncounters,data) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_UPDATE_INSTANCE_DATA, "UPDATE instance SET completedEncounters=?, data=? WHERE id=?", CONNECTION_ASYNC)

View File

@@ -223,6 +223,12 @@ enum CharacterDatabaseStatements
CHAR_SET_PLAYER_ACCOUNT_DATA,
CHAR_DEL_PLAYER_ACCOUNT_DATA,
CHAR_LOAD_TUTORIALS,
CHAR_GET_HAS_TUTORIALS,
CHAR_ADD_TUTORIALS,
CHAR_SET_TUTORIALS,
CHAR_DEL_TUTORIALS,
CHAR_ADD_INSTANCE_SAVE,
CHAR_UPDATE_INSTANCE_DATA,