1//
2// ODBCMetaColumn.cpp
3//
4// Library: Data/ODBC
5// Package: ODBC
6// Module: ODBCMetaColumn
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Data/ODBC/ODBCMetaColumn.h"
16#include "Poco/Data/ODBC/Utility.h"
17
18
19namespace Poco {
20namespace Data {
21namespace ODBC {
22
23
24ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
25 MetaColumn(position),
26 _rStmt(rStmt)
27{
28 init();
29}
30
31
32ODBCMetaColumn::~ODBCMetaColumn()
33{
34}
35
36
37void ODBCMetaColumn::getDescription()
38{
39 std::memset(_columnDesc.name, 0, NAME_BUFFER_LENGTH);
40 _columnDesc.nameBufferLength = 0;
41 _columnDesc.dataType = 0;
42 _columnDesc.size = 0;
43 _columnDesc.decimalDigits = 0;
44 _columnDesc.isNullable = 0;
45
46 if (Utility::isError(Poco::Data::ODBC::SQLDescribeCol(_rStmt,
47 (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based
48 _columnDesc.name,
49 NAME_BUFFER_LENGTH,
50 &_columnDesc.nameBufferLength,
51 &_columnDesc.dataType,
52 &_columnDesc.size,
53 &_columnDesc.decimalDigits,
54 &_columnDesc.isNullable)))
55 {
56 throw StatementException(_rStmt);
57 }
58}
59
60
61bool ODBCMetaColumn::isUnsigned() const
62{
63 SQLLEN val = 0;
64 if (Utility::isError(Poco::Data::ODBC::SQLColAttribute(_rStmt,
65 (SQLUSMALLINT)position() + 1, // ODBC columns are 1-based
66 SQL_DESC_UNSIGNED,
67 0,
68 0,
69 0,
70 &val)))
71 {
72 throw StatementException(_rStmt);
73 }
74 return (val == SQL_TRUE);
75}
76
77
78void ODBCMetaColumn::init()
79{
80 getDescription();
81
82 if (Utility::isError(Poco::Data::ODBC::SQLColAttribute(_rStmt,
83 (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based
84 SQL_DESC_LENGTH,
85 0,
86 0,
87 0,
88 &_dataLength)))
89 {
90 throw StatementException(_rStmt);
91 }
92
93 setName(std::string((char*) _columnDesc.name));
94 setLength(_columnDesc.size);
95 setPrecision(_columnDesc.decimalDigits);
96 setNullable(SQL_NULLABLE == _columnDesc.isNullable);
97 switch(_columnDesc.dataType)
98 {
99 case SQL_BIT:
100 setType(MetaColumn::FDT_BOOL); break;
101
102 case SQL_CHAR:
103 case SQL_VARCHAR:
104 case SQL_LONGVARCHAR:
105#ifdef SQL_GUID
106 case SQL_GUID:
107#endif
108 setType(MetaColumn::FDT_STRING); break;
109
110 case SQL_WCHAR:
111 case SQL_WVARCHAR:
112 case SQL_WLONGVARCHAR:
113 case -350: // IBM DB2 CLOB, which long unicode string
114 setType(MetaColumn::FDT_WSTRING); break;
115
116 case SQL_TINYINT:
117 setType(isUnsigned() ? MetaColumn::FDT_UINT8 : MetaColumn::FDT_INT8);
118 break;
119
120 case SQL_SMALLINT:
121 setType(isUnsigned() ? MetaColumn::FDT_UINT16 : MetaColumn::FDT_INT16);
122 break;
123
124 case SQL_INTEGER:
125 setType(isUnsigned() ? MetaColumn::FDT_UINT32 : MetaColumn::FDT_INT32);
126 break;
127
128 case SQL_BIGINT:
129 setType(isUnsigned() ? MetaColumn::FDT_UINT64 : MetaColumn::FDT_INT64);
130 break;
131
132 case SQL_DOUBLE:
133 case SQL_FLOAT:
134 setType(MetaColumn::FDT_DOUBLE); break;
135
136 case SQL_NUMERIC:
137 case SQL_DECIMAL:
138 // Oracle has no INTEGER type - it's essentially NUMBER with 38 whole and
139 // 0 fractional digits. It also does not recognize SQL_BIGINT type,
140 // so the workaround here is to hardcode it to 32 bit integer
141 if (0 == _columnDesc.decimalDigits) setType(MetaColumn::FDT_INT32);
142 else setType(MetaColumn::FDT_DOUBLE);
143 break;
144
145 case SQL_REAL:
146 setType(MetaColumn::FDT_FLOAT); break;
147
148 case SQL_BINARY:
149 case SQL_VARBINARY:
150 case SQL_LONGVARBINARY:
151 case -98:// IBM DB2 non-standard type
152 case -370: // IBM DB2 XML, documentation advises to bind it as BLOB, not CLOB
153 setType(MetaColumn::FDT_BLOB); break;
154
155 case -99: // IBM DB2 CLOB
156 setType(MetaColumn::FDT_CLOB); break;
157
158 case SQL_TYPE_DATE:
159 setType(MetaColumn::FDT_DATE); break;
160
161 case SQL_TYPE_TIME:
162 setType(MetaColumn::FDT_TIME); break;
163
164 case SQL_TYPE_TIMESTAMP:
165 setType(MetaColumn::FDT_TIMESTAMP); break;
166
167 default:
168 throw DataFormatException("Unsupported data type.");
169 }
170}
171
172
173} } } // namespace Poco::Data::ODBC
174