1//
2// Extractor.cpp
3//
4// Library: Data/ODBC
5// Package: ODBC
6// Module: Extractor
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Data/ODBC/Extractor.h"
16#include "Poco/Data/ODBC/ODBCMetaColumn.h"
17#include "Poco/Data/ODBC/Utility.h"
18#include "Poco/Data/ODBC/ODBCException.h"
19#include "Poco/Data/LOB.h"
20#include "Poco/Buffer.h"
21#include "Poco/Exception.h"
22
23
24namespace Poco {
25namespace Data {
26namespace ODBC {
27
28
29const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z bytes) "
30 "exceeds maximum value (%z).\n"
31 "Use Session.setProperty(\"maxFieldSize\", value) "
32 "to increase the maximum allowed data size\n";
33
34
35Extractor::Extractor(const StatementHandle& rStmt,
36 Preparator::Ptr pPreparator):
37 _rStmt(rStmt),
38 _pPreparator(pPreparator),
39 _dataExtraction(pPreparator->getDataExtraction())
40{
41}
42
43
44Extractor::~Extractor()
45{
46}
47
48
49template<>
50bool Extractor::extractBoundImpl<std::string>(std::size_t pos, std::string& val)
51{
52 if (isNull(pos)) return false;
53
54 std::size_t dataSize = _pPreparator->actualDataSize(pos);
55 char* sp = AnyCast<char*>(_pPreparator->at(pos));
56 std::size_t len = std::strlen(sp);
57 if (len < dataSize) dataSize = len;
58 checkDataSize(dataSize);
59 val.assign(sp, dataSize);
60
61 return true;
62}
63
64
65template<>
66bool Extractor::extractBoundImpl<UTF16String>(std::size_t pos, UTF16String& val)
67{
68 typedef UTF16String::value_type CharT;
69 if (isNull(pos)) return false;
70 std::size_t dataSize = _pPreparator->actualDataSize(pos);
71 CharT* sp = AnyCast<CharT*>(_pPreparator->at(pos));
72 std::size_t len = Poco::UnicodeConverter::UTFStrlen(sp);
73 if (len < dataSize) dataSize = len;
74 checkDataSize(dataSize);
75 val.assign(sp, dataSize);
76
77 return true;
78}
79
80
81template<>
82bool Extractor::extractBoundImpl<Poco::Data::Date>(std::size_t pos, Poco::Data::Date& val)
83{
84 if (isNull(pos)) return false;
85 SQL_DATE_STRUCT& ds = *AnyCast<SQL_DATE_STRUCT>(&(_pPreparator->at(pos)));
86 Utility::dateSync(val, ds);
87 return true;
88}
89
90
91template<>
92bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Date> >(std::size_t pos,
93 std::vector<Poco::Data::Date>& val)
94{
95 std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
96 Utility::dateSync(val, ds);
97 return true;
98}
99
100
101template<>
102bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Date> >(std::size_t pos,
103 std::deque<Poco::Data::Date>& val)
104{
105 std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
106 Utility::dateSync(val, ds);
107 return true;
108}
109
110
111template<>
112bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Date> >(std::size_t pos,
113 std::list<Poco::Data::Date>& val)
114{
115 std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
116 Utility::dateSync(val, ds);
117 return true;
118}
119
120
121template<>
122bool Extractor::extractBoundImpl<Poco::Data::Time>(std::size_t pos, Poco::Data::Time& val)
123{
124 if (isNull(pos)) return false;
125
126 std::size_t dataSize = _pPreparator->actualDataSize(pos);
127 checkDataSize(dataSize);
128 SQL_TIME_STRUCT& ts = *AnyCast<SQL_TIME_STRUCT>(&_pPreparator->at(pos));
129 Utility::timeSync(val, ts);
130
131 return true;
132}
133
134
135template<>
136bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Time> >(std::size_t pos,
137 std::vector<Poco::Data::Time>& val)
138{
139 std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
140 Utility::timeSync(val, ds);
141 return true;
142}
143
144
145template<>
146bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Time> >(std::size_t pos,
147 std::deque<Poco::Data::Time>& val)
148{
149 std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
150 Utility::timeSync(val, ds);
151 return true;
152}
153
154
155template<>
156bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Time> >(std::size_t pos,
157 std::list<Poco::Data::Time>& val)
158{
159 std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
160 Utility::timeSync(val, ds);
161 return true;
162}
163
164
165template<>
166bool Extractor::extractBoundImpl<Poco::DateTime>(std::size_t pos, Poco::DateTime& val)
167{
168 if (isNull(pos)) return false;
169
170 std::size_t dataSize = _pPreparator->actualDataSize(pos);
171 checkDataSize(dataSize);
172 SQL_TIMESTAMP_STRUCT& tss = *AnyCast<SQL_TIMESTAMP_STRUCT>(&_pPreparator->at(pos));
173 Utility::dateTimeSync(val, tss);
174
175 return true;
176}
177
178
179template<>
180bool Extractor::extractBoundImplContainer<std::vector<Poco::DateTime> >(std::size_t pos,
181 std::vector<Poco::DateTime>& val)
182{
183 std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
184 Utility::dateTimeSync(val, ds);
185 return true;
186}
187
188
189template<>
190bool Extractor::extractBoundImplContainer<std::deque<Poco::DateTime> >(std::size_t pos,
191 std::deque<Poco::DateTime>& val)
192{
193 std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
194 Utility::dateTimeSync(val, ds);
195 return true;
196}
197
198
199template<>
200bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_t pos,
201 std::list<Poco::DateTime>& val)
202{
203 std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
204 Utility::dateTimeSync(val, ds);
205 return true;
206}
207
208
209template<>
210bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
211 std::vector<bool>& val)
212{
213 std::size_t length = _pPreparator->getLength();
214 bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
215 val.assign(*p, *p + length);
216 return true;
217}
218
219
220template<>
221bool Extractor::extractBoundImplContainer<std::deque<bool> >(std::size_t pos,
222 std::deque<bool>& val)
223{
224 std::size_t length = _pPreparator->getLength();
225 bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
226 val.assign(*p, *p + length);
227 return true;
228}
229
230
231template<>
232bool Extractor::extractBoundImplContainer<std::list<bool> >(std::size_t pos,
233 std::list<bool>& val)
234{
235 std::size_t length = _pPreparator->getLength();
236 bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
237 val.assign(*p, *p + length);
238 return true;
239}
240
241
242template<>
243bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val, SQLSMALLINT cType)
244{
245 std::size_t maxSize = _pPreparator->getMaxFieldSize();
246 std::size_t fetchedSize = 0;
247 std::size_t totalSize = 0;
248
249 SQLLEN len;
250 const int bufSize = CHUNK_SIZE;
251 Poco::Buffer<char> apChar(bufSize);
252 char* pChar = apChar.begin();
253 SQLRETURN rc = 0;
254
255 val.clear();
256 resizeLengths(pos);
257
258 do
259 {
260 std::memset(pChar, 0, bufSize);
261 len = 0;
262 rc = SQLGetData(_rStmt,
263 (SQLUSMALLINT) pos + 1,
264 cType, //C data type
265 pChar, //returned value
266 bufSize, //buffer length
267 &len); //length indicator
268
269 if (SQL_NO_DATA != rc && Utility::isError(rc))
270 throw StatementException(_rStmt, "SQLGetData()");
271
272 if (SQL_NO_TOTAL == len)//unknown length, throw
273 throw UnknownDataLengthException("Could not determine returned data length.");
274
275 if (isNullLengthIndicator(len))
276 {
277 _lengths[pos] = len;
278 return false;
279 }
280
281 if (SQL_NO_DATA == rc || !len)
282 break;
283
284 _lengths[pos] += len;
285 fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
286 totalSize += fetchedSize;
287 if (totalSize <= maxSize)
288 val.append(pChar, fetchedSize);
289 else
290 throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
291 }while (true);
292
293 return true;
294}
295
296
297template<>
298bool Extractor::extractManualImpl<UTF16String>(std::size_t pos, UTF16String& val, SQLSMALLINT cType)
299{
300 std::size_t maxSize = _pPreparator->getMaxFieldSize();
301 std::size_t fetchedSize = 0;
302 std::size_t totalSize = 0;
303
304 SQLLEN len;
305 const int bufSize = CHUNK_SIZE;
306 Poco::Buffer<UTF16String::value_type> apChar(bufSize);
307 UTF16String::value_type* pChar = apChar.begin();
308 SQLRETURN rc = 0;
309
310 val.clear();
311 resizeLengths(pos);
312
313 do
314 {
315 std::memset(pChar, 0, bufSize);
316 len = 0;
317 rc = SQLGetData(_rStmt,
318 (SQLUSMALLINT)pos + 1,
319 cType, //C data type
320 pChar, //returned value
321 bufSize, //buffer length
322 &len); //length indicator
323
324 if (SQL_NO_DATA != rc && Utility::isError(rc))
325 throw StatementException(_rStmt, "SQLGetData()");
326
327 if (SQL_NO_TOTAL == len)//unknown length, throw
328 throw UnknownDataLengthException("Could not determine returned data length.");
329
330 if (isNullLengthIndicator(len))
331 {
332 _lengths[pos] = len;
333 return false;
334 }
335
336 if (SQL_NO_DATA == rc || !len)
337 break;
338
339 _lengths[pos] += len;
340 fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
341 totalSize += fetchedSize;
342 if (totalSize <= maxSize)
343 val.append(pChar, fetchedSize / sizeof(UTF16Char));
344 else
345 throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
346 } while (true);
347
348 return true;
349}
350
351
352template<>
353bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
354 Poco::Data::CLOB& val,
355 SQLSMALLINT cType)
356{
357 return extractManualLOBImpl(pos, val, cType);
358}
359
360
361template<>
362bool Extractor::extractManualImpl<Poco::Data::BLOB>(std::size_t pos,
363 Poco::Data::BLOB& val,
364 SQLSMALLINT cType)
365{
366 return extractManualLOBImpl(pos, val, cType);
367}
368
369
370template<typename T>
371bool Extractor::extractManualLOBImpl(std::size_t pos,
372 Poco::Data::LOB<T>& val,
373 SQLSMALLINT cType)
374{
375 std::size_t maxSize = _pPreparator->getMaxFieldSize();
376 const int bufSize = CHUNK_SIZE;
377 std::size_t fetchedSize = bufSize;
378 std::size_t totalSize = 0;
379
380 SQLLEN len;
381
382 Poco::Buffer<T> apChar(bufSize);
383 T* pChar = apChar.begin();
384 SQLRETURN rc = 0;
385
386 val.clear();
387 resizeLengths(pos);
388
389 do
390 {
391 // clear out the latest data in the buffer
392 if (fetchedSize > 0)
393 std::memset(pChar, 0, fetchedSize);
394 len = 0;
395 rc = SQLGetData(_rStmt,
396 (SQLUSMALLINT) pos + 1,
397 cType, //C data type
398 pChar, //returned value
399 bufSize, //buffer length
400 &len); //length indicator
401
402 _lengths[pos] += len;
403
404 if (SQL_NO_DATA != rc && Utility::isError(rc))
405 throw StatementException(_rStmt, "SQLGetData()");
406
407 if (SQL_NO_TOTAL == len)//unknown length, throw
408 throw UnknownDataLengthException("Could not determine returned data length.");
409
410 if (isNullLengthIndicator(len))
411 return false;
412
413 if (SQL_NO_DATA == rc || !len)
414 break;
415
416 fetchedSize = len > bufSize ? bufSize : len;
417 totalSize += fetchedSize;
418 if (totalSize <= maxSize)
419 val.appendRaw(pChar, fetchedSize);
420 else
421 throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
422
423 }while (true);
424
425 return true;
426}
427
428
429template<>
430bool Extractor::extractManualImpl<Poco::Data::Date>(std::size_t pos,
431 Poco::Data::Date& val,
432 SQLSMALLINT cType)
433{
434 SQL_DATE_STRUCT ds;
435 resizeLengths(pos);
436
437 SQLRETURN rc = SQLGetData(_rStmt,
438 (SQLUSMALLINT) pos + 1,
439 cType, //C data type
440 &ds, //returned value
441 sizeof(ds), //buffer length
442 &_lengths[pos]); //length indicator
443
444 if (Utility::isError(rc))
445 throw StatementException(_rStmt, "SQLGetData()");
446
447 if (isNullLengthIndicator(_lengths[pos]))
448 return false;
449 else
450 Utility::dateSync(val, ds);
451
452 return true;
453}
454
455
456template<>
457bool Extractor::extractManualImpl<Poco::Data::Time>(std::size_t pos,
458 Poco::Data::Time& val,
459 SQLSMALLINT cType)
460{
461 SQL_TIME_STRUCT ts;
462 resizeLengths(pos);
463
464 SQLRETURN rc = SQLGetData(_rStmt,
465 (SQLUSMALLINT) pos + 1,
466 cType, //C data type
467 &ts, //returned value
468 sizeof(ts), //buffer length
469 &_lengths[pos]); //length indicator
470
471 if (Utility::isError(rc))
472 throw StatementException(_rStmt, "SQLGetData()");
473
474 if (isNullLengthIndicator(_lengths[pos]))
475 return false;
476 else
477 Utility::timeSync(val, ts);
478
479 return true;
480}
481
482
483template<>
484bool Extractor::extractManualImpl<Poco::DateTime>(std::size_t pos,
485 Poco::DateTime& val,
486 SQLSMALLINT cType)
487{
488 SQL_TIMESTAMP_STRUCT ts;
489 resizeLengths(pos);
490
491 SQLRETURN rc = SQLGetData(_rStmt,
492 (SQLUSMALLINT) pos + 1,
493 cType, //C data type
494 &ts, //returned value
495 sizeof(ts), //buffer length
496 &_lengths[pos]); //length indicator
497
498 if (Utility::isError(rc))
499 throw StatementException(_rStmt, "SQLGetData()");
500
501 if (isNullLengthIndicator(_lengths[pos]))
502 return false;
503 else
504 Utility::dateTimeSync(val, ts);
505
506 return true;
507}
508
509
510bool Extractor::extract(std::size_t pos, Poco::Int32& val)
511{
512 if (Preparator::DE_MANUAL == _dataExtraction)
513 return extractManualImpl(pos, val, SQL_C_SLONG);
514 else
515 return extractBoundImpl(pos, val);
516}
517
518
519bool Extractor::extract(std::size_t pos, std::vector<Poco::Int32>& val)
520{
521 if (Preparator::DE_BOUND == _dataExtraction)
522 return extractBoundImplContainer(pos, val);
523 else
524 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
525}
526
527
528bool Extractor::extract(std::size_t pos, std::deque<Poco::Int32>& val)
529{
530 if (Preparator::DE_BOUND == _dataExtraction)
531 return extractBoundImplContainer(pos, val);
532 else
533 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
534}
535
536
537bool Extractor::extract(std::size_t pos, std::list<Poco::Int32>& val)
538{
539 if (Preparator::DE_BOUND == _dataExtraction)
540 return extractBoundImplContainer(pos, val);
541 else
542 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
543}
544
545
546bool Extractor::extract(std::size_t pos, Poco::Int64& val)
547{
548 if (Preparator::DE_MANUAL == _dataExtraction)
549 return extractManualImpl(pos, val, SQL_C_SBIGINT);
550 else
551 return extractBoundImpl(pos, val);
552}
553
554
555bool Extractor::extract(std::size_t pos, std::vector<Poco::Int64>& val)
556{
557 if (Preparator::DE_BOUND == _dataExtraction)
558 return extractBoundImplContainer(pos, val);
559 else
560 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
561}
562
563
564bool Extractor::extract(std::size_t pos, std::deque<Poco::Int64>& val)
565{
566 if (Preparator::DE_BOUND == _dataExtraction)
567 return extractBoundImplContainer(pos, val);
568 else
569 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
570}
571
572
573bool Extractor::extract(std::size_t pos, std::list<Poco::Int64>& val)
574{
575 if (Preparator::DE_BOUND == _dataExtraction)
576 return extractBoundImplContainer(pos, val);
577 else
578 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
579}
580
581
582#ifndef POCO_LONG_IS_64_BIT
583bool Extractor::extract(std::size_t pos, long& val)
584{
585 if (Preparator::DE_MANUAL == _dataExtraction)
586 return extractManualImpl(pos, val, SQL_C_SLONG);
587 else
588 return extractBoundImpl(pos, val);
589}
590
591
592bool Extractor::extract(std::size_t pos, unsigned long& val)
593{
594 if (Preparator::DE_MANUAL == _dataExtraction)
595 return extractManualImpl(pos, val, SQL_C_SLONG);
596 else
597 return extractBoundImpl(pos, val);
598}
599
600
601bool Extractor::extract(std::size_t pos, std::vector<long>& val)
602{
603 if (Preparator::DE_BOUND == _dataExtraction)
604 return extractBoundImplContainer(pos, val);
605 else
606 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
607}
608
609
610bool Extractor::extract(std::size_t pos, std::deque<long>& val)
611{
612 if (Preparator::DE_BOUND == _dataExtraction)
613 return extractBoundImplContainer(pos, val);
614 else
615 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
616}
617
618
619bool Extractor::extract(std::size_t pos, std::list<long>& val)
620{
621 if (Preparator::DE_BOUND == _dataExtraction)
622 return extractBoundImplContainer(pos, val);
623 else
624 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
625}
626#endif
627
628
629bool Extractor::extract(std::size_t pos, double& val)
630{
631 if (Preparator::DE_MANUAL == _dataExtraction)
632 return extractManualImpl(pos, val, SQL_C_DOUBLE);
633 else
634 return extractBoundImpl(pos, val);
635}
636
637
638bool Extractor::extract(std::size_t pos, std::vector<double>& val)
639{
640 if (Preparator::DE_BOUND == _dataExtraction)
641 return extractBoundImplContainer(pos, val);
642 else
643 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
644}
645
646
647bool Extractor::extract(std::size_t pos, std::deque<double>& val)
648{
649 if (Preparator::DE_BOUND == _dataExtraction)
650 return extractBoundImplContainer(pos, val);
651 else
652 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
653}
654
655
656bool Extractor::extract(std::size_t pos, std::list<double>& val)
657{
658 if (Preparator::DE_BOUND == _dataExtraction)
659 return extractBoundImplContainer(pos, val);
660 else
661 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
662}
663
664
665bool Extractor::extract(std::size_t pos, std::string& val)
666{
667 if (Preparator::DE_MANUAL == _dataExtraction)
668 return extractManualImpl(pos, val, SQL_C_CHAR);
669 else
670 return extractBoundImpl(pos, val);
671}
672
673
674bool Extractor::extract(std::size_t pos, std::vector<std::string>& val)
675{
676 if (Preparator::DE_BOUND == _dataExtraction)
677 return extractBoundImplContainer(pos, val);
678 else
679 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
680}
681
682
683bool Extractor::extract(std::size_t pos, std::deque<std::string>& val)
684{
685 if (Preparator::DE_BOUND == _dataExtraction)
686 return extractBoundImplContainer(pos, val);
687 else
688 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
689}
690
691
692bool Extractor::extract(std::size_t pos, std::list<std::string>& val)
693{
694 if (Preparator::DE_BOUND == _dataExtraction)
695 return extractBoundImplContainer(pos, val);
696 else
697 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
698}
699
700
701bool Extractor::extract(std::size_t pos, UTF16String& val)
702{
703 if (Preparator::DE_MANUAL == _dataExtraction)
704 return extractManualImpl(pos, val, SQL_C_WCHAR);
705 else
706 return extractBoundImpl(pos, val);
707}
708
709
710bool Extractor::extract(std::size_t pos, std::vector<UTF16String>& val)
711{
712 if (Preparator::DE_BOUND == _dataExtraction)
713 return extractBoundImplContainer(pos, val);
714 else
715 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
716}
717
718
719bool Extractor::extract(std::size_t pos, std::deque<UTF16String>& val)
720{
721 if (Preparator::DE_BOUND == _dataExtraction)
722 return extractBoundImplContainer(pos, val);
723 else
724 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
725}
726
727
728bool Extractor::extract(std::size_t pos, std::list<UTF16String>& val)
729{
730 if (Preparator::DE_BOUND == _dataExtraction)
731 return extractBoundImplContainer(pos, val);
732 else
733 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
734}
735
736
737bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
738{
739 if (Preparator::DE_MANUAL == _dataExtraction)
740 return extractManualImpl(pos, val, SQL_C_BINARY);
741 else
742 return extractBoundImpl(pos, val);
743}
744
745
746bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
747{
748 if (Preparator::DE_MANUAL == _dataExtraction)
749 return extractManualImpl(pos, val, SQL_C_BINARY);
750 else
751 return extractBoundImpl(pos, val);
752}
753
754
755bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::BLOB>& val)
756{
757 if (Preparator::DE_BOUND == _dataExtraction)
758 return extractBoundImplContainer(pos, val);
759 else
760 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
761}
762
763
764bool Extractor::extract(std::size_t pos, std::deque<Poco::Data::BLOB>& val)
765{
766 if (Preparator::DE_BOUND == _dataExtraction)
767 return extractBoundImplContainer(pos, val);
768 else
769 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
770}
771
772
773bool Extractor::extract(std::size_t pos, std::list<Poco::Data::BLOB>& val)
774{
775 if (Preparator::DE_BOUND == _dataExtraction)
776 return extractBoundImplContainer(pos, val);
777 else
778 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
779}
780
781
782bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::CLOB>& val)
783{
784 if (Preparator::DE_BOUND == _dataExtraction)
785 return extractBoundImplContainer(pos, val);
786 else
787 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
788}
789
790
791bool Extractor::extract(std::size_t pos, std::deque<Poco::Data::CLOB>& val)
792{
793 if (Preparator::DE_BOUND == _dataExtraction)
794 return extractBoundImplContainer(pos, val);
795 else
796 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
797}
798
799
800bool Extractor::extract(std::size_t pos, std::list<Poco::Data::CLOB>& val)
801{
802 if (Preparator::DE_BOUND == _dataExtraction)
803 return extractBoundImplContainer(pos, val);
804 else
805 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
806}
807
808
809bool Extractor::extract(std::size_t pos, Poco::Data::Date& val)
810{
811 if (Preparator::DE_MANUAL == _dataExtraction)
812 return extractManualImpl(pos, val, SQL_C_TYPE_DATE);
813 else
814 return extractBoundImpl(pos, val);
815}
816
817
818bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::Date>& val)
819{
820 if (Preparator::DE_BOUND == _dataExtraction)
821 return extractBoundImplContainer(pos, val);
822 else
823 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
824}
825
826
827bool Extractor::extract(std::size_t pos, std::deque<Poco::Data::Date>& val)
828{
829 if (Preparator::DE_BOUND == _dataExtraction)
830 return extractBoundImplContainer(pos, val);
831 else
832 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
833}
834
835
836bool Extractor::extract(std::size_t pos, std::list<Poco::Data::Date>& val)
837{
838 if (Preparator::DE_BOUND == _dataExtraction)
839 return extractBoundImplContainer(pos, val);
840 else
841 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
842}
843
844
845bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
846{
847 if (Preparator::DE_MANUAL == _dataExtraction)
848 return extractManualImpl(pos, val, SQL_C_TYPE_TIME);
849 else
850 return extractBoundImpl(pos, val);
851}
852
853
854bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::Time>& val)
855{
856 if (Preparator::DE_BOUND == _dataExtraction)
857 return extractBoundImplContainer(pos, val);
858 else
859 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
860}
861
862
863bool Extractor::extract(std::size_t pos, std::deque<Poco::Data::Time>& val)
864{
865 if (Preparator::DE_BOUND == _dataExtraction)
866 return extractBoundImplContainer(pos, val);
867 else
868 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
869}
870
871
872bool Extractor::extract(std::size_t pos, std::list<Poco::Data::Time>& val)
873{
874 if (Preparator::DE_BOUND == _dataExtraction)
875 return extractBoundImplContainer(pos, val);
876 else
877 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
878}
879
880
881bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
882{
883 if (Preparator::DE_MANUAL == _dataExtraction)
884 return extractManualImpl(pos, val, SQL_C_TYPE_TIMESTAMP);
885 else
886 return extractBoundImpl(pos, val);
887}
888
889
890bool Extractor::extract(std::size_t pos, std::vector<Poco::DateTime>& val)
891{
892 if (Preparator::DE_BOUND == _dataExtraction)
893 return extractBoundImplContainer(pos, val);
894 else
895 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
896}
897
898
899bool Extractor::extract(std::size_t pos, std::deque<Poco::DateTime>& val)
900{
901 if (Preparator::DE_BOUND == _dataExtraction)
902 return extractBoundImplContainer(pos, val);
903 else
904 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
905}
906
907
908bool Extractor::extract(std::size_t pos, std::list<Poco::DateTime>& val)
909{
910 if (Preparator::DE_BOUND == _dataExtraction)
911 return extractBoundImplContainer(pos, val);
912 else
913 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
914}
915
916
917bool Extractor::extract(std::size_t pos, Poco::Int8& val)
918{
919 if (Preparator::DE_MANUAL == _dataExtraction)
920 return extractManualImpl(pos, val, SQL_C_STINYINT);
921 else
922 return extractBoundImpl(pos, val);
923}
924
925
926bool Extractor::extract(std::size_t pos, std::vector<Poco::Int8>& val)
927{
928 if (Preparator::DE_BOUND == _dataExtraction)
929 return extractBoundImplContainer(pos, val);
930 else
931 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
932}
933
934
935bool Extractor::extract(std::size_t pos, std::deque<Poco::Int8>& val)
936{
937 if (Preparator::DE_BOUND == _dataExtraction)
938 return extractBoundImplContainer(pos, val);
939 else
940 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
941}
942
943
944bool Extractor::extract(std::size_t pos, std::list<Poco::Int8>& val)
945{
946 if (Preparator::DE_BOUND == _dataExtraction)
947 return extractBoundImplContainer(pos, val);
948 else
949 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
950}
951
952
953bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
954{
955 if (Preparator::DE_MANUAL == _dataExtraction)
956 return extractManualImpl(pos, val, SQL_C_UTINYINT);
957 else
958 return extractBoundImpl(pos, val);
959}
960
961
962bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt8>& val)
963{
964 if (Preparator::DE_BOUND == _dataExtraction)
965 return extractBoundImplContainer(pos, val);
966 else
967 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
968}
969
970
971bool Extractor::extract(std::size_t pos, std::deque<Poco::UInt8>& val)
972{
973 if (Preparator::DE_BOUND == _dataExtraction)
974 return extractBoundImplContainer(pos, val);
975 else
976 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
977}
978
979
980bool Extractor::extract(std::size_t pos, std::list<Poco::UInt8>& val)
981{
982 if (Preparator::DE_BOUND == _dataExtraction)
983 return extractBoundImplContainer(pos, val);
984 else
985 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
986}
987
988
989bool Extractor::extract(std::size_t pos, Poco::Int16& val)
990{
991 if (Preparator::DE_MANUAL == _dataExtraction)
992 return extractManualImpl(pos, val, SQL_C_SSHORT);
993 else
994 return extractBoundImpl(pos, val);
995}
996
997
998bool Extractor::extract(std::size_t pos, std::vector<Poco::Int16>& val)
999{
1000 if (Preparator::DE_BOUND == _dataExtraction)
1001 return extractBoundImplContainer(pos, val);
1002 else
1003 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1004}
1005
1006
1007bool Extractor::extract(std::size_t pos, std::deque<Poco::Int16>& val)
1008{
1009 if (Preparator::DE_BOUND == _dataExtraction)
1010 return extractBoundImplContainer(pos, val);
1011 else
1012 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1013}
1014
1015
1016bool Extractor::extract(std::size_t pos, std::list<Poco::Int16>& val)
1017{
1018 if (Preparator::DE_BOUND == _dataExtraction)
1019 return extractBoundImplContainer(pos, val);
1020 else
1021 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1022}
1023
1024
1025bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
1026{
1027 if (Preparator::DE_MANUAL == _dataExtraction)
1028 return extractManualImpl(pos, val, SQL_C_USHORT);
1029 else
1030 return extractBoundImpl(pos, val);
1031}
1032
1033
1034bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt16>& val)
1035{
1036 if (Preparator::DE_BOUND == _dataExtraction)
1037 return extractBoundImplContainer(pos, val);
1038 else
1039 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1040}
1041
1042
1043bool Extractor::extract(std::size_t pos, std::deque<Poco::UInt16>& val)
1044{
1045 if (Preparator::DE_BOUND == _dataExtraction)
1046 return extractBoundImplContainer(pos, val);
1047 else
1048 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1049}
1050
1051
1052bool Extractor::extract(std::size_t pos, std::list<Poco::UInt16>& val)
1053{
1054 if (Preparator::DE_BOUND == _dataExtraction)
1055 return extractBoundImplContainer(pos, val);
1056 else
1057 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1058}
1059
1060
1061bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
1062{
1063 if (Preparator::DE_MANUAL == _dataExtraction)
1064 return extractManualImpl(pos, val, SQL_C_ULONG);
1065 else
1066 return extractBoundImpl(pos, val);
1067}
1068
1069
1070bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt32>& val)
1071{
1072 if (Preparator::DE_BOUND == _dataExtraction)
1073 return extractBoundImplContainer(pos, val);
1074 else
1075 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1076}
1077
1078
1079bool Extractor::extract(std::size_t pos, std::deque<Poco::UInt32>& val)
1080{
1081 if (Preparator::DE_BOUND == _dataExtraction)
1082 return extractBoundImplContainer(pos, val);
1083 else
1084 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1085}
1086
1087
1088bool Extractor::extract(std::size_t pos, std::list<Poco::UInt32>& val)
1089{
1090 if (Preparator::DE_BOUND == _dataExtraction)
1091 return extractBoundImplContainer(pos, val);
1092 else
1093 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1094}
1095
1096
1097bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
1098{
1099 if (Preparator::DE_MANUAL == _dataExtraction)
1100 return extractManualImpl(pos, val, SQL_C_SBIGINT);
1101 else
1102 return extractBoundImpl(pos, val);
1103}
1104
1105
1106bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt64>& val)
1107{
1108 if (Preparator::DE_BOUND == _dataExtraction)
1109 return extractBoundImplContainer(pos, val);
1110 else
1111 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1112}
1113
1114
1115bool Extractor::extract(std::size_t pos, std::deque<Poco::UInt64>& val)
1116{
1117 if (Preparator::DE_BOUND == _dataExtraction)
1118 return extractBoundImplContainer(pos, val);
1119 else
1120 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1121}
1122
1123
1124bool Extractor::extract(std::size_t pos, std::list<Poco::UInt64>& val)
1125{
1126 if (Preparator::DE_BOUND == _dataExtraction)
1127 return extractBoundImplContainer(pos, val);
1128 else
1129 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1130}
1131
1132
1133bool Extractor::extract(std::size_t pos, bool& val)
1134{
1135 if (Preparator::DE_MANUAL == _dataExtraction)
1136 return extractManualImpl(pos, val, SQL_C_BIT);
1137 else
1138 return extractBoundImpl(pos, val);
1139}
1140
1141
1142bool Extractor::extract(std::size_t pos, std::vector<bool>& val)
1143{
1144 if (Preparator::DE_BOUND == _dataExtraction)
1145 return extractBoundImplContainer(pos, val);
1146 else
1147 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1148}
1149
1150
1151bool Extractor::extract(std::size_t pos, std::deque<bool>& val)
1152{
1153 if (Preparator::DE_BOUND == _dataExtraction)
1154 return extractBoundImplContainer(pos, val);
1155 else
1156 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1157}
1158
1159
1160bool Extractor::extract(std::size_t pos, std::list<bool>& val)
1161{
1162 if (Preparator::DE_BOUND == _dataExtraction)
1163 return extractBoundImplContainer(pos, val);
1164 else
1165 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1166}
1167
1168
1169bool Extractor::extract(std::size_t pos, float& val)
1170{
1171 if (Preparator::DE_MANUAL == _dataExtraction)
1172 return extractManualImpl(pos, val, SQL_C_FLOAT);
1173 else
1174 return extractBoundImpl(pos, val);
1175}
1176
1177
1178bool Extractor::extract(std::size_t pos, std::vector<float>& val)
1179{
1180 if (Preparator::DE_BOUND == _dataExtraction)
1181 return extractBoundImplContainer(pos, val);
1182 else
1183 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1184}
1185
1186
1187bool Extractor::extract(std::size_t pos, std::deque<float>& val)
1188{
1189 if (Preparator::DE_BOUND == _dataExtraction)
1190 return extractBoundImplContainer(pos, val);
1191 else
1192 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1193}
1194
1195
1196bool Extractor::extract(std::size_t pos, std::list<float>& val)
1197{
1198 if (Preparator::DE_BOUND == _dataExtraction)
1199 return extractBoundImplContainer(pos, val);
1200 else
1201 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1202}
1203
1204
1205bool Extractor::extract(std::size_t pos, char& val)
1206{
1207 if (Preparator::DE_MANUAL == _dataExtraction)
1208 return extractManualImpl(pos, val, SQL_C_STINYINT);
1209 else
1210 return extractBoundImpl(pos, val);
1211}
1212
1213
1214bool Extractor::extract(std::size_t pos, std::vector<char>& val)
1215{
1216 if (Preparator::DE_BOUND == _dataExtraction)
1217 return extractBoundImplContainer(pos, val);
1218 else
1219 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1220}
1221
1222
1223bool Extractor::extract(std::size_t pos, std::deque<char>& val)
1224{
1225 if (Preparator::DE_BOUND == _dataExtraction)
1226 return extractBoundImplContainer(pos, val);
1227 else
1228 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1229}
1230
1231
1232bool Extractor::extract(std::size_t pos, std::list<char>& val)
1233{
1234 if (Preparator::DE_BOUND == _dataExtraction)
1235 return extractBoundImplContainer(pos, val);
1236 else
1237 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1238}
1239
1240
1241bool Extractor::extract(std::size_t pos, Poco::Any& val)
1242{
1243 return extractImpl(pos, val);
1244}
1245
1246
1247bool Extractor::extract(std::size_t pos, std::vector<Poco::Any>& val)
1248{
1249 if (Preparator::DE_BOUND == _dataExtraction)
1250 return extractBoundImpl(pos, val);
1251 else
1252 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1253}
1254
1255
1256bool Extractor::extract(std::size_t pos, std::deque<Poco::Any>& val)
1257{
1258 if (Preparator::DE_BOUND == _dataExtraction)
1259 return extractBoundImpl(pos, val);
1260 else
1261 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1262}
1263
1264
1265bool Extractor::extract(std::size_t pos, std::list<Poco::Any>& val)
1266{
1267 if (Preparator::DE_BOUND == _dataExtraction)
1268 return extractBoundImpl(pos, val);
1269 else
1270 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1271}
1272
1273
1274bool Extractor::extract(std::size_t pos, Poco::DynamicAny& val)
1275{
1276 return extractImpl(pos, val);
1277}
1278
1279
1280bool Extractor::extract(std::size_t pos, std::vector<Poco::DynamicAny>& val)
1281{
1282 if (Preparator::DE_BOUND == _dataExtraction)
1283 return extractBoundImpl(pos, val);
1284 else
1285 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1286}
1287
1288
1289bool Extractor::extract(std::size_t pos, std::deque<Poco::DynamicAny>& val)
1290{
1291 if (Preparator::DE_BOUND == _dataExtraction)
1292 return extractBoundImpl(pos, val);
1293 else
1294 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1295}
1296
1297
1298bool Extractor::extract(std::size_t pos, std::list<Poco::DynamicAny>& val)
1299{
1300 if (Preparator::DE_BOUND == _dataExtraction)
1301 return extractBoundImpl(pos, val);
1302 else
1303 throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
1304}
1305
1306
1307bool Extractor::isNull(std::size_t col, std::size_t row)
1308{
1309 if (Preparator::DE_MANUAL == _dataExtraction)
1310 {
1311 try
1312 {
1313 return isNullLengthIndicator(_lengths.at(col));
1314 }
1315 catch (std::out_of_range& ex)
1316 {
1317 throw RangeException(ex.what());
1318 }
1319 }
1320 else return SQL_NULL_DATA == _pPreparator->actualDataSize(col, row);
1321}
1322
1323
1324void Extractor::checkDataSize(std::size_t size)
1325{
1326 std::size_t maxSize = _pPreparator->getMaxFieldSize();
1327 if (size > maxSize)
1328 throw DataException(format(FLD_SIZE_EXCEEDED_FMT, size, maxSize));
1329}
1330
1331
1332} } } // namespace Poco::Data::ODBC
1333