diff options
author | megamage <none@none> | 2009-06-01 21:52:17 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-06-01 21:52:17 -0500 |
commit | 7344a5ef6f776f355cda34da77d2aed01f228b47 (patch) | |
tree | 8f02e0317c9a53de26f59f64f43456f397a4724c /src/shared/Database | |
parent | b05ebfa8e90def21baa98707a1d5e9185950de74 (diff) |
[7935] Move seldom used access to query data by field names to independent object. Author: VladimirMangos
This let not do preparation code for unused later functionlity.
--HG--
branch : trunk
Diffstat (limited to 'src/shared/Database')
-rw-r--r-- | src/shared/Database/Database.cpp | 19 | ||||
-rw-r--r-- | src/shared/Database/Database.h | 2 | ||||
-rw-r--r-- | src/shared/Database/DatabaseMysql.cpp | 62 | ||||
-rw-r--r-- | src/shared/Database/DatabaseMysql.h | 2 | ||||
-rw-r--r-- | src/shared/Database/DatabasePostgre.cpp | 65 | ||||
-rw-r--r-- | src/shared/Database/DatabasePostgre.h | 2 | ||||
-rw-r--r-- | src/shared/Database/QueryResult.h | 56 | ||||
-rw-r--r-- | src/shared/Database/QueryResultMysql.cpp | 9 | ||||
-rw-r--r-- | src/shared/Database/QueryResultMysql.h | 2 | ||||
-rw-r--r-- | src/shared/Database/QueryResultPostgre.cpp | 5 |
10 files changed, 159 insertions, 65 deletions
diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index d5ccc581232..651ea7f41fb 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -133,6 +133,25 @@ QueryResult* Database::PQuery(const char *format,...) return Query(szQuery); } +QueryNamedResult* Database::PQueryNamed(const char *format,...) +{ + if(!format) return 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 false; + } + + return QueryNamed(szQuery); +} + bool Database::PExecute(const char * format,...) { if (!format) diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index a9f7285c223..493ec8a76c0 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -54,6 +54,8 @@ class TRINITY_DLL_SPEC Database virtual QueryResult* Query(const char *sql) = 0; QueryResult* PQuery(const char *format,...) ATTR_PRINTF(2,3); + virtual QueryNamedResult* QueryNamed(const char *sql) = 0; + QueryNamedResult* PQueryNamed(const char *format,...) ATTR_PRINTF(2,3); /// Async queries and query holders, implemented in DatabaseImpl.h diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp index 9574d3dc2ac..0189b5883f7 100644 --- a/src/shared/Database/DatabaseMysql.cpp +++ b/src/shared/Database/DatabaseMysql.cpp @@ -192,15 +192,11 @@ bool DatabaseMysql::Initialize(const char *infoString) } } -QueryResult* DatabaseMysql::Query(const char *sql) +bool DatabaseMysql::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount) { if (!mMysql) return 0; - MYSQL_RES *result = 0; - uint64 rowCount = 0; - uint32 fieldCount = 0; - { // guarded block for thread-safe mySQL request ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex); @@ -211,7 +207,7 @@ QueryResult* DatabaseMysql::Query(const char *sql) { sLog.outErrorDb( "SQL: %s", sql ); sLog.outErrorDb("query ERROR: %s", mysql_error(mMysql)); - return NULL; + return false; } else { @@ -220,29 +216,63 @@ QueryResult* DatabaseMysql::Query(const char *sql) #endif } - result = mysql_store_result(mMysql); - - rowCount = mysql_affected_rows(mMysql); - fieldCount = mysql_field_count(mMysql); + *pResult = mysql_store_result(mMysql); + *pRowCount = mysql_affected_rows(mMysql); + *pFieldCount = mysql_field_count(mMysql); // end guarded block } - if (!result ) - return NULL; + if (!*pResult ) + return false; - if (!rowCount) + if (!*pRowCount) { - mysql_free_result(result); - return NULL; + mysql_free_result(*pResult); + return false; } - QueryResultMysql *queryResult = new QueryResultMysql(result, rowCount, fieldCount); + *pFields = mysql_fetch_fields(*pResult); + return true; +} + +QueryResult* 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 NULL; + + QueryResultMysql *queryResult = new QueryResultMysql(result, fields, rowCount, fieldCount); queryResult->NextRow(); return queryResult; } +QueryNamedResult* DatabaseMysql::QueryNamed(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 NULL; + + QueryFieldNames names(fieldCount); + for (uint32 i = 0; i < fieldCount; i++) + names[i] = fields[i].name; + + QueryResultMysql *queryResult = new QueryResultMysql(result, fields, rowCount, fieldCount); + + queryResult->NextRow(); + + return new QueryNamedResult(queryResult,names); +} + bool DatabaseMysql::Execute(const char *sql) { if (!mMysql) diff --git a/src/shared/Database/DatabaseMysql.h b/src/shared/Database/DatabaseMysql.h index 7f5730f9579..4612ebfc462 100644 --- a/src/shared/Database/DatabaseMysql.h +++ b/src/shared/Database/DatabaseMysql.h @@ -50,6 +50,7 @@ class TRINITY_DLL_SPEC DatabaseMysql : public Database void InitDelayThread(); void HaltDelayThread(); QueryResult* Query(const char *sql); + QueryNamedResult* QueryNamed(const char *sql); bool Execute(const char *sql); bool DirectExecute(const char* sql); bool BeginTransaction(); @@ -75,6 +76,7 @@ class TRINITY_DLL_SPEC DatabaseMysql : public Database static size_t db_count; bool _TransactionCmd(const char *sql); + bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount); }; #endif #endif diff --git a/src/shared/Database/DatabasePostgre.cpp b/src/shared/Database/DatabasePostgre.cpp index 12875b33200..c70067dfdba 100644 --- a/src/shared/Database/DatabasePostgre.cpp +++ b/src/shared/Database/DatabasePostgre.cpp @@ -117,32 +117,27 @@ bool DatabasePostgre::Initialize(const char *infoString) } -QueryResult* DatabasePostgre::Query(const char *sql) +bool DatabasePostgre::_Query(const char *sql, PGresult** pResult, uint64* pRowCount, uint32* pFieldCount) { if (!mPGconn) return 0; - uint64 rowCount = 0; - uint32 fieldCount = 0; - // guarded block for thread-safe request ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex); #ifdef MANGOS_DEBUG uint32 _s = getMSTime(); #endif // Send the query - PGresult * result = PQexec(mPGconn, sql); - if (!result ) - { - return NULL; - } + *pResult = PQexec(mPGconn, sql); + if(!*pResult ) + return false; - if (PQresultStatus(result) != PGRES_TUPLES_OK) + if (PQresultStatus(*pResult) != PGRES_TUPLES_OK) { sLog.outErrorDb( "SQL : %s", sql ); sLog.outErrorDb( "SQL %s", PQerrorMessage(mPGconn)); - PQclear(result); - return NULL; + PQclear(*pResult); + return false; } else { @@ -151,15 +146,29 @@ QueryResult* DatabasePostgre::Query(const char *sql) #endif } - rowCount = PQntuples(result); - fieldCount = PQnfields(result); + *pRowCount = PQntuples(*pResult); + *pFieldCount = PQnfields(*pResult); // end guarded block - if (!rowCount) + if (!*pRowCount) { - PQclear(result); - return NULL; + PQclear(*pResult); + return false; } + return true; +} + +QueryResult* DatabasePostgre::Query(const char *sql) +{ + if (!mPGconn) + return 0; + + PGresult* result = NULL; + uint64 rowCount = 0; + uint32 fieldCount = 0; + + if(!_Query(sql,&result,&rowCount,&fieldCount)) + return NULL; QueryResultPostgre * queryResult = new QueryResultPostgre(result, rowCount, fieldCount); queryResult->NextRow(); @@ -167,6 +176,28 @@ QueryResult* DatabasePostgre::Query(const char *sql) return queryResult; } +QueryNamedResult* DatabasePostgre::QueryNamed(const char *sql) +{ + if (!mPGconn) + return 0; + + PGresult* result = NULL; + uint64 rowCount = 0; + uint32 fieldCount = 0; + + if(!_Query(sql,&result,&rowCount,&fieldCount)) + return NULL; + + QueryFieldNames names(fieldCount); + for (uint32 i = 0; i < fieldCount; i++) + names[i] = PQfname(result, i); + + QueryResultPostgre * queryResult = new QueryResultPostgre(result, rowCount, fieldCount); + queryResult->NextRow(); + + return new QueryNamedResult(queryResult,names); +} + bool DatabasePostgre::Execute(const char *sql) { diff --git a/src/shared/Database/DatabasePostgre.h b/src/shared/Database/DatabasePostgre.h index 53f0802f86c..92a8dff045a 100644 --- a/src/shared/Database/DatabasePostgre.h +++ b/src/shared/Database/DatabasePostgre.h @@ -46,6 +46,7 @@ class DatabasePostgre : public Database void InitDelayThread(); void HaltDelayThread(); QueryResult* Query(const char *sql); + QueryNamedResult* QueryNamed(const char *sql); bool Execute(const char *sql); bool DirectExecute(const char* sql); bool BeginTransaction(); @@ -70,6 +71,7 @@ class DatabasePostgre : public Database static size_t db_count; bool _TransactionCmd(const char *sql); + bool _Query(const char *sql, PGresult **pResult, uint64* pRowCount, uint32* pFieldCount); }; #endif diff --git a/src/shared/Database/QueryResult.h b/src/shared/Database/QueryResult.h index 39228dd4ba9..f9f1a009833 100644 --- a/src/shared/Database/QueryResult.h +++ b/src/shared/Database/QueryResult.h @@ -31,37 +31,53 @@ class TRINITY_DLL_SPEC QueryResult virtual bool NextRow() = 0; - typedef std::map<uint32, std::string> FieldNames; - - uint32 GetField_idx(const std::string &name) const - { - for(FieldNames::const_iterator iter = GetFieldNames().begin(); iter != GetFieldNames().end(); ++iter) - { - if(iter->second == name) - return iter->first; - } - ASSERT(false && "unknown field name"); - return uint32(-1); - } - Field *Fetch() const { return mCurrentRow; } const Field & operator [] (int index) const { return mCurrentRow[index]; } - const Field & operator [] (const std::string &name) const - { - return mCurrentRow[GetField_idx(name)]; - } - uint32 GetFieldCount() const { return mFieldCount; } uint64 GetRowCount() const { return mRowCount; } - FieldNames const& GetFieldNames() const {return mFieldNames; } protected: Field *mCurrentRow; uint32 mFieldCount; uint64 mRowCount; - FieldNames mFieldNames; }; + +typedef std::vector<std::string> QueryFieldNames; + +class MANGOS_DLL_SPEC QueryNamedResult +{ + public: + explicit QueryNamedResult(QueryResult* query, QueryFieldNames const& names) : mQuery(query), mFieldNames(names) {} + ~QueryNamedResult() { delete mQuery; } + + // compatible interface with QueryResult + bool NextRow() { return mQuery->NextRow(); } + Field *Fetch() const { return mQuery->Fetch(); } + uint32 GetFieldCount() const { return mQuery->GetFieldCount(); } + uint64 GetRowCount() const { return mQuery->GetRowCount(); } + Field const& operator[] (int index) const { return (*mQuery)[index]; } + + // named access + Field const& operator[] (const std::string &name) const { return mQuery->Fetch()[GetField_idx(name)]; } + QueryFieldNames const& GetFieldNames() const { return mFieldNames; } + + uint32 GetField_idx(const std::string &name) const + { + for(size_t idx = 0; idx < mFieldNames.size(); ++idx) + { + if(mFieldNames[idx] == name) + return idx; + } + ASSERT(false && "unknown field name"); + return uint32(-1); + } + + protected: + QueryResult *mQuery; + QueryFieldNames mFieldNames; +}; + #endif diff --git a/src/shared/Database/QueryResultMysql.cpp b/src/shared/Database/QueryResultMysql.cpp index 5bc11ae308f..2e4738469c9 100644 --- a/src/shared/Database/QueryResultMysql.cpp +++ b/src/shared/Database/QueryResultMysql.cpp @@ -22,20 +22,15 @@ #include "DatabaseEnv.h" -QueryResultMysql::QueryResultMysql(MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) : -QueryResult(rowCount, fieldCount), mResult(result) +QueryResultMysql::QueryResultMysql(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount) : + QueryResult(rowCount, fieldCount), mResult(result) { mCurrentRow = new Field[mFieldCount]; ASSERT(mCurrentRow); - MYSQL_FIELD *fields = mysql_fetch_fields(mResult); - for (uint32 i = 0; i < mFieldCount; i++) - { - mFieldNames[i] = fields[i].name; mCurrentRow[i].SetType(ConvertNativeType(fields[i].type)); - } } QueryResultMysql::~QueryResultMysql() diff --git a/src/shared/Database/QueryResultMysql.h b/src/shared/Database/QueryResultMysql.h index 06b1353c12e..89aceb12b13 100644 --- a/src/shared/Database/QueryResultMysql.h +++ b/src/shared/Database/QueryResultMysql.h @@ -34,7 +34,7 @@ class QueryResultMysql : public QueryResult { public: - QueryResultMysql(MYSQL_RES *result, uint64 rowCount, uint32 fieldCount); + QueryResultMysql(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount); ~QueryResultMysql(); diff --git a/src/shared/Database/QueryResultPostgre.cpp b/src/shared/Database/QueryResultPostgre.cpp index 500ca053885..915b0fba253 100644 --- a/src/shared/Database/QueryResultPostgre.cpp +++ b/src/shared/Database/QueryResultPostgre.cpp @@ -23,17 +23,14 @@ #include "DatabaseEnv.h" QueryResultPostgre::QueryResultPostgre(PGresult *result, uint64 rowCount, uint32 fieldCount) : -QueryResult(rowCount, fieldCount), mResult(result), mTableIndex(0) + QueryResult(rowCount, fieldCount), mResult(result), mTableIndex(0) { mCurrentRow = new Field[mFieldCount]; ASSERT(mCurrentRow); for (uint32 i = 0; i < mFieldCount; i++) - { - mFieldNames[i] = PQfname(result, i); mCurrentRow[i].SetType(ConvertNativeType(PQftype( result, i ))); - } } QueryResultPostgre::~QueryResultPostgre() |