📄 result.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: result.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 19:21:54 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12 * PRODUCTION * =========================================================================== *//* $Id: result.cpp,v 1000.3 2004/06/01 19:21:54 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Vladimir Soussov * * File Description: DBLib Results * */#include <ncbi_pch.hpp>#include <dbapi/driver/odbc/interfaces.hpp>#include <dbapi/driver/util/numeric_convert.hpp>BEGIN_NCBI_SCOPE/////////////////////////////////////////////////////////////////////////////static EDB_Type s_GetDataType(SQLSMALLINT t, SQLSMALLINT dec_digits, SQLUINTEGER prec){ switch (t) { case SQL_WCHAR: case SQL_CHAR: return (prec < 256)? eDB_Char : eDB_LongChar; case SQL_WVARCHAR: case SQL_VARCHAR: return (prec < 256)? eDB_VarChar : eDB_LongChar; case SQL_LONGVARCHAR: return eDB_Text; case SQL_LONGVARBINARY: case SQL_WLONGVARCHAR: return eDB_Image; case SQL_DECIMAL: case SQL_NUMERIC: if(prec > 20 || dec_digits > 0) return eDB_Numeric; case SQL_BIGINT: return eDB_BigInt; case SQL_SMALLINT: return eDB_SmallInt; case SQL_INTEGER: return eDB_Int; case SQL_REAL: return eDB_Float; case SQL_FLOAT: return eDB_Double; case SQL_BINARY: return (prec < 256)? eDB_Binary : eDB_LongBinary; case SQL_BIT: return eDB_Bit; case SQL_TINYINT: return eDB_TinyInt; case SQL_VARBINARY: return (prec < 256)? eDB_VarBinary : eDB_LongBinary; case SQL_TYPE_TIMESTAMP: return (prec > 16 || dec_digits > 0)? eDB_DateTime : eDB_SmallDateTime; default: return eDB_UnsupportedType; }}///////////////////////////////////////////////////////////////////////////////// CODBC_RowResult:://CODBC_RowResult::CODBC_RowResult(SQLSMALLINT nof_cols, SQLHSTMT cmd, CODBC_Reporter& r) : m_Cmd(cmd), m_Reporter(r), m_CurrItem(-1), m_EOR(false){ m_NofCols = nof_cols; SQLSMALLINT actual_name_size, nullable; m_ColFmt = new SODBC_ColDescr[m_NofCols]; for (unsigned int n = 0; n < m_NofCols; n++) { switch(SQLDescribeCol(m_Cmd, n+1, m_ColFmt[n].ColumnName, ODBC_COLUMN_NAME_SIZE, &actual_name_size, &m_ColFmt[n].DataType, &m_ColFmt[n].ColumnSize, &m_ColFmt[n].DecimalDigits, &nullable)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: continue; case SQL_ERROR: m_Reporter.ReportErrors(); throw CDB_ClientEx(eDB_Error, 420020, "CODBC_RowResult::CODBC_RowResult", "SQLDescribeCol failed"); default: throw CDB_ClientEx(eDB_Error, 420021, "CODBC_RowResult::CODBC_RowResult", "SQLDescribeCol failed (memory corruption suspected)"); } }}EDB_ResType CODBC_RowResult::ResultType() const{ return eDB_RowResult;}unsigned int CODBC_RowResult::NofItems() const{ return m_NofCols;}const char* CODBC_RowResult::ItemName(unsigned int item_num) const{ return item_num < m_NofCols ? (char*)m_ColFmt[item_num].ColumnName : 0;}size_t CODBC_RowResult::ItemMaxSize(unsigned int item_num) const{ return item_num < m_NofCols ? m_ColFmt[item_num].ColumnSize : 0;}EDB_Type CODBC_RowResult::ItemDataType(unsigned int item_num) const{ return item_num < m_NofCols ? s_GetDataType(m_ColFmt[item_num].DataType, m_ColFmt[item_num].DecimalDigits, m_ColFmt[item_num].ColumnSize) : eDB_UnsupportedType;}bool CODBC_RowResult::Fetch(){ m_CurrItem= -1; if (!m_EOR) { switch (SQLFetch(m_Cmd)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: m_CurrItem = 0; return true; case SQL_NO_DATA: m_EOR = true; break; case SQL_ERROR: m_Reporter.ReportErrors(); throw CDB_ClientEx(eDB_Error, 430003, "CODBC_RowResult::Fetch", "SQLFetch failed"); default: throw CDB_ClientEx(eDB_Error, 430004, "CODBC_RowResult::Fetch", "SQLFetch failed (memory corruption suspected)"); } } return false;}int CODBC_RowResult::CurrentItemNo() const{ return m_CurrItem;}int CODBC_RowResult::xGetData(SQLSMALLINT target_type, SQLPOINTER buffer, SQLINTEGER buffer_size){ SQLINTEGER f; switch(SQLGetData(m_Cmd, m_CurrItem+1, target_type, buffer, buffer_size, &f)) { case SQL_SUCCESS_WITH_INFO: switch(f) { case SQL_NO_TOTAL: return buffer_size; case SQL_NULL_DATA: return 0; default: if(f < 0) m_Reporter.ReportErrors(); return (int)f; } case SQL_SUCCESS: if(target_type==SQL_C_CHAR) buffer_size--; return (f > buffer_size)? buffer_size : (int)f; case SQL_NO_DATA: return 0; case SQL_ERROR: m_Reporter.ReportErrors(); default: throw CDB_ClientEx(eDB_Error, 430027, "CODBC_*Result::xGetData", "SQLGetData failed "); }}static void xConvert2CDB_Numeric(CDB_Numeric* d, SQL_NUMERIC_STRUCT& s){ swap_numeric_endian((unsigned int)s.precision, s.val); d->Assign((unsigned int)s.precision, (unsigned int)s.scale, s.sign == 0, s.val);}CDB_Object* CODBC_RowResult::xLoadItem(CDB_Object* item_buf){ char buffer[8*1024]; int outlen; switch(m_ColFmt[m_CurrItem].DataType) { case SQL_WCHAR: case SQL_CHAR: case SQL_VARCHAR: case SQL_WVARCHAR: { switch (item_buf->GetType()) { case eDB_VarBinary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_VarBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_Binary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_Binary*) item_buf)->SetValue(buffer, outlen); break; case eDB_LongBinary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_LongBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_VarChar: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_VarChar*) item_buf) = buffer; break; case eDB_Char: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_Char*) item_buf) = buffer; break; case eDB_LongChar: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_LongChar*) item_buf) = buffer; break; default: throw CDB_ClientEx(eDB_Error, 430020, "CODBC_*Result::GetItem", "Wrong type of CDB_Object"); } break; } case SQL_BINARY: case SQL_VARBINARY: { switch ( item_buf->GetType() ) { case eDB_VarBinary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_VarBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_Binary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_Binary*) item_buf)->SetValue(buffer, outlen); break; case eDB_LongBinary: outlen= xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_LongBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_VarChar: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_VarChar*) item_buf) = buffer; break; case eDB_Char: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Char*) item_buf) = buffer; break; case eDB_LongChar: outlen= xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_LongChar*) item_buf) = buffer; break; default: throw CDB_ClientEx(eDB_Error, 430020, "CODBC_*Result::GetItem", "Wrong type of CDB_Object"); } break; } case SQL_BIT: { SQLCHAR v; switch ( item_buf->GetType() ) { case eDB_Bit: outlen= xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Bit*) item_buf) = (int) v; break; case eDB_TinyInt: outlen= xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_TinyInt*) item_buf) = v ? 1 : 0; break; case eDB_SmallInt: outlen= xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_SmallInt*) item_buf) = v ? 1 : 0; break; case eDB_Int: outlen= xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Int*) item_buf) = v ? 1 : 0; break; default: throw CDB_ClientEx(eDB_Error, 430020, "CODBC_*Result::GetItem", "Wrong type of CDB_Object"); } break; } case SQL_TYPE_TIMESTAMP: { SQL_TIMESTAMP_STRUCT v; switch ( item_buf->GetType() ) { case eDB_SmallDateTime: { outlen= xGetData(SQL_C_TYPE_TIMESTAMP, &v, sizeof(SQL_TIMESTAMP_STRUCT)); if (outlen <= 0) item_buf->AssignNULL(); else { CTime t((int)v.year, (int)v.month, (int)v.day, (int)v.hour, (int)v.minute, (int)v.second, (long)v.fraction); *((CDB_SmallDateTime*) item_buf)= t; } break; } case eDB_DateTime: { outlen= xGetData(SQL_C_TYPE_TIMESTAMP, &v, sizeof(SQL_TIMESTAMP_STRUCT)); if (outlen <= 0) item_buf->AssignNULL(); else { CTime t((int)v.year, (int)v.month, (int)v.day, (int)v.hour, (int)v.minute, (int)v.second, (long)v.fraction); *((CDB_DateTime*) item_buf)= t; } break; } default: throw CDB_ClientEx(eDB_Error, 430020, "CODBC_*Result::GetItem", "Wrong type of CDB_Object"); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -