Register for your free account! | Forgot your password?

You last visited: Today at 09:23

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Release]DBInstance. :)

Discussion on [Release]DBInstance. :) within the Flyff PServer Guides & Releases forum part of the Flyff Private Server category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
[Release]DBInstance. :)

Bla, da ich n abgang schieb, geb ich euch noch paar dinge, davon ist eins die DBInstance wo von mir überarbeitet worden ist, sollte euren DB Server noch etwas ankurbeln, sofern ihr wisst wie man es einsetzt.

DBInstance.cpp:

Code:
#include "StdAfx.h"
#include "DBInstance.h"

CDBInstance::CDBInstance()
{
	m_hStmt	= NULL;
	m_hDbc	= NULL;
	m_hEnv	= NULL;

	for( byte i = 0; i < MAXCOL; i++ )
	{
		m_szCol[i] = new char[4192];
		memset( m_szCol[i], 0, 4192);
	}
}

CDBInstance::~CDBInstance()
{
	Disconnect();

	for( byte i = 0; i < MAXCOL; i++ )
		delete [] ( m_szCol[i] );
}

void CDBInstance::Disconnect()
{
	Clear();
	SQLFreeHandle(SQL_HANDLE_STMT, m_hStmt );

	SQLDisconnect( m_hDbc );
	SQLFreeHandle(SQL_HANDLE_DBC, m_hDbc );
	SQLFreeHandle(SQL_HANDLE_ENV, m_hEnv );
}

void CDBInstance::Clear()
{
	SQLCloseCursor( m_hStmt );
	SQLFreeStmt( m_hStmt, SQL_UNBIND );
}

