home *** CD-ROM | disk | FTP | other *** search
- // ColAttr.cpp -- Column attributes class implementation. The class provides
- // an interface to column data retrieved from an executed SQL Server ODBC
- // statement.
- //
- // This file is part of Microsoft SQL Server online documentation.
- // Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
- //
- // This source code is an intended supplement to the Microsoft SQL
- // Server online references and related electronic documentation.
- #include "stdafx.h"
- #include "ColAttr.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- IMPLEMENT_DYNAMIC(CColAttr, CObject)
-
- /////////////////////////////////////////////////////////////////////////////
- // ASSERT in debug builds if the statement handle or nCol is invalid.
- /////////////////////////////////////////////////////////////////////////////
- CColAttr::CColAttr(SQLHSTMT hstmt, SQLSMALLINT nCol)
- {
- ASSERT(hstmt != SQL_NULL_HANDLE && (nCol > 0 && nCol <= 4000));
- m_hstmt = hstmt;
- m_nCol = nCol;
- m_psColName = NULL;
- m_eSQLType = SQL_CHAR;
- m_eDefaultBindType = SQL_C_CHAR;
- m_cbDefBuffer = 0;
- m_cbCharBuffer = 0;
- m_cbDisplay = 0;
- m_nDecimalDigits = 0;
- m_bNullable = FALSE;
- m_bIsIdentity = FALSE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Do the work of building a column attribute using SQLDescribeCol and
- // SQLColAttribute. Return SQL_ERROR on a problem with the intial
- // description. Otherwise, return SQL_SUCCESS.
- /////////////////////////////////////////////////////////////////////////////
- SQLRETURN CColAttr::GetAttr()
- {
- SQLTCHAR acValue[MAX_COLUMN_NAME];
- SQLSMALLINT cbColName;
-
- // Use SQLDescribeCol to ensure that we've got something good, then
- // ask for specific column attributes that ensure proper sizing for
- // binding and display.
- if (SQL_SUCCEEDED(SQLDescribeCol(m_hstmt, m_nCol, acValue,
- MAX_COLUMN_NAME + 1, &cbColName, &m_eSQLType,
- &m_cbDisplay, &m_nDecimalDigits, &m_bNullable)))
- {
- m_psColName = new CString((TCHAR*) acValue);
-
- switch (m_eSQLType)
- {
- case SQL_NUMERIC: // Character data that may auto increment.
- case SQL_DECIMAL: // Check auto inc. then fall through.
- {
- SQLColAttribute(m_hstmt, m_nCol,
- SQL_DESC_AUTO_UNIQUE_VALUE, NULL, 0, 0, &m_bIsIdentity);
- }
-
- case SQL_CHAR:
- case SQL_VARCHAR:
- {
- m_eDefaultBindType = SQL_C_CHAR;
-
- // Add one character for our terminating null.
- m_cbDefBuffer = m_cbCharBuffer =
- AdjustLen(m_cbDisplay + sizeof(char));
- break;
- }
-
- case SQL_LONGVARCHAR:
- {
- m_eDefaultBindType = SQL_C_CHAR;
-
- // Display length will have to do. Just don't do any
- // allocations based on the number.
- m_cbDefBuffer = m_cbCharBuffer = m_cbDisplay;
- break;
- }
-
- case SQL_WCHAR:
- case SQL_WVARCHAR:
- {
- m_eDefaultBindType = SQL_C_WCHAR;
-
- // Add one character for our terminating null.
- m_cbDefBuffer = m_cbCharBuffer =
- AdjustLen((m_cbDisplay * sizeof(SQLWCHAR)) +
- sizeof(SQLWCHAR));
- break;
- }
-
- case SQL_WLONGVARCHAR:
- {
- m_eDefaultBindType = SQL_C_WCHAR;
-
- // Display length will have to do. Just don't do any
- // allocations based on the number.
- m_cbDefBuffer = m_cbCharBuffer = m_cbDisplay;
- break;
- }
-
- case SQL_BINARY:
- case SQL_VARBINARY:
- {
- m_eDefaultBindType = SQL_C_BINARY;
- m_cbDefBuffer = m_cbDisplay;
-
- // Two ASCII chars needed to display one binary
- // byte in character format (e.g. "1A23\0").
- m_cbCharBuffer = AdjustLen((m_cbDisplay + 1) *
- 2 * sizeof(TCHAR));
- break;
- }
-
- case SQL_LONGVARBINARY:
- {
- m_eDefaultBindType = SQL_C_BINARY;
-
- m_cbDefBuffer = m_cbCharBuffer = m_cbDisplay;
- break;
- }
-
- default:
- {
- m_cbDisplay = AdjustLen(m_cbDisplay);
-
- switch (m_eSQLType)
- {
- case SQL_BIT:
- case SQL_TINYINT:
- case SQL_SMALLINT:
- case SQL_INTEGER:
- {
- // Check SQL Server IDENTITY property.
- SQLColAttribute(m_hstmt, m_nCol,
- SQL_DESC_AUTO_UNIQUE_VALUE, NULL, 0, 0,
- &m_bIsIdentity);
-
- m_eDefaultBindType = SQL_C_LONG;
- m_cbDefBuffer = sizeof(SQLINTEGER);
- m_cbCharBuffer = AdjustLen(m_cbDisplay +
- sizeof(TCHAR));
- break;
- }
-
- case SQL_TYPE_TIMESTAMP:
- {
- m_eDefaultBindType = SQL_C_TYPE_TIMESTAMP;
- m_cbDefBuffer = sizeof(SQL_TIMESTAMP_STRUCT);
- m_cbCharBuffer = AdjustLen(m_cbDisplay +
- sizeof(TCHAR));
- break;
- }
-
- case SQL_FLOAT:
- {
- m_eDefaultBindType = SQL_C_DOUBLE;
- m_cbDefBuffer = sizeof(double);
- m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
- break;
- }
-
- case SQL_REAL:
- {
- m_eDefaultBindType = SQL_C_FLOAT;
- m_cbDefBuffer = sizeof(float);
- m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
- break;
- }
-
- default:
- {
- m_eDefaultBindType = SQL_C_CHAR;
- m_cbDefBuffer = m_cbDisplay;
- m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
- }
- }
-
- break;
- }
- }
- }
- else
- {
- m_cbDisplay = 0;
- return (SQL_ERROR);
- }
-
- return (SQL_SUCCESS);
- }
-
- #ifdef _DEBUG // Non-debug versions are in-line
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the width of the default C data type's bound buffer. Returns 0
- // for bad column definition.
- /////////////////////////////////////////////////////////////////////////////
- UINT CColAttr::GetBoundBufferWidth()
- {
- ASSERT(m_cbDisplay);
- return (m_cbDefBuffer);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the width of a buffer needed to bind the column to SQL_C_CHAR.
- // Returns 0 for bad column definition.
- /////////////////////////////////////////////////////////////////////////////
- UINT CColAttr::GetCharBufferWidth()
- {
- ASSERT(m_cbDisplay);
- return (m_cbCharBuffer);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the number of decimal digits in a fixed-precision numeric type.
- /////////////////////////////////////////////////////////////////////////////
- SQLSMALLINT CColAttr::GetDecimalDigits()
- {
- ASSERT(m_cbDisplay);
- return (m_nDecimalDigits);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the number of characters required to display the data as
- // characters. Supports conversion to character data on binding and
- // fetching.
- /////////////////////////////////////////////////////////////////////////////
- SQLUINTEGER CColAttr::GetDisplaySize()
- {
- ASSERT(m_cbDisplay);
- return (m_cbDisplay);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the default binding type for SQL Server columns. Binding to
- // the default type causes no conversion of data.
- /////////////////////////////////////////////////////////////////////////////
- SQLSMALLINT CColAttr::GetDefaultBindType()
- {
- ASSERT(m_cbDisplay);
- return (m_eDefaultBindType);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Get auto increment property (flagged TRUE for SQL Server IDENTITY
- // columns).
- /////////////////////////////////////////////////////////////////////////////
- BOOL CColAttr::GetIsIdentity()
- {
- ASSERT(m_cbDisplay);
- return ((BOOL) m_bIsIdentity);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Return the column's name as a pointer to a TCHAR string.
- /////////////////////////////////////////////////////////////////////////////
- LPCTSTR CColAttr::GetName()
- {
- ASSERT(m_cbDisplay);
- return ((LPCTSTR) *m_psColName);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the column name length. The length is the number of characters.
- /////////////////////////////////////////////////////////////////////////////
- int CColAttr::GetNameLen()
- {
- ASSERT(m_cbDisplay);
- return (m_psColName->GetLength());
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the type enumerator reported by ODBC.
- /////////////////////////////////////////////////////////////////////////////
- SQLSMALLINT CColAttr::GetODBCType()
- {
- ASSERT(m_cbDisplay);
- return (m_eSQLType);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Report the precision of a fixed numeric data type. This is the same as
- // the data types display size.
- /////////////////////////////////////////////////////////////////////////////
- SQLUINTEGER CColAttr::GetPrecision()
- {
- ASSERT(m_cbDisplay);
- return (m_cbDisplay);
- }
-
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // Determine if column is long data type.
- /////////////////////////////////////////////////////////////////////////////
- BOOL CColAttr::GetIsLongData()
- {
- ASSERT(m_cbDisplay);
- return (m_eSQLType == SQL_LONGVARCHAR || m_eSQLType == SQL_LONGVARBINARY
- || m_eSQLType == SQL_WLONGVARCHAR);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Destructor -- Clean up dynamically allocated resources.
- /////////////////////////////////////////////////////////////////////////////
- CColAttr::~CColAttr()
- {
- if (m_psColName != NULL)
- {
- delete m_psColName;
- }
- }
-
- #ifdef _DEBUG
- // Dump the important parts of a column object.
- void CColAttr::Dump(CDumpContext& dc) const
- {
- // Call the base object first...
- CObject::Dump(dc);
-
- // ...then dump ourselves.
- dc << "m_nCol: " << m_nCol << "\n"
- << "m_sColName: " << m_psColName << "\n";
- }
-
- // ASSERT that the call to SQLDescribeCol succeeded.
- void CColAttr::AssertValid() const
- {
- ASSERT(m_cbDisplay != 0);
- }
- #endif
-