1 //
2 // Preparator.h
3 //
4 // Library: Data/ODBC
5 // Package: ODBC
6 // Module:  Preparator
7 //
8 // Definition of the Preparator 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_Preparator_INCLUDED
18 #define Data_ODBC_Preparator_INCLUDED
19 
20 
21 #include "Poco/Data/Constants.h"
22 #include "Poco/Data/ODBC/ODBC.h"
23 #include "Poco/Data/ODBC/Handle.h"
24 #include "Poco/Data/ODBC/ODBCMetaColumn.h"
25 #include "Poco/Data/ODBC/Utility.h"
26 #include "Poco/Data/AbstractPreparator.h"
27 #include "Poco/Data/LOB.h"
28 #include "Poco/Any.h"
29 #include "Poco/DynamicAny.h"
30 #include "Poco/DateTime.h"
31 #include "Poco/SharedPtr.h"
32 #include "Poco/UTFString.h"
33 #include <vector>
34 #ifdef POCO_OS_FAMILY_WINDOWS
35 #include <windows.h>
36 #endif
37 #include <sqlext.h>
38 
39 
40 namespace Poco {
41 namespace Data {
42 
43 
44 class Date;
45 class Time;
46 
47 
48 namespace ODBC {
49 
50 
51 class ODBC_API Preparator : public AbstractPreparator
52 	/// Class used for database preparation where we first have to register all data types
53 	/// with respective memory output locations before extracting data.
54 	/// Extraction works in two-phases: first prepare is called once, then extract n-times.
55 	/// In ODBC, SQLBindCol/SQLFetch is the preferred method of data retrieval (SQLGetData is available,
56 	/// however with numerous driver implementation dependent limitations and inferior performance).
57 	/// In order to fit this functionality into Poco DataConnectors framework, every ODBC SQL statement
58 	/// instantiates its own Preparator object.
59 	/// This is done once per statement execution (from StatementImpl::bindImpl()).
60 	///
61 	/// Preparator object is used to :
62 	///
63 	///   1) Prepare SQL statement.
64 	///   2) Provide and contain the memory locations where retrieved values are placed during recordset iteration.
65 	///   3) Keep count of returned number of columns with their respective datatypes and sizes.
66 	///
67 	/// Notes:
68 	///
69 	/// - Value datatypes in this interface prepare() calls serve only for the purpose of type distinction.
70 	/// - Preparator keeps its own std::vector<Any> buffer for fetched data to be later retrieved by Extractor.
71 	/// - prepare() methods should not be called when extraction mode is DE_MANUAL
72 	///
73 {
74 public:
75 	typedef std::vector<char*> CharArray;
76 	typedef SharedPtr<Preparator> Ptr;
77 
78 	enum DataExtraction
79 	{
80 		DE_MANUAL,
81 		DE_BOUND
82 	};
83 
84 	enum DataType
85 	{
86 		DT_BOOL,
87 		DT_BOOL_ARRAY,
88 		DT_CHAR,
89 		DT_WCHAR,
90 		DT_UCHAR,
91 		DT_CHAR_ARRAY,
92 		DT_WCHAR_ARRAY,
93 		DT_UCHAR_ARRAY,
94 		DT_DATE,
95 		DT_TIME,
96 		DT_DATETIME
97 	};
98 
99 	Preparator(const StatementHandle& rStmt,
100 		const std::string& statement,
101 		std::size_t maxFieldSize,
102 		DataExtraction dataExtraction = DE_BOUND);
103 		/// Creates the Preparator.
104 
105 	Preparator(const Preparator& other);
106 		/// Copy constructs the Preparator.
107 
108 	~Preparator();
109 		/// Destroys the Preparator.
110 
111 	void prepare(std::size_t pos, const Poco::Int8& val);
112 		/// Prepares an Int8.
113 
114 	void prepare(std::size_t pos, const std::vector<Poco::Int8>& val);
115 		/// Prepares an Int8 vector.
116 
117 	void prepare(std::size_t pos, const std::deque<Poco::Int8>& val);
118 		/// Prepares an Int8 deque.
119 
120 	void prepare(std::size_t pos, const std::list<Poco::Int8>& val);
121 		/// Prepares an Int8 list.
122 
123 	void prepare(std::size_t pos, const Poco::UInt8& val);
124 		/// Prepares an UInt8.
125 
126 	void prepare(std::size_t pos, const std::vector<Poco::UInt8>& val);
127 		/// Prepares an UInt8 vector.
128 
129 	void prepare(std::size_t pos, const std::deque<Poco::UInt8>& val);
130 		/// Prepares an UInt8 deque.
131 
132 	void prepare(std::size_t pos, const std::list<Poco::UInt8>& val);
133 		/// Prepares an UInt8 list.
134 
135 	void prepare(std::size_t pos, const Poco::Int16& val);
136 		/// Prepares an Int16.
137 
138 	void prepare(std::size_t pos, const std::vector<Poco::Int16>& val);
139 		/// Prepares an Int16 vector.
140 
141 	void prepare(std::size_t pos, const std::deque<Poco::Int16>& val);
142 		/// Prepares an Int16 deque.
143 
144 	void prepare(std::size_t pos, const std::list<Poco::Int16>& val);
145 		/// Prepares an Int16 list.
146 
147 	void prepare(std::size_t pos, const Poco::UInt16& val);
148 		/// Prepares an UInt16.
149 
150 	void prepare(std::size_t pos, const std::vector<Poco::UInt16>& val);
151 		/// Prepares an UInt16 vector.
152 
153 	void prepare(std::size_t pos, const std::deque<Poco::UInt16>& val);
154 		/// Prepares an UInt16 deque.
155 
156 	void prepare(std::size_t pos, const std::list<Poco::UInt16>& val);
157 		/// Prepares an UInt16 list.
158 
159 	void prepare(std::size_t pos, const Poco::Int32& val);
160 		/// Prepares an Int32.
161 
162 	void prepare(std::size_t pos, const std::vector<Poco::Int32>& val);
163 		/// Prepares an Int32 vector.
164 
165 	void prepare(std::size_t pos, const std::deque<Poco::Int32>& val);
166 		/// Prepares an Int32 deque.
167 
168 	void prepare(std::size_t pos, const std::list<Poco::Int32>& val);
169 		/// Prepares an Int32 list.
170 
171 	void prepare(std::size_t pos, const Poco::UInt32& val);
172 		/// Prepares an UInt32.
173 
174 	void prepare(std::size_t pos, const std::vector<Poco::UInt32>& val);
175 		/// Prepares an UInt32 vector.
176 
177 	void prepare(std::size_t pos, const std::deque<Poco::UInt32>& val);
178 		/// Prepares an UInt32 deque.
179 
180 	void prepare(std::size_t pos, const std::list<Poco::UInt32>& val);
181 		/// Prepares an UInt32 list.
182 
183 	void prepare(std::size_t pos, const Poco::Int64& val);
184 		/// Prepares an Int64.
185 
186 	void prepare(std::size_t pos, const std::vector<Poco::Int64>& val);
187 		/// Prepares an Int64 vector.
188 
189 	void prepare(std::size_t pos, const std::deque<Poco::Int64>& val);
190 		/// Prepares an Int64 deque.
191 
192 	void prepare(std::size_t pos, const std::list<Poco::Int64>& val);
193 		/// Prepares an Int64 list.
194 
195 	void prepare(std::size_t pos, const Poco::UInt64& val);
196 		/// Prepares an UInt64.
197 
198 	void prepare(std::size_t pos, const std::vector<Poco::UInt64>& val);
199 		/// Prepares an UInt64 vector.
200 
201 	void prepare(std::size_t pos, const std::deque<Poco::UInt64>& val);
202 		/// Prepares an UInt64 deque.
203 
204 	void prepare(std::size_t pos, const std::list<Poco::UInt64>& val);
205 		/// Prepares an UInt64 list.
206 
207 #ifndef POCO_INT64_IS_LONG
208 	void prepare(std::size_t pos, const long& val);
209 		/// Prepares a long.
210 
211 	void prepare(std::size_t pos, const unsigned long& val);
212 		/// Prepares an unsigned long.
213 
214 	void prepare(std::size_t pos, const std::vector<long>& val);
215 		/// Prepares a long vector.
216 
217 	void prepare(std::size_t pos, const std::deque<long>& val);
218 		/// Prepares a long deque.
219 
220 	void prepare(std::size_t pos, const std::list<long>& val);
221 		/// Prepares a long list.
222 #endif
223 
224 	void prepare(std::size_t pos, const bool& val);
225 		/// Prepares a boolean.
226 
227 	void prepare(std::size_t pos, const std::vector<bool>& val);
228 		/// Prepares a boolean vector.
229 
230 	void prepare(std::size_t pos, const std::deque<bool>& val);
231 		/// Prepares a boolean deque.
232 
233 	void prepare(std::size_t pos, const std::list<bool>& val);
234 		/// Prepares a boolean list.
235 
236 	void prepare(std::size_t pos, const float& val);
237 		/// Prepares a float.
238 
239 	void prepare(std::size_t pos, const std::vector<float>& val);
240 		/// Prepares a float vector.
241 
242 	void prepare(std::size_t pos, const std::deque<float>& val);
243 		/// Prepares a float deque.
244 
245 	void prepare(std::size_t pos, const std::list<float>& val);
246 		/// Prepares a float list.
247 
248 	void prepare(std::size_t pos, const double& val);
249 		/// Prepares a double.
250 
251 	void prepare(std::size_t pos, const std::vector<double>& val);
252 		/// Prepares a double vector.
253 
254 	void prepare(std::size_t pos, const std::deque<double>& val);
255 		/// Prepares a double deque.
256 
257 	void prepare(std::size_t pos, const std::list<double>& val);
258 		/// Prepares a double list.
259 
260 	void prepare(std::size_t pos, const char& val);
261 		/// Prepares a single character.
262 
263 	void prepare(std::size_t pos, const std::vector<char>& val);
264 		/// Prepares a single character vector.
265 
266 	void prepare(std::size_t pos, const std::deque<char>& val);
267 		/// Prepares a single character deque.
268 
269 	void prepare(std::size_t pos, const std::list<char>& val);
270 		/// Prepares a single character list.
271 
272 	void prepare(std::size_t pos, const std::string& val);
273 		/// Prepares a string.
274 
275 	void prepare(std::size_t pos, const std::vector<std::string>& val);
276 		/// Prepares a string vector.
277 
278 	void prepare(std::size_t pos, const std::deque<std::string>& val);
279 		/// Prepares a string deque.
280 
281 	void prepare(std::size_t pos, const std::list<std::string>& val);
282 		/// Prepares a string list.
283 
284 	void prepare(std::size_t pos, const UTF16String& val);
285 	/// Prepares a string.
286 
287 	void prepare(std::size_t pos, const std::vector<UTF16String>& val);
288 	/// Prepares a string vector.
289 
290 	void prepare(std::size_t pos, const std::deque<UTF16String>& val);
291 	/// Prepares a string deque.
292 
293 	void prepare(std::size_t pos, const std::list<UTF16String>& val);
294 	/// Prepares a string list.
295 
296 	void prepare(std::size_t pos, const Poco::Data::BLOB& val);
297 		/// Prepares a BLOB.
298 
299 	void prepare(std::size_t pos, const std::vector<Poco::Data::BLOB>& val);
300 		/// Prepares a BLOB vector.
301 
302 	void prepare(std::size_t pos, const std::deque<Poco::Data::BLOB>& val);
303 		/// Prepares a BLOB deque.
304 
305 	void prepare(std::size_t pos, const std::list<Poco::Data::BLOB>& val);
306 		/// Prepares a BLOB list.
307 
308 	void prepare(std::size_t pos, const Poco::Data::CLOB& val);
309 		/// Prepares a CLOB.
310 
311 	void prepare(std::size_t pos, const std::vector<Poco::Data::CLOB>& val);
312 		/// Prepares a CLOB vector.
313 
314 	void prepare(std::size_t pos, const std::deque<Poco::Data::CLOB>& val);
315 		/// Prepares a CLOB deque.
316 
317 	void prepare(std::size_t pos, const std::list<Poco::Data::CLOB>& val);
318 		/// Prepares a CLOB list.
319 
320 	void prepare(std::size_t pos, const Poco::Data::Date& val);
321 		/// Prepares a Date.
322 
323 	void prepare(std::size_t pos, const std::vector<Poco::Data::Date>& val);
324 		/// Prepares a Date vector.
325 
326 	void prepare(std::size_t pos, const std::deque<Poco::Data::Date>& val);
327 		/// Prepares a Date deque.
328 
329 	void prepare(std::size_t pos, const std::list<Poco::Data::Date>& val);
330 		/// Prepares a Date list.
331 
332 	void prepare(std::size_t pos, const Poco::Data::Time& val);
333 		/// Prepares a Time.
334 
335 	void prepare(std::size_t pos, const std::vector<Poco::Data::Time>& val);
336 		/// Prepares a Time vector.
337 
338 	void prepare(std::size_t pos, const std::deque<Poco::Data::Time>& val);
339 		/// Prepares a Time deque.
340 
341 	void prepare(std::size_t pos, const std::list<Poco::Data::Time>& val);
342 		/// Prepares a Time list.
343 
344 	void prepare(std::size_t pos, const Poco::DateTime& val);
345 		/// Prepares a DateTime.
346 
347 	void prepare(std::size_t pos, const std::vector<Poco::DateTime>& val);
348 		/// Prepares a DateTime vector.
349 
350 	void prepare(std::size_t pos, const std::deque<Poco::DateTime>& val);
351 		/// Prepares a DateTime deque.
352 
353 	void prepare(std::size_t pos, const std::list<Poco::DateTime>& val);
354 		/// Prepares a DateTime list.
355 
356 	void prepare(std::size_t pos, const Poco::Any& val);
357 		/// Prepares an Any.
358 
359 	void prepare(std::size_t pos, const std::vector<Poco::Any>& val);
360 		/// Prepares an Any vector.
361 
362 	void prepare(std::size_t pos, const std::deque<Poco::Any>& val);
363 		/// Prepares an Any deque.
364 
365 	void prepare(std::size_t pos, const std::list<Poco::Any>& val);
366 		/// Prepares an Any list.
367 
368 	void prepare(std::size_t pos, const Poco::DynamicAny& val);
369 		/// Prepares a DynamicAny.
370 
371 	void prepare(std::size_t pos, const std::vector<Poco::DynamicAny>& val);
372 		/// Prepares a DynamicAny vector.
373 
374 	void prepare(std::size_t pos, const std::deque<Poco::DynamicAny>& val);
375 		/// Prepares a DynamicAny deque.
376 
377 	void prepare(std::size_t pos, const std::list<Poco::DynamicAny>& val);
378 		/// Prepares a DynamicAny list.
379 
380 	std::size_t columns() const;
381 		/// Returns the number of columns.
382 		/// Resizes the internal storage iff the size is zero.
383 
384 	Poco::Any& operator [] (std::size_t pos);
385 		/// Returns reference to column data.
386 
387 	Poco::Any& at(std::size_t pos);
388 		/// Returns reference to column data.
389 
390 	void setMaxFieldSize(std::size_t size);
391 		/// Sets maximum supported field size.
392 
393 	std::size_t getMaxFieldSize() const;
394 		// Returns maximum supported field size.
395 
396 	std::size_t maxDataSize(std::size_t pos) const;
397 		/// Returns max supported size for column at position pos.
398 		/// Returned length for variable length fields is the one
399 		/// supported by this implementation, not the underlying DB.
400 
401 	std::size_t actualDataSize(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW) const;
402 		/// Returns the returned length for the column and row specified.
403 		/// This is usually equal to the column size, except for
404 		/// variable length fields (BLOB and variable length strings).
405 		/// For null values, the return value is -1 (SQL_NO_DATA)
406 
407 	std::size_t bulkSize(std::size_t col = 0) const;
408 		/// Returns bulk size. Column argument is optional
409 		/// since all columns must be the same size.
410 
411 	void setDataExtraction(DataExtraction ext);
412 		/// Set data extraction mode.
413 
414 	DataExtraction getDataExtraction() const;
415 		/// Returns data extraction mode.
416 
417 private:
418 	typedef std::vector<Poco::Any> ValueVec;
419 	typedef std::vector<SQLLEN>    LengthVec;
420 	typedef std::vector<LengthVec> LengthLengthVec;
421 	typedef std::map<std::size_t, DataType> IndexMap;
422 
423 	Preparator();
424 	Preparator& operator = (const Preparator&);
425 
426 	template <typename C>
427 	void prepareImpl(std::size_t pos, const C* pVal = 0)
428 		/// Utility function to prepare Any and DynamicAny.
429 	{
430 		ODBCMetaColumn col(_rStmt, pos);
431 
432 		switch (col.type())
433 		{
434 			case MetaColumn::FDT_INT8:
435 				if (pVal)
436 					return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, pVal->size());
437 				else
438 					return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
439 
440 			case MetaColumn::FDT_UINT8:
441 				if (pVal)
442 					return prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, pVal->size());
443 				else
444 					return prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT);
445 
446 			case MetaColumn::FDT_INT16:
447 				if (pVal)
448 					return prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, pVal->size());
449 				else
450 					return prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT);
451 
452 			case MetaColumn::FDT_UINT16:
453 				if (pVal)
454 					return prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, pVal->size());
455 				else
456 					return prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT);
457 
458 			case MetaColumn::FDT_INT32:
459 				if (pVal)
460 					return prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, pVal->size());
461 				else
462 					return prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG);
463 
464 			case MetaColumn::FDT_UINT32:
465 				if (pVal)
466 					return prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, pVal->size());
467 				else
468 					return prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG);
469 
470 			case MetaColumn::FDT_INT64:
471 				if (pVal)
472 					return prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, pVal->size());
473 				else
474 					return prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT);
475 
476 			case MetaColumn::FDT_UINT64:
477 				if (pVal)
478 					return prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, pVal->size());
479 				else
480 					return prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT);
481 
482 			case MetaColumn::FDT_BOOL:
483 				if (pVal)
484 					return prepareBoolArray(pos, SQL_C_BIT, pVal->size());
485 				else
486 					return prepareFixedSize<bool>(pos, SQL_C_BIT);
487 
488 			case MetaColumn::FDT_FLOAT:
489 				if (pVal)
490 					return prepareFixedSize<float>(pos, SQL_C_FLOAT, pVal->size());
491 				else
492 					return prepareFixedSize<float>(pos, SQL_C_FLOAT);
493 
494 			case MetaColumn::FDT_DOUBLE:
495 				if (pVal)
496 					return prepareFixedSize<double>(pos, SQL_C_DOUBLE, pVal->size());
497 				else
498 					return prepareFixedSize<double>(pos, SQL_C_DOUBLE);
499 
500 			case MetaColumn::FDT_STRING:
501 				if (pVal)
502 					return prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_CHAR, maxDataSize(pos), pVal->size());
503 				else
504 					return prepareVariableLen<char>(pos, SQL_C_CHAR, maxDataSize(pos), DT_CHAR);
505 
506 			case MetaColumn::FDT_WSTRING:
507 			{
508 				typedef UTF16String::value_type CharType;
509 				if (pVal)
510 					return prepareCharArray<CharType, DT_WCHAR_ARRAY>(pos, SQL_C_WCHAR, maxDataSize(pos), pVal->size());
511 				else
512 					return prepareVariableLen<CharType>(pos, SQL_C_WCHAR, maxDataSize(pos), DT_WCHAR);
513 			}
514 
515 			case MetaColumn::FDT_BLOB:
516 			{
517 				typedef Poco::Data::BLOB::ValueType CharType;
518 				if (pVal)
519 					return prepareCharArray<CharType, DT_UCHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), pVal->size());
520 				else
521 					return prepareVariableLen<CharType>(pos, SQL_C_BINARY, maxDataSize(pos), DT_UCHAR);
522 			}
523 
524 			case MetaColumn::FDT_CLOB:
525 			{
526 				typedef Poco::Data::CLOB::ValueType CharType;
527 				if (pVal)
528 					return prepareCharArray<CharType, DT_CHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), pVal->size());
529 				else
530 					return prepareVariableLen<CharType>(pos, SQL_C_BINARY, maxDataSize(pos), DT_CHAR);
531 			}
532 
533 			case MetaColumn::FDT_DATE:
534 				if (pVal)
535 					return prepareFixedSize<Date>(pos, SQL_C_TYPE_DATE, pVal->size());
536 				else
537 					return prepareFixedSize<Date>(pos, SQL_C_TYPE_DATE);
538 
539 			case MetaColumn::FDT_TIME:
540 				if (pVal)
541 					return prepareFixedSize<Time>(pos, SQL_C_TYPE_TIME, pVal->size());
542 				else
543 					return prepareFixedSize<Time>(pos, SQL_C_TYPE_TIME);
544 
545 			case MetaColumn::FDT_TIMESTAMP:
546 				if (pVal)
547 					return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP, pVal->size());
548 				else
549 					return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP);
550 
551 			default:
552 				throw DataFormatException("Unsupported data type.");
553 		}
554 	}
555 
556 	void resize() const;
557 		/// Resize the values and lengths vectors.
558 
559 	template <typename T>
prepareFixedSize(std::size_t pos,SQLSMALLINT valueType)560 	void prepareFixedSize(std::size_t pos, SQLSMALLINT valueType)
561 		/// Utility function for preparation of fixed length columns.
562 	{
563 		poco_assert (DE_BOUND == _dataExtraction);
564 		std::size_t dataSize = sizeof(T);
565 
566 		poco_assert (pos < _values.size());
567 		_values[pos] = Poco::Any(T());
568 
569 		T* pVal = AnyCast<T>(&_values[pos]);
570 		if (Utility::isError(SQLBindCol(_rStmt,
571 			(SQLUSMALLINT) pos + 1,
572 			valueType,
573 			(SQLPOINTER) pVal,
574 			(SQLINTEGER) dataSize,
575 			&_lengths[pos])))
576 		{
577 			throw StatementException(_rStmt, "SQLBindCol()");
578 		}
579 	}
580 
581 	template <typename T>
prepareFixedSize(std::size_t pos,SQLSMALLINT valueType,std::size_t length)582 	void prepareFixedSize(std::size_t pos, SQLSMALLINT valueType, std::size_t length)
583 		/// Utility function for preparation of fixed length columns that are
584 		/// bound to a std::vector.
585 	{
586 		poco_assert (DE_BOUND == _dataExtraction);
587 		std::size_t dataSize = sizeof(T);
588 
589 		poco_assert (pos < _values.size());
590 		poco_assert (length);
591 		_values[pos] = Poco::Any(std::vector<T>());
592 		_lengths[pos] = 0;
593 		poco_assert (0 == _lenLengths[pos].size());
594 		_lenLengths[pos].resize(length);
595 
596 		std::vector<T>& cache = RefAnyCast<std::vector<T> >(_values[pos]);
597 		cache.resize(length);
598 
599 		if (Utility::isError(SQLBindCol(_rStmt,
600 			(SQLUSMALLINT) pos + 1,
601 			valueType,
602 			(SQLPOINTER) &cache[0],
603 			(SQLINTEGER) dataSize,
604 			&_lenLengths[pos][0])))
605 		{
606 			throw StatementException(_rStmt, "SQLBindCol()");
607 		}
608 	}
609 
610 	template <typename T>
prepareVariableLen(std::size_t pos,SQLSMALLINT valueType,std::size_t size,DataType dt)611 	void prepareVariableLen(std::size_t pos, SQLSMALLINT valueType, std::size_t size, DataType dt)
612 		/// Utility function for preparation of variable length columns.
613 	{
614 		poco_assert (DE_BOUND == _dataExtraction);
615 		poco_assert (pos < _values.size());
616 
617 		T* pCache = new T[size];
618 		std::memset(pCache, 0, size);
619 
620 		_values[pos] = Any(pCache);
621 		_lengths[pos] = (SQLLEN) size;
622 		_varLengthArrays.insert(IndexMap::value_type(pos, dt));
623 
624 		if (Utility::isError(SQLBindCol(_rStmt,
625 			(SQLUSMALLINT) pos + 1,
626 			valueType,
627 			(SQLPOINTER) pCache,
628 			(SQLINTEGER) size*sizeof(T),
629 			&_lengths[pos])))
630 		{
631 			throw StatementException(_rStmt, "SQLBindCol()");
632 		}
633 	}
634 
635 	template <typename T, DataType DT>
prepareCharArray(std::size_t pos,SQLSMALLINT valueType,std::size_t size,std::size_t length)636 	void prepareCharArray(std::size_t pos, SQLSMALLINT valueType, std::size_t size, std::size_t length)
637 		/// Utility function for preparation of bulk variable length character and LOB columns.
638 	{
639 		poco_assert_dbg (DE_BOUND == _dataExtraction);
640 		poco_assert_dbg (pos < _values.size());
641 		poco_assert_dbg (pos < _lengths.size());
642 		poco_assert_dbg (pos < _lenLengths.size());
643 
644 		T* pArray = (T*) std::calloc(length * size, sizeof(T));
645 
646 		_values[pos] = Any(pArray);
647 		_lengths[pos] = 0;
648 		_lenLengths[pos].resize(length);
649 		_varLengthArrays.insert(IndexMap::value_type(pos, DT));
650 
651 		if (Utility::isError(SQLBindCol(_rStmt,
652 			(SQLUSMALLINT) pos + 1,
653 			valueType,
654 			(SQLPOINTER) pArray,
655 			(SQLINTEGER) size,
656 			&_lenLengths[pos][0])))
657 		{
658 			throw StatementException(_rStmt, "SQLBindCol()");
659 		}
660 	}
661 
662 	void prepareBoolArray(std::size_t pos, SQLSMALLINT valueType, std::size_t length);
663 		/// Utility function for preparation of bulk bool columns.
664 
665 	void freeMemory() const;
666 		/// Utility function. Releases memory allocated for variable length columns.
667 
668 	template <typename T>
deleteCachedArray(std::size_t pos)669 	void deleteCachedArray(std::size_t pos) const
670 	{
671 		T** p = Poco::AnyCast<T*>(&_values[pos]);
672 		if (p) delete [] *p;
673 	}
674 
675 	const StatementHandle&  _rStmt;
676 	mutable ValueVec        _values;
677 	mutable LengthVec       _lengths;
678 	mutable LengthLengthVec _lenLengths;
679 	mutable IndexMap        _varLengthArrays;
680 	std::size_t             _maxFieldSize;
681 	DataExtraction          _dataExtraction;
682 };
683 
684 
685 //
686 // inlines
687 //
prepare(std::size_t pos,const Poco::Int8 &)688 inline void Preparator::prepare(std::size_t pos, const Poco::Int8&)
689 {
690 	prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
691 }
692 
693 
prepare(std::size_t pos,const std::vector<Poco::Int8> & val)694 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Int8>& val)
695 {
696 	prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, val.size());
697 }
698 
699 
prepare(std::size_t pos,const std::deque<Poco::Int8> & val)700 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Int8>& val)
701 {
702 	prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, val.size());
703 }
704 
705 
prepare(std::size_t pos,const std::list<Poco::Int8> & val)706 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Int8>& val)
707 {
708 	prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, val.size());
709 }
710 
711 
prepare(std::size_t pos,const Poco::UInt8 &)712 inline void Preparator::prepare(std::size_t pos, const Poco::UInt8&)
713 {
714 	prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT);
715 }
716 
717 
prepare(std::size_t pos,const std::vector<Poco::UInt8> & val)718 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::UInt8>& val)
719 {
720 	prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, val.size());
721 }
722 
723 
prepare(std::size_t pos,const std::deque<Poco::UInt8> & val)724 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::UInt8>& val)
725 {
726 	prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, val.size());
727 }
728 
729 
prepare(std::size_t pos,const std::list<Poco::UInt8> & val)730 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::UInt8>& val)
731 {
732 	prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, val.size());
733 }
734 
735 
prepare(std::size_t pos,const Poco::Int16 &)736 inline void Preparator::prepare(std::size_t pos, const Poco::Int16&)
737 {
738 	prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT);
739 }
740 
741 
prepare(std::size_t pos,const std::vector<Poco::Int16> & val)742 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Int16>& val)
743 {
744 	prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, val.size());
745 }
746 
747 
prepare(std::size_t pos,const std::deque<Poco::Int16> & val)748 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Int16>& val)
749 {
750 	prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, val.size());
751 }
752 
753 
prepare(std::size_t pos,const std::list<Poco::Int16> & val)754 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Int16>& val)
755 {
756 	prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, val.size());
757 }
758 
759 
prepare(std::size_t pos,const Poco::UInt16 &)760 inline void Preparator::prepare(std::size_t pos, const Poco::UInt16&)
761 {
762 	prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT);
763 }
764 
765 
prepare(std::size_t pos,const std::vector<Poco::UInt16> & val)766 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::UInt16>& val)
767 {
768 	prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, val.size());
769 }
770 
771 
prepare(std::size_t pos,const std::deque<Poco::UInt16> & val)772 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::UInt16>& val)
773 {
774 	prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, val.size());
775 }
776 
777 
prepare(std::size_t pos,const std::list<Poco::UInt16> & val)778 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::UInt16>& val)
779 {
780 	prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, val.size());
781 }
782 
783 
prepare(std::size_t pos,const Poco::Int32 &)784 inline void Preparator::prepare(std::size_t pos, const Poco::Int32&)
785 {
786 	prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG);
787 }
788 
789 
prepare(std::size_t pos,const std::vector<Poco::Int32> & val)790 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Int32>& val)
791 {
792 	prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, val.size());
793 }
794 
795 
prepare(std::size_t pos,const std::deque<Poco::Int32> & val)796 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Int32>& val)
797 {
798 	prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, val.size());
799 }
800 
801 
prepare(std::size_t pos,const std::list<Poco::Int32> & val)802 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Int32>& val)
803 {
804 	prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, val.size());
805 }
806 
807 
prepare(std::size_t pos,const Poco::UInt32 &)808 inline void Preparator::prepare(std::size_t pos, const Poco::UInt32&)
809 {
810 	prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG);
811 }
812 
813 
prepare(std::size_t pos,const std::vector<Poco::UInt32> & val)814 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::UInt32>& val)
815 {
816 	prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, val.size());
817 }
818 
819 
prepare(std::size_t pos,const std::deque<Poco::UInt32> & val)820 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::UInt32>& val)
821 {
822 	prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, val.size());
823 }
824 
825 
prepare(std::size_t pos,const std::list<Poco::UInt32> & val)826 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::UInt32>& val)
827 {
828 	prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, val.size());
829 }
830 
831 
prepare(std::size_t pos,const Poco::Int64 &)832 inline void Preparator::prepare(std::size_t pos, const Poco::Int64&)
833 {
834 	prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT);
835 }
836 
837 
prepare(std::size_t pos,const std::vector<Poco::Int64> & val)838 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Int64>& val)
839 {
840 	prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, val.size());
841 }
842 
843 
prepare(std::size_t pos,const std::deque<Poco::Int64> & val)844 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Int64>& val)
845 {
846 	prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, val.size());
847 }
848 
849 
prepare(std::size_t pos,const std::list<Poco::Int64> & val)850 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Int64>& val)
851 {
852 	prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, val.size());
853 }
854 
855 
prepare(std::size_t pos,const Poco::UInt64 &)856 inline void Preparator::prepare(std::size_t pos, const Poco::UInt64&)
857 {
858 	prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT);
859 }
860 
861 
prepare(std::size_t pos,const std::vector<Poco::UInt64> & val)862 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::UInt64>& val)
863 {
864 	prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, val.size());
865 }
866 
867 
prepare(std::size_t pos,const std::deque<Poco::UInt64> & val)868 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::UInt64>& val)
869 {
870 	prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, val.size());
871 }
872 
873 
prepare(std::size_t pos,const std::list<Poco::UInt64> & val)874 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::UInt64>& val)
875 {
876 	prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, val.size());
877 }
878 
879 
880 #ifndef POCO_INT64_IS_LONG
prepare(std::size_t pos,const long &)881 inline void Preparator::prepare(std::size_t pos, const long&)
882 {
883 	prepareFixedSize<long>(pos, SQL_C_SLONG);
884 }
885 
886 
prepare(std::size_t pos,const unsigned long &)887 inline void Preparator::prepare(std::size_t pos, const unsigned long&)
888 {
889 	prepareFixedSize<long>(pos, SQL_C_SLONG);
890 }
891 
892 
prepare(std::size_t pos,const std::vector<long> & val)893 inline void Preparator::prepare(std::size_t pos, const std::vector<long>& val)
894 {
895 	prepareFixedSize<long>(pos, SQL_C_SLONG, val.size());
896 }
897 
898 
prepare(std::size_t pos,const std::deque<long> & val)899 inline void Preparator::prepare(std::size_t pos, const std::deque<long>& val)
900 {
901 	prepareFixedSize<long>(pos, SQL_C_SLONG, val.size());
902 }
903 
904 
prepare(std::size_t pos,const std::list<long> & val)905 inline void Preparator::prepare(std::size_t pos, const std::list<long>& val)
906 {
907 	prepareFixedSize<long>(pos, SQL_C_SLONG, val.size());
908 }
909 #endif
910 
911 
prepare(std::size_t pos,const bool &)912 inline void Preparator::prepare(std::size_t pos, const bool&)
913 {
914 	prepareFixedSize<bool>(pos, SQL_C_BIT);
915 }
916 
917 
prepare(std::size_t pos,const std::vector<bool> & val)918 inline void Preparator::prepare(std::size_t pos, const std::vector<bool>& val)
919 {
920 	prepareBoolArray(pos, SQL_C_BIT, val.size());
921 }
922 
923 
prepare(std::size_t pos,const std::deque<bool> & val)924 inline void Preparator::prepare(std::size_t pos, const std::deque<bool>& val)
925 {
926 	prepareBoolArray(pos, SQL_C_BIT, val.size());
927 }
928 
929 
prepare(std::size_t pos,const std::list<bool> & val)930 inline void Preparator::prepare(std::size_t pos, const std::list<bool>& val)
931 {
932 	prepareBoolArray(pos, SQL_C_BIT, val.size());
933 }
934 
935 
prepare(std::size_t pos,const float &)936 inline void Preparator::prepare(std::size_t pos, const float&)
937 {
938 	prepareFixedSize<float>(pos, SQL_C_FLOAT);
939 }
940 
941 
prepare(std::size_t pos,const std::vector<float> & val)942 inline void Preparator::prepare(std::size_t pos, const std::vector<float>& val)
943 {
944 	prepareFixedSize<float>(pos, SQL_C_FLOAT, val.size());
945 }
946 
947 
prepare(std::size_t pos,const std::deque<float> & val)948 inline void Preparator::prepare(std::size_t pos, const std::deque<float>& val)
949 {
950 	prepareFixedSize<float>(pos, SQL_C_FLOAT, val.size());
951 }
952 
953 
prepare(std::size_t pos,const std::list<float> & val)954 inline void Preparator::prepare(std::size_t pos, const std::list<float>& val)
955 {
956 	prepareFixedSize<float>(pos, SQL_C_FLOAT, val.size());
957 }
958 
959 
prepare(std::size_t pos,const double &)960 inline void Preparator::prepare(std::size_t pos, const double&)
961 {
962 	prepareFixedSize<double>(pos, SQL_C_DOUBLE);
963 }
964 
965 
prepare(std::size_t pos,const std::vector<double> & val)966 inline void Preparator::prepare(std::size_t pos, const std::vector<double>& val)
967 {
968 	prepareFixedSize<double>(pos, SQL_C_DOUBLE, val.size());
969 }
970 
971 
prepare(std::size_t pos,const std::deque<double> & val)972 inline void Preparator::prepare(std::size_t pos, const std::deque<double>& val)
973 {
974 	prepareFixedSize<double>(pos, SQL_C_DOUBLE, val.size());
975 }
976 
977 
prepare(std::size_t pos,const std::list<double> & val)978 inline void Preparator::prepare(std::size_t pos, const std::list<double>& val)
979 {
980 	prepareFixedSize<double>(pos, SQL_C_DOUBLE, val.size());
981 }
982 
983 
prepare(std::size_t pos,const char &)984 inline void Preparator::prepare(std::size_t pos, const char&)
985 {
986 	prepareFixedSize<char>(pos, SQL_C_STINYINT);
987 }
988 
989 
prepare(std::size_t pos,const std::vector<char> & val)990 inline void Preparator::prepare(std::size_t pos, const std::vector<char>& val)
991 {
992 	prepareFixedSize<char>(pos, SQL_C_STINYINT, val.size());
993 }
994 
995 
prepare(std::size_t pos,const std::deque<char> & val)996 inline void Preparator::prepare(std::size_t pos, const std::deque<char>& val)
997 {
998 	prepareFixedSize<char>(pos, SQL_C_STINYINT, val.size());
999 }
1000 
1001 
prepare(std::size_t pos,const std::list<char> & val)1002 inline void Preparator::prepare(std::size_t pos, const std::list<char>& val)
1003 {
1004 	prepareFixedSize<char>(pos, SQL_C_STINYINT, val.size());
1005 }
1006 
1007 
prepare(std::size_t pos,const std::string &)1008 inline void Preparator::prepare(std::size_t pos, const std::string&)
1009 {
1010 	prepareVariableLen<char>(pos, SQL_C_CHAR, maxDataSize(pos), DT_CHAR);
1011 }
1012 
1013 
prepare(std::size_t pos,const std::vector<std::string> & val)1014 inline void Preparator::prepare(std::size_t pos, const std::vector<std::string>& val)
1015 {
1016 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_CHAR, maxDataSize(pos), val.size());
1017 }
1018 
1019 
prepare(std::size_t pos,const std::deque<std::string> & val)1020 inline void Preparator::prepare(std::size_t pos, const std::deque<std::string>& val)
1021 {
1022 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_CHAR, maxDataSize(pos), val.size());
1023 }
1024 
1025 
prepare(std::size_t pos,const std::list<std::string> & val)1026 inline void Preparator::prepare(std::size_t pos, const std::list<std::string>& val)
1027 {
1028 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_CHAR, maxDataSize(pos), val.size());
1029 }
1030 
1031 
prepare(std::size_t pos,const UTF16String &)1032 inline void Preparator::prepare(std::size_t pos, const UTF16String&)
1033 {
1034 	prepareVariableLen<UTF16String::value_type>(pos, SQL_C_WCHAR, maxDataSize(pos), DT_WCHAR);
1035 }
1036 
1037 
prepare(std::size_t pos,const std::vector<UTF16String> & val)1038 inline void Preparator::prepare(std::size_t pos, const std::vector<UTF16String>& val)
1039 {
1040 	prepareCharArray<UTF16String::value_type, DT_WCHAR_ARRAY>(pos, SQL_C_WCHAR, maxDataSize(pos), val.size());
1041 }
1042 
1043 
prepare(std::size_t pos,const std::deque<UTF16String> & val)1044 inline void Preparator::prepare(std::size_t pos, const std::deque<UTF16String>& val)
1045 {
1046 	prepareCharArray<UTF16String::value_type, DT_WCHAR_ARRAY>(pos, SQL_C_WCHAR, maxDataSize(pos), val.size());
1047 }
1048 
1049 
prepare(std::size_t pos,const std::list<UTF16String> & val)1050 inline void Preparator::prepare(std::size_t pos, const std::list<UTF16String>& val)
1051 {
1052 	prepareCharArray<UTF16String::value_type, DT_WCHAR_ARRAY>(pos, SQL_C_WCHAR, maxDataSize(pos), val.size());
1053 }
1054 
1055 
prepare(std::size_t pos,const Poco::Data::BLOB &)1056 inline void Preparator::prepare(std::size_t pos, const Poco::Data::BLOB&)
1057 {
1058 	prepareVariableLen<Poco::Data::BLOB::ValueType>(pos, SQL_C_BINARY, maxDataSize(pos), DT_UCHAR);
1059 }
1060 
1061 
prepare(std::size_t pos,const std::vector<Poco::Data::BLOB> & val)1062 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Data::BLOB>& val)
1063 {
1064 	prepareCharArray<char, DT_UCHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1065 }
1066 
1067 
prepare(std::size_t pos,const std::deque<Poco::Data::BLOB> & val)1068 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Data::BLOB>& val)
1069 {
1070 	prepareCharArray<char, DT_UCHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1071 }
1072 
1073 
prepare(std::size_t pos,const std::list<Poco::Data::BLOB> & val)1074 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Data::BLOB>& val)
1075 {
1076 	prepareCharArray<char, DT_UCHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1077 }
1078 
1079 
prepare(std::size_t pos,const Poco::Data::CLOB &)1080 inline void Preparator::prepare(std::size_t pos, const Poco::Data::CLOB&)
1081 {
1082 	prepareVariableLen<Poco::Data::CLOB::ValueType>(pos, SQL_C_BINARY, maxDataSize(pos), DT_CHAR);
1083 }
1084 
1085 
prepare(std::size_t pos,const std::vector<Poco::Data::CLOB> & val)1086 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Data::CLOB>& val)
1087 {
1088 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1089 }
1090 
1091 
prepare(std::size_t pos,const std::deque<Poco::Data::CLOB> & val)1092 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Data::CLOB>& val)
1093 {
1094 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1095 }
1096 
1097 
prepare(std::size_t pos,const std::list<Poco::Data::CLOB> & val)1098 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Data::CLOB>& val)
1099 {
1100 	prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_BINARY, maxDataSize(pos), val.size());
1101 }
1102 
1103 
prepare(std::size_t pos,const Poco::Data::Date &)1104 inline void Preparator::prepare(std::size_t pos, const Poco::Data::Date&)
1105 {
1106 	prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE);
1107 }
1108 
1109 
prepare(std::size_t pos,const std::vector<Poco::Data::Date> & val)1110 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Data::Date>& val)
1111 {
1112 	prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE, val.size());
1113 }
1114 
1115 
prepare(std::size_t pos,const std::deque<Poco::Data::Date> & val)1116 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Data::Date>& val)
1117 {
1118 	prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE, val.size());
1119 }
1120 
1121 
prepare(std::size_t pos,const std::list<Poco::Data::Date> & val)1122 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Data::Date>& val)
1123 {
1124 	prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE, val.size());
1125 }
1126 
1127 
prepare(std::size_t pos,const Poco::Data::Time &)1128 inline void Preparator::prepare(std::size_t pos, const Poco::Data::Time&)
1129 {
1130 	prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME);
1131 }
1132 
1133 
prepare(std::size_t pos,const std::vector<Poco::Data::Time> & val)1134 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Data::Time>& val)
1135 {
1136 	prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME, val.size());
1137 }
1138 
1139 
prepare(std::size_t pos,const std::deque<Poco::Data::Time> & val)1140 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Data::Time>& val)
1141 {
1142 	prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME, val.size());
1143 }
1144 
1145 
prepare(std::size_t pos,const std::list<Poco::Data::Time> & val)1146 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Data::Time>& val)
1147 {
1148 	prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME, val.size());
1149 }
1150 
1151 
prepare(std::size_t pos,const Poco::DateTime &)1152 inline void Preparator::prepare(std::size_t pos, const Poco::DateTime&)
1153 {
1154 	prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP);
1155 }
1156 
1157 
prepare(std::size_t pos,const std::vector<Poco::DateTime> & val)1158 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::DateTime>& val)
1159 {
1160 	prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP, val.size());
1161 }
1162 
1163 
prepare(std::size_t pos,const std::deque<Poco::DateTime> & val)1164 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::DateTime>& val)
1165 {
1166 	prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP, val.size());
1167 }
1168 
1169 
prepare(std::size_t pos,const std::list<Poco::DateTime> & val)1170 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::DateTime>& val)
1171 {
1172 	prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP, val.size());
1173 }
1174 
1175 
prepare(std::size_t pos,const Poco::Any & val)1176 inline void Preparator::prepare(std::size_t pos, const Poco::Any& val)
1177 {
1178 	prepareImpl<std::vector<Poco::Any> >(pos);
1179 }
1180 
1181 
prepare(std::size_t pos,const std::vector<Poco::Any> & val)1182 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::Any>& val)
1183 {
1184 	prepareImpl<std::vector<Poco::Any> >(pos, &val);
1185 }
1186 
1187 
prepare(std::size_t pos,const std::deque<Poco::Any> & val)1188 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::Any>& val)
1189 {
1190 	prepareImpl<std::deque<Poco::Any> >(pos, &val);
1191 }
1192 
1193 
prepare(std::size_t pos,const std::list<Poco::Any> & val)1194 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::Any>& val)
1195 {
1196 	prepareImpl<std::list<Poco::Any> >(pos, &val);
1197 }
1198 
1199 
prepare(std::size_t pos,const Poco::DynamicAny & val)1200 inline void Preparator::prepare(std::size_t pos, const Poco::DynamicAny& val)
1201 {
1202 	prepareImpl<std::vector<Poco::DynamicAny> >(pos);
1203 }
1204 
1205 
prepare(std::size_t pos,const std::vector<Poco::DynamicAny> & val)1206 inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::DynamicAny>& val)
1207 {
1208 	prepareImpl<std::vector<Poco::DynamicAny> >(pos, &val);
1209 }
1210 
1211 
prepare(std::size_t pos,const std::deque<Poco::DynamicAny> & val)1212 inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::DynamicAny>& val)
1213 {
1214 	prepareImpl<std::deque<Poco::DynamicAny> >(pos, &val);
1215 }
1216 
1217 
prepare(std::size_t pos,const std::list<Poco::DynamicAny> & val)1218 inline void Preparator::prepare(std::size_t pos, const std::list<Poco::DynamicAny>& val)
1219 {
1220 	prepareImpl<std::list<Poco::DynamicAny> >(pos, &val);
1221 }
1222 
1223 
bulkSize(std::size_t col)1224 inline std::size_t Preparator::bulkSize(std::size_t col) const
1225 {
1226 	poco_assert (col < _lenLengths.size());
1227 
1228 	return _lenLengths[col].size();
1229 }
1230 
1231 
setMaxFieldSize(std::size_t size)1232 inline void Preparator::setMaxFieldSize(std::size_t size)
1233 {
1234 	_maxFieldSize = size;
1235 }
1236 
1237 
getMaxFieldSize()1238 inline std::size_t Preparator::getMaxFieldSize() const
1239 {
1240 	return _maxFieldSize;
1241 }
1242 
1243 
setDataExtraction(Preparator::DataExtraction ext)1244 inline void Preparator::setDataExtraction(Preparator::DataExtraction ext)
1245 {
1246 	_dataExtraction = ext;
1247 }
1248 
1249 
getDataExtraction()1250 inline Preparator::DataExtraction Preparator::getDataExtraction() const
1251 {
1252 	return _dataExtraction;
1253 }
1254 
1255 
1256 inline Poco::Any& Preparator::operator [] (std::size_t pos)
1257 {
1258 	return at(pos);
1259 }
1260 
1261 
at(std::size_t pos)1262 inline Poco::Any& Preparator::at(std::size_t pos)
1263 {
1264 	return _values.at(pos);
1265 }
1266 
1267 
1268 } } } // namespace Poco::Data::ODBC
1269 
1270 
1271 #endif // Data_ODBC_Preparator_INCLUDED
1272