aboutsummaryrefslogtreecommitdiff
path: root/src/shared/Database
diff options
context:
space:
mode:
authormegamage <none@none>2009-06-01 21:52:17 -0500
committermegamage <none@none>2009-06-01 21:52:17 -0500
commit7344a5ef6f776f355cda34da77d2aed01f228b47 (patch)
tree8f02e0317c9a53de26f59f64f43456f397a4724c /src/shared/Database
parentb05ebfa8e90def21baa98707a1d5e9185950de74 (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.cpp19
-rw-r--r--src/shared/Database/Database.h2
-rw-r--r--src/shared/Database/DatabaseMysql.cpp62
-rw-r--r--src/shared/Database/DatabaseMysql.h2
-rw-r--r--src/shared/Database/DatabasePostgre.cpp65
-rw-r--r--src/shared/Database/DatabasePostgre.h2
-rw-r--r--src/shared/Database/QueryResult.h56
-rw-r--r--src/shared/Database/QueryResultMysql.cpp9
-rw-r--r--src/shared/Database/QueryResultMysql.h2
-rw-r--r--src/shared/Database/QueryResultPostgre.cpp5
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()