1 //
2 // Binder.h
3 //
4 // Library: Data/ODBC
5 // Package: ODBC
6 // Module:  Binder
7 //
8 // Definition of the Binder class.
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_Binder_INCLUDED
18 #define Data_ODBC_Binder_INCLUDED
19 
20 
21 #include "Poco/Data/ODBC/ODBC.h"
22 #include "Poco/Data/AbstractBinder.h"
23 #include "Poco/Data/LOB.h"
24 #include "Poco/Data/ODBC/Handle.h"
25 #include "Poco/Data/ODBC/Parameter.h"
26 #include "Poco/Data/ODBC/ODBCMetaColumn.h"
27 #include "Poco/Data/ODBC/Utility.h"
28 #include "Poco/Data/ODBC/TypeInfo.h"
29 #include "Poco/Exception.h"
30 #include <vector>
31 #include <deque>
32 #include <list>
33 #include <map>
34 #ifdef POCO_OS_FAMILY_WINDOWS
35 #include <windows.h>
36 #endif
37 #include <sqlext.h>
38 
39 
40 namespace Poco {
41 
42 
43 class DateTime;
44 
45 
46 namespace Data {
47 
48 
49 class Date;
50 class Time;
51 
52 
53 namespace ODBC {
54 
55 
56 class ODBC_API Binder: public Poco::Data::AbstractBinder
57 	/// Binds placeholders in the sql query to the provided values. Performs data types mapping.
58 {
59 public:
60 	typedef AbstractBinder::Direction Direction;
61 	typedef std::map<SQLPOINTER, SQLLEN> ParamMap;
62 
63 	static const size_t DEFAULT_PARAM_SIZE = 1024;
64 
65 	enum ParameterBinding
66 	{
67 		PB_IMMEDIATE,
68 		PB_AT_EXEC
69 	};
70 
71 	Binder(const StatementHandle& rStmt,
72 		std::size_t maxFieldSize,
73 		ParameterBinding dataBinding = PB_IMMEDIATE,
74 		const TypeInfo* pDataTypes = 0);
75 		/// Creates the Binder.
76 
77 	~Binder();
78 		/// Destroys the Binder.
79 
80 	void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
81 		/// Binds an Int8.
82 
83 	void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir);
84 		/// Binds an Int8 vector.
85 
86 	void bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir);
87 		/// Binds an Int8 deque.
88 
89 	void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir);
90 		/// Binds an Int8 list.
91 
92 	void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
93 		/// Binds an UInt8.
94 
95 	void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir);
96 		/// Binds an UInt8 vector.
97 
98 	void bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir);
99 		/// Binds an UInt8 deque.
100 
101 	void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir);
102 		/// Binds an UInt8 list.
103 
104 	void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
105 		/// Binds an Int16.
106 
107 	void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir);
108 		/// Binds an Int16 vector.
109 
110 	void bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir);
111 		/// Binds an Int16 deque.
112 
113 	void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir);
114 		/// Binds an Int16 list.
115 
116 	void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
117 		/// Binds an UInt16.
118 
119 	void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir);
120 		/// Binds an UInt16 vector.
121 
122 	void bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir);
123 		/// Binds an UInt16 deque.
124 
125 	void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir);
126 		/// Binds an UInt16 list.
127 
128 	void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
129 		/// Binds an Int32.
130 
131 	void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir);
132 		/// Binds an Int32 vector.
133 
134 	void bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir);
135 		/// Binds an Int32 deque.
136 
137 	void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir);
138 		/// Binds an Int32 list.
139 
140 	void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
141 		/// Binds an UInt32.
142 
143 	void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir);
144 		/// Binds an UInt32 vector.
145 
146 	void bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir);
147 		/// Binds an UInt32 deque.
148 
149 	void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir);
150 		/// Binds an UInt32 list.
151 
152 	void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
153 		/// Binds an Int64.
154 
155 	void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir);
156 		/// Binds an Int64 vector.
157 
158 	void bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir);
159 		/// Binds an Int64 deque.
160 
161 	void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir);
162 		/// Binds an Int64 list.
163 
164 	void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
165 		/// Binds an UInt64.
166 
167 	void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir);
168 		/// Binds an UInt64 vector.
169 
170 	void bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir);
171 		/// Binds an UInt64 deque.
172 
173 	void bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir);
174 		/// Binds an UInt64 list.
175 
176 #ifndef POCO_INT64_IS_LONG
177 	void bind(std::size_t pos, const long& val, Direction dir);
178 		/// Binds a long.
179 
180 	void bind(std::size_t pos, const unsigned long& val, Direction dir);
181 		/// Binds an unsigned long.
182 
183 	void bind(std::size_t pos, const std::vector<long>& val, Direction dir);
184 		/// Binds a long vector.
185 
186 	void bind(std::size_t pos, const std::deque<long>& val, Direction dir);
187 		/// Binds a long deque.
188 
189 	void bind(std::size_t pos, const std::list<long>& val, Direction dir);
190 		/// Binds a long list.
191 #endif
192 
193 	void bind(std::size_t pos, const bool& val, Direction dir);
194 		/// Binds a boolean.
195 
196 	void bind(std::size_t pos, const std::vector<bool>& val, Direction dir);
197 		/// Binds a boolean vector.
198 
199 	void bind(std::size_t pos, const std::deque<bool>& val, Direction dir);
200 		/// Binds a boolean deque.
201 
202 	void bind(std::size_t pos, const std::list<bool>& val, Direction dir);
203 		/// Binds a boolean list.
204 
205 	void bind(std::size_t pos, const float& val, Direction dir);
206 		/// Binds a float.
207 
208 	void bind(std::size_t pos, const std::vector<float>& val, Direction dir);
209 		/// Binds a float vector.
210 
211 	void bind(std::size_t pos, const std::deque<float>& val, Direction dir);
212 		/// Binds a float deque.
213 
214 	void bind(std::size_t pos, const std::list<float>& val, Direction dir);
215 		/// Binds a float list.
216 
217 	void bind(std::size_t pos, const double& val, Direction dir);
218 		/// Binds a double.
219 
220 	void bind(std::size_t pos, const std::vector<double>& val, Direction dir);
221 		/// Binds a double vector.
222 
223 	void bind(std::size_t pos, const std::deque<double>& val, Direction dir);
224 		/// Binds a double deque.
225 
226 	void bind(std::size_t pos, const std::list<double>& val, Direction dir);
227 		/// Binds a double list.
228 
229 	void bind(std::size_t pos, const char& val, Direction dir);
230 		/// Binds a single character.
231 
232 	void bind(std::size_t pos, const std::vector<char>& val, Direction dir);
233 		/// Binds a character vector.
234 
235 	void bind(std::size_t pos, const std::deque<char>& val, Direction dir);
236 		/// Binds a character deque.
237 
238 	void bind(std::size_t pos, const std::list<char>& val, Direction dir);
239 		/// Binds a character list.
240 
241 	void bind(std::size_t pos, const std::string& val, Direction dir);
242 		/// Binds a string.
243 
244 	void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir);
245 		/// Binds a string vector.
246 
247 	void bind(std::size_t pos, const std::deque<std::string>& val, Direction dir);
248 		/// Binds a string deque.
249 
250 	void bind(std::size_t pos, const std::list<std::string>& val, Direction dir);
251 		/// Binds a string list.
252 
253 	void bind(std::size_t pos, const UTF16String& val, Direction dir);
254 		/// Binds a string.
255 
256 	void bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir);
257 		/// Binds a string vector.
258 
259 	void bind(std::size_t pos, const std::deque<UTF16String>& val, Direction dir);
260 		/// Binds a string deque.
261 
262 	void bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir);
263 		/// Binds a string list.
264 
265 	void bind(std::size_t pos, const BLOB& val, Direction dir);
266 		/// Binds a BLOB. In-bound only.
267 
268 	void bind(std::size_t pos, const CLOB& val, Direction dir);
269 		/// Binds a CLOB. In-bound only.
270 
271 	void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir);
272 		/// Binds a BLOB vector.
273 
274 	void bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir);
275 		/// Binds a BLOB deque.
276 
277 	void bind(std::size_t pos, const std::list<BLOB>& val, Direction dir);
278 		/// Binds a BLOB list.
279 
280 	void bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir);
281 		/// Binds a CLOB vector.
282 
283 	void bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir);
284 		/// Binds a CLOB deque.
285 
286 	void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir);
287 		/// Binds a CLOB list.
288 
289 	void bind(std::size_t pos, const Date& val, Direction dir);
290 		/// Binds a Date.
291 
292 	void bind(std::size_t pos, const std::vector<Date>& val, Direction dir);
293 		/// Binds a Date vector.
294 
295 	void bind(std::size_t pos, const std::deque<Date>& val, Direction dir);
296 		/// Binds a Date deque.
297 
298 	void bind(std::size_t pos, const std::list<Date>& val, Direction dir);
299 		/// Binds a Date list.
300 
301 	void bind(std::size_t pos, const Time& val, Direction dir);
302 		/// Binds a Time.
303 
304 	void bind(std::size_t pos, const std::vector<Time>& val, Direction dir);
305 		/// Binds a Time vector.
306 
307 	void bind(std::size_t pos, const std::deque<Time>& val, Direction dir);
308 		/// Binds a Time deque.
309 
310 	void bind(std::size_t pos, const std::list<Time>& val, Direction dir);
311 		/// Binds a Time list.
312 
313 	void bind(std::size_t pos, const DateTime& val, Direction dir);
314 		/// Binds a DateTime.
315 
316 	void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir);
317 		/// Binds a DateTime vector.
318 
319 	void bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir);
320 		/// Binds a DateTime deque.
321 
322 	void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
323 		/// Binds a DateTime list.
324 
325 	void bind(std::size_t pos, const NullData& val, Direction dir);
326 		/// Binds a null. In-bound only.
327 
328 	void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir);
329 		/// Binds a null vector.
330 
331 	void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir);
332 		/// Binds a null deque.
333 
334 	void bind(std::size_t pos, const std::list<NullData>& val, Direction dir);
335 		/// Binds a null list.
336 
337 	void setDataBinding(ParameterBinding binding);
338 		/// Set data binding type.
339 
340 	ParameterBinding getDataBinding() const;
341 		/// Return data binding type.
342 
343 	std::size_t parameterSize(SQLPOINTER pAddr) const;
344 		/// Returns bound data size for parameter at specified position.
345 
346 	void synchronize();
347 		/// Transfers the results of non-POD outbound parameters from internal
348 		/// holders back into the externally supplied buffers.
349 
350 	void reset();
351 		/// Clears the cached storage.
352 
353 private:
354 	typedef std::vector<SQLLEN*>                             LengthPtrVec;
355 	typedef std::vector<SQLLEN>                              LengthVec;
356 	typedef std::vector<LengthVec*>                          LengthVecVec;
357 	typedef std::vector<char*>                               CharPtrVec;
358 	typedef std::vector<UTF16Char*>                          UTF16CharPtrVec;
359 	typedef std::vector<bool*>                               BoolPtrVec;
360 	typedef std::vector<SQL_DATE_STRUCT>                     DateVec;
361 	typedef std::vector<DateVec*>                            DateVecVec;
362 	typedef std::vector<SQL_TIME_STRUCT>                     TimeVec;
363 	typedef std::vector<TimeVec*>                            TimeVecVec;
364 	typedef std::vector<SQL_TIMESTAMP_STRUCT>                DateTimeVec;
365 	typedef std::vector<DateTimeVec*>                        DateTimeVecVec;
366 	typedef std::vector<Poco::Any>                           AnyVec;
367 	typedef std::vector<AnyVec>                              AnyVecVec;
368 	typedef std::map<char*, std::string*>                    StringMap;
369 	typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
370 	typedef std::map<SQL_DATE_STRUCT*, Date*>                DateMap;
371 	typedef std::map<SQL_TIME_STRUCT*, Time*>                TimeMap;
372 	typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*>       TimestampMap;
373 
374 	void describeParameter(std::size_t pos);
375 		/// Sets the description field for the parameter, if needed.
376 
377 	void bind(std::size_t pos, const char* const& pVal, Direction dir);
378 		/// Binds a const char ptr.
379 		/// This is a private no-op in this implementation
380 		/// due to security risk.
381 
382 	SQLSMALLINT toODBCDirection(Direction dir) const;
383 		/// Returns ODBC parameter direction based on the parameter binding direction
384 		/// specified by user.
385 
386 	template <typename T>
bindImpl(std::size_t pos,T & val,SQLSMALLINT cDataType,Direction dir)387 	void bindImpl(std::size_t pos, T& val, SQLSMALLINT cDataType, Direction dir)
388 	{
389 		SQLINTEGER colSize = 0;
390 		SQLSMALLINT decDigits = 0;
391 		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
392 
393 		_lengthIndicator.push_back(0);
394 
395 		if (Utility::isError(SQLBindParameter(_rStmt,
396 			(SQLUSMALLINT) pos + 1,
397 			toODBCDirection(dir),
398 			cDataType,
399 			Utility::sqlDataType(cDataType),
400 			colSize,
401 			decDigits,
402 			(SQLPOINTER) &val, 0, 0)))
403 		{
404 			throw StatementException(_rStmt, "SQLBindParameter()");
405 		}
406 	}
407 
408 	template <typename L>
bindImplLOB(std::size_t pos,const L & val,Direction dir)409 	void bindImplLOB(std::size_t pos, const L& val, Direction dir)
410 	{
411 		if (isOutBound(dir) || !isInBound(dir))
412 			throw NotImplementedException("LOB parameter type can only be inbound.");
413 
414 		SQLPOINTER pVal = (SQLPOINTER) val.rawContent();
415 		SQLINTEGER size = (SQLINTEGER) val.size();
416 
417 		_inParams.insert(ParamMap::value_type(pVal, size));
418 
419 		SQLLEN* pLenIn = new SQLLEN;
420 		*pLenIn  = size;
421 
422 		if (PB_AT_EXEC == _paramBinding)
423 			*pLenIn  = SQL_LEN_DATA_AT_EXEC(size);
424 
425 		_lengthIndicator.push_back(pLenIn);
426 
427 		if (Utility::isError(SQLBindParameter(_rStmt,
428 			(SQLUSMALLINT) pos + 1,
429 			SQL_PARAM_INPUT,
430 			SQL_C_BINARY,
431 			SQL_LONGVARBINARY,
432 			(SQLUINTEGER) size,
433 			0,
434 			pVal,
435 			(SQLINTEGER) size,
436 			_lengthIndicator.back())))
437 		{
438 			throw StatementException(_rStmt, "SQLBindParameter(LOB)");
439 		}
440 	}
441 
442 	template <typename T>
bindImplVec(std::size_t pos,const std::vector<T> & val,SQLSMALLINT cDataType,Direction dir)443 	void bindImplVec(std::size_t pos, const std::vector<T>& val, SQLSMALLINT cDataType, Direction dir)
444 	{
445 		if (PB_IMMEDIATE != _paramBinding)
446 			throw InvalidAccessException("std::vector can only be bound immediately.");
447 
448 		std::size_t length = val.size();
449 		SQLINTEGER colSize = 0;
450 		SQLSMALLINT decDigits = 0;
451 		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
452 		setParamSetSize(length);
453 
454 		if (_vecLengthIndicator.size() <= pos)
455 		{
456 			_vecLengthIndicator.resize(pos + 1, 0);
457 			_vecLengthIndicator[pos] = new LengthVec(length);
458 		}
459 
460 		if (Utility::isError(SQLBindParameter(_rStmt,
461 			(SQLUSMALLINT) pos + 1,
462 			toODBCDirection(dir),
463 			cDataType,
464 			Utility::sqlDataType(cDataType),
465 			colSize,
466 			decDigits,
467 			(SQLPOINTER) &val[0],
468 			0,
469 			&(*_vecLengthIndicator[pos])[0])))
470 		{
471 			throw StatementException(_rStmt, "SQLBindParameter()");
472 		}
473 	}
474 
475 	template <typename C>
bindImplContainer(std::size_t pos,const C & val,SQLSMALLINT cDataType,Direction dir)476 	void bindImplContainer(std::size_t pos, const C& val, SQLSMALLINT cDataType, Direction dir)
477 		/// Utility function - a "stand-in" for non-vector containers.
478 		/// Creates, fills and stores the reference to the replacement std::vector container
479 		/// for std::deque and std::list. Calls std::vector binding.
480 	{
481 		typedef typename C::value_type Type;
482 
483 		if (_containers.size() <= pos)
484 			_containers.resize(pos + 1);
485 
486 		_containers[pos].push_back(std::vector<Type>());
487 
488 		std::vector<Type>& cont = RefAnyCast<std::vector<Type> >(_containers[pos].back());
489 		cont.assign(val.begin(), val.end());
490 		bindImplVec(pos, cont, cDataType, dir);
491 	}
492 
493 	template <typename C>
bindImplContainerBool(std::size_t pos,const C & val,SQLSMALLINT cDataType,Direction dir)494 	void bindImplContainerBool(std::size_t pos, const C& val, SQLSMALLINT cDataType, Direction dir)
495 	{
496 		if (PB_IMMEDIATE != _paramBinding)
497 			throw InvalidAccessException("std::vector can only be bound immediately.");
498 
499 		std::size_t length = val.size();
500 		SQLINTEGER colSize = 0;
501 		SQLSMALLINT decDigits = 0;
502 		getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
503 
504 		setParamSetSize(val.size());
505 
506 		if (_vecLengthIndicator.size() <= pos)
507 		{
508 			_vecLengthIndicator.resize(pos + 1, 0);
509 			_vecLengthIndicator[pos] = new LengthVec(length);
510 		}
511 
512 		if (_boolPtrs.size() <= pos)
513 			_boolPtrs.resize(pos + 1);
514 
515 		_boolPtrs[pos] = new bool[val.size()];
516 
517 		typename C::const_iterator it = val.begin();
518 		typename C::const_iterator end = val.end();
519 		for (int i = 0; it != end; ++it, ++i) _boolPtrs[pos][i] = *it;
520 
521 		if (Utility::isError(SQLBindParameter(_rStmt,
522 			(SQLUSMALLINT) pos + 1,
523 			toODBCDirection(dir),
524 			cDataType,
525 			Utility::sqlDataType(cDataType),
526 			colSize,
527 			decDigits,
528 			(SQLPOINTER) &_boolPtrs[pos][0],
529 			0,
530 			&(*_vecLengthIndicator[pos])[0])))
531 		{
532 			throw StatementException(_rStmt, "SQLBindParameter()");
533 		}
534 	}
535 
536 	template <typename C>
bindImplContainerString(std::size_t pos,const C & val,Direction dir)537 	void bindImplContainerString(std::size_t pos, const C& val, Direction dir)
538 		/// Utility function to bind containers of strings.
539 	{
540 		if (isOutBound(dir) || !isInBound(dir))
541 			throw NotImplementedException("String container parameter type can only be inbound.");
542 
543 		if (PB_IMMEDIATE != _paramBinding)
544 			throw InvalidAccessException("Containers can only be bound immediately.");
545 
546 		std::size_t length = val.size();
547 
548 		if (0 == length)
549 			throw InvalidArgumentException("Empty container not allowed.");
550 
551 		setParamSetSize(length);
552 
553 		SQLINTEGER size = 0;
554 		getColumnOrParameterSize(pos, size);
555 		poco_assert (size > 0);
556 
557 		if (size == _maxFieldSize)
558 		{
559 			getMinValueSize(val, size);
560 			// accomodate for terminating zero
561 			if (size != _maxFieldSize) ++size;
562 		}
563 
564 		if (_vecLengthIndicator.size() <= pos)
565 		{
566 			_vecLengthIndicator.resize(pos + 1, 0);
567 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1, SQL_NTS);
568 		}
569 
570 		if (_charPtrs.size() <= pos)
571 			_charPtrs.resize(pos + 1, 0);
572 
573 		_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
574 
575 		std::size_t strSize;
576 		std::size_t offset = 0;
577 		typename C::const_iterator it = val.begin();
578 		typename C::const_iterator end = val.end();
579 		for (; it != end; ++it)
580 		{
581 			strSize = it->size();
582 			if (strSize > size)
583 				throw LengthExceededException("SQLBindParameter(std::vector<std::string>)");
584 			std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
585 			offset += size;
586 		}
587 
588 		if (Utility::isError(SQLBindParameter(_rStmt,
589 			(SQLUSMALLINT) pos + 1,
590 			toODBCDirection(dir),
591 			SQL_C_CHAR,
592 			SQL_LONGVARCHAR,
593 			(SQLUINTEGER) size - 1,
594 			0,
595 			_charPtrs[pos],
596 			(SQLINTEGER) size,
597 			&(*_vecLengthIndicator[pos])[0])))
598 		{
599 			throw StatementException(_rStmt, "SQLBindParameter(std::vector<std::string>)");
600 		}
601 	}
602 
603 	template <typename C>
bindImplContainerUTF16String(std::size_t pos,const C & val,Direction dir)604 	void bindImplContainerUTF16String(std::size_t pos, const C& val, Direction dir)
605 		/// Utility function to bind containers of strings.
606 	{
607 		if (isOutBound(dir) || !isInBound(dir))
608 			throw NotImplementedException("String container parameter type can only be inbound.");
609 
610 		if (PB_IMMEDIATE != _paramBinding)
611 			throw InvalidAccessException("Containers can only be bound immediately.");
612 
613 		std::size_t length = val.size();
614 		if (0 == length)
615 			throw InvalidArgumentException("Empty container not allowed.");
616 
617 		setParamSetSize(val.size());
618 
619 		SQLINTEGER size = 0;
620 		getColumnOrParameterSize(pos, size);
621 		poco_assert(size > 0);
622 
623 		if (size == _maxFieldSize)
624 		{
625 			getMinValueSize(val, size);
626 			// accomodate for terminating zero
627 			if (size != _maxFieldSize) size += sizeof(UTF16Char);
628 		}
629 
630 		if (_vecLengthIndicator.size() <= pos)
631 		{
632 			_vecLengthIndicator.resize(pos + 1, 0);
633 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1, SQL_NTS);
634 		}
635 
636 		if (_utf16CharPtrs.size() <= pos)
637 			_utf16CharPtrs.resize(pos + 1, 0);
638 
639 		_utf16CharPtrs[pos] = (UTF16Char*)std::calloc(val.size() * size, sizeof(UTF16Char));
640 
641 		std::size_t strSize;
642 		std::size_t offset = 0;
643 		char* pBuf = (char*)_utf16CharPtrs[pos];
644 		typename C::const_iterator it = val.begin();
645 		typename C::const_iterator end = val.end();
646 		for (; it != end; ++it)
647 		{
648 			strSize = it->size() * sizeof(UTF16Char);
649 			if (strSize > size)
650 				throw LengthExceededException("SQLBindParameter(std::vector<UTF16String>)");
651 			std::memcpy(pBuf + offset, it->data(), strSize);
652 			offset += size;
653 		}
654 
655 		if (Utility::isError(SQLBindParameter(_rStmt,
656 			(SQLUSMALLINT)pos + 1,
657 			toODBCDirection(dir),
658 			SQL_C_WCHAR,
659 			SQL_WLONGVARCHAR,
660 			(SQLUINTEGER)size - 1,
661 			0,
662 			_utf16CharPtrs[pos],
663 			(SQLINTEGER)size,
664 			&(*_vecLengthIndicator[pos])[0])))
665 		{
666 			throw StatementException(_rStmt, "SQLBindParameter(std::vector<UTF16String>)");
667 		}
668 	}
669 
670 	template <typename C>
bindImplContainerLOB(std::size_t pos,const C & val,Direction dir)671 	void bindImplContainerLOB(std::size_t pos, const C& val, Direction dir)
672 	{
673 		typedef typename C::value_type LOBType;
674 		typedef typename LOBType::ValueType CharType;
675 
676 		if (isOutBound(dir) || !isInBound(dir))
677 			throw NotImplementedException("BLOB container parameter type can only be inbound.");
678 
679 		if (PB_IMMEDIATE != _paramBinding)
680 			throw InvalidAccessException("Containers can only be bound immediately.");
681 
682 		std::size_t length = val.size();
683 		if (0 == length)
684 			throw InvalidArgumentException("Empty container not allowed.");
685 
686 		setParamSetSize(length);
687 
688 		SQLINTEGER size = 0;
689 
690 		if (_vecLengthIndicator.size() <= pos)
691 		{
692 			_vecLengthIndicator.resize(pos + 1, 0);
693 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
694 		}
695 
696 		std::vector<SQLLEN>::iterator lIt = _vecLengthIndicator[pos]->begin();
697 		std::vector<SQLLEN>::iterator lEnd = _vecLengthIndicator[pos]->end();
698 		typename C::const_iterator cIt = val.begin();
699 		for (; lIt != lEnd; ++lIt, ++cIt)
700 		{
701 			SQLLEN sz = static_cast<SQLLEN>(cIt->size());
702 			if (sz > size) size = static_cast<SQLINTEGER>(sz);
703 			*lIt = sz;
704 		}
705 
706 		if (_charPtrs.size() <= pos)
707 			_charPtrs.resize(pos + 1, 0);
708 
709 		_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(CharType));
710 		poco_check_ptr (_charPtrs[pos]);
711 
712 		std::size_t blobSize;
713 		std::size_t offset = 0;
714 		cIt = val.begin();
715 		typename C::const_iterator cEnd = val.end();
716 		for (; cIt != cEnd; ++cIt)
717 		{
718 			blobSize = cIt->size();
719 			if (blobSize > size)
720 				throw LengthExceededException("SQLBindParameter(std::vector<BLOB>)");
721 			std::memcpy(_charPtrs[pos] + offset, cIt->rawContent(), blobSize * sizeof(CharType));
722 			offset += size;
723 		}
724 
725 		if (Utility::isError(SQLBindParameter(_rStmt,
726 			(SQLUSMALLINT) pos + 1,
727 			SQL_PARAM_INPUT,
728 			SQL_C_BINARY,
729 			SQL_LONGVARBINARY,
730 			(SQLUINTEGER) size,
731 			0,
732 			_charPtrs[pos],
733 			(SQLINTEGER) size,
734 			&(*_vecLengthIndicator[pos])[0])))
735 		{
736 			throw StatementException(_rStmt, "SQLBindParameter(std::vector<BLOB>)");
737 		}
738 	}
739 
740 	template<typename C>
bindImplContainerDate(std::size_t pos,const C & val,Direction dir)741 	void bindImplContainerDate(std::size_t pos, const C& val, Direction dir)
742 	{
743 		if (isOutBound(dir) || !isInBound(dir))
744 			throw NotImplementedException("Date vector parameter type can only be inbound.");
745 
746 		if (PB_IMMEDIATE != _paramBinding)
747 			throw InvalidAccessException("std::vector can only be bound immediately.");
748 
749 		std::size_t length = val.size();
750 
751 		if (0 == length)
752 			throw InvalidArgumentException("Empty vector not allowed.");
753 
754 		setParamSetSize(length);
755 
756 		if (_vecLengthIndicator.size() <= pos)
757 		{
758 			_vecLengthIndicator.resize(pos + 1, 0);
759 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
760 		}
761 
762 		if (_dateVecVec.size() <= pos)
763 		{
764 			_dateVecVec.resize(pos + 1, 0);
765 			_dateVecVec[pos] = new DateVec(length ? length : 1);
766 		}
767 
768 		Utility::dateSync(*_dateVecVec[pos], val);
769 
770 		SQLINTEGER colSize = 0;
771 		SQLSMALLINT decDigits = 0;
772 		getColSizeAndPrecision(pos, SQL_TYPE_DATE, colSize, decDigits);
773 
774 		if (Utility::isError(SQLBindParameter(_rStmt,
775 			(SQLUSMALLINT) pos + 1,
776 			toODBCDirection(dir),
777 			SQL_C_TYPE_DATE,
778 			SQL_TYPE_DATE,
779 			colSize,
780 			decDigits,
781 			(SQLPOINTER) &(*_dateVecVec[pos])[0],
782 			0,
783 			&(*_vecLengthIndicator[pos])[0])))
784 		{
785 			throw StatementException(_rStmt, "SQLBindParameter(Date[])");
786 		}
787 	}
788 
789 	template<typename C>
bindImplContainerTime(std::size_t pos,const C & val,Direction dir)790 	void bindImplContainerTime(std::size_t pos, const C& val, Direction dir)
791 	{
792 		if (isOutBound(dir) || !isInBound(dir))
793 			throw NotImplementedException("Time container parameter type can only be inbound.");
794 
795 		if (PB_IMMEDIATE != _paramBinding)
796 			throw InvalidAccessException("Containers can only be bound immediately.");
797 
798 		std::size_t length = val.size();
799 		if (0 == length)
800 			throw InvalidArgumentException("Empty container not allowed.");
801 
802 		setParamSetSize(val.size());
803 
804 		if (_vecLengthIndicator.size() <= pos)
805 		{
806 			_vecLengthIndicator.resize(pos + 1, 0);
807 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
808 		}
809 
810 		if (_timeVecVec.size() <= pos)
811 		{
812 			_timeVecVec.resize(pos + 1, 0);
813 			_timeVecVec[pos] = new TimeVec(length ? length : 1);
814 		}
815 
816 		Utility::timeSync(*_timeVecVec[pos], val);
817 
818 		SQLINTEGER colSize = 0;
819 		SQLSMALLINT decDigits = 0;
820 		getColSizeAndPrecision(pos, SQL_TYPE_TIME, colSize, decDigits);
821 
822 		if (Utility::isError(SQLBindParameter(_rStmt,
823 			(SQLUSMALLINT) pos + 1,
824 			toODBCDirection(dir),
825 			SQL_C_TYPE_TIME,
826 			SQL_TYPE_TIME,
827 			colSize,
828 			decDigits,
829 			(SQLPOINTER) &(*_timeVecVec[pos])[0],
830 			0,
831 			&(*_vecLengthIndicator[pos])[0])))
832 		{
833 			throw StatementException(_rStmt, "SQLBindParameter(Time[])");
834 		}
835 	}
836 
837 	template<typename C>
bindImplContainerDateTime(std::size_t pos,const C & val,Direction dir)838 	void bindImplContainerDateTime(std::size_t pos, const C& val, Direction dir)
839 	{
840 		if (isOutBound(dir) || !isInBound(dir))
841 			throw NotImplementedException("DateTime container parameter type can only be inbound.");
842 
843 		if (PB_IMMEDIATE != _paramBinding)
844 			throw InvalidAccessException("Containers can only be bound immediately.");
845 
846 		std::size_t length = val.size();
847 
848 		if (0 == length)
849 			throw InvalidArgumentException("Empty Containers not allowed.");
850 
851 		setParamSetSize(length);
852 
853 		if (_vecLengthIndicator.size() <= pos)
854 		{
855 			_vecLengthIndicator.resize(pos + 1, 0);
856 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
857 		}
858 
859 		if (_dateTimeVecVec.size() <= pos)
860 		{
861 			_dateTimeVecVec.resize(pos + 1, 0);
862 			_dateTimeVecVec[pos] = new DateTimeVec(length ? length : 1);
863 		}
864 
865 		Utility::dateTimeSync(*_dateTimeVecVec[pos], val);
866 
867 		SQLINTEGER colSize = 0;
868 		SQLSMALLINT decDigits = 0;
869 		getColSizeAndPrecision(pos, SQL_TYPE_TIMESTAMP, colSize, decDigits);
870 
871 		if (Utility::isError(SQLBindParameter(_rStmt,
872 			(SQLUSMALLINT) pos + 1,
873 			toODBCDirection(dir),
874 			SQL_C_TYPE_TIMESTAMP,
875 			SQL_TYPE_TIMESTAMP,
876 			colSize,
877 			decDigits,
878 			(SQLPOINTER) &(*_dateTimeVecVec[pos])[0],
879 			0,
880 			&(*_vecLengthIndicator[pos])[0])))
881 		{
882 			throw StatementException(_rStmt, "SQLBindParameter(Time[])");
883 		}
884 	}
885 
886 	template<typename C>
bindImplNullContainer(std::size_t pos,const C & val,Direction dir)887 	void bindImplNullContainer(std::size_t pos, const C& val, Direction dir)
888 	{
889 		if (isOutBound(dir) || !isInBound(dir))
890 			throw NotImplementedException("Null container parameter type can only be inbound.");
891 
892 		if (PB_IMMEDIATE != _paramBinding)
893 			throw InvalidAccessException("Container can only be bound immediately.");
894 
895 		std::size_t length = val.size();
896 
897 		if (0 == length)
898 			throw InvalidArgumentException("Empty container not allowed.");
899 
900 		setParamSetSize(length);
901 
902 		if (_vecLengthIndicator.size() <= pos)
903 		{
904 			_vecLengthIndicator.resize(pos + 1, 0);
905 			_vecLengthIndicator[pos] = new LengthVec(length ? length : 1);
906 		}
907 
908 		SQLINTEGER colSize = 0;
909 		SQLSMALLINT decDigits = 0;
910 		getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
911 
912 		if (Utility::isError(SQLBindParameter(_rStmt,
913 			(SQLUSMALLINT) pos + 1,
914 			SQL_PARAM_INPUT,
915 			SQL_C_STINYINT,
916 			Utility::sqlDataType(SQL_C_STINYINT),
917 			colSize,
918 			decDigits,
919 			0,
920 			0,
921 			&(*_vecLengthIndicator[pos])[0])))
922 		{
923 			throw StatementException(_rStmt, "SQLBindParameter()");
924 		}
925 	}
926 
927 	void getColSizeAndPrecision(std::size_t pos,
928 		SQLSMALLINT cDataType,
929 		SQLINTEGER& colSize,
930 		SQLSMALLINT& decDigits,
931 		std::size_t actualSize = 0);
932 		/// Used to retrieve column size and precision.
933 		/// Not all drivers cooperate with this inquiry under all circumstances
934 		/// This function runs for query and stored procedure parameters (in and
935 		/// out-bound). Some drivers, however, do not care about knowing this
936 		/// information to start with. For that reason, after all the attempts
937 		/// to discover the required values are unsuccesfully exhausted, the values
938 		/// are both set to zero and no exception is thrown.
939 		/// However, if the colSize is succesfully retrieved and it is greater than
940 		/// session-wide maximum allowed field size, LengthExceededException is thrown.
941 
942 	void setParamSetSize(std::size_t length);
943 		/// Sets the parameter set size. Used for column-wise binding.
944 
945 	void getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size);
946 		/// Fills the column or parameter size into the 'size' argument.
947 		/// Does nothing if neither can be obtained from the driver, so
948 		/// size should be set to some default value prior to calling this
949 		/// function in order to avoid undefined size value.
950 
951 	void freeMemory();
952 		/// Frees all dynamically allocated memory resources.
953 
954 	template<typename T>
getMinValueSize(T & val,SQLINTEGER & size)955 	void getMinValueSize(T& val, SQLINTEGER& size)
956 		/// Some ODBC drivers return DB-wide maximum allowed size for variable size columns,
957 		/// rather than the allowed size for the actual column. In such cases, the length is
958 		/// automatically resized to the maximum field size allowed by the session.
959 		/// This function, in order to prevent unnecessary memory allocation, does further
960 		/// optimization, looking for the maximum length within supplied data container and
961 		/// uses the smaller of maximum found and maximum predefined data length.
962 	{
963 		typedef typename T::value_type ContainedValType;
964 		typedef typename ContainedValType::value_type BaseValType;
965 		std::size_t typeSize = sizeof(BaseValType);
966 		std::size_t maxSize = 0;
967 		typename T::const_iterator it = val.begin();
968 		typename T::const_iterator end = val.end();
969 		for (; it != end; ++it)
970 		{
971 			std::size_t sz = it->size() * typeSize;
972 			if (sz > _maxFieldSize)
973 				throw LengthExceededException();
974 
975 			if (sz == _maxFieldSize)
976 			{
977 				maxSize = 0;
978 				break;
979 			}
980 
981 			if (sz < _maxFieldSize && sz > maxSize)
982 				maxSize = sz;
983 		}
984 		if (maxSize) size = static_cast<SQLINTEGER>(maxSize);
985 	}
986 
987 	const StatementHandle& _rStmt;
988 
989 	LengthPtrVec     _lengthIndicator;
990 	LengthVecVec     _vecLengthIndicator;
991 
992 	ParamMap         _inParams;
993 	ParamMap         _outParams;
994 	ParameterBinding _paramBinding;
995 
996 	DateMap          _dates;
997 	TimeMap          _times;
998 	TimestampMap     _timestamps;
999 	StringMap        _strings;
1000 	UTF16StringMap   _utf16Strings;
1001 
1002 	DateVecVec       _dateVecVec;
1003 	TimeVecVec       _timeVecVec;
1004 	DateTimeVecVec   _dateTimeVecVec;
1005 	CharPtrVec       _charPtrs;
1006 	UTF16CharPtrVec  _utf16CharPtrs;
1007 	BoolPtrVec       _boolPtrs;
1008 	const TypeInfo*  _pTypeInfo;
1009 	SQLINTEGER       _paramSetSize;
1010 	std::size_t      _maxFieldSize;
1011 	AnyVecVec        _containers;
1012 };
1013 
1014 
1015 //
1016 // inlines
1017 //
bind(std::size_t pos,const Poco::Int8 & val,Direction dir)1018 inline void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
1019 {
1020 	bindImpl(pos, val, SQL_C_STINYINT, dir);
1021 }
1022 
1023 
bind(std::size_t pos,const std::vector<Poco::Int8> & val,Direction dir)1024 inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
1025 {
1026 	bindImplVec(pos, val, SQL_C_STINYINT, dir);
1027 }
1028 
1029 
bind(std::size_t pos,const std::deque<Poco::Int8> & val,Direction dir)1030 inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir)
1031 {
1032 	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
1033 }
1034 
1035 
bind(std::size_t pos,const std::list<Poco::Int8> & val,Direction dir)1036 inline void Binder::bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir)
1037 {
1038 	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
1039 }
1040 
1041 
bind(std::size_t pos,const Poco::UInt8 & val,Direction dir)1042 inline void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
1043 {
1044 	bindImpl(pos, val, SQL_C_UTINYINT, dir);
1045 }
1046 
1047 
bind(std::size_t pos,const std::vector<Poco::UInt8> & val,Direction dir)1048 inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
1049 {
1050 	bindImplVec(pos, val, SQL_C_UTINYINT, dir);
1051 }
1052 
1053 
bind(std::size_t pos,const std::deque<Poco::UInt8> & val,Direction dir)1054 inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir)
1055 {
1056 	bindImplContainer(pos, val, SQL_C_UTINYINT, dir);
1057 }
1058 
1059 
bind(std::size_t pos,const std::list<Poco::UInt8> & val,Direction dir)1060 inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir)
1061 {
1062 	bindImplContainer(pos, val, SQL_C_UTINYINT, dir);
1063 }
1064 
1065 
bind(std::size_t pos,const Poco::Int16 & val,Direction dir)1066 inline void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
1067 {
1068 	bindImpl(pos, val, SQL_C_SSHORT, dir);
1069 }
1070 
1071 
bind(std::size_t pos,const std::vector<Poco::Int16> & val,Direction dir)1072 inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
1073 {
1074 	bindImplVec(pos, val, SQL_C_SSHORT, dir);
1075 }
1076 
1077 
bind(std::size_t pos,const std::deque<Poco::Int16> & val,Direction dir)1078 inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir)
1079 {
1080 	bindImplContainer(pos, val, SQL_C_SSHORT, dir);
1081 }
1082 
1083 
bind(std::size_t pos,const std::list<Poco::Int16> & val,Direction dir)1084 inline void Binder::bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir)
1085 {
1086 	bindImplContainer(pos, val, SQL_C_SSHORT, dir);
1087 }
1088 
1089 
bind(std::size_t pos,const Poco::UInt16 & val,Direction dir)1090 inline void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
1091 {
1092 	bindImpl(pos, val, SQL_C_USHORT, dir);
1093 }
1094 
1095 
bind(std::size_t pos,const std::vector<Poco::UInt16> & val,Direction dir)1096 inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
1097 {
1098 	bindImplVec(pos, val, SQL_C_USHORT, dir);
1099 }
1100 
1101 
bind(std::size_t pos,const std::deque<Poco::UInt16> & val,Direction dir)1102 inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir)
1103 {
1104 	bindImplContainer(pos, val, SQL_C_USHORT, dir);
1105 }
1106 
1107 
bind(std::size_t pos,const std::list<Poco::UInt16> & val,Direction dir)1108 inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir)
1109 {
1110 	bindImplContainer(pos, val, SQL_C_USHORT, dir);
1111 }
1112 
1113 
bind(std::size_t pos,const Poco::Int32 & val,Direction dir)1114 inline void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
1115 {
1116 	bindImpl(pos, val, SQL_C_SLONG, dir);
1117 }
1118 
1119 
bind(std::size_t pos,const std::vector<Poco::Int32> & val,Direction dir)1120 inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
1121 {
1122 	bindImplVec(pos, val, SQL_C_SLONG, dir);
1123 }
1124 
1125 
bind(std::size_t pos,const std::deque<Poco::Int32> & val,Direction dir)1126 inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir)
1127 {
1128 	bindImplContainer(pos, val, SQL_C_SLONG, dir);
1129 }
1130 
1131 
bind(std::size_t pos,const std::list<Poco::Int32> & val,Direction dir)1132 inline void Binder::bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir)
1133 {
1134 	bindImplContainer(pos, val, SQL_C_SLONG, dir);
1135 }
1136 
1137 
bind(std::size_t pos,const Poco::UInt32 & val,Direction dir)1138 inline void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
1139 {
1140 	bindImpl(pos, val, SQL_C_ULONG, dir);
1141 }
1142 
1143 
bind(std::size_t pos,const std::vector<Poco::UInt32> & val,Direction dir)1144 inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
1145 {
1146 	bindImplVec(pos, val, SQL_C_ULONG, dir);
1147 }
1148 
1149 
bind(std::size_t pos,const std::deque<Poco::UInt32> & val,Direction dir)1150 inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir)
1151 {
1152 	bindImplContainer(pos, val, SQL_C_ULONG, dir);
1153 }
1154 
1155 
bind(std::size_t pos,const std::list<Poco::UInt32> & val,Direction dir)1156 inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir)
1157 {
1158 	bindImplContainer(pos, val, SQL_C_ULONG, dir);
1159 }
1160 
1161 
bind(std::size_t pos,const Poco::Int64 & val,Direction dir)1162 inline void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
1163 {
1164 	bindImpl(pos, val, SQL_C_SBIGINT, dir);
1165 }
1166 
1167 
bind(std::size_t pos,const std::vector<Poco::Int64> & val,Direction dir)1168 inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
1169 {
1170 	bindImplVec(pos, val, SQL_C_SBIGINT, dir);
1171 }
1172 
1173 
bind(std::size_t pos,const std::deque<Poco::Int64> & val,Direction dir)1174 inline void Binder::bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir)
1175 {
1176 	bindImplContainer(pos, val, SQL_C_SBIGINT, dir);
1177 }
1178 
1179 
bind(std::size_t pos,const std::list<Poco::Int64> & val,Direction dir)1180 inline void Binder::bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir)
1181 {
1182 	bindImplContainer(pos, val, SQL_C_SBIGINT, dir);
1183 }
1184 
1185 
bind(std::size_t pos,const Poco::UInt64 & val,Direction dir)1186 inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
1187 {
1188 	bindImpl(pos, val, SQL_C_UBIGINT, dir);
1189 }
1190 
1191 
bind(std::size_t pos,const std::vector<Poco::UInt64> & val,Direction dir)1192 inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
1193 {
1194 	bindImplVec(pos, val, SQL_C_UBIGINT, dir);
1195 }
1196 
1197 
bind(std::size_t pos,const std::deque<Poco::UInt64> & val,Direction dir)1198 inline void Binder::bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir)
1199 {
1200 	bindImplContainer(pos, val, SQL_C_UBIGINT, dir);
1201 }
1202 
1203 
bind(std::size_t pos,const std::list<Poco::UInt64> & val,Direction dir)1204 inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir)
1205 {
1206 	bindImplContainer(pos, val, SQL_C_UBIGINT, dir);
1207 }
1208 
1209 
1210 #ifndef POCO_INT64_IS_LONG
bind(std::size_t pos,const long & val,Direction dir)1211 inline void Binder::bind(std::size_t pos, const long& val, Direction dir)
1212 {
1213 	bindImpl(pos, val, SQL_C_SLONG, dir);
1214 }
1215 
1216 
bind(std::size_t pos,const unsigned long & val,Direction dir)1217 inline void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
1218 {
1219 	bindImpl(pos, val, SQL_C_SLONG, dir);
1220 }
1221 
1222 
bind(std::size_t pos,const std::vector<long> & val,Direction dir)1223 inline void Binder::bind(std::size_t pos, const std::vector<long>& val, Direction dir)
1224 {
1225 	bindImplVec(pos, val, SQL_C_SLONG, dir);
1226 }
1227 
1228 
bind(std::size_t pos,const std::deque<long> & val,Direction dir)1229 inline void Binder::bind(std::size_t pos, const std::deque<long>& val, Direction dir)
1230 {
1231 	bindImplContainer(pos, val, SQL_C_SLONG, dir);
1232 }
1233 
1234 
bind(std::size_t pos,const std::list<long> & val,Direction dir)1235 inline void Binder::bind(std::size_t pos, const std::list<long>& val, Direction dir)
1236 {
1237 	bindImplContainer(pos, val, SQL_C_SLONG, dir);
1238 }
1239 #endif
1240 
1241 
bind(std::size_t pos,const float & val,Direction dir)1242 inline void Binder::bind(std::size_t pos, const float& val, Direction dir)
1243 {
1244 	bindImpl(pos, val, SQL_C_FLOAT, dir);
1245 }
1246 
1247 
bind(std::size_t pos,const std::vector<float> & val,Direction dir)1248 inline void Binder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
1249 {
1250 	bindImplVec(pos, val, SQL_C_FLOAT, dir);
1251 }
1252 
1253 
bind(std::size_t pos,const std::deque<float> & val,Direction dir)1254 inline void Binder::bind(std::size_t pos, const std::deque<float>& val, Direction dir)
1255 {
1256 	bindImplContainer(pos, val, SQL_C_FLOAT, dir);
1257 }
1258 
1259 
bind(std::size_t pos,const std::list<float> & val,Direction dir)1260 inline void Binder::bind(std::size_t pos, const std::list<float>& val, Direction dir)
1261 {
1262 	bindImplContainer(pos, val, SQL_C_FLOAT, dir);
1263 }
1264 
1265 
bind(std::size_t pos,const double & val,Direction dir)1266 inline void Binder::bind(std::size_t pos, const double& val, Direction dir)
1267 {
1268 	bindImpl(pos, val, SQL_C_DOUBLE, dir);
1269 }
1270 
1271 
bind(std::size_t pos,const std::vector<double> & val,Direction dir)1272 inline void Binder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
1273 {
1274 	bindImplVec(pos, val, SQL_C_DOUBLE, dir);
1275 }
1276 
1277 
bind(std::size_t pos,const std::deque<double> & val,Direction dir)1278 inline void Binder::bind(std::size_t pos, const std::deque<double>& val, Direction dir)
1279 {
1280 	bindImplContainer(pos, val, SQL_C_DOUBLE, dir);
1281 }
1282 
1283 
bind(std::size_t pos,const std::list<double> & val,Direction dir)1284 inline void Binder::bind(std::size_t pos, const std::list<double>& val, Direction dir)
1285 {
1286 	bindImplContainer(pos, val, SQL_C_DOUBLE, dir);
1287 }
1288 
1289 
bind(std::size_t pos,const bool & val,Direction dir)1290 inline void Binder::bind(std::size_t pos, const bool& val, Direction dir)
1291 {
1292 	bindImpl(pos, val, SQL_C_BIT, dir);
1293 }
1294 
1295 
bind(std::size_t pos,const std::vector<bool> & val,Direction dir)1296 inline void Binder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
1297 {
1298 	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
1299 }
1300 
1301 
bind(std::size_t pos,const std::deque<bool> & val,Direction dir)1302 inline void Binder::bind(std::size_t pos, const std::deque<bool>& val, Direction dir)
1303 {
1304 	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
1305 }
1306 
1307 
bind(std::size_t pos,const std::list<bool> & val,Direction dir)1308 inline void Binder::bind(std::size_t pos, const std::list<bool>& val, Direction dir)
1309 {
1310 	bindImplContainerBool(pos, val, SQL_C_BIT, dir);
1311 }
1312 
1313 
bind(std::size_t pos,const char & val,Direction dir)1314 inline void Binder::bind(std::size_t pos, const char& val, Direction dir)
1315 {
1316 	bindImpl(pos, val, SQL_C_STINYINT, dir);
1317 }
1318 
1319 
bind(std::size_t pos,const std::vector<char> & val,Direction dir)1320 inline void Binder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
1321 {
1322 	bindImplVec(pos, val, SQL_C_STINYINT, dir);
1323 }
1324 
1325 
bind(std::size_t pos,const std::deque<char> & val,Direction dir)1326 inline void Binder::bind(std::size_t pos, const std::deque<char>& val, Direction dir)
1327 {
1328 	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
1329 }
1330 
1331 
bind(std::size_t pos,const std::list<char> & val,Direction dir)1332 inline void Binder::bind(std::size_t pos, const std::list<char>& val, Direction dir)
1333 {
1334 	bindImplContainer(pos, val, SQL_C_STINYINT, dir);
1335 }
1336 
1337 
bind(std::size_t pos,const std::vector<std::string> & val,Direction dir)1338 inline void Binder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
1339 {
1340 	bindImplContainerString(pos, val, dir);
1341 }
1342 
1343 
bind(std::size_t pos,const std::deque<std::string> & val,Direction dir)1344 inline void Binder::bind(std::size_t pos, const std::deque<std::string>& val, Direction dir)
1345 {
1346 	bindImplContainerString(pos, val, dir);
1347 }
1348 
1349 
bind(std::size_t pos,const std::list<std::string> & val,Direction dir)1350 inline void Binder::bind(std::size_t pos, const std::list<std::string>& val, Direction dir)
1351 {
1352 	bindImplContainerString(pos, val, dir);
1353 }
1354 
1355 
bind(std::size_t pos,const std::vector<UTF16String> & val,Direction dir)1356 inline void Binder::bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir)
1357 {
1358 	bindImplContainerUTF16String(pos, val, dir);
1359 }
1360 
1361 
bind(std::size_t pos,const std::deque<UTF16String> & val,Direction dir)1362 inline void Binder::bind(std::size_t pos, const std::deque<UTF16String>& val, Direction dir)
1363 {
1364 	bindImplContainerUTF16String(pos, val, dir);
1365 }
1366 
1367 
bind(std::size_t pos,const std::list<UTF16String> & val,Direction dir)1368 inline void Binder::bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir)
1369 {
1370 	bindImplContainerUTF16String(pos, val, dir);
1371 }
1372 
bind(std::size_t pos,const BLOB & val,Direction dir)1373 inline void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
1374 {
1375 	bindImplLOB<BLOB>(pos, val, dir);
1376 }
1377 
1378 
bind(std::size_t pos,const CLOB & val,Direction dir)1379 inline void Binder::bind(std::size_t pos, const CLOB& val, Direction dir)
1380 {
1381 	bindImplLOB<CLOB>(pos, val, dir);
1382 }
1383 
1384 
bind(std::size_t pos,const std::vector<BLOB> & val,Direction dir)1385 inline void Binder::bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir)
1386 {
1387 	bindImplContainerLOB(pos, val, dir);
1388 }
1389 
1390 
bind(std::size_t pos,const std::deque<BLOB> & val,Direction dir)1391 inline void Binder::bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir)
1392 {
1393 	bindImplContainerLOB(pos, val, dir);
1394 }
1395 
1396 
bind(std::size_t pos,const std::list<BLOB> & val,Direction dir)1397 inline void Binder::bind(std::size_t pos, const std::list<BLOB>& val, Direction dir)
1398 {
1399 	bindImplContainerLOB(pos, val, dir);
1400 }
1401 
1402 
bind(std::size_t pos,const std::vector<CLOB> & val,Direction dir)1403 inline void Binder::bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir)
1404 {
1405 	bindImplContainerLOB(pos, val, dir);
1406 }
1407 
1408 
bind(std::size_t pos,const std::deque<CLOB> & val,Direction dir)1409 inline void Binder::bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir)
1410 {
1411 	bindImplContainerLOB(pos, val, dir);
1412 }
1413 
1414 
bind(std::size_t pos,const std::list<CLOB> & val,Direction dir)1415 inline void Binder::bind(std::size_t pos, const std::list<CLOB>& val, Direction dir)
1416 {
1417 	bindImplContainerLOB(pos, val, dir);
1418 }
1419 
1420 
bind(std::size_t pos,const std::vector<Date> & val,Direction dir)1421 inline void Binder::bind(std::size_t pos, const std::vector<Date>& val, Direction dir)
1422 {
1423 	bindImplContainerDate(pos, val, dir);
1424 }
1425 
1426 
bind(std::size_t pos,const std::deque<Date> & val,Direction dir)1427 inline void Binder::bind(std::size_t pos, const std::deque<Date>& val, Direction dir)
1428 {
1429 	bindImplContainerDate(pos, val, dir);
1430 }
1431 
1432 
bind(std::size_t pos,const std::list<Date> & val,Direction dir)1433 inline void Binder::bind(std::size_t pos, const std::list<Date>& val, Direction dir)
1434 {
1435 	bindImplContainerDate(pos, val, dir);
1436 }
1437 
1438 
bind(std::size_t pos,const std::vector<Time> & val,Direction dir)1439 inline void Binder::bind(std::size_t pos, const std::vector<Time>& val, Direction dir)
1440 {
1441 	bindImplContainerTime(pos, val, dir);
1442 }
1443 
1444 
bind(std::size_t pos,const std::deque<Time> & val,Direction dir)1445 inline void Binder::bind(std::size_t pos, const std::deque<Time>& val, Direction dir)
1446 {
1447 	bindImplContainerTime(pos, val, dir);
1448 }
1449 
1450 
bind(std::size_t pos,const std::list<Time> & val,Direction dir)1451 inline void Binder::bind(std::size_t pos, const std::list<Time>& val, Direction dir)
1452 {
1453 	bindImplContainerTime(pos, val, dir);
1454 }
1455 
1456 
bind(std::size_t pos,const std::vector<DateTime> & val,Direction dir)1457 inline void Binder::bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir)
1458 {
1459 	bindImplContainerDateTime(pos, val, dir);
1460 }
1461 
1462 
bind(std::size_t pos,const std::deque<DateTime> & val,Direction dir)1463 inline void Binder::bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir)
1464 {
1465 	bindImplContainerDateTime(pos, val, dir);
1466 }
1467 
1468 
bind(std::size_t pos,const std::list<DateTime> & val,Direction dir)1469 inline void Binder::bind(std::size_t pos, const std::list<DateTime>& val, Direction dir)
1470 {
1471 	bindImplContainerDateTime(pos, val, dir);
1472 }
1473 
1474 
bind(std::size_t pos,const std::vector<NullData> & val,Direction dir)1475 inline void Binder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
1476 {
1477 	bindImplNullContainer(pos, val, dir);
1478 }
1479 
1480 
bind(std::size_t pos,const std::deque<NullData> & val,Direction dir)1481 inline void Binder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir)
1482 {
1483 	bindImplNullContainer(pos, val, dir);
1484 }
1485 
1486 
bind(std::size_t pos,const std::list<NullData> & val,Direction dir)1487 inline void Binder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir)
1488 {
1489 	bindImplNullContainer(pos, val, dir);
1490 }
1491 
1492 
setDataBinding(Binder::ParameterBinding binding)1493 inline void Binder::setDataBinding(Binder::ParameterBinding binding)
1494 {
1495 	_paramBinding = binding;
1496 }
1497 
1498 
getDataBinding()1499 inline Binder::ParameterBinding Binder::getDataBinding() const
1500 {
1501 	return _paramBinding;
1502 }
1503 
1504 
1505 } } } // namespace Poco::Data::ODBC
1506 
1507 
1508 #endif // Data_ODBC_Binder_INCLUDED
1509