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
19 namespace Poco {
20 namespace Data {
21 namespace ODBC {
22
23
ODBCMetaColumn(const StatementHandle & rStmt,std::size_t position)24 ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
25 MetaColumn(position),
26 _rStmt(rStmt)
27 {
28 init();
29 }
30
31
~ODBCMetaColumn()32 ODBCMetaColumn::~ODBCMetaColumn()
33 {
34 }
35
36
getDescription()37 void 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
isUnsigned() const61 bool 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
init()78 void 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 setType(MetaColumn::FDT_WSTRING); break;
114
115 case SQL_TINYINT:
116 setType(isUnsigned() ? MetaColumn::FDT_UINT8 : MetaColumn::FDT_INT8);
117 break;
118
119 case SQL_SMALLINT:
120 setType(isUnsigned() ? MetaColumn::FDT_UINT16 : MetaColumn::FDT_INT16);
121 break;
122
123 case SQL_INTEGER:
124 setType(isUnsigned() ? MetaColumn::FDT_UINT32 : MetaColumn::FDT_INT32);
125 break;
126
127 case SQL_BIGINT:
128 setType(isUnsigned() ? MetaColumn::FDT_UINT64 : MetaColumn::FDT_INT64);
129 break;
130
131 case SQL_DOUBLE:
132 case SQL_FLOAT:
133 setType(MetaColumn::FDT_DOUBLE); break;
134
135 case SQL_NUMERIC:
136 case SQL_DECIMAL:
137 // Oracle has no INTEGER type - it's essentially NUMBER with 38 whole and
138 // 0 fractional digits. It also does not recognize SQL_BIGINT type,
139 // so the workaround here is to hardcode it to 32 or 64 bit integer
140 if (0 == _columnDesc.decimalDigits)
141 {
142 if (_columnDesc.size > 9)
143 setType(MetaColumn::FDT_INT64);
144 else
145 setType(MetaColumn::FDT_INT32);
146 }
147 else
148 {
149 setType(MetaColumn::FDT_DOUBLE);
150 }
151 break;
152
153 case SQL_REAL:
154 setType(MetaColumn::FDT_FLOAT); break;
155
156 case SQL_BINARY:
157 case SQL_VARBINARY:
158 case SQL_LONGVARBINARY:
159 case -98:// IBM DB2 non-standard type
160 setType(MetaColumn::FDT_BLOB); break;
161
162 case SQL_TYPE_DATE:
163 setType(MetaColumn::FDT_DATE); break;
164
165 case SQL_TYPE_TIME:
166 setType(MetaColumn::FDT_TIME); break;
167
168 case SQL_TYPE_TIMESTAMP:
169 setType(MetaColumn::FDT_TIMESTAMP); break;
170
171 default:
172 throw DataFormatException("Unsupported data type.");
173 }
174 }
175
176
177 } } } // namespace Poco::Data::ODBC
178