📄 podbc.cxx
字号:
SQLRETURN nRet=SQLFetchScroll(m_hStmt,SQL_FETCH_PRIOR,0);
return SQL_OK(nRet);
}
BOOL PODBCStmt::FetchNext()
{
SQLRETURN nRet=SQLFetchScroll(m_hStmt,SQL_FETCH_NEXT,0);
return SQL_OK(nRet);
}
BOOL PODBCStmt::FetchRow(PINDEX nRow,BOOL Absolute)
{
SQLRETURN nRet=SQLFetchScroll(m_hStmt,
(Absolute ? SQL_FETCH_ABSOLUTE : SQL_FETCH_RELATIVE),nRow);
return SQL_OK(nRet);
}
BOOL PODBCStmt::FetchFirst()
{
SQLRETURN nRet=SQLFetchScroll(m_hStmt,SQL_FETCH_FIRST,0);
return SQL_OK(nRet);
}
BOOL PODBCStmt::FetchLast()
{
SQLRETURN nRet=SQLFetchScroll(m_hStmt,SQL_FETCH_LAST,0);
return SQL_OK(nRet);
}
BOOL PODBCStmt::Cancel()
{
SQLRETURN nRet=SQLCancel(m_hStmt);
return SQL_OK(nRet);
}
PStringArray PODBCStmt::TableList(PString option)
{
PString list;
PString entry;
SQLINTEGER len = 129;
SQLINTEGER cb = 0;
SQLRETURN nRet;
/// This Statement will need reviewing as it
/// depends on the Database, Might work on some
/// but not on others
nRet = SQLTables(m_hStmt, 0, SQL_NTS, 0, SQL_NTS,0, SQL_NTS,(unsigned char *)(const char *)option,option.GetLength());
if (SQL_OK(nRet)) {
SQLBindCol(m_hStmt, 3, SQL_C_CHAR, entry.GetPointer(len),129,&cb);
while (Fetch())
{
SQLGetData(m_hStmt, 3, SQL_C_CHAR, entry.GetPointer(len), 129, &cb);
if (entry.GetLength() > 0) {
list = list + ":" + entry;
entry.MakeEmpty();
}
}
}
return list.Tokenise(":",FALSE);
}
BOOL PODBCStmt::SQL_OK(SQLRETURN res)
{
if ((res==SQL_SUCCESS_WITH_INFO) || (res==SQL_SUCCESS))
return TRUE;
if (res != SQL_NEED_DATA)
GetLastError();
return FALSE;
}
void PODBCStmt::GetLastError()
{
SQLRETURN rc;
SQLINTEGER NativeError;
int buflen = SQL_MAX_MESSAGE_LENGTH;
SQLSMALLINT MsgLen, i = 1;
PString ErrStr, Msg;
while ((rc = SQLGetDiagRec(SQL_HANDLE_STMT, m_hStmt, i, (unsigned char *)ErrStr.GetPointer(6),
&NativeError,(unsigned char *)Msg.GetPointer(buflen), buflen, &MsgLen)) != SQL_NO_DATA)
{
odbclink->OnSQLError(ErrStr, Msg);
i++;
}
}
//////////////////////////////////////////////////////////////////////////////
/// PODBCRecord
unsigned int PODBCRecord::Precision;
int PODBCRecord::MaxCharSize;
PTime::TimeFormat PODBCRecord::TimeFormat;
//--
PODBCRecord::PODBCRecord(PODBCStmt * hStmt)
: Stmt(hStmt)
{
m_hStmt=*hStmt;
dbase = (PODBC::DataSources)hStmt->dbase; // Database name
if (!Precision)
Precision = 4;
if (!TimeFormat)
TimeFormat = PTime::RFC1123;
MaxCharSize = 56; //56 Kbytes (Stupid MSAccess)
}
PINDEX PODBCRecord::ColumnCount()
{
short nCols=0;
if(!Stmt->SQL_OK(SQLNumResultCols(m_hStmt,&nCols)))
return 0;
return nCols;
}
BOOL PODBCRecord::InternalBindColumn(USHORT Column,LPVOID pBuffer,
ULONG pBufferSize,LONG * pReturnedBufferSize,
USHORT nType)
{
LONG pReturnedSize=0;
SQLRETURN Ret=SQLBindCol(m_hStmt,Column,nType,
pBuffer,pBufferSize,&pReturnedSize);
if(*pReturnedBufferSize)
*pReturnedBufferSize=pReturnedSize;
cout << pReturnedSize;
return Stmt->SQL_OK(Ret);
}
PINDEX PODBCRecord::ColumnByName(PString Column)
{
PINDEX nCols=ColumnCount();
for(PINDEX i=1;i<(nCols+1);i++)
{
if(Column == ColumnName(i))
return i;
}
return 0;
}
BOOL PODBCRecord::InternalGetData(USHORT Column, LPVOID pBuffer,
ULONG pBufLen, LONG * dataLen, int Type)
{
SQLINTEGER od=0;
int Err=SQLGetData(m_hStmt,Column,Type,pBuffer,pBufLen,&od);
if (!Stmt->SQL_OK(Err))
return FALSE;
if(dataLen)
*dataLen=od;
return TRUE;
}
PString PODBCRecord::GetLongData(PINDEX Column)
{
PString sbin;
PString Data;
SQLINTEGER len = MAX_DATA_LEN;
SQLINTEGER cb =0;
while (InternalGetData((USHORT)Column,sbin.GetPointer(len + 1),len,&cb))
{
if (sbin.Right(1) == '\0') // Remove Null Char
Data = Data + sbin.Left(sbin.GetLength()-1);
else
Data = Data + sbin;
}
return Data;
}
void PODBCRecord::Data(PINDEX Column, PODBC::Field & field)
{
SQLINTEGER len = MAX_DATA_LEN;
// SQLINTEGER cb =0;
BOOL B = TRUE; /// Bind Switch (Readonly Fields are not Bound
PODBC::Field::Bind & b = field.Data;
PODBC::FieldTypes ctype = ColumnType(Column);
/// Set the Attributes
field.isReadOnly = !IsColumnUpdatable(Column);
field.isNullable = IsColumnNullable(Column);
field.isAutoInc = IsColumnAutoIndex(Column);
/// Mark Columns which ReadOnly to Be Ignored when Binding.
if (field.isReadOnly) B = FALSE;
switch (ctype) {
/// Numeric Data
case PODBC::BigInt:
if (B)
SQLBindCol(m_hStmt, Column,SQL_C_SBIGINT, &b.sbint,0,&b.dataLen);
AddField(field,ColumnName(Column),ctype, PODBC::oPInt64);
break;
case PODBC::TinyInt:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_UTINYINT, &b.sbit, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype, PODBC::oshort);
break;
case PODBC::Bit:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_BIT, &b.sbit, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype, PODBC::oBOOL);
break;
case PODBC::Char:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_CHAR, &b.suchar, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::ochar);
break;
case PODBC::Integer:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_LONG, &b.slint, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::olong);
break;
case PODBC::SmallInt:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_SSHORT, &b.ssint, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype, PODBC::oint);
break;
case PODBC::Numeric:
case PODBC::Decimal:
case PODBC::Float:
case PODBC::Real:
case PODBC::Double:
field.Decimals = ColumnPrecision(Column);
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_DOUBLE, &b.sdoub, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::odouble);
break;
// Data Structures
case PODBC::Date:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_TYPE_DATE, &b.date, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::oPTime);
break;
case PODBC::Time:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_TYPE_TIME, &b.time, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::oPTime);
break;
case PODBC::TimeStamp:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_TYPE_TIMESTAMP, &b.timestamp, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::oPTime);
break;
case PODBC::Guid:
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_GUID, &b.guid, 0, &b.dataLen);
AddField(field,ColumnName(Column),ctype,PODBC::oPGUID);
break;
/// Binary Data
case PODBC::Binary:
case PODBC::VarBinary:
case PODBC::LongVarBinary:
case PODBC::LongVarChar:
if (dbase == PODBC::MSAccess) /// Stupid Access Stuff!
if (B)
SQLBindCol(m_hStmt, field.col, SQL_C_CHAR, b.sbinlong.GetPointer(len*MaxCharSize), len*MaxCharSize, &b.dataLen);
else {
if (B)
SQLBindCol(m_hStmt, Column, SQL_LONGVARCHAR, (SQLPOINTER)Column, 0, &b.dataLen);
if (field.LongData)
b.dataLen = SQL_LEN_DATA_AT_EXEC(0);
else
b.dataLen = SQL_LEN_DATA_AT_EXEC(len);
}
AddField(field,ColumnName(Column),ctype,PODBC::oPString);
break;
/// Character
case PODBC::DateTime:
case PODBC::Unknown:
case PODBC::VarChar:
default:
b.sbin.SetSize(len+1);
AddField(field,ColumnName(Column),ctype,PODBC::oPString);
if (B)
SQLBindCol(m_hStmt, Column, SQL_C_CHAR, b.sbin.GetPointer(len), len, &b.dataLen);
break;
};
}
BOOL PODBCRecord::PostNew(PODBC::Row & rec)
{
SQLRETURN nRet;
nRet = SQLBulkOperations(m_hStmt, // Statement handle
SQL_ADD // Operation
);
return InternalSaveLongData(nRet,rec);
}
BOOL PODBCRecord::PostUpdate(PODBC::Row & rec)
{
SQLRETURN nRet;
nRet = SQLSetPos(m_hStmt, // Statement handle
(unsigned short)1, // RowNumber
SQL_UPDATE, // Operation
SQL_LOCK_NO_CHANGE // LockType
);
return InternalSaveLongData(nRet,rec);
}
BOOL PODBCRecord::PostDelete(PINDEX row)
{
SQLRETURN nRet;
nRet = SQLSetPos(m_hStmt, // Statement handle
(unsigned short)row, // RowNumber
SQL_DELETE, // Operation
SQL_LOCK_NO_CHANGE // LockType
);
return (Stmt->SQL_OK(nRet));
}
BOOL PODBCRecord::InternalSaveLongData(SQLRETURN nRet, PODBC::Row & rec)
{
SQLPOINTER pToken;
SQLINTEGER cbData;
PString DataSlice;
PINDEX frag, col=0;
/// Everything OK but no Long Data
if (Stmt->SQL_OK(nRet))
return TRUE;
/// Error Somewhere else.
if (nRet != SQL_NEED_DATA)
return FALSE;
/// If More Data Required
while (nRet == SQL_NEED_DATA) {
nRet = SQLParamData(m_hStmt,&pToken);
if (col != (PINDEX)pToken) {
col = (PINDEX)pToken;
DataSlice = PString();
frag = 0;
cbData = MAX_DATA_LEN;
}
if (nRet == SQL_NEED_DATA) {
while (rec[col].DataFragment(DataSlice,frag, cbData))
SQLPutData(m_hStmt,DataSlice.GetPointer(cbData),cbData);
}
}
return TRUE;
}
PODBC::FieldTypes PODBCRecord::ColumnType( PINDEX Column )
{
int nType=SQL_C_DEFAULT;
SQLTCHAR svColName[ 256 ]=_T("");
SWORD swCol=0,swType=0,swScale=0,swNull=0;
UDWORD pcbColDef;
SQLDescribeCol( m_hStmt, // Statement handle
Column, // ColumnNumber
svColName, // ColumnName
sizeof( svColName), // BufferLength
&swCol, // NameLengthPtr
&swType, // DataTypePtr
&pcbColDef, // ColumnSizePtr
&swScale, // DecimalDigitsPtr
&swNull ); // NullablePtr
nType=(int)swType;
return( (PODBC::FieldTypes)nType );
}
DWORD PODBCRecord::ColumnSize( PINDEX Column )
{
// int nType=SQL_C_DEFAULT;
SQLTCHAR svColName[ 256 ]=_T("");
SWORD swCol=0,swType=0,swScale=0,swNull=0;
DWORD pcbColDef=0;
SQLDescribeCol( m_hStmt, // Statement handle
Column, // ColumnNumber
svColName, // ColumnName
sizeof( svColName), // BufferLength
&swCol, // NameLengthPtr
&swType, // DataTypePtr
&pcbColDef, // ColumnSizePtr
&swScale, // DecimalDigitsPtr
&swNull ); // NullablePtr
return pcbColDef;
}
DWORD PODBCRecord::ColumnScale( PINDEX Column )
{
// int nType=SQL_C_DEFAULT;
SQLTCHAR svColName[ 256 ]=_T("");
SWORD swCol=0,swType=0,swScale=0,swNull=0;
DWORD pcbColDef=0;
SQLDescribeCol( m_hStmt, // Statement handle
Column, // ColumnNumber
svColName, // ColumnName
sizeof( svColName), // BufferLength
&swCol, // NameLengthPtr
&swType, // DataTypePtr
&pcbColDef, // ColumnSizePtr
&swScale, // DecimalDigitsPtr
&swNull ); // NullablePtr
return swScale;
}
PString PODBCRecord::ColumnName(PINDEX Column) //, PString Name, SHORT NameLen )
{
// int nType=SQL_C_DEFAULT;
SWORD swCol=0,swType=0,swScale=0,swNull=0;
DWORD pcbColDef=0;
TCHAR Name[256]=_T("");
SQLRETURN Ret=
SQLDescribeCol( m_hStmt, // Statement handle
Column, // ColumnNumber
(SQLTCHAR*)(LPTSTR)Name, // ColumnName
sizeof(Name), // BufferLength
&swCol, // NameLengthPtr
&swType, // DataTypePtr
&pcbColDef, // ColumnSizePtr
&swScale, // DecimalDigitsPtr
&swNull ); // NullablePtr
if (!Stmt->SQL_OK(Ret))
return PString();
return Name;
}
BOOL PODBCRecord::IsColumnNullable( PINDEX Column )
{
// int nType=SQL_C_DEFAULT;
SQLTCHAR svColName[ 256 ]=_T("");
SWORD swCol=0,swType=0,swScale=0,swNull=0;
UDWORD pcbColDef;
SQLDescribeCol( m_hStmt, // Statement handle
Column, // ColumnNumber
svColName, // ColumnName
sizeof( svColName), // BufferLength
&swCol, // NameLengthPtr
&swType, // DataTypePtr
&pcbColDef, // ColumnSizePtr
&swScale, // DecimalDigitsPtr
&swNull ); // NullablePtr
return (swNull==SQL_NULLABLE);
}
BOOL PODBCRecord::IsColumnUpdatable(PINDEX Column )
{
SWORD colUpdate=0;
SQLColAttribute(m_hStmt, // StatementHandle
(SQLSMALLINT)(Column), // ColumnNumber
SQL_DESC_UPDATABLE, // FieldIdentifier
NULL, // CharacterAttributePtr
0, // BufferLength
NULL, // StringLengthPtr
&colUpdate); // NumericAttributePtr
return (colUpdate != SQL_ATTR_READONLY);
}
BOOL PODBCRecord::IsColumnAutoIndex(PINDEX Column )
{
SWORD colIndex=0;
SQLColAttribute(m_hStmt, // StatementHandle
(SQLSMALLINT)(Column), // ColumnNumber
SQL_DESC_AUTO_UNIQUE_VALUE, // FieldIdentifier
NULL, // CharacterAttributePtr
0, // BufferLength
NULL, // StringLengthPtr
&colIndex); // NumericAttributePtr
return (colIndex == SQL_TRUE);
}
unsigned int PODBCRecord::ColumnPrecision(PINDEX Column )
{
SWORD coldigits=0;
SQLColAttribute(m_hStmt, // StatementHandle
(SQLSMALLINT)(Column), // ColumnNumber
SQL_DESC_PRECISION, // FieldIdentifier
NULL, // CharacterAttributePtr
0, // BufferLength
NULL, // StringLengthPtr
&coldigits); // NumericAttributePtr
if (Precision < (unsigned)coldigits)
return Precision;
else
return coldigits;
}
#pragma warning(default:4100)
#pragma warning(default:4244)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -