blob: a0a63e9cc073c17d8615cd91ce15b5f913ae5f95 [file] [log] [blame]
/**************************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**************************************************************************/
//
// MODULE: CSrvrConnect.cpp
//
/* Change Log:
* Methods Changed: addSrvrStmt(SRVR_STMT_HDL *); removeSrvrStmt(SRVR_STMT_HDL *); getSrvrStmt(const char *,long *,const char *)
* Methods Added: getSrvrStmt(long,long,long *)
*/
#include <platform_ndcs.h>
#ifdef NSK_PLATFORM
#include <sqlWin.h>
#else
#include <sql.h>
#include <sys/syscall.h>
#endif
#include <sqlext.h>
#include "Debug.h"
#include "SrvrCommon.h"
#include "CommonDiags.h"
#include "CSrvrConnect.h"
#include "SqlInterface.h"
#include <string>
#include <map>
#include <vector>
#include <ext/hash_map>
using namespace std;
// +++ T2_REPO
#include <tr1/memory>
#include <pthread.h>
#include <PubQueryStats.h>
typedef struct _REPOS_STATS
{
std::tr1::shared_ptr<SESSION_END> m_pSessionStats;
std::tr1::shared_ptr<STATEMENT_QUERYEXECUTION> m_pQuery_stats;
std::tr1::shared_ptr<SESSION_AGGREGATION> m_pAggr_stats;
pub_struct_type m_pub_type;
}REPOS_STATS, *pREPOS_STATS;
extern void sendSessionEnd(std::tr1::shared_ptr<SESSION_END> pSession_info);
extern void sendQueryStats(pub_struct_type pub_type, std::tr1::shared_ptr<STATEMENT_QUERYEXECUTION> pQuery_info);
//
SRVR_CONNECT_HDL::SRVR_CONNECT_HDL()
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::SRVR_CONNECT_HDL",(NULL));
isClosed = TRUE;
pSrvrStmtListHead = NULL;
pCurrentSrvrStmt = NULL;
count = 0;
isSPJRS = 0;
pSrvrStmtInternal = NULL;
CLEAR_WARNING(sqlWarning);
CLEAR_ERROR(sqlError);
memset(DefaultCatalog, '\0', 129);
memset(DefaultSchema, '\0', 129);
memset(CurrentCatalog, '\0', 129);
memset(CurrentSchema, '\0', 129);
FUNCTION_RETURN_VOID((NULL));
}
SRVR_CONNECT_HDL::~SRVR_CONNECT_HDL()
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::~SRVR_CONNECT_HDL",(NULL));
sqlClose();
cleanupSQLMessage();
for (MapOfSrvrStmt::iterator iter = mapOfSrvrStmt.begin(); iter != mapOfSrvrStmt.end(); )
{
MapOfSrvrStmt::iterator current = iter;
iter++;
MEMORY_DELETE(current->second);
mapOfSrvrStmt.erase(current);
}
FUNCTION_RETURN_VOID((NULL));
}
SQLRETURN SRVR_CONNECT_HDL::sqlConnect(const char *uid, const char *pwd)
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::sqlConnect",("uid=%s,pwd=%s",
DebugString(uid),
DebugString(pwd)));
SQLRETURN rc;
cleanupSQLMessage();
rc = CONNECT(this);
switch (rc)
{
case SQL_SUCCESS:
isClosed = FALSE;
break;
case SQL_SUCCESS_WITH_INFO:
isClosed = FALSE;
GETSQLWARNING(NULL, &sqlWarning);
break;
default:
GETSQLERROR(NULL, &sqlError);
break;
}
CLI_DEBUG_RETURN_SQL(rc);
}
SQLRETURN SRVR_CONNECT_HDL::sqlClose()
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::sqlClose",(NULL));
SQLRETURN rc;
long sqlcode;
if (isClosed) CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
rc = switchContext(&sqlcode);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
// Might need to write an EMS event
CLI_DEBUG_RETURN_SQL(SQL_SUCCESS);
}
cleanupSQLMessage();
// We have to do this since the ptrToStmt->Close(SQL_DROP) will modify the listOfSrvrStmt.
// First we put all the pointers in a tempContainer and just close them and clear the list and the tempContainer
std::vector<SRVR_STMT_HDL*> vecOfStmts;
//Stan's performance improvement changes
for (MapOfInternalSrvrStmt::iterator iterOfStmt =
mapOfInternalSrvrStmt.begin();
! (iterOfStmt == mapOfInternalSrvrStmt.end()); ++iterOfStmt)
{
SRVR_STMT_HDL* ptrToStmt = (SRVR_STMT_HDL *)iterOfStmt->second;
vecOfStmts.push_back(ptrToStmt);
}
for(int nfor = 0; nfor < vecOfStmts.size(); ++nfor)
{
((SRVR_STMT_HDL*)vecOfStmts[nfor])->InternalStmtClose(SQL_DROP);
}
vecOfStmts.clear();
//Stan's performance improvement changes
// for(__gnu_cxx::hash_map<long,SRVR_STMT_HDL*>::iterator iterOfStmt = mapOfSrvrStmt.begin(); ! (iterOfStmt == mapOfSrvrStmt.end()); ++iterOfStmt)
for(MapOfSrvrStmt::iterator iterOfStmt = mapOfSrvrStmt.begin(); !(iterOfStmt == mapOfSrvrStmt.end()); ++iterOfStmt)
{
SRVR_STMT_HDL* ptrToStmt = (SRVR_STMT_HDL *)iterOfStmt->second;
vecOfStmts.push_back(ptrToStmt);
}
for(int nfor = 0; nfor < vecOfStmts.size(); ++nfor)
{
((SRVR_STMT_HDL*)vecOfStmts[nfor])->Close(SQL_DROP);
}
vecOfStmts.clear();
//End of Soln. No.: 10-100202-7923
count = 0;
rc = DISCONNECT(this);
switch (rc)
{
case SQL_SUCCESS:
isClosed = TRUE;
break;
case SQL_SUCCESS_WITH_INFO:
isClosed = TRUE;
GETSQLWARNING(NULL, &sqlWarning);
break;
default:
GETSQLERROR(NULL, &sqlError);
break;
}
CLI_DEBUG_RETURN_SQL(rc);
}
SQLRETURN SRVR_CONNECT_HDL::switchContext(long *sqlcode)
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::switchContext",("sqlcode=0x%08x",sqlcode));
SQLRETURN rc;
cleanupSQLMessage();
if (isClosed) // Need to populdate the error
CLI_DEBUG_RETURN_SQL(SQL_ERROR);
rc = SWITCHCONTEXT(this, sqlcode);
switch (rc)
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
break;
default:
GETSQLERROR(NULL, &sqlError);
break;
}
CLI_DEBUG_RETURN_SQL(rc);
}
void SRVR_CONNECT_HDL::cleanupSQLMessage()
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::cleanupSQLMessage",(NULL));
unsigned long i;
ERROR_DESC_def *errorDesc;
// Cleanup SQLWarning
if (sqlWarning._buffer)
{
DEBUG_ASSERT(sqlError.errorList._buffer!=sqlWarning._buffer,
("sqlError and sqlWarning buffers (0x%08x) are the same",sqlError.errorList._buffer));
for (i = 0 ; i < sqlWarning._length; i++)
{
errorDesc = (ERROR_DESC_def *)sqlWarning._buffer + i;
DEBUG_OUT(DEBUG_LEVEL_MEM,("errorDesc = (ERROR_DESC_def *) sqlWarning._buffer[%ld] (0x%08x)",i,errorDesc));
DEBUG_ASSERT(errorDesc!=NULL,("sqlWarning._buffer + %ld is NULL",i));
MEMORY_DELETE(errorDesc->errorText);
}
MEMORY_DELETE(sqlWarning._buffer);
sqlWarning._length = 0;
}
// Cleanup sqlErrror
for (i = 0 ; i < sqlError.errorList._length && sqlError.errorList._buffer != NULL ; i++)
{
errorDesc = (ERROR_DESC_def *)sqlError.errorList._buffer + i;
DEBUG_OUT(DEBUG_LEVEL_MEM,("errorDesc = (ERROR_DESC_def *) sqlError.errorList._buffer[%ld] (0x%08x)",i,errorDesc));
DEBUG_ASSERT(errorDesc!=NULL,("sqlError.errorList._buffer + %ld is NULL",i));
MEMORY_DELETE(errorDesc->errorText);
MEMORY_DELETE(errorDesc->Param1);
MEMORY_DELETE(errorDesc->Param2);
MEMORY_DELETE(errorDesc->Param3);
MEMORY_DELETE(errorDesc->Param4);
MEMORY_DELETE(errorDesc->Param5);
MEMORY_DELETE(errorDesc->Param6);
MEMORY_DELETE(errorDesc->Param7);
}
MEMORY_DELETE(sqlError.errorList._buffer);
sqlError.errorList._length = 0;
FUNCTION_RETURN_VOID((NULL));
}
const ERROR_DESC_LIST_def *SRVR_CONNECT_HDL::getSQLError()
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::getSQLError",(NULL));
FUNCTION_RETURN_PTR((const ERROR_DESC_LIST_def *)&sqlError.errorList,(NULL));
}
void SRVR_CONNECT_HDL::addSrvrStmt(SRVR_STMT_HDL *pSrvrStmt,BOOL internalStmt)
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::addSrvrStmt",("pSrvrStmt=0x%08x",
pSrvrStmt));
mapOfSrvrStmt[(long)pSrvrStmt]=pSrvrStmt;
if(internalStmt){
mapOfInternalSrvrStmt[pSrvrStmt->stmtName]= pSrvrStmt; // +++ map error
}
count++;
//pSrvrStmt->myKey = count;
FUNCTION_RETURN_VOID((NULL));
}
void SRVR_CONNECT_HDL::removeSrvrStmt(SRVR_STMT_HDL *pSrvrStmt)
{
FUNCTION_ENTRY_LEVEL(DEBUG_LEVEL_STMT,"SRVR_CONNECT_HDL::removeSrvrStmt",("pSrvrStmt=0x%08x",
pSrvrStmt));
#if defined(TAG64)
int _ptr32 *tempPtr;
#endif
//Soln. No.: 10-100202-7923
/*SRVR_STMT_HDL_LIST *pSrvrStmtList;*/
SRVR_STMT_HDL *lpSrvrStmt;
//End of Soln. No.: 10-100202-7923
if (pSrvrStmt->stmtType == INTERNAL_STMT)
mapOfInternalSrvrStmt.erase(pSrvrStmt->stmtName);
if(mapOfSrvrStmt.find((long)pSrvrStmt) != mapOfSrvrStmt.end())
{
lpSrvrStmt=(SRVR_STMT_HDL * )mapOfSrvrStmt.find((long)pSrvrStmt)->second;
if (lpSrvrStmt == pSrvrStmt)
{
#if defined(TAG64)
if(tempStmtIdMap.find(lpSrvrStmt->stmt.tag) != tempStmtIdMap.end())
{
tempPtr=(int _ptr32*)lpSrvrStmt->stmt.tag;
//printf("The value is frestmt %ld %p\n",tempPtr,lpSrvrStmt);
tempStmtIdMap.erase(lpSrvrStmt->stmt.tag);
free32(tempPtr);
}
#endif
// If the statement being deleted is current statement, reset the current statement
if (pCurrentSrvrStmt == lpSrvrStmt)
{
pCurrentSrvrStmt = NULL;
}
mapOfSrvrStmt.erase((long)pSrvrStmt);
MEMORY_DELETE_OBJ(lpSrvrStmt);
}
count--;
}
FUNCTION_RETURN_VOID((NULL));
}
SRVR_STMT_HDL *SRVR_CONNECT_HDL::createSrvrStmt(
const char *stmtLabel,
long *sqlcode,
const char *moduleName,
long moduleVersion,
long long moduleTimestamp,
short sqlStmtType,
BOOL useDefaultDesc,
BOOL internalStmt,
long stmtId,
short sqlQueryType, // If sqlQueryType indicates it's SPJ statement, then the member variable
Int32 resultSetIndex, // resultSetIndex and callStmtId of SRVR_STMT_HDL should be initialized
SQLSTMT_ID* callStmtId) // with these passed in args
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::createSrvrStmt",("..."));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" stmtLabel=%s, sqlcode=0x%08x",
DebugString(stmtLabel),
sqlcode));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" moduleName=%s",
DebugString(moduleName)));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" moduleVersion=%ld, moduleTimestamp=%s",
moduleVersion,
DebugTimestampStr(moduleTimestamp)));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" sqlStmtType=%s, useDefaultDesc=%d",
CliDebugSqlStatementType(sqlStmtType),
useDefaultDesc));
SQLRETURN rc;
SRVR_STMT_HDL *pSrvrStmt;
long internalStmtid=0;
pSrvrStmt = NULL;
if(internalStmt)
{
//Stan's performance improvement changes
MapOfInternalSrvrStmt::iterator iterOfStmtId
= mapOfInternalSrvrStmt.find(stmtLabel);
if( !(iterOfStmtId == mapOfInternalSrvrStmt.end()) )
pSrvrStmt =(SRVR_STMT_HDL *)iterOfStmtId->second;
if(pSrvrStmt != NULL)
FUNCTION_RETURN_PTR(pSrvrStmt,(NULL));
}
else
pSrvrStmt = getSrvrStmt(0,stmtId,0);
if (pSrvrStmt == NULL)
{
MEMORY_ALLOC_OBJ(pSrvrStmt,SRVR_STMT_HDL((long)this));
if (sqlQueryType == SQL_SP_RESULT_SET)
{
pSrvrStmt->sqlQueryType = SQL_SP_RESULT_SET;
pSrvrStmt->callStmtId = callStmtId;
pSrvrStmt->resultSetIndex = resultSetIndex;
}
rc = pSrvrStmt->allocSqlmxHdls(stmtLabel, moduleName, moduleTimestamp,
moduleVersion, sqlStmtType, useDefaultDesc);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
MEMORY_DELETE_OBJ(pSrvrStmt);
if (sqlcode) *sqlcode = rc;
FUNCTION_RETURN_PTR(NULL,("pSrvrStmt->allocSqlmxHdls returned %s",CliDebugSqlError(rc)));
}
addSrvrStmt(pSrvrStmt,internalStmt);
}
if (sqlcode) *sqlcode = SQL_SUCCESS;
FUNCTION_RETURN_PTR(pSrvrStmt,(NULL));
}
SRVR_STMT_HDL *SRVR_CONNECT_HDL::createSpjrsSrvrStmt(
SRVR_STMT_HDL *inpSrvrStmt,
const char *RSstmtLabel,
long *sqlcode,
const char *moduleName,
long moduleVersion,
long long moduleTimestamp,
short sqlStmtType,
long RSindex,
const char *RSstmtName,
BOOL useDefaultDesc)
{
FUNCTION_ENTRY("SRVR_CONNECT_HDL::createSrvrStmt",("..."));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" inpSrvrStmt=0x%08x , RSstmtLabel=%s, sqlcode=0x%08x",
inpSrvrStmt,
DebugString(RSstmtLabel),
sqlcode));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" moduleName=%s",
DebugString(moduleName)));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" moduleVersion=%ld, moduleTimestamp=%s",
moduleVersion,
DebugTimestampStr(moduleTimestamp)));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" sqlStmtType=%s, useDefaultDesc=%d",
CliDebugSqlStatementType(sqlStmtType),
useDefaultDesc));
DEBUG_OUT(DEBUG_LEVEL_ENTRY,(" RSindex=%ld, RSstmtName=%s",
RSindex,
DebugString(RSstmtName)));
SQLRETURN rc;
SRVR_STMT_HDL *pSrvrStmt;
SQLSTMT_ID *callpStmt = &inpSrvrStmt->stmt;
int retcode;
pSrvrStmt = NULL;//getSrvrStmt(RSstmtLabel, sqlcode, moduleName);
MEMORY_ALLOC_OBJ(pSrvrStmt,SRVR_STMT_HDL((long)this));
rc = pSrvrStmt->allocSqlmxHdls_spjrs(callpStmt, RSstmtLabel, moduleName, moduleTimestamp,
moduleVersion, sqlStmtType, useDefaultDesc, RSindex, RSstmtName);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
MEMORY_DELETE_OBJ(pSrvrStmt);
if (sqlcode) *sqlcode = rc;
FUNCTION_RETURN_PTR(NULL,("pSrvrStmt->allocSqlmxHdls_spjrs returned %s",CliDebugSqlError(rc)));
}
addSrvrStmt(pSrvrStmt);
if (sqlcode) *sqlcode = SQL_SUCCESS;
FUNCTION_RETURN_PTR(pSrvrStmt,(NULL));
}
//Soln. No. : 10-100202-7923
SRVR_STMT_HDL *SRVR_CONNECT_HDL::getSrvrStmt(long dialogueId,long stmtId,long *sqlcode)
{
FUNCTION_ENTRY("getSrvrStmt",("dialogueId=0x%08x, stmtId=0x%08x, sqlcode=0x%08x",
dialogueId,
stmtId,
sqlcode));
//Stan's performance improvement changes
MapOfSrvrStmt::iterator iterOfStmtId = mapOfSrvrStmt.find(stmtId);
if(! (iterOfStmtId == mapOfSrvrStmt.end()) )
FUNCTION_RETURN_PTR(((SRVR_STMT_HDL *)iterOfStmtId->second),(NULL));
FUNCTION_RETURN_PTR(NULL,(NULL));
}
SRVR_STMT_HDL *SRVR_CONNECT_HDL::getInternalSrvrStmt(long dialogueId, const char* stmtLabel, long *sqlcode)
{
FUNCTION_ENTRY("getInternalSrvrStmt",("dialogueId=0x%08x, stmtLabel=0x%08x, sqlcode=0x%08x",
dialogueId,
stmtLabel,
sqlcode));
SRVR_STMT_HDL *pSrvrStmt = NULL;
MapOfInternalSrvrStmt::iterator iterOfStmtId = mapOfInternalSrvrStmt.find(stmtLabel);
if( !(iterOfStmtId == mapOfInternalSrvrStmt.end()) )
pSrvrStmt =(SRVR_STMT_HDL *)iterOfStmtId->second;
if(pSrvrStmt != NULL)
FUNCTION_RETURN_PTR(pSrvrStmt,(NULL));
else
{
*sqlcode = SQL_INVALID_HANDLE;
FUNCTION_RETURN_PTR(NULL, ("getInternalSrvrStmt() failed to find the internal statement \"%s\"", stmtLabel));
}
}
// +++ T2_REPO
void sendSessionEnd(std::tr1::shared_ptr<SESSION_END> pSession_info)
{
REPOS_STATS session_stats;
session_stats.m_pSessionStats = pSession_info;
session_stats.m_pub_type = PUB_TYPE_SESSION_END;
/* +++ T2_REPO ToDo
if (record_session_done)
{
//boost::thread thrd(&SessionWatchDog);
pthread_t thrd;
pthread_create(&thrd, NULL, SessionWatchDog, NULL);
}
repos_queue.push_task(session_stats);
*/
}
void sendAggrStats(pub_struct_type pub_type, std::tr1::shared_ptr<SESSION_AGGREGATION> pAggr_info)
{
REPOS_STATS aggr_stats;
aggr_stats.m_pAggr_stats = pAggr_info;
aggr_stats.m_pub_type = pub_type;
/* +++ T2_REPO ToDo
if (record_session_done)
{
//boost::thread thrd(&SessionWatchDog);
pthread_t thrd;
pthread_create(&thrd, NULL, SessionWatchDog, NULL);
}
repos_queue.push_task(aggr_stats);
*/
}
void sendQueryStats(pub_struct_type pub_type, std::tr1::shared_ptr<STATEMENT_QUERYEXECUTION> pQuery_info)
{
REPOS_STATS query_stats;
query_stats.m_pQuery_stats = pQuery_info;
query_stats.m_pub_type = pub_type;
/* +++ T2_REPO ToDo
if (record_session_done)
{
//boost::thread thrd(&SessionWatchDog);
pthread_t thrd;
pthread_create(&thrd, NULL, SessionWatchDog, NULL);
}
repos_queue.push_task(query_stats);
*/
}
// T2_REPO