bool CDBInstance::Connect( _In_ char* szDBName, _In_ char* szLogin, _In_ char* szDBPass )
{
	SQLAllocHandle( SQL_HANDLE_ENV,SQL_NULL_HANDLE, &m_hEnv );
	SQLSetEnvAttr( m_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, SQL_IS_INTEGER );

	SQLAllocHandle( SQL_HANDLE_DBC, m_hEnv, &m_hDbc );

	SQLSetConnectAttr(m_hDbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
	if(!SQL_SUCCEEDED( SQLConnect( m_hDbc, (SQLCHAR*)szDBName, SQL_NTS, (SQLCHAR*)szLogin, SQL_NTS, (SQLCHAR*)szDBPass, SQL_NTS ) ))
	{
		Error( "(ERROR) %s(%d): Can't connect to Database!! [%s]", __FUNCTION__, __LINE__, szDBName );
		return false;
	}

	SQLAllocHandle( SQL_HANDLE_STMT, m_hDbc, &m_hStmt );
	return true;
}

bool CDBInstance::BindParameter( _In_ SQLUSMALLINT parameterNumber, _In_ SQLSMALLINT inputOutputType, _In_ SQLSMALLINT valueType, _In_ SQLSMALLINT parameterType, _In_ SQLUINTEGER columnSize, _In_ SQLSMALLINT decimalDigits, _In_ SQLPOINTER  parameterValuePtr, _In_ SQLINTEGER bufferLength, _In_ SQLINTEGER *strLen_or_IndPtr )
{
	return SQL_SUCCEEDED( SQLBindParameter( m_hStmt, parameterNumber, inputOutputType, valueType, parameterType, columnSize, decimalDigits, parameterValuePtr, bufferLength, strLen_or_IndPtr ) );
}

void CDBInstance::PrepareFetch()
{
	SQLNumResultCols( m_hStmt, &m_nCol );

	SWORD	nActualLen		= NULL;
	SWORD	m_nSQLType		= NULL;
	UDWORD	m_nPrecision	= NULL;
	SWORD	m_nScale		= NULL;
	SWORD	m_nNullability	= NULL;

	for( short i = 0; i < m_nCol; i++ ) 
	{
		if( !SQL_SUCCEEDED( SQLBindCol( m_hStmt, i+1, SQL_C_CHAR, m_szCol[i], 8192, &m_nColLength[i] ) ) )
			Error( "(ERROR) %s(%d): Bin col failed. [%d]", __FUNCTION__, __LINE__, i );
		if( !SQL_SUCCEEDED( SQLDescribeCol( m_hStmt, i+1, m_szColName[i], 16, &nActualLen, &m_nSQLType, &m_nPrecision, &m_nScale, &m_nNullability ) ) )
			Error( "(ERROR) %s(%d): Bin describe failed. [%d]", __FUNCTION__, __LINE__, i );
	}
}

void CDBInstance::Execute( _In_ char* szFormat, _In_ ... )
{
	char szBuffer[1024] = { NULL };

	va_list arg;
	va_start( arg, szFormat );
	int nLength = vsnprintf_s( szBuffer, 1024, szFormat, arg );
	va_end(arg);

	Clear();

	if( !SQL_SUCCEEDED( SQLExecDirect( m_hStmt, (SQLCHAR*)szBuffer, nLength ) ) )
	{
		Error( "(ERROR) %s(%d): Query execute failed. [%d][ %s ]", __FUNCTION__, __LINE__, nLength, szBuffer );
		return;
	}

	PrepareFetch();
}

short CDBInstance::FindCol( _In_ char* szName )
{
	for( short i = NULL; i < m_nCol; i++ ) 
	{
		if ( strcmp( szName, (char*)m_szColName[i] ) == 0 )
			return i + 1;
	}

	__debugbreak();
	return -1;
}
DBInstance.h:

Code:
#pragma once

#define MAXCOL		128

#include <sql.h>
#include <sqlext.h>

class CDBInstance
{
public:
	CDBInstance();
	virtual ~CDBInstance();
	inline void Clear();

	bool Connect( _In_ char* szDBName, _In_ char* szLogin, _In_ char* szDBPass );
	void Disconnect();

	void Execute( _In_ char* szFormat, _In_ ... );
	bool BindParameter( _In_ SQLUSMALLINT parameterNumber, _In_ SQLSMALLINT inputOutputType, _In_ SQLSMALLINT valueType, _In_ SQLSMALLINT parameterType, _In_ SQLUINTEGER columnSize, _In_ SQLSMALLINT decimalDigits, _In_ SQLPOINTER  parameterValuePtr, _In_ SQLINTEGER bufferLength, _In_ SQLINTEGER *strLen_or_IndPtr );

	inline bool Fetch()		{ return SQL_SUCCEEDED( SQLFetch( m_hStmt ) ); }
private:
	void			PrepareFetch();	
public:
	inline	byte	GetByte( _In_ char* szColumn )		{ return atoi( m_szCol[FindCol(szColumn)-1] ); }
	inline	double	GetDouble( _In_ char* szColumn )	{ return atof( m_szCol[FindCol(szColumn)-1] ); }
	inline	int		GetInt( _In_ char* szColumn )		{ return atoi( m_szCol[FindCol(szColumn)-1] ); }
	inline	__int64	GetInt64( _In_ char* szColumn )		{ return _atoi64( m_szCol[FindCol(szColumn)-1] ); }
	inline	float	GetFloat( _In_ char* szColumn )		{ return (float)atof( m_szCol[FindCol(szColumn)-1] ); }
	inline	char	GetChar( _In_ char* szColumn )		{ return m_szCol[FindCol(szColumn)-1][0]; }
private:
	SQLHENV		m_hEnv;
	SQLHDBC		m_hDbc;
	SQLHSTMT	m_hStmt;

	char*		m_szCol[MAXCOL];
	SQLCHAR		m_szColName[MAXCOL][32];
	SQLINTEGER	m_nColLength[MAXCOL];

	SQLSMALLINT m_nCol;

	short FindCol( _In_ char* szName );
};
Wie gesagt, ihr müsst nur wissen wie ihr es einsetzt, ich werde es euch nicht verraten.

Credits: Crasy, Clemi.

Mfg.
Wanetrain is offline  
Thanks
5 Users
Old 07/29/2013, 13:14   #2
 
elite*gold: 0
Join Date: Jan 2008
Posts: 52
Received Thanks: 58
So und einmal die "richtige" version:

Code:
#include "StdAfx.h"
#include "Query.h"

CQuery::CQuery()
{
	ZeroMemory( this, sizeof( CQuery ) );

	for( byte i = 0; i < MAXCOL; i++ )
	{
		m_szCol[ i ] = new char[8192];
		ZeroMemory( m_szCol, 8192 );
	}
}

CQuery::~CQuery()
{
	Disconnect();

	for( byte i = 0; i < MAXCOL; i++ )
		delete [] m_szCol[ i ];
}

void CQuery::Disconnect()
{
	Clear();
	SQLFreeHandle( SQL_HANDLE_STMT, m_hStmt );

	SQLDisconnect( m_hDbc );
	SQLFreeHandle( SQL_HANDLE_DBC, m_hDbc );
	SQLFreeHandle( SQL_HANDLE_ENV, m_hEnv );
}

void CQuery::Clear()
{
	SQLCloseCursor( m_hStmt );
	SQLFreeStmt( m_hStmt, SQL_UNBIND );
}

bool CQuery::Connect( _In_ const char* szDBName, _In_ const char* szLogin, _In_ const char* szDBPass )
{
	SQLAllocHandle( SQL_HANDLE_ENV,SQL_NULL_HANDLE, &m_hEnv );
	SQLSetEnvAttr( m_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, SQL_IS_INTEGER );

	SQLAllocHandle( SQL_HANDLE_DBC, m_hEnv, &m_hDbc );

	SQLSetConnectAttr(m_hDbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
	if(!SQL_SUCCEEDED( SQLConnect( m_hDbc, (SQLCHAR*)szDBName, SQL_NTS, (SQLCHAR*)szLogin, SQL_NTS, (SQLCHAR*)szDBPass, SQL_NTS ) ))
	{
		Error( "(ERROR) %s(%d): Can't connect to Database!! [%s]", __FUNCTION__, __LINE__, szDBName );
		return false;
	}

	return SQL_SUCCEEDED( SQLAllocHandle( SQL_HANDLE_STMT, m_hDbc, &m_hStmt ) );
}

void CQuery::Execute( _In_ const char* szBuff )
{
	Clear();

	int nLen = strlen( szBuff );
	if( !SQL_SUCCEEDED( SQLExecDirect( m_hStmt, (SQLCHAR*)szBuff, nLen ) ) )
	{
		Error( "(ERROR) %s(%d): Query execute failed. [%d][ %s ]", __FUNCTION__, __LINE__, nLen, szBuff );
		return;
	}

	PrepareFetch();
}

void CQuery::Execute( _In_ const char* szBuff, _In_ int nLen )
{
	Clear();

	if( !SQL_SUCCEEDED( SQLExecDirect( m_hStmt, (SQLCHAR*)szBuff, nLen ) ) )
	{
		Error( "(ERROR) %s(%d): Query execute failed. [%d][ %s ]", __FUNCTION__, __LINE__, nLen, szBuff );
		return;
	}

	PrepareFetch();
}

void CQuery::Execute( _In_ const char* szFormat, _In_opt_ ... )
{
	char szBuffer[1024] = { NULL };

	va_list arg;
	va_start( arg, szFormat );
	int nLength = vsnprintf_s( szBuffer, 1024, szFormat, arg );
	va_end(arg);

	Clear();

	if( !SQL_SUCCEEDED( SQLExecDirect( m_hStmt, (SQLCHAR*)szBuffer, nLength ) ) )
	{
		Error( "(ERROR) %s(%d): Query execute failed. [%d][ %s ]", __FUNCTION__, __LINE__, nLength, szBuffer );
		return;
	}

	PrepareFetch();
}

void CQuery::PrepareFetch()
{
	SQLNumResultCols( m_hStmt, &m_nCol );

	SWORD	nActualLen		= 0;
	SWORD	m_nSQLType		= 0;
	UDWORD	m_nPrecision	= 0;
	SWORD	m_nScale		= 0;
	SWORD	m_nNullability	= 0;

	for( short i = 0; i < m_nCol; i++ ) 
	{
		if( !SQL_SUCCEEDED( SQLBindCol( m_hStmt, i+1, SQL_C_CHAR, m_szCol[i], 8192, &m_nColLength[i] ) ) ||
			!SQL_SUCCEEDED( SQLDescribeCol( m_hStmt, i+1, m_szColName[i], 16, &nActualLen, &m_nSQLType, &m_nPrecision, &m_nScale, &m_nNullability ) ) )
			Error( "(ERROR) %s(%d): failed. [%d]", __FUNCTION__, __LINE__, i );
	}
}
Code:
#pragma once


#include <sql.h>
#include <sqlext.h>

#define MAXCOL 256

static inline bool EnableConnectionPooling()	{	return SQL_SUCCEEDED( SQLSetEnvAttr( NULL, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER)SQL_CP_ONE_PER_DRIVER, SQL_IS_INTEGER ) ); 	}

class CQuery
{
public:
	CQuery();
	~CQuery();

private:
	void Clear();
	void Disconnect();
	void PrepareFetch();

public:
	bool Connect( _In_ const char* szDBName, _In_ const char* szLogin, _In_ const char* szDBPass );

	void Execute( _In_ const char* szBuff );
	void Execute( _In_ const char* szBuff, _In_ int nLen );
	void Execute( _In_ const char* szFormat, _In_opt_ ... );

private:
	inline bool		BindParameter( _In_ SQLUSMALLINT iPar, _In_ SQLSMALLINT fParam, _In_ SQLSMALLINT val, _In_ SQLSMALLINT param, _In_ SQLUINTEGER col, _In_ SQLSMALLINT digits, _In_ SQLPOINTER  valPtr, _In_ SQLINTEGER len, _In_ SQLINTEGER* ptr )
	{	return SQL_SUCCEEDED( SQLBindParameter( m_hStmt, iPar, fParam, val, param, col, digits, valPtr, len, ptr ) );	}
	
	inline bool		Fetch()		{ return SQL_SUCCEEDED( SQLFetch( m_hStmt ) ); }
	inline short	FindCol( _In_ const char* szName )
	{
		for( short i = 0; i < m_nCol; i++ ) 
		{
			if( strcmp( szName, (char*)m_szColName[ i ] ) == 0 )
				return i;
		}

		Error( "(ERROR) %s(%d): Cannot find col [%s]", __FUNCTION__, __LINE__, szName );

		__debugbreak();
		return 0;
	}


public:
	inline EXPINTEGER	GetExpInteger( const char* szCol )			{	return GetInt64( szCol ); 	}
	inline SERIALNUMBER	GetSerialNumber( const char* szCol )		{	return GetInt( szCol );		}

	inline	char		GetChar( _In_ const char* szCol )			{	return *m_szCol[ FindCol( szCol ) ];				}
	inline	byte		GetByte( _In_ const char* szCol )			{	return atoi( m_szCol[ FindCol( szCol) ] );			}
	inline	int			GetInt( _In_ const char* szCol )			{	return atoi( m_szCol[ FindCol( szCol ) ] );			}
	inline	__int64		GetInt64( _In_ const char* szCol )			{	return _atoi64( m_szCol[ FindCol( szCol ) ] );		}
	inline	float		GetFloat( _In_ const char* szCol )			{	return (float)atof( m_szCol[ FindCol( szCol ) ] );	}
	inline	double		GetDouble( _In_ const char* szCol )			{	return atof( m_szCol[ FindCol( szCol ) ] );			}


private:
	SQLHENV		m_hEnv;
	SQLHDBC		m_hDbc;
	char*		m_szCol[MAXCOL];

	SQLHSTMT	m_hStmt;
	SQLSMALLINT m_nCol;
	SQLCHAR		m_szColName[MAXCOL][50];
	SQLINTEGER	m_nColLength[MAXCOL];
};
Lg, Clemi
cletite is offline  
Thanks
6 Users
Old 07/29/2013, 13:26   #3
 
elite*gold: 0
Join Date: Jul 2013
Posts: 23
Received Thanks: 6
Was muss man damit machen?
DieLachnummer is offline  
Old 07/29/2013, 13:46   #4
 
elite*gold: 0
Join Date: Jul 2013
Posts: 24
Received Thanks: 5
Quote:
Originally Posted by Wanetrain View Post
Wie gesagt, ihr müsst nur wissen wie ihr es einsetzt, ich werde es euch nicht verraten.
Lesen dann weißt du das er keinen Support gibt.
Uloure is offline  
Old 07/29/2013, 13:49   #5

 
elite*gold: 142
Join Date: Apr 2010
Posts: 859
Received Thanks: 428
:3 Nice - kannte ich ja schon durch Erzählung
Wenn man eben weis wie es einzusetzen ist, sehr geil.


Greetz,
Cross


Sent via Tapatalk 2
©ross is offline  
Old 11/14/2013, 09:09   #6
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
Little Update.

Da mir zu ohren gekommen ist es sei ein Fehler drin hab ich dass ganze nochmal mit einer Privaten "Version" abgeglichen und ja, es ist wirklich ein Fehler bei "GetChar" drin, einfach Replacen mit:

Quote:
inline char* GetChar( _In_ char* szColumn ) { return m_szCol[FindCol(szColumn)]; }
Dann ist euer Fehler auch schon weg.
Wanetrain is offline  
Old 11/14/2013, 13:12   #7
 
elite*gold: 0
Join Date: Nov 2013
Posts: 124
Received Thanks: 115
what does the purpose of this?
Rhyder' is offline  
Old 11/14/2013, 14:10   #8
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
Quote:
Originally Posted by Rhyder' View Post
what does the purpose of this?
Still more performance for DB Server.^^
Wanetrain is offline  
Old 11/14/2013, 15:53   #9
 
elite*gold: 59
Join Date: Oct 2012
Posts: 716
Received Thanks: 465
Ja, eher nutzlos, da man die meisten server eh kein 500+ user haben und alle die es haben haben auch hardware die stark genug ist.
FlyCraft.TobiLap is offline  
Old 11/14/2013, 22:56   #10
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
Quote:
Originally Posted by FlyCraft.TobiLap View Post
Ja, eher nutzlos, da man die meisten server eh kein 500+ user haben und alle die es haben haben auch hardware die stark genug ist.
Ich denke du hast relativ wenig Ahnung von dem hier, oder? wenn am nes ordentlich verbaut kann man einfach mal dass Character Speichern anstat alle 15min einfach mal auf min. 5min runter drücken, dass macht dann weniger Schaden bei einem Server absturz, also von dem her.

zzgl. schafft man es Deutlich schneller Querys durch zu ballern als davor, somit ist es auch schneller ein ganzen Character zu laden.
Wanetrain is offline  
Old 11/14/2013, 23:46   #11
 
elite*gold: 0
Join Date: Nov 2013
Posts: 124
Received Thanks: 115
Quote:
Originally Posted by Wanetrain View Post
Still more performance for DB Server.^^
when i add this to my dbserver it gives a lot of errors :O
Rhyder' is offline  
Old 11/15/2013, 05:09   #12
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
Quote:
Originally Posted by Rhyder' View Post
tutorial to work this? it gives a lot of errors :O
I work on a tutorial for you.
Wanetrain is offline  
Old 11/15/2013, 11:38   #13



 
Sedrika's Avatar
 
elite*gold: 18
The Black Market: 103/0/0
Join Date: Sep 2009
Posts: 20,174
Received Thanks: 14,475
Ich sehe nicht, wieso deine Klasse hier besser sein soll als das was bereits im Source steht?
Sedrika is offline  
Old 11/15/2013, 12:05   #14
 
elite*gold: 0
Join Date: Apr 2013
Posts: 511
Received Thanks: 431
Die klasse ist in sofern besser weil es großteils Inline ist, sehr viele unnütze Abfragen weg lässt und man sie ohne Probleme in Threads einbauen kann, aber hey, verstehst ja hier bei den ePVP leuten am meisten, also erzähl mal was.
Wanetrain is offline  
Old 11/15/2013, 12:23   #15



 
Sedrika's Avatar
 
elite*gold: 18
The Black Market: 103/0/0
Join Date: Sep 2009
Posts: 20,174
Received Thanks: 14,475
Welche unnötigen Abfragen hast du denn entfernt, wenn du sagst, dass du welche entfernt hast. Zudem ist der einzige vorteil von Inline, dass diese keinen Aufruf mehr braucht. Die 1ms kann man sich sparen.
Sedrika is offline  
Thanks
1 User
Reply




All times are GMT +1. The time now is 09:23.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.