// Include
#include "sqlaccountstmt.h"

// Local definitions

// Global data

// cSQLAccountStmt Constructor.
cSQLAccountStmt::cSQLAccountStmt(void)
{
}

// ~cSQLAccountStmt Destructor.
cSQLAccountStmt::~cSQLAccountStmt(void)
{
}

// MatrixCreate Method.
// GP_MATRIX_CREATE.SQL 파일참조.
//   @MAX_SERVER  [smallint]    --최대 서버번호
//   @MAX_CHANNEL [smallint]    --최대 채널번호
SQLRETURN cSQLAccountStmt::MatrixCreate(MATRIX_CREATE* matrixCreate)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_MATRIX_CREATE(?, ?, ?)}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &matrixCreate->maxServer,  0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &matrixCreate->maxChannel, 0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &matrixCreate->retvalue,   0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}

// ServerList Method.
//  GP_SERVER_LIST.SQL 파일참조.
SQLRETURN cSQLAccountStmt::ServerList(SERVER_LIST* serverList, u_long& cbLength)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_SERVER_LIST}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLExecDirect( mHstmt, statement, SQL_NTS );

	if ( SQL_SUCCEEDED( retcode ) )
	{
		TB_SERVER* table     = serverList->table;
		SQLINTEGER tableSize = sizeof(serverList->table);

		SQLINTEGER nameSize  = sizeof(table->name);
		SQLINTEGER cbName    = 0;

		SQLINTEGER descSize  = sizeof(table->description);
		SQLINTEGER cbDesc    = 0;

		while ( (retcode = SQLFetch( mHstmt )) == SQL_SUCCESS )
		{
			SQLGetData( mHstmt, 0x01, SQL_C_SLONG,   &table->idx,        0,        &(strLenOrInd=0) );
			SQLGetData( mHstmt, 0x02, SQL_C_WCHAR,   table->name,        nameSize, &cbName          );
			SQLGetData( mHstmt, 0x03, SQL_C_WCHAR,   table->description, descSize, &cbDesc          );
			SQLGetData( mHstmt, 0x04, SQL_C_TINYINT, &table->status,     0,        &(strLenOrInd=0) );
			table++;

			serverList->rowCount++;
			cbLength += tableSize;
		}

		// 저장프로시저 쿼리 마무리.
		while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

		// 열려있는 결과 닫기. (Close the open result set.)
		SQLCloseCursor( mHstmt );
	}
	return SQL_SUCCESS;
}

// ChannelUpdate Method.
//  GP_CHANNEL_UPDATE.SQL 파일참조.
//   @SERVER_NUM  [smallint]  --서버번호
//   @CHANNEL_NUM [smallint]  --채널번호
//   @STATUS      [tinyint]   --상태(0원활/1보통/2혼잡)
//   @RETVALUE    [int]OUTPUT --반환값
SQLRETURN cSQLAccountStmt::ChannelUpdate(CHANNEL_UPDATE* channelUpdate)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_CHANNEL_UPDATE(?, ?, ?, ?)}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT,  SQL_C_SLONG,   SQL_INTEGER, 0, 0, &channelUpdate->serverNum,  0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x2, SQL_PARAM_INPUT,  SQL_C_SLONG,   SQL_INTEGER, 0, 0, &channelUpdate->channelNum, 0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x3, SQL_PARAM_INPUT,  SQL_C_TINYINT, SQL_TINYINT, 0, 0, &channelUpdate->status,     0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x4, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0, 0, &channelUpdate->retvalue,   0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}

// ConcurrentUser Method.
// GP_CONCURRENT_USER.SQL 파일참조.
SQLRETURN cSQLAccountStmt::ConcurrentUser(CONCURRENT_USER* concurrentUser)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_CONCURRENT_USER(?, ?)}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER, 0, 0, &concurrentUser->serverIdx, 0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x2, SQL_PARAM_OUTPUT, SQL_C_SLONG,  SQL_INTEGER, 0, 0, &concurrentUser->value,     0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}

// ServerDown Method.
// GP_SERVERDOWN.SQL 파일참조.
//   @SERVER_NUM  [smallint]  --서버번호
//   @CHANNEL_NUM [smallint]  --채널번호
SQLRETURN cSQLAccountStmt::ServerDown(SERVER_DOWN* serverDown)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_SERVERDOWN(?, ?)}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &serverDown->serverNum,  0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &serverDown->channelNum, 0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}

