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