1//
2// MySQLException.cpp
3//
4// Library: SQL/MySQL
5// Package: MySQL
6// Module: Extractor
7//
8// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/SQL/MySQL/Extractor.h"
16
17#include "Poco/SQL/Date.h"
18#include "Poco/SQL/Time.h"
19#include "Poco/Dynamic/Var.h"
20
21namespace Poco {
22namespace SQL {
23namespace MySQL {
24
25
26Extractor::Extractor(StatementExecutor& st, ResultMetadata& md): _stmt(st), _metadata(md)
27{
28}
29
30
31Extractor::~Extractor()
32{
33}
34
35
36bool Extractor::extract(std::size_t pos, Poco::Int8& val)
37{
38 return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
39}
40
41
42bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
43{
44 return realExtractFixed(pos, MYSQL_TYPE_TINY, &val, true);
45}
46
47
48bool Extractor::extract(std::size_t pos, Poco::Int16& val)
49{
50 return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val);
51}
52
53
54bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
55{
56 return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val, true);
57}
58
59
60bool Extractor::extract(std::size_t pos, Poco::Int32& val)
61{
62 return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
63}
64
65
66bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
67{
68 return realExtractFixed(pos, MYSQL_TYPE_LONG, &val, true);
69}
70
71
72bool Extractor::extract(std::size_t pos, Poco::Int64& val)
73{
74 return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val);
75}
76
77
78bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
79{
80 return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val, true);
81}
82
83
84#ifndef POCO_LONG_IS_64_BIT
85bool Extractor::extract(std::size_t pos, long& val)
86{
87 return realExtractFixed(pos, MYSQL_TYPE_LONG, &val);
88}
89
90
91bool Extractor::extract(std::size_t pos, unsigned long& val)
92{
93 return realExtractFixed(pos, MYSQL_TYPE_LONG, &val, true);
94}
95#endif
96
97
98bool Extractor::extract(std::size_t pos, bool& val)
99{
100 return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
101}
102
103
104bool Extractor::extract(std::size_t pos, float& val)
105{
106 return realExtractFixed(pos, MYSQL_TYPE_FLOAT, &val);
107}
108
109
110bool Extractor::extract(std::size_t pos, double& val)
111{
112 return realExtractFixed(pos, MYSQL_TYPE_DOUBLE, &val);
113}
114
115
116bool Extractor::extract(std::size_t pos, char& val)
117{
118 return realExtractFixed(pos, MYSQL_TYPE_TINY, &val);
119}
120
121
122bool Extractor::extract(std::size_t pos, std::string& val)
123{
124 if (_metadata.columnsReturned() <= pos)
125 throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
126
127 if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
128 return false;
129
130 //mysql reports TEXT types as FDT_BLOB when being extracted
131 MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
132 if (columnType != Poco::SQL::MetaColumn::FDT_STRING && columnType != Poco::SQL::MetaColumn::FDT_BLOB)
133 throw MySQLException("Extractor: not a string");
134
135 if (columnType == Poco::SQL::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
136 {
137 std::vector<char> buffer(_metadata.length(pos), 0);
138 bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
139 if (ret)
140 val.assign(buffer.data(), buffer.size());
141
142 return ret;
143 }
144
145 val.assign(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
146 return true;
147}
148
149
150bool Extractor::extract(std::size_t pos, Poco::SQL::BLOB& val)
151{
152 if (_metadata.columnsReturned() <= pos)
153 throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
154
155 if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
156 return false;
157
158 MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
159 if (columnType != Poco::SQL::MetaColumn::FDT_BLOB)
160 throw MySQLException("Extractor: not a blob");
161
162 if (columnType == Poco::SQL::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
163 {
164 std::vector<unsigned char> buffer(_metadata.length(pos), 0);
165 bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
166 if (ret)
167 val.assignRaw(buffer.data(), buffer.size());
168
169 return ret;
170 }
171
172 val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
173 return true;
174}
175
176
177bool Extractor::extract(std::size_t pos, Poco::SQL::CLOB& val)
178{
179 if (_metadata.columnsReturned() <= pos)
180 throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
181
182 if (_metadata.isNull(static_cast<Poco::UInt32>(pos)))
183 return false;
184
185 MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
186 if (columnType != Poco::SQL::MetaColumn::FDT_BLOB)
187 throw MySQLException("Extractor: not a blob");
188
189 if (columnType == Poco::SQL::MetaColumn::FDT_BLOB && _metadata.length(pos) > 0 && _metadata.rawData(pos) == NULL)
190 {
191 std::vector<char> buffer(_metadata.length(pos), 0);
192 bool ret = realExtractFixedBlob(pos, _metadata.row()[pos].buffer_type, buffer.data(), buffer.size());
193 if (ret)
194 val.assignRaw(buffer.data(), buffer.size());
195
196 return ret;
197 }
198
199 val.assignRaw(reinterpret_cast<const char*>(_metadata.rawData(pos)), _metadata.length(pos));
200 return true;
201}
202
203
204bool Extractor::extract(std::size_t pos, DateTime& val)
205{
206 MYSQL_TIME mt = {0};
207
208 if (!realExtractFixed(pos, MYSQL_TYPE_DATETIME, &mt))
209 return false;
210
211 val.assign(mt.year, mt.month, mt.day, mt.hour, mt.minute, mt.second, mt.second_part / 1000, mt.second_part % 1000);
212 return true;
213}
214
215
216bool Extractor::extract(std::size_t pos, Date& val)
217{
218 MYSQL_TIME mt = {0};
219
220 if (!realExtractFixed(pos, MYSQL_TYPE_DATE, &mt))
221 return false;
222
223 val.assign(mt.year, mt.month, mt.day);
224 return true;
225}
226
227
228bool Extractor::extract(std::size_t pos, Time& val)
229{
230 MYSQL_TIME mt = {0};
231
232 if (!realExtractFixed(pos, MYSQL_TYPE_TIME, &mt))
233 return false;
234
235 val.assign(mt.hour, mt.minute, mt.second);
236 return true;
237}
238
239
240bool Extractor::extract(std::size_t pos, Any& val)
241{
242 return extractToDynamic<Any>(pos, val);
243}
244
245
246bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
247{
248 return extractToDynamic<Dynamic::Var>(pos, val);
249}
250
251
252bool Extractor::isNull(std::size_t col, std::size_t row)
253{
254 poco_assert(row == POCO_DATA_INVALID_ROW);
255
256 if (_metadata.columnsReturned() <= col)
257 throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
258
259 if (_metadata.isNull(static_cast<Poco::UInt32>(col)))
260 return true;
261
262 return false;
263}
264
265void Extractor::reset()
266{
267 AbstractExtractor::reset();
268}
269
270
271bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned)
272{
273 MYSQL_BIND bind = {0};
274 my_bool isNull = 0;
275
276 bind.is_null = &isNull;
277 bind.buffer_type = type;
278 bind.buffer = buffer;
279 bind.is_unsigned = isUnsigned;
280
281 if (!_stmt.fetchColumn(pos, &bind))
282 return false;
283
284 return isNull == 0;
285}
286
287bool Extractor::realExtractFixedBlob(std::size_t pos, enum_field_types type, void* buffer, size_t len)
288{
289 MYSQL_BIND bind = {0};
290 my_bool isNull = 0;
291
292 bind.is_null = &isNull;
293 bind.buffer_type = type;
294 bind.buffer = buffer;
295 bind.buffer_length = static_cast<unsigned long>(len);
296
297 if (!_stmt.fetchColumn(pos, &bind))
298 return false;
299
300 return isNull == 0;
301}
302
303//////////////
304// Not implemented
305//////////////
306
307
308bool Extractor::extract(std::size_t , std::vector<Poco::Int8>& )
309{
310 throw NotImplementedException("std::vector extractor must be implemented.");
311}
312
313
314bool Extractor::extract(std::size_t , std::deque<Poco::Int8>& )
315{
316 throw NotImplementedException("std::deque extractor must be implemented.");
317}
318
319
320bool Extractor::extract(std::size_t , std::list<Poco::Int8>& )
321{
322 throw NotImplementedException("std::list extractor must be implemented.");
323}
324
325
326bool Extractor::extract(std::size_t , std::vector<Poco::UInt8>& )
327{
328 throw NotImplementedException("std::vector extractor must be implemented.");
329}
330
331
332bool Extractor::extract(std::size_t , std::deque<Poco::UInt8>& )
333{
334 throw NotImplementedException("std::deque extractor must be implemented.");
335}
336
337
338bool Extractor::extract(std::size_t , std::list<Poco::UInt8>& )
339{
340 throw NotImplementedException("std::list extractor must be implemented.");
341}
342
343
344bool Extractor::extract(std::size_t , std::vector<Poco::Int16>& )
345{
346 throw NotImplementedException("std::vector extractor must be implemented.");
347}
348
349
350bool Extractor::extract(std::size_t , std::deque<Poco::Int16>& )
351{
352 throw NotImplementedException("std::deque extractor must be implemented.");
353}
354
355
356bool Extractor::extract(std::size_t , std::list<Poco::Int16>& )
357{
358 throw NotImplementedException("std::list extractor must be implemented.");
359}
360
361
362bool Extractor::extract(std::size_t , std::vector<Poco::UInt16>& )
363{
364 throw NotImplementedException("std::vector extractor must be implemented.");
365}
366
367
368bool Extractor::extract(std::size_t , std::deque<Poco::UInt16>& )
369{
370 throw NotImplementedException("std::deque extractor must be implemented.");
371}
372
373
374bool Extractor::extract(std::size_t , std::list<Poco::UInt16>& )
375{
376 throw NotImplementedException("std::list extractor must be implemented.");
377}
378
379
380bool Extractor::extract(std::size_t , std::vector<Poco::Int32>& )
381{
382 throw NotImplementedException("std::vector extractor must be implemented.");
383}
384
385
386bool Extractor::extract(std::size_t , std::deque<Poco::Int32>& )
387{
388 throw NotImplementedException("std::deque extractor must be implemented.");
389}
390
391
392bool Extractor::extract(std::size_t , std::list<Poco::Int32>& )
393{
394 throw NotImplementedException("std::list extractor must be implemented.");
395}
396
397
398bool Extractor::extract(std::size_t , std::vector<Poco::UInt32>& )
399{
400 throw NotImplementedException("std::vector extractor must be implemented.");
401}
402
403
404bool Extractor::extract(std::size_t , std::deque<Poco::UInt32>& )
405{
406 throw NotImplementedException("std::deque extractor must be implemented.");
407}
408
409
410bool Extractor::extract(std::size_t , std::list<Poco::UInt32>& )
411{
412 throw NotImplementedException("std::list extractor must be implemented.");
413}
414
415
416bool Extractor::extract(std::size_t , std::vector<Poco::Int64>& )
417{
418 throw NotImplementedException("std::vector extractor must be implemented.");
419}
420
421
422bool Extractor::extract(std::size_t , std::deque<Poco::Int64>& )
423{
424 throw NotImplementedException("std::deque extractor must be implemented.");
425}
426
427
428bool Extractor::extract(std::size_t , std::list<Poco::Int64>& )
429{
430 throw NotImplementedException("std::list extractor must be implemented.");
431}
432
433
434bool Extractor::extract(std::size_t , std::vector<Poco::UInt64>& )
435{
436 throw NotImplementedException("std::vector extractor must be implemented.");
437}
438
439
440bool Extractor::extract(std::size_t , std::deque<Poco::UInt64>& )
441{
442 throw NotImplementedException("std::deque extractor must be implemented.");
443}
444
445
446bool Extractor::extract(std::size_t , std::list<Poco::UInt64>& )
447{
448 throw NotImplementedException("std::list extractor must be implemented.");
449}
450
451
452#ifndef POCO_LONG_IS_64_BIT
453bool Extractor::extract(std::size_t , std::vector<long>& )
454{
455 throw NotImplementedException("std::vector extractor must be implemented.");
456}
457
458
459bool Extractor::extract(std::size_t , std::deque<long>& )
460{
461 throw NotImplementedException("std::deque extractor must be implemented.");
462}
463
464
465bool Extractor::extract(std::size_t , std::list<long>& )
466{
467 throw NotImplementedException("std::list extractor must be implemented.");
468}
469#endif
470
471
472bool Extractor::extract(std::size_t , std::vector<bool>& )
473{
474 throw NotImplementedException("std::vector extractor must be implemented.");
475}
476
477
478bool Extractor::extract(std::size_t , std::deque<bool>& )
479{
480 throw NotImplementedException("std::deque extractor must be implemented.");
481}
482
483
484bool Extractor::extract(std::size_t , std::list<bool>& )
485{
486 throw NotImplementedException("std::list extractor must be implemented.");
487}
488
489
490bool Extractor::extract(std::size_t , std::vector<float>& )
491{
492 throw NotImplementedException("std::vector extractor must be implemented.");
493}
494
495
496bool Extractor::extract(std::size_t , std::deque<float>& )
497{
498 throw NotImplementedException("std::deque extractor must be implemented.");
499}
500
501
502bool Extractor::extract(std::size_t , std::list<float>& )
503{
504 throw NotImplementedException("std::list extractor must be implemented.");
505}
506
507
508bool Extractor::extract(std::size_t , std::vector<double>& )
509{
510 throw NotImplementedException("std::vector extractor must be implemented.");
511}
512
513
514bool Extractor::extract(std::size_t , std::deque<double>& )
515{
516 throw NotImplementedException("std::deque extractor must be implemented.");
517}
518
519
520bool Extractor::extract(std::size_t , std::list<double>& )
521{
522 throw NotImplementedException("std::list extractor must be implemented.");
523}
524
525
526bool Extractor::extract(std::size_t , std::vector<char>& )
527{
528 throw NotImplementedException("std::vector extractor must be implemented.");
529}
530
531
532bool Extractor::extract(std::size_t , std::deque<char>& )
533{
534 throw NotImplementedException("std::deque extractor must be implemented.");
535}
536
537
538bool Extractor::extract(std::size_t , std::list<char>& )
539{
540 throw NotImplementedException("std::list extractor must be implemented.");
541}
542
543
544bool Extractor::extract(std::size_t , std::vector<std::string>& )
545{
546 throw NotImplementedException("std::vector extractor must be implemented.");
547}
548
549
550bool Extractor::extract(std::size_t , std::deque<std::string>& )
551{
552 throw NotImplementedException("std::deque extractor must be implemented.");
553}
554
555
556bool Extractor::extract(std::size_t , std::list<std::string>& )
557{
558 throw NotImplementedException("std::list extractor must be implemented.");
559}
560
561
562bool Extractor::extract(std::size_t , std::vector<BLOB>& )
563{
564 throw NotImplementedException("std::vector extractor must be implemented.");
565}
566
567
568bool Extractor::extract(std::size_t , std::deque<BLOB>& )
569{
570 throw NotImplementedException("std::deque extractor must be implemented.");
571}
572
573
574bool Extractor::extract(std::size_t , std::list<BLOB>& )
575{
576 throw NotImplementedException("std::list extractor must be implemented.");
577}
578
579
580bool Extractor::extract(std::size_t , std::vector<CLOB>& )
581{
582 throw NotImplementedException("std::vector extractor must be implemented.");
583}
584
585
586bool Extractor::extract(std::size_t , std::deque<CLOB>& )
587{
588 throw NotImplementedException("std::deque extractor must be implemented.");
589}
590
591
592bool Extractor::extract(std::size_t , std::list<CLOB>& )
593{
594 throw NotImplementedException("std::list extractor must be implemented.");
595}
596
597
598bool Extractor::extract(std::size_t , std::vector<DateTime>& )
599{
600 throw NotImplementedException("std::vector extractor must be implemented.");
601}
602
603
604bool Extractor::extract(std::size_t , std::deque<DateTime>& )
605{
606 throw NotImplementedException("std::deque extractor must be implemented.");
607}
608
609
610bool Extractor::extract(std::size_t , std::list<DateTime>& )
611{
612 throw NotImplementedException("std::list extractor must be implemented.");
613}
614
615
616bool Extractor::extract(std::size_t , std::vector<Date>& )
617{
618 throw NotImplementedException("std::vector extractor must be implemented.");
619}
620
621
622bool Extractor::extract(std::size_t , std::deque<Date>& )
623{
624 throw NotImplementedException("std::deque extractor must be implemented.");
625}
626
627
628bool Extractor::extract(std::size_t , std::list<Date>& )
629{
630 throw NotImplementedException("std::list extractor must be implemented.");
631}
632
633
634bool Extractor::extract(std::size_t , std::vector<Time>& )
635{
636 throw NotImplementedException("std::vector extractor must be implemented.");
637}
638
639
640bool Extractor::extract(std::size_t , std::deque<Time>& )
641{
642 throw NotImplementedException("std::deque extractor must be implemented.");
643}
644
645
646bool Extractor::extract(std::size_t , std::list<Time>& )
647{
648 throw NotImplementedException("std::list extractor must be implemented.");
649}
650
651
652bool Extractor::extract(std::size_t , std::vector<Any>& )
653{
654 throw NotImplementedException("std::vector extractor must be implemented.");
655}
656
657
658bool Extractor::extract(std::size_t , std::deque<Any>& )
659{
660 throw NotImplementedException("std::deque extractor must be implemented.");
661}
662
663
664bool Extractor::extract(std::size_t , std::list<Any>& )
665{
666 throw NotImplementedException("std::list extractor must be implemented.");
667}
668
669
670bool Extractor::extract(std::size_t , std::vector<Dynamic::Var>& )
671{
672 throw NotImplementedException("std::vector extractor must be implemented.");
673}
674
675
676bool Extractor::extract(std::size_t , std::deque<Dynamic::Var>& )
677{
678 throw NotImplementedException("std::deque extractor must be implemented.");
679}
680
681
682bool Extractor::extract(std::size_t , std::list<Dynamic::Var>& )
683{
684 throw NotImplementedException("std::list extractor must be implemented.");
685}
686
687
688
689} } } // namespace Poco::SQL::MySQL
690