// MemberLogin Method
// GP_MEMBER_LOGIN.SQL 파일참조.
//   @MEMBER_IDX       [int]OUTPUT   --고유번호 - 회원 테이블
//   @LOGON_IDX        [int]OUTPUT   --고유번호 - 로그 테이블
//   @LOGINID          [varchar](16) --사용자 계정(ID)
//   @PASSWORD         [varchar](16) --암호
//   @INETNUM          [varchar](20) --IP주소(IPv4)
//   @LAST_SERVER_NUM  [int]OUTPUT   --서버번호(마지막 접속)
//   @LAST_CHANNEL_NUM [int]OUTPUT   --채널번호(마지막 접속)
//   @RETVALUE         [int]OUTPUT   --반환값
SQLRETURN cSQLAccountStmt::MemberLogin(MEMBER_LOGIN* memberLogin)
{
	SQLCHAR*     statement = (SQLCHAR*)"{call GP_MEMBER_LOGIN(?, ?, ?, ?, ?, ?, ?, ?, ?)}";
	SQLINTEGER   strLenOrInd;
	SQLRETURN    retcode;
	SQLUSMALLINT param;

	long       loginidLen  = (long)sizeof( memberLogin->loginid );
	long       cbLoginid   = SQL_NTS;
	long       passwordLen = (long)sizeof( memberLogin->password );
	long       cbPassword  = SQL_NTS;
	long       inetnumLen  = (long)sizeof( memberLogin->inetnum );
	long       cbInetnum   = SQL_NTS;

	retcode = SQLBindParameter( mHstmt, param=1, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0,  0, &memberLogin->memberIdx,      0,           &(strLenOrInd=0) );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0,  0, &memberLogin->loginIdx,       0,           &(strLenOrInd=0) );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_CHAR,    SQL_VARCHAR, 16, 0, memberLogin->loginid,         loginidLen,  &cbLoginid       );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_CHAR,    SQL_VARCHAR, 16, 0, memberLogin->password,        passwordLen, &cbPassword      );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_CHAR,    SQL_VARCHAR, 20, 0, memberLogin->inetnum,         inetnumLen,  &cbInetnum       );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0,  0, &memberLogin->lastServerNum,  0,           &(strLenOrInd=0) );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0,  0, &memberLogin->lastChannelNum, 0,           &(strLenOrInd=0) );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_TINYINT, SQL_TINYINT, 0,  0, &memberLogin->slevel,         0,           &(strLenOrInd=0) );
	retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,   SQL_INTEGER, 0,  0, &memberLogin->retvalue,       0,           &(strLenOrInd=0) );
	retcode = SQLExecDirect( mHstmt, statement, SQL_NTS );

	if ( SQL_SUCCEEDED( retcode ) )
	{
		// 저장프로시저 쿼리 마무리.
		while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

		// 열려있는 결과 닫기. (Close the open result set.)
		SQLCloseCursor( mHstmt );
	}

	return retcode;
}

// MemberLogout Method
// GP_MEMBER_LOGOUT.SQL 파일참조.
//   @LOGIN_IDX   [int]       --고유번호 - 로그 테이블
//   @MEMBER_IDX  [int]       --고유번호 - 회원 테이블
//   @RETVALUE    [int]OUTPUT --반환값
SQLRETURN cSQLAccountStmt::MemberLogout(MEMBER_LOGOUT* memberLogout)
{
	SQLCHAR*   statement = (SQLCHAR*)"{call GP_MEMBER_LOGOUT(?, ?, ?)}";
	SQLINTEGER strLenOrInd;
	SQLRETURN  retcode;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &memberLogout->loginIdx,  0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &memberLogout->memberIdx, 0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, 0x3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &memberLogout->retvalue,  0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}

// ComeinGame Method.
// GP_COMEIN_GAME.SQL 파일참조.
SQLRETURN cSQLAccountStmt::ComeinGame(COMEIN_GAME* comeinGame)
{
	SQLCHAR*     statement = (SQLCHAR*)"{call GP_COMEIN_GAME(?, ?, ?, ?, ?, ?, ?, ?, ?)}";
	SQLINTEGER   strLenOrInd;
	SQLRETURN    retcode;
	SQLUSMALLINT param;

	retcode = SQLPrepare( mHstmt, statement, SQL_NTS );
	if ( SQL_SUCCEEDED( retcode ) )
	{
		retcode = SQLBindParameter( mHstmt, param=1, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->loginIdx,       0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->serverNum,      0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->channelNum,     0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->lastChannel,    0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->characterIdx,   0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_INPUT,  SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->instantDungeon, 0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->ipv4,           0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_SMALLINT, 0,  0, &comeinGame->port,           0, &(strLenOrInd=0) );
		retcode = SQLBindParameter( mHstmt, ++param, SQL_PARAM_OUTPUT, SQL_C_SLONG,  SQL_INTEGER,  0,  0, &comeinGame->retvalue,       0, &(strLenOrInd=0) );
		retcode = SQLExecute( mHstmt );

		if ( SQL_SUCCEEDED( retcode ) )
		{
			// 저장프로시저 쿼리 마무리.
			while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS );

			// 열려있는 결과 닫기. (Close the open result set.)
			SQLCloseCursor( mHstmt );
		}
	}

	return retcode;
}
