1//
2// Utility.cpp
3//
4// Library: Data/ODBC
5// Package: ODBC
6// Module: Utility
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/Utility.h"
16#include "Poco/Data/ODBC/Handle.h"
17#include "Poco/Data/ODBC/ODBCException.h"
18#include "Poco/NumberFormatter.h"
19#include "Poco/DateTime.h"
20#include <cmath>
21
22
23namespace Poco {
24namespace Data {
25namespace ODBC {
26
27
28const TypeInfo Utility::_dataTypes;
29
30
31Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
32{
33 static const EnvironmentHandle henv;
34 const int length = sizeof(SQLCHAR) * 512;
35
36 SQLCHAR desc[length];
37 std::memset(desc, 0, length);
38 SQLSMALLINT len1 = length;
39 SQLCHAR attr[length];
40 std::memset(attr, 0, length);
41 SQLSMALLINT len2 = length;
42 RETCODE rc = 0;
43
44 if (!Utility::isError(rc = Poco::Data::ODBC::SQLDrivers(henv,
45 SQL_FETCH_FIRST,
46 desc,
47 length,
48 &len1,
49 attr,
50 len2,
51 &len2)))
52 {
53 do
54 {
55 driverMap.insert(DSNMap::value_type(std::string((char *) desc),
56 std::string((char *) attr)));
57 std::memset(desc, 0, length);
58 std::memset(attr, 0, length);
59 len2 = length;
60 }while (!Utility::isError(rc = Poco::Data::ODBC::SQLDrivers(henv,
61 SQL_FETCH_NEXT,
62 desc,
63 length,
64 &len1,
65 attr,
66 len2,
67 &len2)));
68 }
69
70 if (SQL_NO_DATA != rc)
71 throw EnvironmentException(henv);
72
73 return driverMap;
74}
75
76
77Utility::DSNMap& Utility::dataSources(Utility::DSNMap& dsnMap)
78{
79 static const EnvironmentHandle henv;
80 const int length = sizeof(SQLCHAR) * 512;
81 const int dsnLength = sizeof(SQLCHAR) * (SQL_MAX_DSN_LENGTH + 1);
82
83 SQLCHAR dsn[dsnLength];
84 std::memset(dsn, 0, dsnLength);
85 SQLSMALLINT len1 = sizeof(SQLCHAR) * SQL_MAX_DSN_LENGTH;
86 SQLCHAR desc[length];
87 std::memset(desc, 0, length);
88 SQLSMALLINT len2 = length;
89 RETCODE rc = 0;
90
91 while (!Utility::isError(rc = Poco::Data::ODBC::SQLDataSources(henv,
92 SQL_FETCH_NEXT,
93 dsn,
94 SQL_MAX_DSN_LENGTH,
95 &len1,
96 desc,
97 len2,
98 &len2)))
99 {
100 dsnMap.insert(DSNMap::value_type(std::string((char *) dsn), std::string((char *) desc)));
101 std::memset(dsn, 0, dsnLength);
102 std::memset(desc, 0, length);
103 len2 = length;
104 }
105
106 if (SQL_NO_DATA != rc)
107 throw EnvironmentException(henv);
108
109 return dsnMap;
110}
111
112
113void Utility::dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts)
114{
115 double msec = ts.fraction/1000000;
116 double usec = 1000 * (msec - std::floor(msec));
117
118 dt.assign(ts.year,
119 ts.month,
120 ts.day,
121 ts.hour,
122 ts.minute,
123 ts.second,
124 (int) std::floor(msec),
125 (int) std::floor(usec));
126}
127
128
129void Utility::dateSync(SQL_DATE_STRUCT& ds, const Date& d)
130{
131 ds.year = d.year();
132 ds.month = d.month();
133 ds.day = d.day();
134}
135
136
137void Utility::timeSync(SQL_TIME_STRUCT& ts, const Time& t)
138{
139 ts.hour = t.hour();
140 ts.minute = t.minute();
141 ts.second = t.second();
142}
143
144
145void Utility::dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt)
146{
147 ts.year = dt.year();
148 ts.month = dt.month();
149 ts.day = dt.day();
150 ts.hour = dt.hour();
151 ts.minute = dt.minute();
152 ts.second = dt.second();
153 // Fraction support is limited to milliseconds due to MS SQL Server limitation
154 // see http://support.microsoft.com/kb/263872
155 ts.fraction = (dt.millisecond() * 1000000);// + (dt.microsecond() * 1000);
156}
157
158
159} } } // namespace Poco::Data::ODBC
160