Files
mars-flaim/sql/src/sqlstatement.h
dsandersoremutah 5b0a6fe8b5 Checked in all ODBC stuff
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1014 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2007-02-08 19:48:35 +00:00

484 lines
9.6 KiB
C++

//------------------------------------------------------------------------------
// Desc: This file contains SQL statement class.
// Tabs: 3
//
// Copyright (c) 2006-2007 Novell, Inc. All Rights Reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version 2.1
// of the License.
//
// This library 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
// Library Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com.
//
// $Id$
//------------------------------------------------------------------------------
#ifndef SQLSTATEMENT_H
#define SQLSTATEMENT_H
// Maximum name length for table names, column names, and index names
#define MAX_SQL_NAME_LEN 128
class SQLQuery;
typedef struct SELECT_EXPR
{
SQLQuery * pSqlQuery;
SELECT_EXPR * pNext;
} SELECT_EXPR;
typedef struct COLUMN_SET
{
FLMUINT uiColumnNum;
SQLQuery * pSqlQuery;
COLUMN_SET * pNext;
} COLUMN_SET;
typedef struct TABLE_ITEM
{
FLMUINT uiTableNum;
const char * pszTableAlias;
FLMUINT uiIndexNum;
FLMBOOL bScan;
} TABLE_ITEM;
typedef enum
{
SQL_PARSE_STATS
} eSQLStatus;
typedef RCODE (* SQL_STATUS_HOOK)(
eSQLStatus eStatusType,
void * pvArg1,
void * pvArg2,
void * pvArg3,
void * pvUserData);
//------------------------------------------------------------------------------
// Desc: Base object that defines methods which must be present for all ODBC
// handle objects.
//------------------------------------------------------------------------------
class ODBCObject : public F_Object
{
public:
ODBCObject()
{
m_hMutex = F_MUTEX_NULL;
m_pszStateInfo = NULL;
m_uiErrMsgLen = 0;
m_bHaveError = FALSE;
m_uiNumDiagRecs = 0;
}
virtual ~ODBCObject()
{
if (m_hMutex != F_MUTEX_NULL)
{
f_mutexDestroy( &m_hMutex);
}
}
FINLINE FLMINT FLMAPI AddRef( void)
{
return( f_atomicInc( &m_refCnt);
}
FINLINE FLMINT FLMAPI Release( void)
{
FLMINT iRefCnt;
if ((iRefCnt = f_atomicDec( &m_refCnt)) == 0)
{
delete this;
}
return( iRefCnt);
}
FINLINE RCODE setupObject( void)
{
return( f_mutexCreate( &m_hMutex));
}
FINLINE void lockObject( void)
{
f_mutexLock( m_hMutex);
}
FINLINE void unlockObject( void)
{
f_mutexUnlock( m_hMutex);
}
FINLINE const char * getStateInfo( void)
{
return( m_pszStateInfo);
}
FINLINE FLMUINT getErrMsgLen( void)
{
return( m_uiErrMsgLen);
}
FINLINE const char * getErrMsg( void)
{
if (m_uiErrMsgLen)
{
return( &m_szErrMsg [0]);
}
else
{
return( NULL);
}
}
FINLINE RCODE getRCODE( void)
{
return( m_rc);
}
FINLINE FLMBOOL haveError( void)
{
return( m_bHaveError);
}
FINLINE void clearState( void)
{
m_bHaveError = FALSE;
m_uiNumDiagRecs = 0;
}
FINLINE void setStateInfo(
const char * pszStateInfo)
{
m_pszStateInfo = pszStateInfo;
m_uiErrMsgLen = 0;
m_rc = NE_SFLM_OK;
m_bHaveError = TRUE;
}
FINLINE void setGeneralErrMsg(
const char * pszErrMsg,
RCODE rc = NE_SFLM_OK)
{
m_pszStateInfo = "HY000";
m_uiErrMsgLen = f_strlen( pszErrMsg);
// Copy null terminator character too.
f_memcpy( m_szErrMsg, pszErrMsg, m_uiErrMsgLen + 1);
m_rc = rc;
m_bHaveError = TRUE;
}
// Must be implemented by inheriting class.
virtual FLMBOOL canRelease( void) = 0;
private:
F_MUTEX m_hMutex;
const char * m_pszLastStateInfo;
char * m_szErrMsg [200];
FLMUINT m_uiErrMsgLen;
RCODE m_rc;
FLMUINT m_bHaveError;
FLMUINT m_uiNumDiagRecs;
}
/*============================================================================
Desc: SQL statement class. Parses and executes SQL statements. This object
type is returned for ODBC for handles of type SQL_HANDLE_STMT or
SQLHSTMT.
============================================================================*/
class SQLStatement : public ODBCObject
{
public:
#define MAX_SQL_TOKEN_SIZE 80
SQLStatement();
virtual ~SQLStatement();
FLMBOOL canRelease( void);
RCODE setupStatement( void);
void resetStatement( void);
RCODE executeSQL(
IF_IStream * pStream,
F_Db * pDb,
SQL_STATS * pSQLStats);
FINLINE FLMBOOL canRelease( void)
{
// VISIT: Need to determine whether or not this is possible.
return( TRUE);
}
SQLConnection * getConnection( void)
{
return( m_pConnection);
}
private:
// Methods
RCODE getByte(
FLMBYTE * pucByte);
FINLINE void ungetByte(
FLMBYTE ucByte)
{
// Can only unget a single byte.
flmAssert( !m_ucUngetByte);
m_ucUngetByte = ucByte;
m_sqlStats.uiChars--;
}
RCODE getLine( void);
FINLINE FLMBYTE getChar( void)
{
if (m_uiCurrLineOffset == m_uiCurrLineBytes)
{
return( (FLMBYTE)0);
}
else
{
FLMBYTE ucChar = m_pucCurrLineBuf [m_uiCurrLineOffset++];
return( ucChar);
}
}
FINLINE FLMBYTE peekChar( void)
{
if (m_uiCurrLineOffset == m_uiCurrLineBytes)
{
return( (FLMBYTE)0);
}
else
{
return( m_pucCurrLineBuf [m_uiCurrLineOffset]);
}
}
FINLINE void ungetChar( void)
{
// There should never be a reason to unget past the beginning of the current
// line.
flmAssert( m_uiCurrLineOffset);
m_uiCurrLineOffset--;
}
RCODE skipWhitespace(
FLMBOOL bRequired);
RCODE haveToken(
const char * pszToken,
FLMBOOL bEofOK,
SQLParseError eNotHaveErr = SQL_NO_ERROR);
RCODE getToken(
char * pszToken,
FLMUINT uiTokenBufSize,
FLMBOOL bEofOK,
FLMUINT * puiTokenLineOffset,
FLMUINT * puiTokenLen);
FINLINE void setErrInfo(
FLMUINT uiErrLineNum,
FLMUINT uiErrLineOffset,
SQLParseError eErrorType,
FLMUINT uiErrLineFilePos,
FLMUINT uiErrLineBytes)
{
m_sqlStats.uiErrLineNum = uiErrLineNum;
m_sqlStats.uiErrLineOffset = uiErrLineOffset;
m_sqlStats.eErrorType = eErrorType;
m_sqlStats.uiErrLineFilePos = uiErrLineFilePos;
m_sqlStats.uiErrLineBytes = uiErrLineBytes;
}
RCODE getBinaryValue(
F_DynaBuf * pDynaBuf);
RCODE getUTF8String(
FLMBOOL bMustHaveEqual,
FLMBOOL bStripWildcardEscapes,
FLMBYTE * pszStr,
FLMUINT uiStrBufSize,
FLMUINT * puiStrLen,
FLMUINT * puiNumChars,
F_DynaBuf * pDynaBuf);
RCODE getNumber(
FLMBOOL bMustHaveEqual,
FLMUINT64 * pui64Num,
FLMBOOL * pbNeg,
FLMBOOL bNegAllowed);
RCODE getBool(
FLMBOOL bMustHaveEqual,
FLMBOOL * pbBool);
RCODE getUINT(
FLMBOOL bMustHaveEqual,
FLMUINT * puiNum);
RCODE getName(
char * pszName,
FLMUINT uiNameBufSize,
FLMUINT * puiNameLen,
FLMUINT * puiTokenLineOffset);
RCODE getEncDefName(
FLMBOOL bMustExist,
char * pszEncDefName,
FLMUINT uiEncDefNameBufSize,
FLMUINT * puiEncDefNameLen,
F_ENCDEF ** ppEncDef);
RCODE getTableName(
FLMBOOL bMustExist,
char * pszTableName,
FLMUINT uiTableNameBufSize,
FLMUINT * puiTableNameLen,
F_TABLE ** ppTable);
RCODE getIndexName(
FLMBOOL bMustExist,
F_TABLE * pTable,
char * pszIndexName,
FLMUINT uiIndexNameBufSize,
FLMUINT * puiIndexNameLen,
F_INDEX ** ppIndex);
RCODE getStringValue(
F_COLUMN * pColumn,
F_COLUMN_VALUE * pColumnValue);
RCODE getNumberValue(
F_COLUMN_VALUE * pColumnValue);
RCODE getBinaryValue(
F_COLUMN * pColumn,
F_COLUMN_VALUE * pColumnValue);
RCODE getValue(
F_COLUMN * pColumn,
F_COLUMN_VALUE * pColumnValue);
RCODE insertRow( void);
RCODE processCreateDatabase( void);
RCODE processOpenDatabase( void);
RCODE processDropDatabase( void);
RCODE getDataType(
eDataType * peDataType,
FLMUINT * puiMax,
FLMUINT * puiEncDefNum,
FLMUINT * puiFlags);
RCODE processCreateTable( void);
RCODE processDropTable( void);
RCODE processCreateIndex(
FLMBOOL bUnique);
RCODE processDropIndex( void);
RCODE processInsertRow( void);
RCODE parseSetColumns(
TABLE_ITEM * pTableList,
COLUMN_SET ** ppFirstColumnSet,
COLUMN_SET ** ppLastColumnSet,
FLMUINT * puiNumColumnsToSet,
FLMBOOL * pbHadWhere);
RCODE processUpdateRows( void);
RCODE processDeleteRows( void);
RCODE processAlphaToken(
TABLE_ITEM * pTableList,
const char ** ppszTerminatingTokens,
const char ** ppszTerminator,
SQLQuery * pSqlQuery,
FLMBOOL * pbDone);
RCODE parseCriteria(
TABLE_ITEM * pTableList,
const char ** ppszTerminatingTokens,
FLMBOOL bEofOK,
const char ** ppszTerminator,
SQLQuery * pSqlQuery);
RCODE parseSelectExpressions(
SELECT_EXPR ** ppFirstSelectExpr,
SELECT_EXPR ** ppLastSelectExpr);
RCODE processSelect( void);
// Data
F_Db * m_pDb;
IF_XML * m_pXml;
FLMBYTE m_ucUngetByte;
FLMBYTE * m_pucCurrLineBuf;
FLMUINT m_uiCurrLineBufMaxBytes;
FLMUINT m_uiCurrLineOffset;
FLMUINT m_uiCurrLineNum;
FLMUINT m_uiCurrLineFilePos;
FLMUINT m_uiCurrLineBytes;
IF_IStream * m_pStream;
FLMUINT m_uiFlags;
SQL_STATUS_HOOK m_fnStatus;
void * m_pvCallbackData;
SQL_STATS m_sqlStats;
F_Pool m_tmpPool;
SQLConnection * m_pConnection;
SQLStatement * m_pNextInConnection;
SQLStatement * m_pPrevInConnection;
friend class F_Db;
friend class F_Database;
friend class SQLConnection;
friend class SQLEnv;
friend class SQLDesc;
};
RCODE resolveColumnName(
F_Db * pDb,
TABLE_ITEM * pTableList,
const char * pszTableAlias,
const char * pszColumnName,
FLMUINT * puiTableNum,
FLMUINT * puiColumnNum,
SQLParseError * peParseError);
#endif // SQLSTATEMENT_H