1 //
2 // Utility.h
3 //
4 // Library: Data/ODBC
5 // Package: ODBC
6 // Module:  Utility
7 //
8 // Definition of Utility.
9 //
10 // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier:	BSL-1.0
14 //
15 
16 
17 #ifndef Data_ODBC_Utility_INCLUDED
18 #define Data_ODBC_Utility_INCLUDED
19 
20 
21 #include "Poco/Data/ODBC/ODBC.h"
22 #include "Poco/Data/ODBC/TypeInfo.h"
23 #include "Poco/Data/Date.h"
24 #include "Poco/Data/Time.h"
25 #include "Poco/DateTime.h"
26 #include <sstream>
27 #include <map>
28 #include <sqltypes.h>
29 
30 
31 namespace Poco {
32 namespace Data {
33 namespace ODBC {
34 
35 
36 class ODBC_API Utility
37 	/// Various utility functions
38 {
39 public:
40 	typedef std::map<std::string, std::string> DSNMap;
41 	typedef DSNMap DriverMap;
42 
43 	static bool isError(SQLRETURN rc);
44 		/// Returns true if return code is error
45 
46 	static DriverMap& drivers(DriverMap& driverMap);
47 		/// Returns driver-attributes map of available ODBC drivers.
48 
49 	static DSNMap& dataSources(DSNMap& dsnMap);
50 		/// Returns DSN-description map of available ODBC data sources.
51 
52 	template<typename MapType, typename KeyArgType, typename ValueArgType>
mapInsert(MapType & m,const KeyArgType & k,const ValueArgType & v)53 	static typename MapType::iterator mapInsert(MapType& m, const KeyArgType& k, const ValueArgType& v)
54 		/// Utility map "insert or replace" function (from S. Meyers: Effective STL, Item 24)
55 	{
56 		typename MapType::iterator lb = m.lower_bound(k);
57 		if (lb != m.end() && !(m.key_comp()(k, lb->first)))
58 		{
59 			lb->second = v;
60 			return lb;
61 		}
62 		else
63 		{
64 			typedef typename MapType::value_type MVT;
65 			return m.insert(lb, MVT(k,v));
66 		}
67 	}
68 
69 	static int cDataType(int sqlDataType);
70 		/// Returns C data type corresponding to supplied SQL data type.
71 
72 	static int sqlDataType(int cDataType);
73 		/// Returns SQL data type corresponding to supplied C data type.
74 
75 	static void dateSync(Date& dt, const SQL_DATE_STRUCT& ts);
76 		/// Transfers data from ODBC SQL_DATE_STRUCT to Poco::DateTime.
77 
78 	template <typename T, typename F>
dateSync(T & d,const F & ds)79 	static void dateSync(T& d, const F& ds)
80 		/// Transfers data from ODBC SQL_DATE_STRUCT container to Poco::DateTime container.
81 	{
82 		std::size_t size = ds.size();
83 		if (d.size() != size) d.resize(size);
84 		typename T::iterator dIt = d.begin();
85 		typename F::const_iterator it = ds.begin();
86 		typename F::const_iterator end = ds.end();
87 		for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
88 	}
89 
90 	static void timeSync(Time& dt, const SQL_TIME_STRUCT& ts);
91 		/// Transfers data from ODBC SQL_TIME_STRUCT to Poco::DateTime.
92 
93 	template <typename T, typename F>
timeSync(T & t,const F & ts)94 	static void timeSync(T& t, const F& ts)
95 		/// Transfers data from ODBC SQL_TIME_STRUCT container to Poco::DateTime container.
96 	{
97 		std::size_t size = ts.size();
98 		if (t.size() != size) t.resize(size);
99 		typename T::iterator dIt = t.begin();
100 		typename F::const_iterator it = ts.begin();
101 		typename F::const_iterator end = ts.end();
102 		for (; it != end; ++it, ++dIt) timeSync(*dIt, *it);
103 	}
104 
105 	static void dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts);
106 		/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT to Poco::DateTime.
107 
108 	template <typename T, typename F>
dateTimeSync(T & dt,const F & ts)109 	static void dateTimeSync(T& dt, const F& ts)
110 		/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT container to Poco::DateTime container.
111 	{
112 		std::size_t size = ts.size();
113 		if (dt.size() != size) dt.resize(size);
114 		typename T::iterator dIt = dt.begin();
115 		typename F::const_iterator it = ts.begin();
116 		typename F::const_iterator end = ts.end();
117 		for (; it != end; ++it, ++dIt) dateTimeSync(*dIt, *it);
118 	}
119 
120 	static void dateSync(SQL_DATE_STRUCT& ts, const Date& dt);
121 		/// Transfers data from Poco::Data::Date to ODBC SQL_DATE_STRUCT.
122 
123 	template <typename C>
dateSync(std::vector<SQL_DATE_STRUCT> & ds,const C & d)124 	static void dateSync(std::vector<SQL_DATE_STRUCT>& ds, const C& d)
125 		/// Transfers data from Poco::Data::Date vector to ODBC SQL_DATE_STRUCT container.
126 	{
127 		std::size_t size = d.size();
128 		if (ds.size() != size) ds.resize(size);
129 		std::vector<SQL_DATE_STRUCT>::iterator dIt = ds.begin();
130 		typename C::const_iterator it = d.begin();
131 		typename C::const_iterator end = d.end();
132 		for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
133 	}
134 
135 	static void timeSync(SQL_TIME_STRUCT& ts, const Time& dt);
136 		/// Transfers data from Poco::Data::Time to ODBC SQL_TIME_STRUCT.
137 
138 	template <typename C>
timeSync(std::vector<SQL_TIME_STRUCT> & ts,const C & t)139 	static void timeSync(std::vector<SQL_TIME_STRUCT>& ts, const C& t)
140 		/// Transfers data from Poco::Data::Time container to ODBC SQL_TIME_STRUCT vector.
141 	{
142 		std::size_t size = t.size();
143 		if (ts.size() != size) ts.resize(size);
144 		std::vector<SQL_TIME_STRUCT>::iterator tIt = ts.begin();
145 		typename C::const_iterator it = t.begin();
146 		typename C::const_iterator end = t.end();
147 		for (; it != end; ++it, ++tIt) timeSync(*tIt, *it);
148 	}
149 
150 	static void dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt);
151 		/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
152 
153 	template <typename C>
dateTimeSync(std::vector<SQL_TIMESTAMP_STRUCT> & ts,const C & dt)154 	static void dateTimeSync(std::vector<SQL_TIMESTAMP_STRUCT>& ts, const C& dt)
155 		/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
156 	{
157 		std::size_t size = dt.size();
158 		if (ts.size() != size) ts.resize(size);
159 		std::vector<SQL_TIMESTAMP_STRUCT>::iterator tIt = ts.begin();
160 		typename C::const_iterator it = dt.begin();
161 		typename C::const_iterator end = dt.end();
162 		for (; it != end; ++it, ++tIt) dateTimeSync(*tIt, *it);
163 	}
164 
165 private:
166 	static const TypeInfo _dataTypes;
167 		/// C <==> SQL data type mapping
168 };
169 
170 
171 ///
172 /// inlines
173 ///
isError(SQLRETURN rc)174 inline bool Utility::isError(SQLRETURN rc)
175 {
176 	return (0 != (rc & (~1)));
177 }
178 
179 
cDataType(int sqlDataType)180 inline int Utility::cDataType(int sqlDataType)
181 {
182 	return _dataTypes.cDataType(sqlDataType);
183 }
184 
185 
sqlDataType(int cDataType)186 inline int Utility::sqlDataType(int cDataType)
187 {
188 	return _dataTypes.sqlDataType(cDataType);
189 }
190 
191 
dateSync(Date & d,const SQL_DATE_STRUCT & ts)192 inline void Utility::dateSync(Date& d, const SQL_DATE_STRUCT& ts)
193 {
194 	d.assign(ts.year, ts.month, ts.day);
195 }
196 
197 
timeSync(Time & t,const SQL_TIME_STRUCT & ts)198 inline void Utility::timeSync(Time& t, const SQL_TIME_STRUCT& ts)
199 {
200 	t.assign(ts.hour, ts.minute, ts.second);
201 }
202 
203 
204 } } } // namespace Poco::Data::ODBC
205 
206 
207 #endif
208