Exemple #1
0
QueryResult_AutoPtr DatabaseMysql::Query(const char *sql)
{
    MYSQL_RES *result = NULL;
    MYSQL_FIELD *fields = NULL;
    uint64 rowCount = 0;
    uint32 fieldCount = 0;

    if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
        return QueryResult_AutoPtr(NULL);

    QueryResultMysql *queryResult = new QueryResultMysql(result, fields, rowCount, fieldCount);

    queryResult->NextRow();

    return QueryResult_AutoPtr(queryResult);
}
Exemple #2
0
QueryResult_AutoPtr Database::PQuery(const char *format,...)
{
    if (!format) return QueryResult_AutoPtr(NULL);

    va_list ap;
    char szQuery [MAX_QUERY_LEN];
    va_start(ap, format);
    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
    va_end(ap);

    if (res==-1)
    {
        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
        return QueryResult_AutoPtr(NULL);
    }

    return Query(szQuery);
}
Exemple #3
0
QueryResult_AutoPtr MySQLConnection::Query(const char* sql)
{
    if (!sql)
        return QueryResult_AutoPtr(NULL);

    MYSQL_RES *result = NULL;
    MYSQL_FIELD *fields = NULL;
    uint64 rowCount = 0;
    uint32 fieldCount = 0;

    if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
        return QueryResult_AutoPtr(NULL);

    QueryResult *queryResult = new QueryResult(result, fields, rowCount, fieldCount);

    queryResult->NextRow();

    return QueryResult_AutoPtr(queryResult);
}
QueryResult_AutoPtr DatabaseWorkerPool::PQuery(const char* sql, ...)
{
    if (!sql)
        return QueryResult_AutoPtr(NULL);

    va_list ap;
    char szQuery[MAX_QUERY_LEN];
    va_start(ap, sql);
    int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
    va_end(ap);

    return Query(szQuery);
}
Exemple #5
0
QueryResult_AutoPtr SQLQueryHolder::GetResult(size_t index)
{
    if (index < m_queries.size())
    {
        /// the query strings are freed on the first GetResult or in the destructor
        if (m_queries[index].first != NULL)
        {
            free((void*)(const_cast<char*>(m_queries[index].first)));
            m_queries[index].first = NULL;
        }
        /// when you get a result aways remember to delete it!
        return m_queries[index].second;
    }
    else
        return QueryResult_AutoPtr(NULL);
}
Exemple #6
0
bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
{
    if (m_queries.size() <= index)
    {
        sLog.outError("Query index (%u) out of range (size: %u) for query: %s", index, (uint32)m_queries.size(), sql);
        return false;
    }

    if (m_queries[index].first != NULL)
    {
        sLog.outError("Attempt assign query to holder index (%u) where other query stored (Old: [%s] New: [%s])",
            index, m_queries[index].first, sql);
        return false;
    }

    /// not executed yet, just stored (it's not called a holder for nothing)
    m_queries[index] = SQLResultPair(strdup(sql), QueryResult_AutoPtr(NULL));
    return true;
}
Exemple #7
0
DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, std::string name, uint32 guid)
{
    uint32 charcount = accmgr.GetCharactersCount(account);
    if (charcount >= 10)
        return DUMP_TOO_MANY_CHARS;

    FILE *fin = fopen(file.c_str(), "r");
    if (!fin)
        return DUMP_FILE_OPEN_ERROR;

    QueryResult_AutoPtr result = QueryResult_AutoPtr(NULL);
    char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20];

    // make sure the same guid doesn't already exist and is safe to use
    bool incHighest = true;
    if (guid != 0 && guid < objmgr.m_hiCharGuid)
    {
        result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE guid = '%d'", guid);
        if (result)
            guid = objmgr.m_hiCharGuid;                     // use first free if exists
        else incHighest = false;
    }
    else
        guid = objmgr.m_hiCharGuid;

    // normalize the name if specified and check if it exists
    if (!normalizePlayerName(name))
        name = "";

    if (ObjectMgr::CheckPlayerName(name,true) == CHAR_NAME_SUCCESS)
    {
        CharacterDatabase.escape_string(name);              // for safe, we use name only for sql quearies anyway
        result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
        if (result)
            name = "";                                      // use the one from the dump
    }
    else
        name = "";

    // name encoded or empty

    snprintf(newguid, 20, "%d", guid);
    snprintf(chraccount, 20, "%d", account);
    snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
    snprintf(lastpetid, 20, "%s", "");

    std::map<uint32,uint32> items;
    std::map<uint32,uint32> mails;
    char buf[32000] = "";

    typedef std::map<uint32, uint32> PetIds;                // old->new petid relation
    typedef PetIds::value_type PetIdsPair;
    PetIds petids;

    CharacterDatabase.BeginTransaction();
    while (!feof(fin))
    {
        if (!fgets(buf, 32000, fin))
        {
            if (feof(fin)) break;
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        std::string line;
        line.assign(buf);

        // skip empty strings
        size_t nw_pos = line.find_first_not_of(" \t\n\r\7");
        if (nw_pos == std::string::npos)
            continue;

        // skip logfile-side dump start notice, the important notes and dump end notices
        if ((line.substr(nw_pos,16) == "== START DUMP ==") ||
                (line.substr(nw_pos,15) == "IMPORTANT NOTE:") ||
                (line.substr(nw_pos,14) == "== END DUMP =="))
            continue;

        // add required_ check
        /*
        if (line.substr(nw_pos,41) == "UPDATE character_db_version SET required_")
        {
            if (!CharacterDatabase.Execute(line.c_str()))
                ROLLBACK(DUMP_FILE_BROKEN);

            continue;
        }
        */

        // determine table name and load type
        std::string tn = gettablename(line);
        if (tn.empty())
        {
            sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str());
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        DumpTableType type;
        uint8 i;
        for (i = 0; i < DUMP_TABLE_COUNT; ++i)
        {
            if (tn == dumpTables[i].name)
            {
                type = dumpTables[i].type;
                break;
            }
        }

        if (i == DUMP_TABLE_COUNT)
        {
            sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str());
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        // change the data to server values
        switch(type)
        {
        case DTT_CHAR_TABLE:
            if (!changenth(line, 1, newguid))           // character_*.guid update
                ROLLBACK(DUMP_FILE_BROKEN);
            break;

        case DTT_CHARACTER:
        {
            if (!changenth(line, 1, newguid))           // characters.guid update
                ROLLBACK(DUMP_FILE_BROKEN);

            if (!changenth(line, 2, chraccount))        // characters.account update
                ROLLBACK(DUMP_FILE_BROKEN);

            if (name == "")
            {
                // check if the original name already exists
                name = getnth(line, 3);
                CharacterDatabase.escape_string(name);

                result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
                if (result)
                {
                    if (!changenth(line, 37, "1"))       // characters.at_login set to "rename on login"
                        ROLLBACK(DUMP_FILE_BROKEN);
                }
            }
            else if (!changenth(line, 3, name.c_str())) // characters.name
                ROLLBACK(DUMP_FILE_BROKEN);

            const char null[5] = "NULL";
            if (!changenth(line, 68, null))             // characters.deleteInfos_Account
                ROLLBACK(DUMP_FILE_BROKEN);
            if (!changenth(line, 69, null))             // characters.deleteInfos_Name
                ROLLBACK(DUMP_FILE_BROKEN);
            if (!changenth(line, 70, null))             // characters.deleteDate
                ROLLBACK(DUMP_FILE_BROKEN);
            break;
        }
        case DTT_INVENTORY:
        {
            if (!changenth(line, 1, newguid))           // character_inventory.guid update
                ROLLBACK(DUMP_FILE_BROKEN);

            if (!changeGuid(line, 2, items, objmgr.m_hiItemGuid, true))
                ROLLBACK(DUMP_FILE_BROKEN);             // character_inventory.bag update
            if (!changeGuid(line, 4, items, objmgr.m_hiItemGuid))
                ROLLBACK(DUMP_FILE_BROKEN);             // character_inventory.item update
            break;
        }
        case DTT_ITEM:
        {
            // item, owner, data field:item, owner guid
            if (!changeGuid(line, 1, items, objmgr.m_hiItemGuid))
                ROLLBACK(DUMP_FILE_BROKEN);              // item_instance.guid update
            if (!changenth(line, 2, newguid))           // item_instance.owner_guid update
                ROLLBACK(DUMP_FILE_BROKEN);
            break;
        }
        case DTT_ITEM_GIFT:
        {
            if (!changenth(line, 1, newguid))           // character_gifts.guid update
                ROLLBACK(DUMP_FILE_BROKEN);
            if (!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
                ROLLBACK(DUMP_FILE_BROKEN);             // character_gifts.item_guid update
            break;
        }
        case DTT_PET:
        {
            //store a map of old pet id to new inserted pet id for use by type 5 tables
            snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
            if (strlen(lastpetid) == 0) snprintf(lastpetid, 20, "%s", currpetid);
            if (strcmp(lastpetid,currpetid) != 0)
            {
                snprintf(newpetid, 20, "%d", objmgr.GeneratePetNumber());
                snprintf(lastpetid, 20, "%s", currpetid);
            }

            std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));

            if (petids_iter == petids.end())
            {
                petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
            }

            if (!changenth(line, 1, newpetid))          // character_pet.id update
                ROLLBACK(DUMP_FILE_BROKEN);
            if (!changenth(line, 3, newguid))           // character_pet.owner update
                ROLLBACK(DUMP_FILE_BROKEN);

            break;
        }
        case DTT_PET_TABLE:                             // pet_aura, pet_spell, pet_spell_cooldown
        {
            snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());

            // lookup currpetid and match to new inserted pet id
            std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
            if (petids_iter == petids.end())             // couldn't find new inserted id
                ROLLBACK(DUMP_FILE_BROKEN);

            snprintf(newpetid, 20, "%d", petids_iter->second);

            if (!changenth(line, 1, newpetid))
                ROLLBACK(DUMP_FILE_BROKEN);

            break;
        }
        case DTT_MAIL:                                  // mail
        {
            if (!changeGuid(line, 1, mails, objmgr.m_mailid))
                ROLLBACK(DUMP_FILE_BROKEN);             // mail.id update
            if (!changenth(line, 6, newguid))           // mail.receiver update
                ROLLBACK(DUMP_FILE_BROKEN);
            break;
        }
        case DTT_MAIL_ITEM:                             // mail_items
        {
            if (!changeGuid(line, 1, mails, objmgr.m_mailid))
                ROLLBACK(DUMP_FILE_BROKEN);             // mail_items.id
            if (!changeGuid(line, 2, items, objmgr.m_hiItemGuid))
                ROLLBACK(DUMP_FILE_BROKEN);             // mail_items.item_guid
            if (!changenth(line, 4, newguid))           // mail_items.receiver
                ROLLBACK(DUMP_FILE_BROKEN);
            break;
        }
        default:
            sLog.outError("Unknown dump table type: %u",type);
            break;
        }

        fixNULLfields(line);

        if (!CharacterDatabase.Execute(line.c_str()))
            ROLLBACK(DUMP_FILE_BROKEN);
    }

    CharacterDatabase.CommitTransaction();

    objmgr.m_hiItemGuid += items.size();
    objmgr.m_mailid     += mails.size();

    if (incHighest)
        ++objmgr.m_hiCharGuid;

    fclose(fin);

    return DUMP_SUCCESS;
}
Exemple #8
0
DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, std::string name, uint32 guid)
{
    // check character count
    {
        QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", account);
        uint8 charcount = 0;
        if (result)
        {
            Field *fields=result->Fetch();
            charcount = fields[0].GetUInt8();

            if (charcount >= 10)
                return DUMP_TOO_MANY_CHARS;
        }
    }

    FILE *fin = fopen(file.c_str(), "r");
    if (!fin)
        return DUMP_FILE_OPEN_ERROR;

    QueryResult_AutoPtr result = QueryResult_AutoPtr(NULL);
    char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20];

    // make sure the same guid doesn't already exist and is safe to use
    bool incHighest = true;
    if (guid != 0 && guid < sObjectMgr.m_hiCharGuid)
    {
        result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE guid = '%d'", guid);
        if (result)
            guid = sObjectMgr.m_hiCharGuid;                     // use first free if exists
        else incHighest = false;
    }
    else
        guid = sObjectMgr.m_hiCharGuid;

    // normalize the name if specified and check if it exists
    if (!normalizePlayerName(name))
        name = "";

    if (ObjectMgr::CheckPlayerName(name,true) == CHAR_NAME_SUCCESS)
    {
        CharacterDatabase.escape_string(name);              // for safe, we use name only for sql quearies anyway
        result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
        if (result)
            name = "";                                      // use the one from the dump
    }
    else
        name = "";

    // name encoded or empty

    snprintf(newguid, 20, "%d", guid);
    snprintf(chraccount, 20, "%d", account);
    snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
    snprintf(lastpetid, 20, "%s", "");

    std::map<uint32,uint32> items;
    std::map<uint32,uint32> mails;
    std::map<uint32,uint32> itemTexts;
    char buf[32000] = "";

    typedef std::map<uint32, uint32> PetIds;                // old->new petid relation
    typedef PetIds::value_type PetIdsPair;
    PetIds petids;

    CharacterDatabase.BeginTransaction();
    while(!feof(fin))
    {
        if (!fgets(buf, 32000, fin))
        {
            if (feof(fin)) break;
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        std::string line; line.assign(buf);

        // skip empty strings
        size_t nw_pos = line.find_first_not_of(" \t\n\r\7");
        if (nw_pos==std::string::npos)
            continue;

        // skip NOTE
        if (line.substr(nw_pos,15)=="IMPORTANT NOTE:")
            continue;

        // add required_ check
        /*
        if (line.substr(nw_pos,41)=="UPDATE character_db_version SET required_")
        {
            if (!CharacterDatabase.Execute(line.c_str()))
                ROLLBACK(DUMP_FILE_BROKEN);

            continue;
        }
        */

        // determine table name and load type
        std::string tn = gettablename(line);
        if (tn.empty())
        {
            sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str());
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        DumpTableType type;
        uint8 i;
        for (i = 0; i < DUMP_TABLE_COUNT; ++i)
        {
            if (tn == dumpTables[i].name)
            {
                type = dumpTables[i].type;
                break;
            }
        }

        if (i == DUMP_TABLE_COUNT)
        {
            sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str());
            ROLLBACK(DUMP_FILE_BROKEN);
        }

        // change the data to server values
        switch (type)
        {
            case DTT_CHAR_TABLE:
                if (!changenth(line, 1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;

            case DTT_CHARACTER:                             // character t.
            {
                if (!changenth(line, 1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);

                // guid, data field:guid, items
                if (!changenth(line, 2, chraccount))
                    ROLLBACK(DUMP_FILE_BROKEN);
                std::string vals = getnth(line, 3);
                if (!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                for (uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
                    if (!changetokGuid(vals, field+1, items, sObjectMgr.m_hiItemGuid, true))
                        ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 3, vals.c_str()))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (name == "")
                {
                    // check if the original name already exists
                    name = getnth(line, 4);
                    CharacterDatabase.escape_string(name);

                    result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
                    if (result)
                    {
                        if (!changenth(line, 37, "1"))       // rename on login: `at_login` field 37 in raw field list
                            ROLLBACK(DUMP_FILE_BROKEN);
                    }
                }
                else if (!changenth(line, 4, name.c_str()))
                    ROLLBACK(DUMP_FILE_BROKEN);

                break;
            }
            case DTT_INVENTORY:                             // character_inventory t.
            {
                if (!changenth(line, 1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);

                // bag, item
                if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid, true))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changeGuid(line, 4, items, sObjectMgr.m_hiItemGuid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;
            }
            case DTT_ITEM:                                  // item_instance t.
            {
                // item, owner, data field:item, owner guid
                if (!changeGuid(line, 1, items, sObjectMgr.m_hiItemGuid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 2, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                std::string vals = getnth(line,3);
                if (!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_hiItemGuid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextId,true))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 3, vals.c_str()))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;
            }
            case DTT_ITEM_GIFT:                             // character_gift
            {
                // guid,item_guid,
                if (!changenth(line, 1, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;
            }
            case DTT_PET:                                   // character_pet t
            {
                //store a map of old pet id to new inserted pet id for use by type 5 tables
                snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
                if (strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid);
                if (strcmp(lastpetid,currpetid)!=0)
                {
                    snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
                    snprintf(lastpetid, 20, "%s", currpetid);
                }

                std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));

                if (petids_iter == petids.end())
                {
                    petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
                }

                // item, entry, owner, ...
                if (!changenth(line, 1, newpetid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 3, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);

                break;
            }
            case DTT_PET_TABLE:                             // pet_aura, pet_spell, pet_spell_cooldown t
            {
                snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());

                // lookup currpetid and match to new inserted pet id
                std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
                if (petids_iter == petids.end())             // couldn't find new inserted id
                    ROLLBACK(DUMP_FILE_BROKEN);

                snprintf(newpetid, 20, "%d", petids_iter->second);

                if (!changenth(line, 1, newpetid))
                    ROLLBACK(DUMP_FILE_BROKEN);

                break;
            }
            case DTT_MAIL:                                  // mail
            {
                // id,messageType,stationery,mailtemplate,sender,receiver,subject,itemText
                if (!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 6, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextId))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;
            }
            case DTT_MAIL_ITEM:                             // mail_items
            {
                // mail_id,item_guid,item_template,receiver
                if (!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                if (!changenth(line, 4, newguid))
                    ROLLBACK(DUMP_FILE_BROKEN);
                break;
            }
            case DTT_ITEM_TEXT:                             // item_text
            {
                // id
                if (!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextId))
                    ROLLBACK(DUMP_FILE_BROKEN);

                // add it to cache
                uint32 id= atoi(getnth(line,1).c_str());
                std::string text = getnth(line,2);
                sObjectMgr.AddItemText(id,text);
                break;
            }
            default:
                sLog.outError("Unknown dump table type: %u",type);
                break;
        }

        if (!CharacterDatabase.Execute(line.c_str()))
            ROLLBACK(DUMP_FILE_BROKEN);
    }

    CharacterDatabase.CommitTransaction();

    sObjectMgr.m_hiItemGuid += items.size();
    sObjectMgr.m_mailid     += mails.size();
    sObjectMgr.m_ItemTextId += itemTexts.size();

    if (incHighest)
        ++sObjectMgr.m_hiCharGuid;

    fclose(fin);

    return DUMP_SUCCESS;
}