#ifdef ALLCLUB_MODULE
#define _FEDSRV_PCH_ #endif
#include "pch.h"
#if !defined(ALLSRV_STANDALONE)
#include <sql.h>
#include <sqlext.h>
SQLHENV hSqlEnv = 0; SQLHDBC hSqlDbc = 0; SQLHSTMT g_rghstmt[CSTATEMENTS];
SQLCHAR * g_rgscstmt[CSTATEMENTS];
SQLSMALLINT * g_rgssiColType[CSTATEMENTS];
SQLSMALLINT * g_rgssiParmType[CSTATEMENTS];
int g_iSql = 0; \
int g_iCol = 0; \
int g_iParm = 0;
TRef<ISQLSite> g_pSQLSite;
bool g_fSQLRetry = false;
int g_cSQLRetries = 0;
SQLHSTMT g_hstmt_Last = 0;
void SQLWhatsWrong(SQLSMALLINT ssiHandleType, SQLHANDLE sh)
{
SQLCHAR scState[5];
SQLINTEGER siNativeError;
SQLCHAR scMsgText[512];
SQLSMALLINT cbMsgText;
SQLRETURN sqlret = SQLGetDiagRec(ssiHandleType, sh, 1, scState, &siNativeError,
scMsgText, sizeof(scMsgText), &cbMsgText);
ZDebugOutput((char *) scMsgText);
if (7312 == siNativeError)
return;
if (1205 == siNativeError)
{
debugf("Query deadlocked. Retry #%d.", g_cSQLRetries);
g_fSQLRetry = true;
g_cSQLRetries++;
SQLCloseCursor(g_hstmt_Last); Sleep(50 * g_cSQLRetries);
return;
}
if(g_pSQLSite) g_pSQLSite->OnMessageBox((char *) scMsgText, "FedSrv SQL Error", MB_OK | MB_ICONINFORMATION);
else
{
debugf("SQL Error %s\n", scMsgText);
printf("SQL Error %s\n", scMsgText);
}
assert(0); exit(EXIT_FAILURE);
}
SQLHSTMT AddStatement(SQLCHAR * scSQL)
{
if (g_iSql >= CSTATEMENTS)
{
OutputDebugString("Too many SQL statements. Increment CSTATEMENTS\n");
DebugBreak();
exit(0);
}
SQLRETURN sqlret;
sqlret = SQLAllocHandle(SQL_HANDLE_STMT, hSqlDbc, &g_rghstmt[g_iSql]);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_STMT, g_rghstmt[g_iSql]);
sqlret = SQLPrepare(g_rghstmt[g_iSql], scSQL, SQL_NTS);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_STMT, g_rghstmt[g_iSql]);
g_iCol = 0;
g_iParm = 0;
return g_rghstmt[g_iSql++];
}
int AddCol(void * pvBuff, SQLSMALLINT ssiCType, SQLPARM parmtype, int cbBuff)
{
SQLRETURN sqlret;
static SQLINTEGER cbWhoCares;
switch (parmtype)
{
case SQL_OUT_PARM:
sqlret = SQLBindCol(g_rghstmt[g_iSql - 1], ++g_iCol, ssiCType, pvBuff,
cbBuff, &cbWhoCares);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_STMT, g_rghstmt[g_iSql - 1]);
break;
case SQL_IN_PARM:
sqlret = SQLBindParameter(g_rghstmt[g_iSql - 1], ++g_iParm, SQL_PARAM_INPUT,
ssiCType, ssiCType, cbBuff, 0, pvBuff, cbBuff, NULL);
break;
case SQL_OUT_PROC: sqlret = SQLBindParameter(g_rghstmt[g_iSql - 1], ++g_iParm, SQL_PARAM_OUTPUT,
ssiCType, ssiCType, cbBuff, 0, pvBuff, cbBuff, &cbWhoCares);
break;
case SQL_INOUT_PROC: sqlret = SQLBindParameter(g_rghstmt[g_iSql - 1], ++g_iParm, SQL_PARAM_INPUT_OUTPUT,
ssiCType, ssiCType, cbBuff, 0, pvBuff, cbBuff, &cbWhoCares);
break;
}
return 0;
}
char* ParseCommandLine (char * szRegKey, char* szParameterName, char* szDefault = 0)
{
static char szBuffer[64];
LPTSTR szCommandLine = GetCommandLine ();
char* location = strstr (szCommandLine, szParameterName);
szBuffer[0] = 0;
if (location)
{
location += strlen (szParameterName);
assert (*location == '=');
location++;
char* szBufferPtr = szBuffer;
while (!isspace (*location))
*szBufferPtr++ = *location++;
*szBufferPtr = 0;
}
else if (szDefault)
{
strcpy (szBuffer, szDefault);
}
else
{
HKEY hKey;
DWORD dw;
DWORD cb = sizeof(szBuffer);
if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_READ, &hKey))
RegQueryValueEx (hKey, szParameterName, NULL, &dw, (LPBYTE)szBuffer, &cb);
RegCloseKey(hKey);
}
return szBuffer;
}
int InitSql(char * szRegKey, ISQLSite * pSQLSite)
{
g_pSQLSite = pSQLSite;
SQLRETURN sqlret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hSqlEnv);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_ENV, hSqlEnv);
sqlret = SQLSetEnvAttr(hSqlEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC2, 0);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_ENV, hSqlEnv);
sqlret = SQLAllocHandle(SQL_HANDLE_DBC, hSqlEnv, &hSqlDbc);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_DBC, hSqlDbc);
#if 0
SQLCHAR StrConnectionOut[1<<10];
SQLSMALLINT cbStrConnectionOut;
sqlret = SQLDriverConnect(hSqlDbc, NULL, (SQLCHAR*)
"DRIVER={SQL Server};SERVER=FEDSRV", SQL_NTS,
StrConnectionOut, sizeof(StrConnectionOut),
&cbStrConnectionOut, SQL_DRIVER_NOPROMPT);
#else
char szUser[64];
char szPW[64];
char szDatabase[64];
strcpy (szUser, ParseCommandLine (szRegKey, "SQLUser"));
strcpy (szPW, ParseCommandLine (szRegKey, "SQLPW"));
strcpy (szDatabase, ParseCommandLine (szRegKey, "SQLSrc", "Federation"));
printf (" Connecting to DSN (%s) as user (%s) with password (%s)...\n", szDatabase, szUser, szPW);
sqlret = SQLConnect(hSqlDbc, (SQLCHAR*) szDatabase, SQL_NTS, (SQLCHAR*) szUser, SQL_NTS, (SQLCHAR*) szPW, SQL_NTS);
#endif
if (SQL_SUCCESS != sqlret && SQL_SUCCESS_WITH_INFO != sqlret)
SQLWhatsWrong(SQL_HANDLE_DBC, hSqlDbc);
SQLCHAR scODBCver[6];
SQLSMALLINT cbODBCver;
sqlret = SQLGetInfo(hSqlDbc, SQL_DRIVER_ODBC_VER, scODBCver, sizeof(scODBCver), &cbODBCver);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_DBC, hSqlDbc);
return 0;
}
void ShutDownSQL()
{
int iHStmt;
for (iHStmt = 0; iHStmt < g_iSql; iHStmt++)
SQLFreeHandle(SQL_HANDLE_STMT, g_rghstmt[g_iSql]);
SQLDisconnect(hSqlDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hSqlDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hSqlEnv);
}
SQLRETURN SqlGo(SQLHSTMT hstmt)
{
SQLRETURN sqlret;
static CTempTimer tt("in SqlGo", .05f);
tt.Start();
if (g_hstmt_Last)
SQLCloseCursor(g_hstmt_Last); g_hstmt_Last = hstmt;
g_fSQLRetry = false;
g_cSQLRetries = 0;
do
{
sqlret = SQLExecute(hstmt);
if (SQL_SUCCESS != sqlret)
SQLWhatsWrong(SQL_HANDLE_STMT, hstmt);
} while (g_fSQLRetry);
tt.Stop();
return sqlret;
}
SQLRETURN SqlGetRow(SQLHSTMT hstmt)
{
SQLRETURN sqlret;
static CTempTimer tt("in SqlGetRow", .01f);
tt.Start();
sqlret = SQLFetch(hstmt);
if (SQL_SUCCESS != sqlret && SQL_NO_DATA != sqlret)
SQLWhatsWrong(SQL_HANDLE_STMT, hstmt);
tt.Stop();
return sqlret;
}
void SqlStrCpy(char * szDest, SQLCHAR * szSrc, unsigned int cbSrc)
{
if ('~' == szSrc[0] && '\0'== szSrc[1]) *szDest = '\0';
else
CopyMemory(szDest, szSrc, cbSrc);
}
#endif