From 4535d38cc9564047571bda8f91331c1a732d46d7 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 17 Feb 2012 23:54:27 -0800 Subject: [PATCH] Kill pnSqlLib. --- Sources/Plasma/NucleusLib/CMakeLists.txt | 1 - Sources/Plasma/NucleusLib/pnSqlLib/Intern.h | 51 - Sources/Plasma/NucleusLib/pnSqlLib/Pch.h | 62 - .../pnSqlLib/Private/pnSqlAllIncludes.h | 55 - .../NucleusLib/pnSqlLib/Private/pnSqlConn.cpp | 1439 ----------------- .../NucleusLib/pnSqlLib/Private/pnSqlConn.h | 308 ---- .../NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp | 196 --- .../NucleusLib/pnSqlLib/Private/pnSqlUtil.h | 86 - Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h | 59 - 9 files changed, 2257 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Intern.h delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Pch.h delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h delete mode 100644 Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h diff --git a/Sources/Plasma/NucleusLib/CMakeLists.txt b/Sources/Plasma/NucleusLib/CMakeLists.txt index 5f4d5698..336bbfae 100644 --- a/Sources/Plasma/NucleusLib/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/CMakeLists.txt @@ -25,7 +25,6 @@ add_subdirectory(pnNetProtocol) add_subdirectory(pnProduct) add_subdirectory(pnSceneObject) add_subdirectory(pnSimpleNet) -#add_subdirectory(pnSqlLib) # Not being used in any current sln add_subdirectory(pnTimer) add_subdirectory(pnUtils) add_subdirectory(pnUtilsExe) diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h b/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h deleted file mode 100644 index ea716d7f..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h +++ /dev/null @@ -1,51 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_INTERN_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Intern.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_INTERN_H diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h b/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h deleted file mode 100644 index 548b0f5e..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h +++ /dev/null @@ -1,62 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PCH_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Pch.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PCH_H - -#include "pnUtils/pnUtils.h" -#include "pnNetBase/pnNetBase.h" -#include "pnAsyncCore/pnAsyncCore.h" - -// Include ODBC API -#include -#include - -#include "Private/pnSqlAllIncludes.h" -#include "Intern.h" diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h b/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h deleted file mode 100644 index e528a84b..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h +++ /dev/null @@ -1,55 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLALLINCLUDES_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlAllIncludes.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLALLINCLUDES_H - - -#include "pnSqlConn.h" -#include "pnSqlUtil.h" diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.cpp b/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.cpp deleted file mode 100644 index 164bcfa1..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.cpp +++ /dev/null @@ -1,1439 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.cpp -* -***/ - -#include "../Pch.h" -#pragma hdrstop - -//#define LOG_SQL_STMTS -//#define ODBC_TRACING -#define ORACLE_FREE_DRIVER - - -/***************************************************************************** -* -* Private -* -***/ - -static unsigned kConnectionTaskCount = 10; -static unsigned kCheckDeadTaskCount = 5; - -static unsigned kLoginTimeoutSecs = 30; -static unsigned kConnectionTimeoutSecs = 60; - -struct SqlState { - SQLCHAR buffer[6]; -}; - -struct SqlStmtHash { - FSqlBindPrepare prepare; - - SqlStmtHash (); - SqlStmtHash (FSqlBindPrepare prepare); - uint32_t GetHash () const; - bool operator== (const SqlStmtHash & rhs) const; -}; - -static const unsigned kStmtFlagBindColMode = 1<<0; -static const unsigned kStmtFlagBindParamMode = 1<<1; -static const unsigned kStmtFlagDriverConnected = 1<<2; -static const unsigned kStmtFlagDelete = 1<<3; -static const unsigned kStmtFlagReset = 1<<4; - -struct SqlStmt : SqlStmtHash { - HASHLINK(SqlStmt) hashLink; - LINK(SqlStmt) listLink; - SqlConn * conn; - SQLHDBC hdbc; - SQLHSTMT hstmt; - unsigned flags; - int bindCol; - int bindParam; - FSqlConnErrorHandler errHandler; - void * errHandlerParam; - unsigned sequence; - unsigned timeoutSecs; - uint8_t * data; - wchar_t debug[128]; - - SqlStmt (SqlConn * conn); - ~SqlStmt (); - SqlStmt & operator= (const SqlStmt &); // not impl. - bool Initialize (const wchar_t connectStr[]); - void Reset (); - bool QueryDead (unsigned method); -}; - -static const unsigned kConnFlagInvalid = 1<<0; - -struct SqlConn { - CCritSect critsect; - SQLHENV henv; - unsigned flags; - unsigned desiredConns; - unsigned currentConns; - unsigned connectTasks; - unsigned checkDeadTasks; - unsigned sequence; - unsigned timeoutSecs; - AsyncThreadTaskList * taskList; - wchar_t * connectStr; - - LISTDECL( - SqlStmt, - listLink - ) stmts; - - HASHTABLEDECL( - SqlStmt, - SqlStmtHash, - hashLink - ) freeStmts; - - SqlConn ( - const wchar_t connectStr[], - SQLHENV henv - ); - ~SqlConn (); - - bool GrowConnections_CS (unsigned attempts); - void AsyncGrowConnections_CS (); - - void CheckDead_CS (); - void AsyncCheckDead_CS (); -}; - - -/***************************************************************************** -* -* Private data -* -***/ - -static long s_perf[kSqlConnNumPerf]; - - -/***************************************************************************** -* -* Logging -* -***/ - -//============================================================================ -static bool EnumDiagRec ( - SQLSMALLINT handleType, - SQLHANDLE handle, - unsigned index, - unsigned code, - SQLSMALLINT destChars, - SQLCHAR dest[], - SQLINTEGER * native, - SqlState * state -) { - SQLSMALLINT msgLen; - int result = SQLGetDiagRec( - handleType, - handle, - (SQLSMALLINT) index, - state->buffer, - native, - dest, - destChars, - &msgLen - ); - - if (result == SQL_NO_DATA) - return false; - - if (!SQL_SUCCEEDED(result)) { - LogMsg(kLogError, "Sql(%u) %d, DiagRec", code, result); - return false; - } - - return true; -} - -//============================================================================ -static void LogErr ( - int result, - SQLSMALLINT handleType, - SQLHANDLE handle, - const wchar_t function[], - const wchar_t command[] -) { - if (SQL_SUCCEEDED(result) && result != SQL_SUCCESS_WITH_INFO) - return; - if (result == SQL_NEED_DATA) - return; - if (result == SQL_NO_DATA) - return; - - static long s_code = 1; - long code = AtomicAdd(&s_code, 1); - ELogSeverity severity = result == SQL_SUCCESS_WITH_INFO ? kLogPerf : kLogError; - LogMsg(severity, "Sql(%u) %d, %S, %S", code, result, function, command); - - for (int index = 1;; ++index) { - // Get next message - SqlState state; - SQLINTEGER native; - SQLCHAR msgStr[512]; - const bool indexValid = EnumDiagRec( - handleType, - handle, - index, - code, - arrsize(msgStr), - msgStr, - &native, - &state - ); - if (!indexValid) - break; - - LogMsg(severity, " Sql(%u) %d, %s, %s", code, native, state.buffer, msgStr); - } -} - -//============================================================================ -static void LogStmtError ( - int result, - SqlStmt * stmt, - const wchar_t function[] -) { - if (result == SQL_SUCCESS) - return; - if (result == SQL_NEED_DATA) - return; - if (result == SQL_NO_DATA) - return; - - // Once a statement has an error, it is possible for it to get "wedged"; - // so reset the statement after this transaction to make it happy. - stmt->flags |= kStmtFlagReset; - - // Get any diagnostics from SQL - ARRAY(char) diagRecs; - for (int index = 1;; ++index) { - // Get next message - SqlState state; - SQLINTEGER native; - SQLCHAR msgStr[512]; - const bool indexValid = EnumDiagRec( - SQL_HANDLE_STMT, - stmt->hstmt, - index, - 0, - arrsize(msgStr), - msgStr, - &native, - &state - ); - - if (!indexValid) - break; - - diagRecs.Add((const char *)msgStr, StrLen((const char *) msgStr) + 1); - } - diagRecs.Add(L'\0'); - - // If the statement doesn't have a handler, handle it the default way - if (!stmt->errHandler) { - LogErr(result, SQL_HANDLE_STMT, stmt->hstmt, function, stmt->debug); - return; - } - - // Send the error to the statement's handler - stmt->errHandler( - result, - function, - stmt->debug, - diagRecs.Ptr(), - stmt->errHandlerParam - ); -} - - -/***************************************************************************** -* -* SqlStmtHash -* -***/ - -//============================================================================ -inline SqlStmtHash::SqlStmtHash () -: prepare(nil) -{} - -//============================================================================ -inline SqlStmtHash::SqlStmtHash (FSqlBindPrepare prepare) -: prepare(prepare) -{} - -//============================================================================ -inline uint32_t SqlStmtHash::GetHash () const { - return (uint32_t) prepare; -} - -//============================================================================ -inline bool SqlStmtHash::operator== (const SqlStmtHash & rhs) const { - return prepare == rhs.prepare; -} - - -/***************************************************************************** -* -* SqlStmt -* -***/ - -//============================================================================ -SqlStmt::SqlStmt (SqlConn * conn) -: conn(conn) -, hdbc(nil) -, hstmt(nil) -, flags(0) -, bindCol(0) -, bindParam(0) -, timeoutSecs(0) -, data(nil) -, errHandler(nil) -, errHandlerParam(nil) -{ - debug[0] = 0; - - if (conn) { - // This is a real statement, so add it to the statement count - ++conn->currentConns; - sequence = conn->sequence; - } - else { - // This statement is a list marker object - sequence = 0; - } -} - -//============================================================================ -SqlStmt::~SqlStmt () { - int result; - - Reset(); - - if (hstmt) { - result = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); - LogStmtError(result, this, L"SQLFreeHandle"); - AtomicAdd(&s_perf[kSqlConnPerfConnCurrent], -1); - } - - if (flags & kStmtFlagDriverConnected) { - ASSERT(hdbc); - result = SQLDisconnect(hdbc); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLDisconnect", debug); - } - - if (hdbc) { - result = SQLFreeHandle(SQL_HANDLE_DBC, hdbc); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLFreeHandle", debug); - } - - if (conn) - --conn->currentConns; -} - -//============================================================================ -bool SqlStmt::Initialize (const wchar_t connectStr[]) { - ASSERT(!hdbc); - - for (;;) { - // Allocate connection handle - int result; - result = SQLAllocHandle( - SQL_HANDLE_DBC, - conn->henv, - &hdbc - ); - LogErr(result, SQL_HANDLE_ENV, conn->henv, L"SQLAllocHandle(dbc)", debug); - if (!SQL_SUCCEEDED(result)) - break; - - // Set login timeout - /* -- Crashes EasySoft Oracle driver - -- Not supported by Oracle's driver - result = SQLSetConnectAttr( - hdbc, - SQL_ATTR_LOGIN_TIMEOUT, - (SQLPOINTER) &kLoginTimeoutSecs, - SQL_IS_UINTEGER - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLSetConnectAttr(loginTimeout)", debug); - if (!SQL_SUCCEEDED(result)) - break; - */ - -#ifdef ODBC_TRACING - result = SQLSetConnectAttr( - hdbc, - SQL_ATTR_TRACEFILE, - "odbc.log", - SQL_NTS - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLSetConnectAttr(tracefile)", debug); - result = SQLSetConnectAttr( - hdbc, - SQL_ATTR_TRACE, - (SQLPOINTER) SQL_OPT_TRACE_ON, - SQL_IS_INTEGER - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLSetConnectAttr(trace)", debug); -#endif - - /* -- Crashes EasySoft Oracle driver - -- Not supported by Oracle's driver - result = SQLSetConnectAttr( - hdbc, - SQL_ATTR_CONNECTION_TIMEOUT, - (SQLPOINTER) &kConnectionTimeoutSecs, - SQL_IS_UINTEGER - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLSetConnectAttr(connectTimeout)", debug); - if (!SQL_SUCCEEDED(result)) - break; - */ - - // Perform driver connection - SQLWCHAR outConnectStr[1024]; - SQLSMALLINT outConnectLen; - result = SQLDriverConnectW( - hdbc, - (HWND) nil, - (SQLWCHAR *) connectStr, - SQL_NTS, - outConnectStr, - (SQLSMALLINT) arrsize(outConnectStr), - &outConnectLen, - SQL_DRIVER_NOPROMPT - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLDriverConnect()", debug); - if (!SQL_SUCCEEDED(result)) - break; - flags |= kStmtFlagDriverConnected; - - // Create statement for connection - result = SQLAllocHandle( - SQL_HANDLE_STMT, - hdbc, - &hstmt - ); - LogStmtError(result, this, L"SQLAllocHandle(stmt)"); - if (!SQL_SUCCEEDED(result)) { - ASSERT(!hstmt); - break; - } - - // Success! - AtomicAdd(&s_perf[kSqlConnPerfConnCurrent], 1); - return true; - } - - // Failure! - return false; -} - -//============================================================================ -void SqlStmt::Reset () { - flags &= ~kStmtFlagReset; - prepare = nil; - - SqlConnBindColReset(this); - SqlConnBindParameterReset(this); - - #ifdef ORACLE_FREE_DRIVER - { // Oracle's driver can't handle cached stmts, so blow it all away. - int result; - - // Destroy old statement - if (hstmt) { - result = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); - LogStmtError(result, this, L"SQLFreeHandle"); - } - - // Create new statement - result = SQLAllocHandle( - SQL_HANDLE_STMT, - hdbc, - &hstmt - ); - LogStmtError(result, this, L"SQLAllocHandle(stmt)"); - if (!SQL_SUCCEEDED(result)) - ASSERT(!hstmt); - } - #endif // ORACLE_FREE_DRIVER - - free(data); - data = nil; - debug[0] = 0; -} - -//============================================================================ -bool SqlStmt::QueryDead (unsigned method) { - SQLUINTEGER dead; - int result = SQLGetConnectAttr( - hdbc, - method, - &dead, - SQL_IS_UINTEGER, - nil - ); - LogErr(result, SQL_HANDLE_DBC, hdbc, L"SQLGetConnectAttr(dead)", debug); - if (!SQL_SUCCEEDED(result)) - return false; - - return dead == SQL_CD_TRUE; -} - - -/***************************************************************************** -* -* StmtConn -* -***/ - -//============================================================================ -SqlConn::SqlConn ( - const wchar_t connectStr[], - SQLHENV henv -) : henv(henv) -, flags(0) -, desiredConns(0) -, currentConns(0) -, connectTasks(0) -, checkDeadTasks(0) -, sequence(0) -, timeoutSecs(0) -, connectStr(StrDup(connectStr)) -, taskList(AsyncThreadTaskListCreate()) -{} - -//=========================================================================== -SqlConn::~SqlConn () { - ASSERT(!freeStmts.Head()); - ASSERT(!stmts.Head()); - delete connectStr; - SQLFreeHandle(SQL_HANDLE_ENV, henv); - AsyncThreadTaskListDestroy(taskList, kNetErrRemoteShutdown); - AtomicAdd(&s_perf[kSqlConnPerfConnDesired], - (long) desiredConns); -} - - -/**************************************************************************** -* -* Connection management functions -* -***/ - -//============================================================================ -bool SqlConn::GrowConnections_CS (unsigned attempts) { - for (unsigned i = 0; i < attempts; ++i) { - // If the maximum number of connections has been reached then bail - if (currentConns >= desiredConns) - break; - - // If the server decided to shut down then bail - if (flags & kConnFlagInvalid) - break; - - // Leave the critical section to perform connection - SqlStmt * stmt = new SqlStmt(this); - - // Ensure that the connection string is valid - // for the duration of the initialization by - // creating a reference to the string. - critsect.Leave(); - bool result = stmt->Initialize(connectStr); - critsect.Enter(); - - // If the connection failed then bail - if (!result) { - delete stmt; - return false; - } - - // Add new connection to free list - freeStmts.Add(stmt); - stmts.Link(stmt); - } - - // Return true only if all connection attempts were successful - return true; -} - -//============================================================================ -static void SqlConnConnectCallback (void * param, ENetError error) { - SqlConn & conn = * (SqlConn *) param; - - AtomicAdd(&s_perf[kSqlConnPerfConnPending], 1); - conn.critsect.Enter(); - { - if (!error) - conn.GrowConnections_CS((unsigned) -1); - conn.connectTasks -= 1; - } - conn.critsect.Leave(); - AtomicAdd(&s_perf[kSqlConnPerfConnPending], -1); -} - -//============================================================================ -void SqlConn::AsyncGrowConnections_CS () { - // If the conn structure is being destroyed - // then it cannot initiate any new connections - if (flags & kConnFlagInvalid) - return; - - // How many additional tasks need to be started in - // order to reach the desired number of connections? - unsigned tasks = desiredConns - currentConns - connectTasks; - if ((int) tasks <= 0) - return; - - // Set upper bound on connection tasks - if (connectTasks + tasks > kConnectionTaskCount) - tasks = kConnectionTaskCount - connectTasks; - - // Initiate connection tasks - connectTasks += tasks; - for (unsigned i = 0; i < tasks; ++i) { - AsyncThreadTaskAdd( - taskList, - SqlConnConnectCallback, - this, - L"pnSqlConn.SqlConn::AsyncGrowConnections_CS" - ); - } -} - - -/**************************************************************************** -* -* CheckDead management functions -* -***/ - -//============================================================================ -void SqlConn::CheckDead_CS () { - // Use a list-position marker to allow this function to - // safely walk through the linked list even though it - // leaves the critical section. - SqlStmt marker(nil); - stmts.Link(&marker, kListHead); - while (SqlStmt * stmt = marker.listLink.Next()) { - // Move the marker to the next location - stmts.Link(&marker, kListLinkAfter, stmt); - - // The statement can't be used if either: - // - it is in use - // - it is a marker - if (!stmt->hashLink.IsLinked()) - continue; - - // If the statement has already been processed during - // this generation then do not process it again - if ((int) (sequence - stmt->sequence) <= 0) - continue; - - // Prevent this statement from being used during check - stmt->sequence = sequence; - stmt->hashLink.Unlink(); - - // Leave the critical section to check connection - critsect.Leave(); - bool dead = stmt->QueryDead(SQL_ATTR_CONNECTION_DEAD); - critsect.Enter(); - - // Deallocate the statement if it's bogus - if (dead) { - delete stmt; - AsyncGrowConnections_CS(); - } - else { - freeStmts.Add(stmt); - } - - // If the server decided to shut down then bail - if (flags & kConnFlagInvalid) - break; - } -} - -//============================================================================ -static void SqlConnCheckDeadCallback (void * param, ENetError error) { - SqlConn & conn = * (SqlConn *) param; - - AtomicAdd(&s_perf[kSqlConnPerfConnCheckDead], 1); - conn.critsect.Enter(); - { - if (!error) - conn.CheckDead_CS(); - conn.checkDeadTasks -= 1; - } - conn.critsect.Leave(); - AtomicAdd(&s_perf[kSqlConnPerfConnCheckDead], -1); -} - -//============================================================================ -void SqlConn::AsyncCheckDead_CS () { - // Don't start new checking tasks while there are others outstanding - if (checkDeadTasks) - return; - - // Start the next generation of check-dead tasks - ++sequence; - checkDeadTasks = kCheckDeadTaskCount; - for (unsigned i = 0; i < kCheckDeadTaskCount; ++i) { - AsyncThreadTaskAdd( - taskList, - SqlConnCheckDeadCallback, - this, - L"pnSqlConn.SqlConn::AsyncCheckDead_CS" - ); - } -} - - -/***************************************************************************** -* -* Exports -* -***/ - -//============================================================================ -SqlConn * SqlConnCreate ( - const wchar_t connectStr[], - unsigned maxConnections, - unsigned transTimeoutSeconds -) { - ASSERT(connectStr); - ASSERT(maxConnections); - - /* Connection pooling not needed because connections - are held for the entire duration of the program. - SQLSetEnvAttr( - nil, - SQL_ATTR_CONNECTION_POOLING, - (SQLPOINTER) SQL_CP_ONE_PER_DRIVER, - SQL_IS_INTEGER - ); - */ - - // Allocate environment - SQLHENV henv; - int result = SQLAllocHandle( - SQL_HANDLE_ENV, - SQL_NULL_HANDLE, - &henv - ); - LogErr(result, SQL_HANDLE_ENV, henv, L"SQLAllocHandle(env)", L""); - if (!SQL_SUCCEEDED(result)) - return nil; - - // Set ODBC version - result = SQLSetEnvAttr( - henv, - SQL_ATTR_ODBC_VERSION, - (SQLPOINTER) SQL_OV_ODBC3, - 0 - ); - LogErr(result, SQL_HANDLE_ENV, henv, L"SQLSetEnvAttr(version)", L""); - - // Allocate a connection record - SqlConn * conn = new SqlConn(connectStr, henv); - - // Update configuration options - conn->critsect.Enter(); - { - // Update timeout - conn->timeoutSecs = transTimeoutSeconds; - - // Update connection count - int delta = (int) (maxConnections - conn->desiredConns); - AtomicAdd(&s_perf[kSqlConnPerfConnDesired], delta); - conn->desiredConns += delta; - - // Create more connections - conn->AsyncGrowConnections_CS(); - } - conn->critsect.Leave(); - - return conn; -} - -//============================================================================ -void SqlConnShutdown (SqlConn * conn) { - conn->critsect.Enter(); - { - conn->flags |= kConnFlagInvalid; - SqlStmt * stmt = conn->stmts.Head(); - for (; stmt; stmt = conn->stmts.Next(stmt)) - SQLCancel(stmt->hstmt); - } - conn->critsect.Leave(); -} - -//============================================================================ -void SqlConnDestroy (SqlConn * conn) { - for (;; AsyncSleep(1)) { - - bool wait; - conn->critsect.Enter(); - { - // Signal shutdown - conn->flags |= kConnFlagInvalid; - - // Delete free and disconnected statements - conn->freeStmts.Clear(); - - // Wait until tasks are complete and statements have been destroyed - wait = conn->currentConns || conn->connectTasks || conn->checkDeadTasks; - } - conn->critsect.Leave(); - if (wait) - continue; - - // Complete! - break; - } - - delete conn; -} - -//============================================================================ -void SqlConnFreeStmt (SqlStmt * stmt) { - ASSERT(stmt); - ASSERT(stmt->listLink.IsLinked()); - ASSERT(!stmt->hashLink.IsLinked()); - - SqlConnCloseCursor(stmt); - - #ifdef ORACLE_FREE_DRIVER - { // Oracle's driver can't handle cached stmts, so blow it all away. - stmt->flags |= kStmtFlagReset; - } - #endif // ORACLE_FREE_DRIVER - - // If this statement was used for an ad hoc query - // then it can't be cached, so reset the bindings - if (!stmt->prepare || (stmt->flags & kStmtFlagReset)) - stmt->Reset(); - - bool dead = (stmt->flags & kStmtFlagDelete) || stmt->QueryDead(SQL_ATTR_CONNECTION_DEAD); - SqlConn * conn = stmt->conn; - conn->critsect.Enter(); - { - if (stmt->flags & kStmtFlagDelete) { - delete stmt; - conn->AsyncGrowConnections_CS(); - } - else if (dead) { - delete stmt; - conn->AsyncCheckDead_CS(); - } - else { - conn->freeStmts.Add(stmt); - } - } - conn->critsect.Leave(); -} - -//============================================================================ -void SqlStmtSetAttr ( - SqlStmt * stmt, - int attr, - void * valPtr, - int strLen -) { - ASSERT(stmt); - ASSERT(!stmt->prepare); - int result = SQLSetStmtAttr( - stmt->hstmt, - (SQLINTEGER)attr, - (SQLPOINTER)valPtr, - (SQLINTEGER)strLen - ); - LogErr(result, SQL_HANDLE_STMT, stmt->hstmt, L"SQLSetStmtAttr", nil); -} - - -//============================================================================ -SqlStmt * SqlConnAllocStmt (SqlConn * conn) { - return SqlConnAllocStmt(conn, nil, nil); -} - -//============================================================================ -SqlStmt * SqlConnAllocStmt ( - SqlConn * conn, - FSqlBindPrepare prepare, - uint8_t ** bindData // [OUT] -) { - ASSERT(prepare || !bindData); - if (!conn) - return nil; - - SqlStmt * stmt; - FSqlBindPrepare reset = nil; - FSqlBindPrepare cached = prepare; - unsigned timeoutSeconds = 0; - conn->critsect.Enter(); - { - // Get the transaction timeout value - timeoutSeconds = conn->timeoutSecs; - - for (;;) { - // Is the server permanently dead? - if (conn->flags & kConnFlagInvalid) { - prepare = nil; - stmt = nil; - break; - } - - // If there is already a cached statement that has - // been prepared with the same data then recycle it - if (prepare && (nil != (stmt = conn->freeStmts.Find(SqlStmtHash(prepare))))) { - *bindData = stmt->data; - prepare = nil; - conn->freeStmts.Unlink(stmt); - break; - } - - // If there is a statement that hasn't been prepared then use it now - if (nil != (stmt = conn->freeStmts.Find(SqlStmtHash(nil)))) { - ASSERT(!stmt->data); - conn->freeStmts.Unlink(stmt); - break; - } - - // Take the least recently used item from the table and reinitialize - if (nil != (stmt = conn->freeStmts.Head())) { - ASSERT(stmt->prepare); - ASSERT(stmt->data); - reset = stmt->prepare; - conn->freeStmts.Unlink(stmt); - break; - } - - if (conn->desiredConns == conn->currentConns) { - // Since there aren't enough statements on the free list, - // allocate new connections to the server. Since this is - // a very time-consuming operation, and it means that there - // isn't a surplus of connections for caching (more connections - // than threads, so that statements can be cached), this is a - // very serious error. - LogMsg(kLogError, "SqlConn: no free statements"); - AtomicAdd(&s_perf[kSqlConnPerfConnDesired], 50); - conn->desiredConns += 50; - } - - // Don't allow too many threads to be performing connection tasks - // so that this module doesn't starve the rest of the system - bool result = conn->connectTasks < kConnectionTaskCount; - if (result) { - // There is a crash bug where when the first connection to the - // server is allocated and then immediately used, but it occurs - // on the second use of the statement. I have no idea why this - // bug occurs. - ++conn->connectTasks; - conn->AsyncGrowConnections_CS(); - result = conn->GrowConnections_CS(5); - --conn->connectTasks; - } - - // Did the connection attempt fail? - if (!result) { - prepare = nil; - stmt = nil; - break; - } - } - - // If at any time there aren't connections then create more of them! - if (stmt && (conn->desiredConns != conn->currentConns)) - conn->AsyncGrowConnections_CS(); - } - conn->critsect.Leave(); - - // If no statement could be allocated then bail - if (!stmt) - return nil; - - // Ensure that statement was removed from the free list - ASSERT(!stmt->hashLink.IsLinked()); - - if (reset) { - stmt->Reset(); - } - - if (stmt->timeoutSecs != timeoutSeconds) { - stmt->timeoutSecs = timeoutSeconds; - int result = SQLSetConnectAttr( - stmt->hdbc, - SQL_ATTR_QUERY_TIMEOUT, - (SQLPOINTER) timeoutSeconds, - SQL_IS_UINTEGER - ); - LogErr(result, SQL_HANDLE_DBC, stmt->hdbc, L"SQLSetConnectAttr(queryTimeout)", stmt->debug); - } - - if (prepare) { - ARRAY(uint8_t) data; - prepare(stmt, &data); - stmt->prepare = prepare; - stmt->data = data.Detach(); - *bindData = stmt->data; - AtomicAdd(&s_perf[kSqlConnPerfCacheMisses], 1); - } - else if (cached) { - AtomicAdd(&s_perf[kSqlConnPerfCacheHits], 1); - } - - return stmt; -} - -//============================================================================ -void SqlConnSetErrorHandler ( - SqlStmt * stmt, - FSqlConnErrorHandler handler, - void * userParam -) { - stmt->errHandler = handler; - stmt->errHandlerParam = userParam; -} - -//============================================================================ -void SqlConnBindColReset (SqlStmt * stmt) { - ASSERT(!stmt->prepare); - - if (stmt->bindCol) { - SQLFreeStmt(stmt->hstmt, SQL_UNBIND); - stmt->bindCol = 0; - } - - if (stmt->flags & kStmtFlagBindColMode) { - SqlConnBindColMode( - stmt, - nil, // rowCountPtr - 0, // structSize - 1, // arraySize - nil // statusArrayPtr - ); - stmt->flags &= ~kStmtFlagBindColMode; - } -} - -//============================================================================ -void SqlConnBindColMode ( - SqlStmt * stmt, - SQLUINTEGER * rowCount, // SQL_ATTR_ROWS_FETCHED_PTR - SQLUINTEGER structSize, // SQL_ATTR_ROW_BIND_TYPE - SQLUINTEGER arraySize, // SQL_ATTR_ROW_ARRAY_SIZE - SQLUSMALLINT * statusArray // SQL_ATTR_ROW_STATUS_PTR -) { - ASSERT(!stmt->prepare); - - // Bind mode set to non-default value, so it - // must be reset before statement is re-used - stmt->flags |= kStmtFlagBindColMode; - - // Set rowCount - int result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_ROWS_FETCHED_PTR, rowCount, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set row/col binding - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER) structSize, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set number of elements in parameter arrays - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) arraySize, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set status array - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_ROW_STATUS_PTR, statusArray, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); -} - -//============================================================================ -void SqlConnBindCol ( - SqlStmt * stmt, - SQLINTEGER targetType, - SQLPOINTER targetValue, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -) { - ASSERT(!stmt->prepare); - - int result = SQLBindCol( - stmt->hstmt, - (SQLUSMALLINT) ++stmt->bindCol, - (SQLSMALLINT) targetType, - targetValue, - bufferLength, - indPtr - ); - LogStmtError(result, stmt, L"SQLBindCol"); -} - -//============================================================================ -void SqlConnBindParameterReset (SqlStmt * stmt) { - ASSERT(!stmt->prepare); - - if (stmt->bindParam) { - SQLFreeStmt(stmt->hstmt, SQL_RESET_PARAMS); - stmt->bindParam = 0; - } - - if (stmt->flags & kStmtFlagBindParamMode) { - SqlConnBindParameterMode( - stmt, - nil, // processCountPtr - 0, // structSize - 1, // arraySize - nil // statusArrayPtr - ); - stmt->flags &= ~kStmtFlagBindParamMode; - } - -} - -//============================================================================ -void SqlConnBindParameterMode ( - SqlStmt * stmt, - SQLUINTEGER * processCount, // SQL_ATTR_PARAMS_PROCESSED_PTR - SQLUINTEGER structSize, // SQL_ATTR_PARAM_BIND_TYPE - SQLUINTEGER arraySize, // SQL_ATTR_PARAMSET_SIZE - SQLUSMALLINT * statusArray // SQL_ATTR_PARAM_STATUS_PTR -) { - ASSERT(!stmt->prepare); - - // Bind mode set to non-default value, so it - // must be reset before statement is re-used - stmt->flags |= kStmtFlagBindParamMode; - - // Set processCount - int result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, processCount, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set row/col binding - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_PARAM_BIND_TYPE, (SQLPOINTER) structSize, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set number of elements in parameter arrays - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) arraySize, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); - - // Set status array - result = SQLSetStmtAttr(stmt->hstmt, SQL_ATTR_PARAM_STATUS_PTR, statusArray, 0); - LogStmtError(result, stmt, L"SQLSetStmtAttr"); -} - -//============================================================================ -void SqlConnBindParameter ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLINTEGER valueType, - SQLINTEGER parameterType, - SQLUINTEGER columnSize, - SQLINTEGER decimalDigits, - SQLPOINTER parameterValuePtr, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -) { - ASSERT(!stmt->prepare); - int result = SQLBindParameter( - stmt->hstmt, - (SQLUSMALLINT) ++stmt->bindParam, - (SQLSMALLINT) inputOutputType, - (SQLSMALLINT) valueType, - (SQLSMALLINT) parameterType, - columnSize, - (SQLSMALLINT) decimalDigits, - parameterValuePtr, - bufferLength, - indPtr - ); - LogStmtError(result, stmt, L"SQLBindParameter"); -} - -//============================================================================ -void SqlConnBindParameterInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLINTEGER * parameterValuePtr, - SQLINTEGER * indPtr -) { - SqlConnBindParameter( - stmt, - inputOutputType, - SQL_C_LONG, - SQL_INTEGER, - 0, - 0, - parameterValuePtr, - 0, - indPtr - ); -} - -//============================================================================ -void SqlConnBindParameterUInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER * parameterValuePtr, - SQLINTEGER * indPtr -) { - SqlConnBindParameter( - stmt, - inputOutputType, - SQL_C_ULONG, - SQL_INTEGER, - 0, - 0, - parameterValuePtr, - 0, - indPtr - ); -} - -//============================================================================ -void SqlConnBindParameterString ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER columnSize, // bytes, NOT chars - SQLWCHAR * parameterValuePtr, - SQLINTEGER * indPtr -) { - SqlConnBindParameter( - stmt, - inputOutputType, - SQL_C_WCHAR, - SQL_WVARCHAR, - columnSize, - 0, - parameterValuePtr, - inputOutputType == SQL_PARAM_OUTPUT ? columnSize : 0, - indPtr - ); -} - -//============================================================================ -void SqlConnBindParameterStringA ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER columnSize, // bytes, NOT chars - SQLCHAR * parameterValuePtr, - SQLINTEGER * indPtr -) { - SqlConnBindParameter( - stmt, - inputOutputType, - SQL_C_CHAR, - SQL_VARCHAR, - columnSize, - 0, - parameterValuePtr, - inputOutputType == SQL_PARAM_OUTPUT ? columnSize : 0, - indPtr - ); -} - -//============================================================================ -int SqlConnExecDirect ( - SqlStmt * stmt, - const wchar_t string[] -) { - #ifdef LOG_SQL_STMTS - LogMsg(kLogDebug, L"SQL: %s", string); - #endif - StrCopy(stmt->debug, string, arrsize(stmt->debug)); - int result = SQLExecDirectW(stmt->hstmt, const_cast(string), SQL_NTS); - LogStmtError(result, stmt, L"SqlExecute"); - return result; -} - -//============================================================================ -int SqlConnPrepare ( - SqlStmt * stmt, - const wchar_t string[] -) { - // Using {call ...} or {?= call ...} with SqlPrepare doesn't allow - // the ODBC expression parser to perform escape sequence fixup for - // return value and output parameters; to call stored procedures, - // use SqlConnExecDirect instead - #ifdef HS_DEBUGGING - ASSERT(string[0] != L'{'); - #endif - - StrCopy(stmt->debug, string, arrsize(stmt->debug)); - int result = SQLPrepareW(stmt->hstmt, const_cast(string), SQL_NTS); - LogStmtError(result, stmt, L"SqlPrepare"); - return result; -} - -//============================================================================ -int SqlConnExecute (SqlStmt * stmt) { - int result = SQLExecute(stmt->hstmt); - LogStmtError(result, stmt, L"SQLExecute"); - return result; -} - -//============================================================================ -int SqlConnFetch (SqlStmt * stmt) { - int result = SQLFetch(stmt->hstmt); - LogStmtError(result, stmt, L"SQLFetch"); - return result; -} - -//============================================================================ -int SqlConnMoreResults (SqlStmt * stmt) { - int result = SQLMoreResults(stmt->hstmt); - LogStmtError(result, stmt, L"SQLMoreResults"); - return result; -} - -//============================================================================ -int SqlConnParamData ( - SqlStmt * stmt, - SQLPOINTER * put -) { - int result = SQLParamData(stmt->hstmt, put); - LogStmtError(result, stmt, L"SQLParamData"); - return result; -} - -//============================================================================ -bool SqlConnPutData ( - SqlStmt * stmt, - SQLPOINTER data, - SQLINTEGER bytes -) { - int result = SQLPutData(stmt->hstmt, data, bytes); - LogStmtError(result, stmt, L"SQLPutData"); - return SQL_SUCCEEDED(result); -} - -//============================================================================ -int SqlConnGetData ( - SqlStmt * stmt, - SQLINTEGER columnNumber, - SQLINTEGER targetType, - SQLPOINTER targetValue, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -) { - int result = SQLGetData( - stmt->hstmt, - (SQLUSMALLINT) columnNumber, - (SQLSMALLINT) targetType, - targetValue, - bufferLength, - indPtr - ); - LogStmtError(result, stmt, L"SQLGetData"); - return result; -} - -//============================================================================ -void SqlConnCloseCursor (SqlStmt * stmt) { - int result = SQLFreeStmt(stmt->hstmt, SQL_CLOSE); - LogStmtError(result, stmt, L"SQLFreeStmt"); -} - -//============================================================================ -int SqlConnNumResultCols ( - SqlStmt * stmt -) { - // @@@ TODO: Ensure that statement has been executed - SQLSMALLINT colCount = 0; - int result = SQLNumResultCols( - stmt->hstmt, - &colCount - ); - LogStmtError(result, stmt, L"SQLNumResultCols"); - - return colCount; -} - -//============================================================================ -int SqlConnDescribeCol ( - SqlStmt * stmt, - SQLSMALLINT columnNumber, - SQLWCHAR * columnName, - SQLSMALLINT bufferLength, - SQLSMALLINT * nameLengthPtr, - SQLSMALLINT * dataTypePtr, - SQLUINTEGER * columnSizePtr, - SQLSMALLINT * decimalDigitsPtr, - SQLSMALLINT * nullablePtr -) { - - int result = SQLDescribeColW( - stmt->hstmt, - columnNumber, - columnName, - bufferLength, - nameLengthPtr, - dataTypePtr, - columnSizePtr, - decimalDigitsPtr, - nullablePtr - ); - LogStmtError(result, stmt, L"SQLDescribeCol"); - return result; - -} - -//============================================================================ -unsigned SqlConnGetPerf (unsigned id) { - ASSERT(id < arrsize(s_perf)); - return (unsigned) s_perf[id]; -} diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h b/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h deleted file mode 100644 index 30cd78bb..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h +++ /dev/null @@ -1,308 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLCONN_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlConn.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLCONN_H - - -/***************************************************************************** -* -* Types -* -***/ - -struct SqlConn; -struct SqlStmt; -struct SqlTrans; - -typedef void (* FSqlBindPrepare)( - SqlStmt * stmt, - ARRAY(uint8_t) * bindData -); - - -/***************************************************************************** -* -* Init API -* -***/ - -SqlConn * SqlConnCreate ( - const wchar_t connectStr[], - unsigned maxConnections, - unsigned transTimeoutMs -); -void SqlConnShutdown (SqlConn * conn); -void SqlConnDestroy (SqlConn * conn); - - -/***************************************************************************** -* -* Ad-hoc query API -* -* For queries that will be performed and therefore don't want to incur -* binding and preparing overhead. -* -***/ - -SqlStmt * SqlConnAllocStmt ( - SqlConn * conn -); -void SqlConnFreeStmt ( - SqlStmt * stmt -); -void SqlStmtSetAttr ( - SqlStmt * stmt, - int attr, - void * valPtr, - int strLen -); - - -/***************************************************************************** -* -* "Optimized" query API -* -* The "prepare" function will only be called once for a statement, and it -* will retain its bindings and memory set by the prepare function until -* SqlConnDisconnect is called (i.e. until program shutdown). -* -* -* -***/ - -SqlStmt * SqlConnAllocStmt ( - SqlConn * conn, - FSqlBindPrepare prepare, - uint8_t ** bindData // [OUT] -); - - -/***************************************************************************** -* -* Error handling -* -***/ - -typedef void (* FSqlConnErrorHandler)( - int result, - const wchar_t function[], - const wchar_t command[], - const char diagnostics[], // double-null terminated - void * userParam -); - -void SqlConnSetErrorHandler ( - SqlStmt * stmt, - FSqlConnErrorHandler handler, - void * userParam -); - - -/***************************************************************************** -* -* Output binding -* -***/ - -// Reset all changes done by SqlConnBindCol*() functions -void SqlConnBindColReset (SqlStmt * stmt); - -// Obtain multiple rows in a result set by rows or columns -void SqlConnBindColMode ( - SqlStmt * stmt, - SQLUINTEGER * rowCount, // SQL_ATTR_ROWS_FETCHED_PTR - SQLUINTEGER structSize, // SQL_ATTR_ROW_BIND_TYPE - SQLUINTEGER arraySize, // SQL_ATTR_ROW_ARRAY_SIZE - SQLUSMALLINT * statusArray // SQL_ATTR_ROW_STATUS_PTR -); - -// Bind parameters of various types -void SqlConnBindCol ( - SqlStmt * stmt, - SQLINTEGER targetType, - SQLPOINTER targetValue, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -); - - -/***************************************************************************** -* -* Parameter binding -* -***/ - -// Reset all changes done by SqlConnBindParameter*() functions -void SqlConnBindParameterReset (SqlStmt * stmt); - -// Set multiple rows in an output set by rows or columns -void SqlConnBindParameterMode ( - SqlStmt * stmt, - SQLUINTEGER * processCount, // SQL_ATTR_PARAMS_PROCESSED_PTR - SQLUINTEGER structSize, // SQL_ATTR_PARAM_BIND_TYPE - SQLUINTEGER arraySize, // SQL_ATTR_PARAMSET_SIZE - SQLUSMALLINT * statusArray // SQL_ATTR_PARAM_STATUS_PTR -); - -// Bind parameters of various types -void SqlConnBindParameter ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLINTEGER valueType, - SQLINTEGER parameterType, - SQLUINTEGER columnSize, - SQLINTEGER decimalDigits, - SQLPOINTER parameterValuePtr, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -); -void SqlConnBindParameterInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLINTEGER * parameterValuePtr, - SQLINTEGER * indPtr -); -void SqlConnBindParameterUInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER * parameterValuePtr, - SQLINTEGER * indPtr -); -void SqlConnBindParameterString ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER columnSize, // bytes, NOT chars - SQLWCHAR * parameterValuePtr, - SQLINTEGER * indPtr -); -void SqlConnBindParameterStringA ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLUINTEGER columnSize, // bytes, NOT chars - SQLCHAR * parameterValuePtr, - SQLINTEGER * indPtr -); - -/**************************************************************************** -* -* Execution -* -***/ - -int SqlConnExecDirect ( - SqlStmt * stmt, - const wchar_t string[] -); -int SqlConnPrepare ( - SqlStmt * stmt, - const wchar_t string[] -); -int SqlConnExecute ( - SqlStmt * stmt -); -int SqlConnFetch ( - SqlStmt * stmt -); -int SqlConnMoreResults ( - SqlStmt * stmt -); -int SqlConnParamData ( - SqlStmt * stmt, - SQLPOINTER * put -); -bool SqlConnPutData ( - SqlStmt * stmt, - SQLPOINTER data, - SQLINTEGER bytes -); -int SqlConnGetData ( - SqlStmt * stmt, - SQLINTEGER columnNumber, - SQLINTEGER targetType, - SQLPOINTER targetValue, - SQLINTEGER bufferLength, - SQLINTEGER * indPtr -); -void SqlConnCloseCursor ( - SqlStmt * stmt -); -int SqlConnNumResultCols ( - SqlStmt * stmt -); -int SqlConnDescribeCol ( - SqlStmt * stmt, - SQLSMALLINT columnNumber, - SQLWCHAR * columnName, - SQLSMALLINT bufferLength, - SQLSMALLINT * nameLengthPtr, - SQLSMALLINT * dataTypePtr, - SQLUINTEGER * columnSizePtr, - SQLSMALLINT * decimalDigitsPtr, - SQLSMALLINT * nullablePtr -); - - -/***************************************************************************** -* -* Performance API -* -***/ - -enum { - kSqlConnPerfConnDesired, - kSqlConnPerfConnCurrent, - kSqlConnPerfConnPending, - kSqlConnPerfConnCheckDead, - kSqlConnPerfCacheHits, - kSqlConnPerfCacheMisses, - kSqlConnNumPerf -}; - -unsigned SqlConnGetPerf (unsigned id); diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp b/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp deleted file mode 100644 index 56ea468a..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.cpp -* -***/ - -#include "../Pch.h" -#pragma hdrstop - - -/***************************************************************************** -* -* Exports -* -***/ - -//=========================================================================== -void SqlConnBindParameterInputGuid ( - SqlStmt * stmt, - Uuid * uuid, - SQLINTEGER * uuidLen -) { - SqlConnBindParameter( - stmt, - SQL_PARAM_INPUT, - SQL_C_BINARY, - SQL_BINARY, - sizeof(Uuid), - 0, - uuid, - sizeof(Uuid), - uuidLen - ); -} - -//=========================================================================== -void SqlConnBindParameterOutputGuid ( - SqlStmt * stmt, - Uuid * uuid, - SQLINTEGER * uuidLen -) { - SqlConnBindParameter( - stmt, - SQL_PARAM_OUTPUT, - SQL_C_BINARY, - SQL_BINARY, - sizeof(Uuid), - 0, - uuid, - sizeof(Uuid), - uuidLen - ); -} - -//=========================================================================== -void SqlConnBindParameterBigInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLBIGINT * parameterValuePtr, - SQLINTEGER * indPtr -) { - SqlConnBindParameter( - stmt, - inputOutputType, - SQL_C_SBIGINT, - SQL_BIGINT, - sizeof(uint64_t), - 0, - parameterValuePtr, - 0, - indPtr - ); -} - -//=========================================================================== -bool SqlConnGetBlobData ( - SqlStmt * stmt, - unsigned colIndex, - ARRAY(uint8_t) * buffer, - unsigned * bytesAdded -) { - // Since a number of routines use this function, set the chunk size to be - // fairly large to avoid the necessity of reallocing the block, and further - // to prevent memory fragmentation by allocating variously sized blocks. - // In for a penny, in for a pound... - const unsigned CHUNK_SIZE = 32 * 1024; - SQLINTEGER length = CHUNK_SIZE - 1; - unsigned bytes = buffer->Bytes(); - *bytesAdded = 0 - bytes; - for (;;) { - // Allocate memory that is evenly aligned to CHUNK_SIZE, which - // reduces memory fragmentation by allocating on 32K multiples. - // Use SetCount() instead of New() to ensure that this is true - // even if the buffer already contains data. - buffer->SetCount( - MathNextMultiplePow2( - buffer->Bytes() + length, - CHUNK_SIZE - ) - ); - - // Read column data - int result = SqlConnGetData( - stmt, - colIndex, - SQL_C_BINARY, - buffer->Ptr() + bytes, - buffer->Bytes() - bytes, - &length - ); - - // Handle SQL_NO_TOTAL and SQL_NULL_DATA values - if (length < 0) { - buffer->ZeroCount(); - *bytesAdded = 0; - return result == SQL_SUCCESS; - } - - // Keep getting data until we have the entire buffer - if (result == SQL_SUCCESS_WITH_INFO) { - // length contains the number of remaining bytes - bytes = buffer->Bytes(); - continue; - } - - // Is the buffer complete? - if (result == SQL_SUCCESS) { - buffer->SetCountFewer(length + bytes); - *bytesAdded += buffer->Bytes(); - return true; - } - - // An error occurred - break; - } - - buffer->ZeroCount(); - *bytesAdded = 0; - return false; -} - -//=========================================================================== -int SqlConnPutBlobData ( - SqlStmt * stmt, - unsigned bytes, - const uint8_t data[] -) { - int result; - SQLPOINTER putPtr; - while (SQL_NEED_DATA == (result = SqlConnParamData(stmt, &putPtr))) { - if (!SqlConnPutData(stmt, const_cast(data), bytes)) - return SQL_ERROR; - } - return result; -} diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h b/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h deleted file mode 100644 index 09052018..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h +++ /dev/null @@ -1,86 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h -* -***/ - -#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLUTIL_H -#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/Private/pnSqlUtil.h included more than once" -#endif -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PRIVATE_PNSQLUTIL_H - - -/***************************************************************************** -* -* SqlUtil API -* -***/ - -void SqlConnBindParameterInputGuid ( - SqlStmt * stmt, - Uuid * uuid, - SQLINTEGER * uuidLen -); -void SqlConnBindParameterOutputGuid ( - SqlStmt * stmt, - Uuid * uuid, - SQLINTEGER * uuidLen -); -void SqlConnBindParameterBigInt ( - SqlStmt * stmt, - SQLINTEGER inputOutputType, - SQLBIGINT * parameterValuePtr, - SQLINTEGER * indPtr -); -bool SqlConnGetBlobData ( - SqlStmt * stmt, - unsigned colIndex, - ARRAY(uint8_t) * buffer, - unsigned * bytesAdded -); -int SqlConnPutBlobData ( - SqlStmt * stmt, - unsigned bytes, - const uint8_t data[] -); diff --git a/Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h b/Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h deleted file mode 100644 index d4de6542..00000000 --- a/Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h +++ /dev/null @@ -1,59 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnSqlLib/pnSqlLib.h -* -***/ - -#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H - - -// Include ODBC API -#include -#include - -#include "Private/pnSqlAllIncludes.h" - - -#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNSQLLIB_PNSQLLIB_H