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 | |
23 | namespace Poco { |
24 | namespace Data { |
25 | namespace ODBC { |
26 | |
27 | |
28 | const TypeInfo Utility::_dataTypes; |
29 | |
30 | |
31 | Utility::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 | |
77 | Utility::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 | |
113 | void 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 | |
129 | void 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 | |
137 | void 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 | |
145 | void 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 | |