home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 32 / IOPROG_32.ISO / SOFT / SqlEval7 / devtools / samples / ODBC / loaddata / colattr.cpp next >
Encoding:
C/C++ Source or Header  |  1997-10-30  |  11.8 KB  |  341 lines

  1. // ColAttr.cpp -- Column attributes class implementation. The class provides
  2. //  an interface to column data retrieved from an executed SQL Server ODBC
  3. //  statement.
  4. //
  5. // This file is part of Microsoft SQL Server online documentation.
  6. // Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  7. //
  8. // This source code is an intended supplement to the Microsoft SQL
  9. // Server online references and related electronic documentation.
  10. #include "stdafx.h"
  11. #include "ColAttr.h"
  12.  
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18.  
  19. IMPLEMENT_DYNAMIC(CColAttr, CObject)
  20.  
  21. /////////////////////////////////////////////////////////////////////////////
  22. // ASSERT in debug builds if the statement handle or nCol is invalid.
  23. /////////////////////////////////////////////////////////////////////////////
  24. CColAttr::CColAttr(SQLHSTMT hstmt, SQLSMALLINT nCol)
  25.     {
  26.     ASSERT(hstmt != SQL_NULL_HANDLE && (nCol > 0 && nCol <= 4000));
  27.     m_hstmt             = hstmt;
  28.     m_nCol              = nCol;
  29.     m_psColName         = NULL;
  30.     m_eSQLType          = SQL_CHAR;
  31.     m_eDefaultBindType  = SQL_C_CHAR;
  32.     m_cbDefBuffer       = 0;
  33.     m_cbCharBuffer      = 0;
  34.     m_cbDisplay         = 0;
  35.     m_nDecimalDigits    = 0;
  36.     m_bNullable         = FALSE;
  37.     m_bIsIdentity       = FALSE;
  38.     }
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // Do the work of building a column attribute using SQLDescribeCol and
  42. //  SQLColAttribute. Return SQL_ERROR on a problem with the intial
  43. //  description. Otherwise, return SQL_SUCCESS.
  44. /////////////////////////////////////////////////////////////////////////////
  45. SQLRETURN CColAttr::GetAttr()
  46.     {
  47.     SQLTCHAR        acValue[MAX_COLUMN_NAME];
  48.     SQLSMALLINT     cbColName;
  49.  
  50.     // Use SQLDescribeCol to ensure that we've got something good, then
  51.     //  ask for specific column attributes that ensure proper sizing for
  52.     //  binding and display.
  53.     if (SQL_SUCCEEDED(SQLDescribeCol(m_hstmt, m_nCol, acValue,
  54.         MAX_COLUMN_NAME + 1, &cbColName, &m_eSQLType,
  55.         &m_cbDisplay, &m_nDecimalDigits, &m_bNullable)))
  56.         {
  57.         m_psColName = new CString((TCHAR*) acValue);
  58.  
  59.         switch (m_eSQLType)
  60.             {
  61.             case SQL_NUMERIC:   // Character data that may auto increment.
  62.             case SQL_DECIMAL:   //  Check auto inc. then fall through.
  63.                 {
  64.                 SQLColAttribute(m_hstmt, m_nCol,
  65.                     SQL_DESC_AUTO_UNIQUE_VALUE, NULL, 0, 0, &m_bIsIdentity);
  66.                 }
  67.  
  68.             case SQL_CHAR:
  69.             case SQL_VARCHAR:
  70.                 {
  71.                 m_eDefaultBindType = SQL_C_CHAR;
  72.                 
  73.                 // Add one character for our terminating null.
  74.                 m_cbDefBuffer = m_cbCharBuffer = 
  75.                     AdjustLen(m_cbDisplay + sizeof(char));
  76.                 break;
  77.                 }
  78.  
  79.             case SQL_LONGVARCHAR:
  80.                 {
  81.                 m_eDefaultBindType = SQL_C_CHAR;
  82.                 
  83.                 // Display length will have to do. Just don't do any
  84.                 // allocations based on the number.
  85.                 m_cbDefBuffer = m_cbCharBuffer =  m_cbDisplay;
  86.                 break;
  87.                 }
  88.  
  89.             case SQL_WCHAR:
  90.             case SQL_WVARCHAR:
  91.                 {
  92.                 m_eDefaultBindType = SQL_C_WCHAR;
  93.                 
  94.                 // Add one character for our terminating null.
  95.                 m_cbDefBuffer = m_cbCharBuffer = 
  96.                     AdjustLen((m_cbDisplay * sizeof(SQLWCHAR)) +
  97.                     sizeof(SQLWCHAR));
  98.                 break;
  99.                 }
  100.  
  101.             case SQL_WLONGVARCHAR:
  102.                 {
  103.                 m_eDefaultBindType = SQL_C_WCHAR;
  104.                 
  105.                 // Display length will have to do. Just don't do any
  106.                 // allocations based on the number.
  107.                 m_cbDefBuffer = m_cbCharBuffer =  m_cbDisplay;
  108.                 break;
  109.                 }
  110.  
  111.             case SQL_BINARY:
  112.             case SQL_VARBINARY:
  113.                 {
  114.                 m_eDefaultBindType = SQL_C_BINARY;
  115.                 m_cbDefBuffer = m_cbDisplay;
  116.                 
  117.                 // Two ASCII chars needed to display one binary
  118.                 //  byte in character format (e.g. "1A23\0").
  119.                 m_cbCharBuffer = AdjustLen((m_cbDisplay + 1) * 
  120.                     2 * sizeof(TCHAR));
  121.                 break;
  122.                 }
  123.  
  124.             case SQL_LONGVARBINARY:
  125.                 {
  126.                 m_eDefaultBindType = SQL_C_BINARY;
  127.  
  128.                 m_cbDefBuffer = m_cbCharBuffer =  m_cbDisplay;
  129.                 break;
  130.                 }
  131.  
  132.             default:
  133.                 {
  134.                 m_cbDisplay = AdjustLen(m_cbDisplay);
  135.  
  136.                 switch (m_eSQLType)
  137.                     {
  138.                     case SQL_BIT:
  139.                     case SQL_TINYINT:
  140.                     case SQL_SMALLINT:
  141.                     case SQL_INTEGER:
  142.                         {
  143.                         // Check SQL Server IDENTITY property.
  144.                         SQLColAttribute(m_hstmt, m_nCol,
  145.                             SQL_DESC_AUTO_UNIQUE_VALUE, NULL, 0, 0, 
  146.                             &m_bIsIdentity);
  147.  
  148.                         m_eDefaultBindType = SQL_C_LONG;
  149.                         m_cbDefBuffer = sizeof(SQLINTEGER);
  150.                         m_cbCharBuffer = AdjustLen(m_cbDisplay + 
  151.                             sizeof(TCHAR));
  152.                         break;
  153.                         }
  154.                 
  155.                     case SQL_TYPE_TIMESTAMP:
  156.                         {
  157.                         m_eDefaultBindType = SQL_C_TYPE_TIMESTAMP;
  158.                         m_cbDefBuffer = sizeof(SQL_TIMESTAMP_STRUCT);
  159.                         m_cbCharBuffer = AdjustLen(m_cbDisplay + 
  160.                             sizeof(TCHAR));
  161.                         break;
  162.                         }
  163.  
  164.                     case SQL_FLOAT:
  165.                         {
  166.                         m_eDefaultBindType = SQL_C_DOUBLE;
  167.                         m_cbDefBuffer = sizeof(double);
  168.                         m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
  169.                         break;
  170.                         }
  171.  
  172.                     case SQL_REAL:
  173.                         {
  174.                         m_eDefaultBindType = SQL_C_FLOAT;
  175.                         m_cbDefBuffer = sizeof(float);
  176.                         m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
  177.                         break;
  178.                         }
  179.  
  180.                     default:
  181.                         {
  182.                         m_eDefaultBindType = SQL_C_CHAR;
  183.                         m_cbDefBuffer = m_cbDisplay;
  184.                         m_cbCharBuffer = AdjustLen(m_cbDisplay + sizeof(TCHAR));
  185.                         }
  186.                     }
  187.  
  188.                 break;
  189.                 }
  190.             }
  191.         }
  192.     else
  193.         {
  194.         m_cbDisplay = 0;
  195.         return (SQL_ERROR);
  196.         }
  197.  
  198.     return (SQL_SUCCESS);
  199.     }
  200.  
  201. #ifdef _DEBUG // Non-debug versions are in-line
  202.  
  203. /////////////////////////////////////////////////////////////////////////////
  204. // Report the width of the default C data type's bound buffer. Returns 0
  205. //  for bad column definition.
  206. /////////////////////////////////////////////////////////////////////////////
  207. UINT CColAttr::GetBoundBufferWidth()
  208.     {
  209.     ASSERT(m_cbDisplay);
  210.     return (m_cbDefBuffer);
  211.     }
  212.  
  213. /////////////////////////////////////////////////////////////////////////////
  214. // Report the width of a buffer needed to bind the column to SQL_C_CHAR.
  215. //   Returns 0 for bad column definition.
  216. /////////////////////////////////////////////////////////////////////////////
  217. UINT CColAttr::GetCharBufferWidth()
  218.     {
  219.     ASSERT(m_cbDisplay);
  220.     return (m_cbCharBuffer);
  221.     }
  222.  
  223. /////////////////////////////////////////////////////////////////////////////
  224. // Report the number of decimal digits in a fixed-precision numeric type.
  225. /////////////////////////////////////////////////////////////////////////////
  226. SQLSMALLINT CColAttr::GetDecimalDigits()
  227.     {
  228.     ASSERT(m_cbDisplay);
  229.     return (m_nDecimalDigits);
  230.     }
  231.  
  232. /////////////////////////////////////////////////////////////////////////////
  233. // Report the number of characters required to display the data as
  234. //  characters. Supports conversion to character data on binding and
  235. //  fetching.
  236. /////////////////////////////////////////////////////////////////////////////
  237. SQLUINTEGER CColAttr::GetDisplaySize()
  238.     {
  239.     ASSERT(m_cbDisplay);
  240.     return (m_cbDisplay);
  241.     }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // Report the default binding type for SQL Server columns. Binding to
  245. //  the default type causes no conversion of data.
  246. /////////////////////////////////////////////////////////////////////////////
  247. SQLSMALLINT CColAttr::GetDefaultBindType()
  248.     {
  249.     ASSERT(m_cbDisplay);
  250.     return (m_eDefaultBindType);
  251.     }
  252.  
  253. /////////////////////////////////////////////////////////////////////////////
  254. // Get auto increment property (flagged TRUE for SQL Server IDENTITY
  255. //  columns).
  256. /////////////////////////////////////////////////////////////////////////////
  257. BOOL CColAttr::GetIsIdentity()
  258.     {
  259.     ASSERT(m_cbDisplay);
  260.     return ((BOOL) m_bIsIdentity);
  261.     }
  262.  
  263. /////////////////////////////////////////////////////////////////////////////
  264. // Return the column's name as a pointer to a TCHAR string.
  265. /////////////////////////////////////////////////////////////////////////////
  266. LPCTSTR CColAttr::GetName()
  267.     {
  268.     ASSERT(m_cbDisplay);
  269.     return ((LPCTSTR) *m_psColName);
  270.     }
  271.  
  272. /////////////////////////////////////////////////////////////////////////////
  273. // Report the column name length. The length is the number of characters.
  274. /////////////////////////////////////////////////////////////////////////////
  275. int CColAttr::GetNameLen()
  276.     {
  277.     ASSERT(m_cbDisplay);
  278.     return (m_psColName->GetLength());
  279.     }
  280.  
  281. /////////////////////////////////////////////////////////////////////////////
  282. // Report the type enumerator reported by ODBC.
  283. /////////////////////////////////////////////////////////////////////////////
  284. SQLSMALLINT CColAttr::GetODBCType()
  285.     {
  286.     ASSERT(m_cbDisplay);
  287.     return (m_eSQLType);
  288.     }
  289.  
  290. /////////////////////////////////////////////////////////////////////////////
  291. // Report the precision of a fixed numeric data type. This is the same as
  292. //  the data types display size.
  293. /////////////////////////////////////////////////////////////////////////////
  294. SQLUINTEGER CColAttr::GetPrecision()
  295.     {
  296.     ASSERT(m_cbDisplay);
  297.     return (m_cbDisplay);
  298.     }
  299.  
  300. #endif
  301.  
  302. /////////////////////////////////////////////////////////////////////////////
  303. // Determine if column is long data type.
  304. /////////////////////////////////////////////////////////////////////////////
  305. BOOL CColAttr::GetIsLongData()
  306.     {
  307.     ASSERT(m_cbDisplay);
  308.     return (m_eSQLType == SQL_LONGVARCHAR || m_eSQLType == SQL_LONGVARBINARY
  309.         || m_eSQLType == SQL_WLONGVARCHAR);
  310.     }
  311.  
  312. /////////////////////////////////////////////////////////////////////////////
  313. // Destructor -- Clean up dynamically allocated resources.
  314. /////////////////////////////////////////////////////////////////////////////
  315. CColAttr::~CColAttr()
  316.     {
  317.     if (m_psColName != NULL)
  318.         {
  319.         delete m_psColName;
  320.         }
  321.     }
  322.  
  323. #ifdef _DEBUG
  324. // Dump the important parts of a column object.
  325. void CColAttr::Dump(CDumpContext& dc) const
  326.     {
  327.     // Call the base object first...
  328.     CObject::Dump(dc);
  329.  
  330.     // ...then dump ourselves.
  331.     dc  << "m_nCol:     "   << m_nCol << "\n"
  332.         << "m_sColName: "   << m_psColName << "\n";
  333.     }
  334.  
  335. // ASSERT that the call to SQLDescribeCol succeeded.
  336. void CColAttr::AssertValid() const
  337.     {
  338.     ASSERT(m_cbDisplay != 0);
  339.     }
  340. #endif
  341.