rendered paste bodydiff --git a/dep/include/mersennetwister/MersenneTwister.h b/dep/include/mersennetwister/MersenneTwister.h
index af91931..ab8d94c 100644
--- a/dep/include/mersennetwister/MersenneTwister.h
+++ b/dep/include/mersennetwister/MersenneTwister.h
@@ -70,69 +70,69 @@ class MTRand {
// Data
public:
typedef ::uint32 uint32;
- enum { N = 624 }; // length of state vector
- enum { SAVE = N + 1 }; // length of array for save()
+ enum { N = 624 }; // length of state vector
+ enum { SAVE = N + 1 }; // length of array for save()
protected:
- enum { M = 397 }; // period parameter
-
- uint32 state[N]; // internal state
- uint32 *pNext; // next value to get from state
- int left; // number of values left before reload needed
+ enum { M = 397 }; // period parameter
+
+ uint32 state[N]; // internal state
+ uint32 *pNext; // next value to get from state
+ int left; // number of values left before reload needed
//Methods
public:
- MTRand( const uint32& oneSeed ); // initialize with a simple uint32
- MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
- MTRand(); // auto-initialize with /dev/urandom or time() and clock()
- MTRand(const MTRand&); // prevent copy constructor
- MTRand& operator=(const MTRand&); // no-op operator=
-
- // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
- // values together, otherwise the generator state can be learned after
- // reading 624 consecutive values.
-
- // Access to 32-bit random numbers
- double rand(); // real number in [0,1]
- double rand( const double& n ); // real number in [0,n]
- double randExc(); // real number in [0,1)
- double randExc( const double& n ); // real number in [0,n)
- double randDblExc(); // real number in (0,1)
- double randDblExc( const double& n ); // real number in (0,n)
- uint32 randInt(); // integer in [0,2^32-1]
- uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
- double operator()() { return rand(); } // same as rand()
-
- // Access to 53-bit random numbers (capacity of IEEE double precision)
- double rand53(); // real number in [0,1)
-
- // Access to nonuniform random number distributions
- double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
-
- // Re-seeding functions with same behavior as initializers
- void seed( const uint32 oneSeed );
- void seed( uint32 *const bigSeed, const uint32 seedLength = N );
- void seed();
-
- // Saving and loading generator state
- void save( uint32* saveArray ) const; // to array of size SAVE
- void load( uint32 *const loadArray ); // from such array
+ MTRand( const uint32& oneSeed ); // initialize with a simple uint32
+ MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
+ MTRand(); // auto-initialize with /dev/urandom or time() and clock()
+ MTRand(const MTRand&); // prevent copy constructor
+ MTRand& operator=(const MTRand&); // no-op operator=
+
+ // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
+ // values together, otherwise the generator state can be learned after
+ // reading 624 consecutive values.
+
+ // Access to 32-bit random numbers
+ double rand(); // real number in [0,1]
+ double rand( const double& n ); // real number in [0,n]
+ double randExc(); // real number in [0,1)
+ double randExc( const double& n ); // real number in [0,n)
+ double randDblExc(); // real number in (0,1)
+ double randDblExc( const double& n ); // real number in (0,n)
+ uint32 randInt(); // integer in [0,2^32-1]
+ uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
+ double operator()() { return rand(); } // same as rand()
+
+ // Access to 53-bit random numbers (capacity of IEEE double precision)
+ double rand53(); // real number in [0,1)
+
+ // Access to nonuniform random number distributions
+ double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
+
+ // Re-seeding functions with same behavior as initializers
+ void seed( const uint32 oneSeed );
+ void seed( uint32 *const bigSeed, const uint32 seedLength = N );
+ void seed();
+
+ // Saving and loading generator state
+ void save( uint32* saveArray ) const; // to array of size SAVE
+ void load( uint32 *const loadArray ); // from such array
/* Mangos not use streams for random values output
- friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
- friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
+ friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
+ friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
*/
protected:
- void initialize( const uint32 oneSeed );
- void reload();
- uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
- uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
- uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
- uint32 mixBits( const uint32& u, const uint32& v ) const
- { return hiBit(u) | loBits(v); }
- uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
- { return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); }
- static uint32 hash( time_t t, clock_t c );
+ void initialize( const uint32 oneSeed );
+ void reload();
+ uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
+ uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
+ uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
+ uint32 mixBits( const uint32& u, const uint32& v ) const
+ { return hiBit(u) | loBits(v); }
+ uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
+ { return m ^ (mixBits(s0,s1)>>1) ^ uint32(-(int32)(loBit(s1) & 0x9908b0dfUL)); }
+ static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand(const MTRand&)
@@ -142,232 +142,232 @@ inline MTRand& MTRand::operator=(const MTRand&)
{ return *this; }
inline MTRand::MTRand( const uint32& oneSeed )
- { seed(oneSeed); }
+ { seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
- { seed(bigSeed,seedLength); }
+ { seed(bigSeed,seedLength); }
inline MTRand::MTRand()
- { seed(); }
+ { seed(); }
inline double MTRand::rand()
- { return double(randInt()) * (1.0/4294967295.0); }
+ { return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
- { return rand() * n; }
+ { return rand() * n; }
inline double MTRand::randExc()
- { return double(randInt()) * (1.0/4294967296.0); }
+ { return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
- { return randExc() * n; }
+ { return randExc() * n; }
inline double MTRand::randDblExc()
- { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
+ { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
- { return randDblExc() * n; }
+ { return randDblExc() * n; }
inline double MTRand::rand53()
{
- uint32 a = randInt() >> 5, b = randInt() >> 6;
- return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
+ uint32 a = randInt() >> 5, b = randInt() >> 6;
+ return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
- // Return a real number from a normal (Gaussian) distribution with given
- // mean and variance by Box-Muller method
- double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
- double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
- return mean + r * cos(phi);
+ // Return a real number from a normal (Gaussian) distribution with given
+ // mean and variance by Box-Muller method
+ double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
+ double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
+ return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
- // Pull a 32-bit integer from the generator state
- // Every other access function simply transforms the numbers extracted here
-
- if( left == 0 ) reload();
- --left;
-
- register uint32 s1;
- s1 = *pNext++;
- s1 ^= (s1 >> 11);
- s1 ^= (s1 << 7) & 0x9d2c5680UL;
- s1 ^= (s1 << 15) & 0xefc60000UL;
- return ( s1 ^ (s1 >> 18) );
+ // Pull a 32-bit integer from the generator state
+ // Every other access function simply transforms the numbers extracted here
+
+ if( left == 0 ) reload();
+ --left;
+
+ register uint32 s1;
+ s1 = *pNext++;
+ s1 ^= (s1 >> 11);
+ s1 ^= (s1 << 7) & 0x9d2c5680UL;
+ s1 ^= (s1 << 15) & 0xefc60000UL;
+ return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
- // Find which bits are used in n
- // Optimized by Magnus Jonsson (magnus@smartelectronix.com)
- uint32 used = n;
- used |= used >> 1;
- used |= used >> 2;
- used |= used >> 4;
- used |= used >> 8;
- used |= used >> 16;
-
- // Draw numbers until one is found in [0,n]
- uint32 i;
- do
- i = randInt() & used; // toss unused bits to shorten search
- while( i > n );
- return i;
+ // Find which bits are used in n
+ // Optimized by Magnus Jonsson (magnus@smartelectronix.com)
+ uint32 used = n;
+ used |= used >> 1;
+ used |= used >> 2;
+ used |= used >> 4;
+ used |= used >> 8;
+ used |= used >> 16;
+
+ // Draw numbers until one is found in [0,n]
+ uint32 i;
+ do
+ i = randInt() & used; // toss unused bits to shorten search
+ while( i > n );
+ return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
- // Seed the generator with a simple uint32
- initialize(oneSeed);
- reload();
+ // Seed the generator with a simple uint32
+ initialize(oneSeed);
+ reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
- // Seed the generator with an array of uint32's
- // There are 2^19937-1 possible initial states. This function allows
- // all of those to be accessed by providing at least 19937 bits (with a
- // default seed length of N = 624 uint32's). Any bits above the lower 32
- // in each element are discarded.
- // Just call seed() if you want to get array from /dev/urandom
- initialize(19650218UL);
- register int i = 1;
- register uint32 j = 0;
- register int k = ( N > seedLength ? N : seedLength );
- for( ; k; --k )
- {
- state[i] =
- state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
- state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
- state[i] &= 0xffffffffUL;
- ++i; ++j;
- if( i >= N ) { state[0] = state[N-1]; i = 1; }
- if( j >= seedLength ) j = 0;
- }
- for( k = N - 1; k; --k )
- {
- state[i] =
- state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
- state[i] -= i;
- state[i] &= 0xffffffffUL;
- ++i;
- if( i >= N ) { state[0] = state[N-1]; i = 1; }
- }
- state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
- reload();
+ // Seed the generator with an array of uint32's
+ // There are 2^19937-1 possible initial states. This function allows
+ // all of those to be accessed by providing at least 19937 bits (with a
+ // default seed length of N = 624 uint32's). Any bits above the lower 32
+ // in each element are discarded.
+ // Just call seed() if you want to get array from /dev/urandom
+ initialize(19650218UL);
+ register int i = 1;
+ register uint32 j = 0;
+ register int k = ( N > seedLength ? N : seedLength );
+ for( ; k; --k )
+ {
+ state[i] =
+ state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
+ state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
+ state[i] &= 0xffffffffUL;
+ ++i; ++j;
+ if( i >= N ) { state[0] = state[N-1]; i = 1; }
+ if( j >= seedLength ) j = 0;
+ }
+ for( k = N - 1; k; --k )
+ {
+ state[i] =
+ state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
+ state[i] -= i;
+ state[i] &= 0xffffffffUL;
+ ++i;
+ if( i >= N ) { state[0] = state[N-1]; i = 1; }
+ }
+ state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
+ reload();
}
inline void MTRand::seed()
{
- // Seed the generator with hash of time() and clock() values
- seed( hash( time(NULL), clock() ) );
+ // Seed the generator with hash of time() and clock() values
+ seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
- // Initialize generator state with seed
- // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
- // In previous versions, most significant bits (MSBs) of the seed affect
- // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
- register uint32 *s = state;
- register uint32 *r = state;
- register int i = 1;
- *s++ = seed & 0xffffffffUL;
- for( ; i < N; ++i )
- {
- *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
- r++;
- }
+ // Initialize generator state with seed
+ // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
+ // In previous versions, most significant bits (MSBs) of the seed affect
+ // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
+ register uint32 *s = state;
+ register uint32 *r = state;
+ register int i = 1;
+ *s++ = seed & 0xffffffffUL;
+ for( ; i < N; ++i )
+ {
+ *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
+ r++;
+ }
}
inline void MTRand::reload()
{
- // Generate N new values in state
- // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
- register uint32 *p = state;
- register int i;
- for( i = N - M; i--; ++p )
- *p = twist( p[M], p[0], p[1] );
- for( i = M; --i; ++p )
- *p = twist( p[M-N], p[0], p[1] );
- *p = twist( p[M-N], p[0], state[0] );
-
- left = N, pNext = state;
+ // Generate N new values in state
+ // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
+ register uint32 *p = state;
+ register int i;
+ for( i = N - M; i--; ++p )
+ *p = twist( p[M], p[0], p[1] );
+ for( i = M; --i; ++p )
+ *p = twist( p[M-N], p[0], p[1] );
+ *p = twist( p[M-N], p[0], state[0] );
+
+ left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
- // Get a uint32 from t and c
- // Better than uint32(x) in case x is floating point in [0,1]
- // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
-
- static uint32 differ = 0; // guarantee time-based seeds will change
-
- uint32 h1 = 0;
- unsigned char *p = (unsigned char *) &t;
- for( size_t i = 0; i < sizeof(t); ++i )
- {
- h1 *= UCHAR_MAX + 2U;
- h1 += p[i];
- }
- uint32 h2 = 0;
- p = (unsigned char *) &c;
- for( size_t j = 0; j < sizeof(c); ++j )
- {
- h2 *= UCHAR_MAX + 2U;
- h2 += p[j];
- }
- return ( h1 + differ++ ) ^ h2;
+ // Get a uint32 from t and c
+ // Better than uint32(x) in case x is floating point in [0,1]
+ // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
+
+ static uint32 differ = 0; // guarantee time-based seeds will change
+
+ uint32 h1 = 0;
+ unsigned char *p = (unsigned char *) &t;
+ for( size_t i = 0; i < sizeof(t); ++i )
+ {
+ h1 *= UCHAR_MAX + 2U;
+ h1 += p[i];
+ }
+ uint32 h2 = 0;
+ p = (unsigned char *) &c;
+ for( size_t j = 0; j < sizeof(c); ++j )
+ {
+ h2 *= UCHAR_MAX + 2U;
+ h2 += p[j];
+ }
+ return ( h1 + differ++ ) ^ h2;
}
inline void MTRand::save( uint32* saveArray ) const
{
- register uint32 *sa = saveArray;
- register const uint32 *s = state;
- register int i = N;
- for( ; i--; *sa++ = *s++ ) {}
- *sa = left;
+ register uint32 *sa = saveArray;
+ register const uint32 *s = state;
+ register int i = N;
+ for( ; i--; *sa++ = *s++ ) {}
+ *sa = left;
}
inline void MTRand::load( uint32 *const loadArray )
{
- register uint32 *s = state;
- register uint32 *la = loadArray;
- register int i = N;
- for( ; i--; *s++ = *la++ ) {}
- left = *la;
- pNext = &state[N-left];
+ register uint32 *s = state;
+ register uint32 *la = loadArray;
+ register int i = N;
+ for( ; i--; *s++ = *la++ ) {}
+ left = *la;
+ pNext = &state[N-left];
}
/* Mangos not use streams for random values output
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
{
- register const MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
- for( ; i--; os << *s++ << "\t" ) {}
- return os << mtrand.left;
+ register const MTRand::uint32 *s = mtrand.state;
+ register int i = mtrand.N;
+ for( ; i--; os << *s++ << "\t" ) {}
+ return os << mtrand.left;
}
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
{
- register MTRand::uint32 *s = mtrand.state;
- register int i = mtrand.N;
- for( ; i--; is >> *s++ ) {}
- is >> mtrand.left;
- mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
- return is;
+ register MTRand::uint32 *s = mtrand.state;
+ register int i = mtrand.N;
+ for( ; i--; is >> *s++ ) {}
+ is >> mtrand.left;
+ mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
+ return is;
}
*/
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index ecde680..e1f0ad5 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -937,10 +937,14 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
CharacterDatabase.escape_string(newname);
- CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack, GUID_LOPART(guid), newname, "SELECT guid, at_login, name FROM characters WHERE guid = '%u' XOR name = '%s'", GUID_LOPART(guid), newname.c_str());
+ CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack,
+ GetAccountId(), newname, GUID_LOPART(guid),
+ "SELECT NULL FROM characters WHERE guid = '%d' and account = '%d' and (at_login & 1) = 1 and not exists (SELECT NULL FROM characters WHERE name = 'Timoha2')",
+ GUID_LOPART(guid), newname.c_str()
+ );
}
-void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname)
+void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname, uint32 guid_low)
{
WorldSession * session = sWorld.FindSession(accountId);
if(!session)
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 7e20ad4..eca441f 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -542,7 +542,7 @@ class MANGOS_DLL_SPEC WorldSession
void HandleSetActionBar(WorldPacket& recv_data);
void HandleChangePlayerNameOpcode(WorldPacket& recv_data);
- static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname);
+ static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname, uint32 guid_low);
void HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data);
void HandleTotemDestroy(WorldPacket& recv_data);
diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h
index a62675c..16fa0e9 100644
--- a/src/shared/Database/Database.h
+++ b/src/shared/Database/Database.h
@@ -55,27 +55,41 @@ class MANGOS_DLL_SPEC Database
QueryResult* PQuery(const char *format,...) ATTR_PRINTF(2,3);
/// Async queries and query holders, implemented in DatabaseImpl.h
+
+ // Query / member
template<class Class>
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql);
template<class Class, typename ParamType1>
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
template<class Class, typename ParamType1, typename ParamType2>
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+ template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+ // Query / static
template<typename ParamType1>
bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
template<typename ParamType1, typename ParamType2>
bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+ template<typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+ // PQuery / member
template<class Class>
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
template<class Class, typename ParamType1>
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
template<class Class, typename ParamType1, typename ParamType2>
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
+ template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(5,6);
+ // PQuery / static
template<typename ParamType1>
bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
template<typename ParamType1, typename ParamType2>
bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
+ template<typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(5,6);
template<class Class>
+ // QueryHolder
bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder);
template<class Class, typename ParamType1>
bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1);
diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h
index d3eae74..0a150b7 100644
--- a/src/shared/Database/DatabaseImpl.h
+++ b/src/shared/Database/DatabaseImpl.h
@@ -21,84 +21,100 @@
/// Function body definitions for the template function members of the Database class
+#define ASYNC_QUERY_BODY(new_sqlquery) \
+ if (!sql) return false; \
+ ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \
+ QueryQueues::iterator itr = m_queryQueues.find(queryThread); \
+ if (itr == m_queryQueues.end()) return false;
+
+#define ASYNC_PQUERY_BODY \
+ if(!format) return false; \
+ \
+ 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; \
+ }
+
+#define ASYNC_DELAYHOLDER_BODY \
+ if (!holder) return false; \
+ ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); \
+ QueryQueues::iterator itr = m_queryQueues.find(queryThread); \
+ if (itr == m_queryQueues.end()) return false;
+
+// -- Query / member --
+
template<class Class>
bool
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql)
{
- if (!sql) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
- return true;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class>(object, method), itr->second));
}
template<class Class, typename ParamType1>
bool
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
{
- if (!sql) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
- return true;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second));
}
template<class Class, typename ParamType1, typename ParamType2>
bool
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
{
- if (!sql) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
- return true;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
+}
+
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
+{
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second));
}
+// -- Query / static --
+
template<typename ParamType1>
bool
Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql)
{
- if (!sql) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
- return true;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second));
}
template<typename ParamType1, typename ParamType2>
bool
Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
{
- if (!sql) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
- return true;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
}
-template<class Class>
+template<typename ParamType1, typename ParamType2, typename ParamType3>
bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
+Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
{
- if(!format) return false;
+ ASYNC_QUERY_BODY
+ return m_threadBody->Delay(new SqlQuery(sql, new MaNGOS::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult*)NULL, param1, param2, param3), itr->second));
+}
- 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;
- }
+// -- PQuery / member --
+template<class Class>
+bool
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...)
+{
+ ASYNC_PQUERY_BODY
return AsyncQuery(object, method, szQuery);
}
@@ -106,20 +122,7 @@ template<class Class, typename ParamType1>
bool
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
{
- if(!format) return false;
-
- 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;
- }
-
+ ASYNC_PQUERY_BODY
return AsyncQuery(object, method, param1, szQuery);
}
@@ -127,41 +130,25 @@ template<class Class, typename ParamType1, typename ParamType2>
bool
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
{
- if(!format) return false;
-
- 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;
- }
-
+ ASYNC_PQUERY_BODY
return AsyncQuery(object, method, param1, param2, szQuery);
}
-template<typename ParamType1>
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
bool
-Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
{
- if(!format) return false;
+ ASYNC_PQUERY_BODY
+ return AsyncQuery(object, method, param1, param2, param3, szQuery);
+}
- 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;
- }
+// -- PQuery / static --
+template<typename ParamType1>
+bool
+Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...)
+{
+ ASYNC_PQUERY_BODY
return AsyncQuery(method, param1, szQuery);
}
@@ -169,43 +156,32 @@ template<typename ParamType1, typename ParamType2>
bool
Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
{
- if(!format) return false;
-
- 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;
- }
-
+ ASYNC_PQUERY_BODY
return AsyncQuery(method, param1, param2, szQuery);
}
+template<typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
+{
+ ASYNC_PQUERY_BODY
+ return AsyncQuery(method, param1, param2, param3, szQuery);
+}
+
+// -- QueryHolder --
+
template<class Class>
bool
Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder)
{
- if (!holder) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult*)NULL, holder), m_threadBody, itr->second);
- return true;
+ ASYNC_DELAYHOLDER_BODY
+ return holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult*)NULL, holder), m_threadBody, itr->second);
}
template<class Class, typename ParamType1>
bool
Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1)
{
- if (!holder) return false;
- ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
- QueryQueues::iterator itr = m_queryQueues.find(queryThread);
- if (itr == m_queryQueues.end()) return false;
- holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult*)NULL, holder, param1), m_threadBody, itr->second);
- return true;
+ ASYNC_DELAYHOLDER_BODY
+ return holder->Execute(new MaNGOS::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult*)NULL, holder, param1), m_threadBody, itr->second);
}
diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h
index d80098d..7d3187a 100644
--- a/src/shared/Database/SqlDelayThread.h
+++ b/src/shared/Database/SqlDelayThread.h
@@ -40,7 +40,7 @@ class SqlDelayThread : public ZThread::Runnable
SqlDelayThread(Database* db);
///< Put sql statement to delay queue
- inline void Delay(SqlOperation* sql) { m_sqlQueue.add(sql); }
+ inline bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; }
virtual void Stop(); ///< Stop event
virtual void run(); ///< Main Thread loop
diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp
index bc75c59..70a1ff0 100644
--- a/src/shared/Database/SqlOperations.cpp
+++ b/src/shared/Database/SqlOperations.cpp
@@ -79,15 +79,16 @@ void SqlResultQueue::Update()
}
}
-void SqlQueryHolder::Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
+bool SqlQueryHolder::Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
{
if(!callback || !thread || !queue)
- return;
+ return false;
/// delay the execution of the queries, sync them with the delay thread
/// which will in turn resync on execution (via the queue) and call back
SqlQueryHolderEx *holderEx = new SqlQueryHolderEx(this, callback, queue);
thread->Delay(holderEx);
+ return true;
}
bool SqlQueryHolder::SetQuery(size_t index, const char *sql)
diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h
index a5aa911..41ae69e 100644
--- a/src/shared/Database/SqlOperations.h
+++ b/src/shared/Database/SqlOperations.h
@@ -104,7 +104,7 @@ class SqlQueryHolder
void SetSize(size_t size);
QueryResult* GetResult(size_t index);
void SetResult(size_t index, QueryResult *result);
- void Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
+ bool Execute(MaNGOS::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
};
class SqlQueryHolderEx : public SqlOperation
diff --git a/win/VC90/shared.vcproj b/win/VC90/shared.vcproj
index 3254e55..5f8c07a 100644
--- a/win/VC90/shared.vcproj
+++ b/win/VC90/shared.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="shared"
ProjectGUID="{90297C34-F231-4DF4-848E-A74BCC0E40ED}"
RootNamespace="shared"
@@ -211,7 +211,7 @@
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\..\dep\include;..\..\dep\include\g3dlite;..\..\src\framework;..\..\src\shared;..\..\dep\ACE_wrappers"
- PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE"
+ PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;DO_POSTGRESQL"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
EnableFunctionLevelLinking="true"
@@ -373,6 +373,14 @@
>
</File>
<File
+ RelativePath="..\..\src\shared\Database\DatabasePostgre.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\DatabasePostgre.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\shared\Database\DatabaseSqlite.cpp"
>
</File>
@@ -393,6 +401,30 @@
>
</File>
<File
+ RelativePath="..\..\src\shared\Database\MySQLPreparedStatement.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\MySQLPreparedStatement.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\PGSQLPreparedStatement.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\PGSQLPreparedStatement.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\PreparedStatement.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\PreparedStatement.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\shared\Database\QueryResult.h"
>
</File>
@@ -405,6 +437,14 @@
>
</File>
<File
+ RelativePath="..\..\src\shared\Database\QueryResultPostgre.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\shared\Database\QueryResultPostgre.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\shared\Database\QueryResultSqlite.cpp"
>
</File>