1 /* $Id: dbapi_object_convert.cpp 563801 2018-05-15 15:55:00Z ucko $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Sergey Sikorskiy
27 *
28 * File Description:
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33
34 #include <dbapi/driver/dbapi_object_convert.hpp>
35 #include <dbapi/driver/exception.hpp>
36 #include <corelib/ncbi_safe_static.hpp>
37
38 #include <common/test_assert.h> /* This header must go last */
39
40
41 BEGIN_NCBI_SCOPE
42
43 namespace value_slice
44 {
45
46 ////////////////////////////////////////////////////////////////////////////////
47 static
48 void
ReportTypeConvError(EDB_Type from_type,EDB_Type to_type)49 ReportTypeConvError(EDB_Type from_type, EDB_Type to_type)
50 {
51 string err_str("Cannot convert type " );
52 err_str += CDB_Object::GetTypeName(from_type, false);
53 err_str += " to type ";
54 err_str += CDB_Object::GetTypeName(to_type, false);
55
56 DATABASE_DRIVER_ERROR(err_str, 101100);
57 }
58
59 static
60 void
ReportTypeConvError(EDB_Type from_type,const char * to_type)61 ReportTypeConvError(EDB_Type from_type, const char* to_type)
62 {
63 string err_str("Cannot convert type " );
64 err_str += CDB_Object::GetTypeName(from_type, false);
65 err_str += " to type ";
66 err_str += to_type;
67
68 DATABASE_DRIVER_ERROR(err_str, 101100);
69 }
70
71 inline
72 void
CheckNULL(const CDB_Object & value)73 CheckNULL(const CDB_Object& value)
74 {
75 if (value.IsNULL()) {
76 DATABASE_DRIVER_ERROR("Trying to access a NULL value.", 101100);
77 }
78 }
79
80 inline
81 void
CheckType(const CDB_Object & value,EDB_Type type1)82 CheckType(const CDB_Object& value, EDB_Type type1)
83 {
84 EDB_Type cur_type = value.GetType();
85
86 if (cur_type != type1) {
87 ReportTypeConvError(cur_type, type1);
88 }
89 }
90
91 inline
92 void
CheckType(const CDB_Object & value,EDB_Type type1,EDB_Type type2)93 CheckType(const CDB_Object& value, EDB_Type type1, EDB_Type type2)
94 {
95 EDB_Type cur_type = value.GetType();
96
97 if (!(cur_type == type1 || cur_type == type2)) {
98 DATABASE_DRIVER_ERROR(string("Invalid type conversion: have ")
99 + CDB_Object::GetTypeName(cur_type, false)
100 + " but need either "
101 + CDB_Object::GetTypeName(type1, false)
102 + " or " + CDB_Object::GetTypeName(type2, false),
103 101100);
104 }
105 }
106
107 inline
108 void
CheckType(const CDB_Object & value,EDB_Type type1,EDB_Type type2,EDB_Type type3)109 CheckType(const CDB_Object& value, EDB_Type type1, EDB_Type type2,
110 EDB_Type type3)
111 {
112 EDB_Type cur_type = value.GetType();
113
114 if (!(cur_type == type1 || cur_type == type2 || cur_type == type3)) {
115 DATABASE_DRIVER_ERROR(string("Invalid type conversion: have ")
116 + CDB_Object::GetTypeName(cur_type, false)
117 + " but need either "
118 + CDB_Object::GetTypeName(type1, false) + ", "
119 + CDB_Object::GetTypeName(type2, false) + ", or "
120 + CDB_Object::GetTypeName(type3, false),
121 101100);
122 }
123 }
124
125 ////////////////////////////////////////////////////////////////////////////////
CValueConvert(obj_type & value)126 CValueConvert<SSafeCP, CDB_Object>::CValueConvert(obj_type& value)
127 : m_Value(value)
128 {
129 }
130
operator bool(void) const131 CValueConvert<SSafeCP, CDB_Object>::operator bool(void) const
132 {
133 CheckNULL(m_Value);
134 CheckType(m_Value, eDB_Bit);
135
136 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
137 }
138
operator Uint1(void) const139 CValueConvert<SSafeCP, CDB_Object>::operator Uint1(void) const
140 {
141 CheckNULL(m_Value);
142
143 const EDB_Type cur_type = m_Value.GetType();
144
145 switch (cur_type) {
146 case eDB_TinyInt:
147 return Convert(static_cast<const CDB_TinyInt&>(m_Value).Value());
148 case eDB_Bit:
149 // CDB_Bit is for some reason "Int4" ...
150 // return Convert(static_cast<const CDB_Bit&>(m_Value).Value());
151 return (static_cast<const CDB_Bit&>(m_Value).Value() == 0 ? 0 : 1);
152 default:
153 ReportTypeConvError(cur_type, "Uint1");
154 }
155
156 return 0;
157 }
158
operator Int2(void) const159 CValueConvert<SSafeCP, CDB_Object>::operator Int2(void) const
160 {
161 CheckNULL(m_Value);
162
163 const EDB_Type cur_type = m_Value.GetType();
164
165 switch (cur_type) {
166 case eDB_SmallInt:
167 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
168 case eDB_TinyInt:
169 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
170 case eDB_Bit:
171 // CDB_Bit is for some reason "Int4" ...
172 // return Convert(static_cast<const CDB_Bit&>(m_Value).Value());
173 return (static_cast<const CDB_Bit&>(m_Value).Value() == 0 ? 0 : 1);
174 default:
175 ReportTypeConvError(cur_type, "Int2");
176 }
177
178 return 0;
179 }
180
operator Int4(void) const181 CValueConvert<SSafeCP, CDB_Object>::operator Int4(void) const
182 {
183 CheckNULL(m_Value);
184
185 const EDB_Type cur_type = m_Value.GetType();
186
187 switch (cur_type) {
188 case eDB_Int:
189 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
190 case eDB_SmallInt:
191 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
192 case eDB_TinyInt:
193 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
194 case eDB_Bit:
195 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
196 default:
197 ReportTypeConvError(cur_type, "Int4");
198 }
199
200 return 0;
201 }
202
operator Int8(void) const203 CValueConvert<SSafeCP, CDB_Object>::operator Int8(void) const
204 {
205 CheckNULL(m_Value);
206
207 const EDB_Type cur_type = m_Value.GetType();
208
209 switch (cur_type) {
210 case eDB_BigInt:
211 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
212 case eDB_Int:
213 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
214 case eDB_SmallInt:
215 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
216 case eDB_TinyInt:
217 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
218 case eDB_Bit:
219 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
220 default:
221 ReportTypeConvError(cur_type, "Int8");
222 }
223
224 return 0;
225 }
226
operator float(void) const227 CValueConvert<SSafeCP, CDB_Object>::operator float(void) const
228 {
229 CheckNULL(m_Value);
230
231 const EDB_Type cur_type = m_Value.GetType();
232
233 switch (cur_type) {
234 case eDB_Float:
235 return ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value());
236 case eDB_BigInt:
237 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
238 case eDB_Int:
239 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
240 case eDB_SmallInt:
241 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
242 case eDB_TinyInt:
243 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
244 case eDB_Bit:
245 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
246 default:
247 ReportTypeConvError(cur_type, "float");
248 }
249
250 return 0.0;
251 }
252
operator double(void) const253 CValueConvert<SSafeCP, CDB_Object>::operator double(void) const
254 {
255 CheckNULL(m_Value);
256
257 const EDB_Type cur_type = m_Value.GetType();
258
259 switch (cur_type) {
260 case eDB_Double:
261 return ConvertSafe(static_cast<const CDB_Double&>(m_Value).Value());
262 case eDB_Float:
263 return ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value());
264 case eDB_BigInt:
265 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
266 case eDB_Int:
267 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
268 case eDB_SmallInt:
269 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
270 case eDB_TinyInt:
271 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
272 case eDB_Bit:
273 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
274 default:
275 ReportTypeConvError(cur_type, "double");
276 }
277
278 return 0.0;
279 }
280
operator string(void) const281 CValueConvert<SSafeCP, CDB_Object>::operator string(void) const
282 {
283 CheckNULL(m_Value);
284
285 string result;
286
287 const EDB_Type cur_type = m_Value.GetType();
288
289 switch (cur_type) {
290 case eDB_Int:
291 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value()), std::string);
292 case eDB_SmallInt:
293 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value()), std::string);
294 case eDB_TinyInt:
295 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value()), std::string);
296 case eDB_BigInt:
297 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value()), std::string);
298 case eDB_Bit:
299 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value()), std::string);
300 case eDB_Float:
301 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value()), std::string);
302 case eDB_Double:
303 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Double&>(m_Value).Value()), std::string);
304 case eDB_Numeric:
305 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Numeric&>(m_Value).Value()), std::string);
306 case eDB_Char:
307 case eDB_VarChar:
308 case eDB_LongChar:
309 {
310 const CDB_String& cdb_str = static_cast<const CDB_String&>(m_Value);
311 const string& str = cdb_str.AsString();
312 return ConvertSafe(str);
313 }
314 case eDB_Binary:
315 return ConvertSafe(string(
316 static_cast<const char*>(static_cast<const CDB_Binary&>(m_Value).Value()),
317 static_cast<const CDB_Binary&>(m_Value).Size()
318 ));
319 case eDB_VarBinary:
320 return ConvertSafe(string(
321 static_cast<const char*>(static_cast<const CDB_VarBinary&>(m_Value).Value()),
322 static_cast<const CDB_VarBinary&>(m_Value).Size()
323 ));
324 case eDB_LongBinary:
325 return Convert(string(
326 static_cast<const char*>(static_cast<const CDB_LongBinary&>(m_Value).Value()),
327 static_cast<const CDB_LongBinary&>(m_Value).DataSize()
328 ));
329 case eDB_Text:
330 case eDB_Image:
331 case eDB_VarCharMax:
332 case eDB_VarBinaryMax:
333 {
334 CDB_Stream& strm = const_cast<CDB_Stream&>(static_cast<const CDB_Stream&>(m_Value));
335 result.resize(strm.Size());
336 strm.Read(const_cast<void*>(static_cast<const void*>(result.data())),
337 strm.Size()
338 );
339 }
340 break;
341 case eDB_DateTime:
342 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_DateTime&>(m_Value).Value()), std::string);
343 case eDB_BigDateTime:
344 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_BigDateTime&>(m_Value).GetCTime()), std::string);
345 case eDB_SmallDateTime:
346 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_SmallDateTime&>(m_Value).Value()), std::string);
347 default:
348 ReportTypeConvError(cur_type, "string");
349 break;
350 }
351
352
353 return Convert(result);
354 }
355
operator const CTime&(void) const356 CValueConvert<SSafeCP, CDB_Object>::operator const CTime&(void) const
357 {
358 CheckNULL(m_Value);
359 CheckType(m_Value, eDB_SmallDateTime, eDB_DateTime, eDB_BigDateTime);
360
361 EDB_Type cur_type = m_Value.GetType();
362
363 if (cur_type == eDB_SmallDateTime) {
364 return static_cast<const CDB_SmallDateTime&>(m_Value).Value();
365 } else if (cur_type == eDB_DateTime) {
366 return static_cast<const CDB_DateTime&>(m_Value).Value();
367 } else if (cur_type == eDB_BigDateTime) {
368 return static_cast<const CDB_BigDateTime&>(m_Value).GetCTime();
369 } else {
370 ReportTypeConvError(cur_type, "CTime");
371 }
372
373 static CSafeStatic<CTime> value;
374 return value.Get();
375 }
376
377 ////////////////////////////////////////////////////////////////////////////////
CValueConvert(obj_type & value)378 CValueConvert<SSafeSqlCP, CDB_Object>::CValueConvert(obj_type& value)
379 : m_Value(value)
380 {
381 }
382
operator bool(void) const383 CValueConvert<SSafeSqlCP, CDB_Object>::operator bool(void) const
384 {
385 if (m_Value.IsNULL()) {
386 return bool();
387 }
388
389 CheckType(m_Value, eDB_Bit);
390
391 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
392 }
393
operator Uint1(void) const394 CValueConvert<SSafeSqlCP, CDB_Object>::operator Uint1(void) const
395 {
396 if (m_Value.IsNULL()) {
397 return Uint1();
398 }
399
400 const EDB_Type cur_type = m_Value.GetType();
401
402 switch (cur_type) {
403 case eDB_TinyInt:
404 return Convert(static_cast<const CDB_TinyInt&>(m_Value).Value());
405 case eDB_Bit:
406 // CDB_Bit is for some reason "Int4" ...
407 // return Convert(static_cast<const CDB_Bit&>(m_Value).Value());
408 return (static_cast<const CDB_Bit&>(m_Value).Value() == 0 ? 0 : 1);
409 default:
410 ReportTypeConvError(cur_type, "Uint1");
411 }
412
413 return 0;
414 }
415
operator Int2(void) const416 CValueConvert<SSafeSqlCP, CDB_Object>::operator Int2(void) const
417 {
418 if (m_Value.IsNULL()) {
419 return Int2();
420 }
421
422 const EDB_Type cur_type = m_Value.GetType();
423
424 switch (cur_type) {
425 case eDB_SmallInt:
426 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
427 case eDB_TinyInt:
428 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
429 case eDB_Bit:
430 // CDB_Bit is for some reason "Int4" ...
431 // return Convert(static_cast<const CDB_Bit&>(m_Value).Value());
432 return (static_cast<const CDB_Bit&>(m_Value).Value() == 0 ? 0 : 1);
433 default:
434 ReportTypeConvError(cur_type, "Int2");
435 }
436
437 return 0;
438 }
439
operator Int4(void) const440 CValueConvert<SSafeSqlCP, CDB_Object>::operator Int4(void) const
441 {
442 if (m_Value.IsNULL()) {
443 return Int4();
444 }
445
446 const EDB_Type cur_type = m_Value.GetType();
447
448 switch (cur_type) {
449 case eDB_Int:
450 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
451 case eDB_SmallInt:
452 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
453 case eDB_TinyInt:
454 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
455 case eDB_Bit:
456 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
457 default:
458 ReportTypeConvError(cur_type, "Int4");
459 }
460
461 return 0;
462 }
463
operator Int8(void) const464 CValueConvert<SSafeSqlCP, CDB_Object>::operator Int8(void) const
465 {
466 if (m_Value.IsNULL()) {
467 return Int8();
468 }
469
470 const EDB_Type cur_type = m_Value.GetType();
471
472 switch (cur_type) {
473 case eDB_BigInt:
474 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
475 case eDB_Int:
476 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
477 case eDB_SmallInt:
478 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
479 case eDB_TinyInt:
480 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
481 case eDB_Bit:
482 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
483 default:
484 ReportTypeConvError(cur_type, "Int8");
485 }
486
487 return 0;
488 }
489
operator float(void) const490 CValueConvert<SSafeSqlCP, CDB_Object>::operator float(void) const
491 {
492 if (m_Value.IsNULL()) {
493 return float();
494 }
495
496 const EDB_Type cur_type = m_Value.GetType();
497
498 switch (cur_type) {
499 case eDB_Float:
500 return ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value());
501 case eDB_BigInt:
502 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
503 case eDB_Int:
504 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
505 case eDB_SmallInt:
506 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
507 case eDB_TinyInt:
508 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
509 case eDB_Bit:
510 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
511 default:
512 ReportTypeConvError(cur_type, "float");
513 }
514
515 return 0.0;
516 }
517
operator double(void) const518 CValueConvert<SSafeSqlCP, CDB_Object>::operator double(void) const
519 {
520 if (m_Value.IsNULL()) {
521 return double();
522 }
523
524 const EDB_Type cur_type = m_Value.GetType();
525
526 switch (cur_type) {
527 case eDB_Double:
528 return ConvertSafe(static_cast<const CDB_Double&>(m_Value).Value());
529 case eDB_Float:
530 return ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value());
531 case eDB_BigInt:
532 return ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value());
533 case eDB_Int:
534 return ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value());
535 case eDB_SmallInt:
536 return ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value());
537 case eDB_TinyInt:
538 return ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value());
539 case eDB_Bit:
540 return ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value());
541 default:
542 ReportTypeConvError(cur_type, "double");
543 }
544
545 return 0.0;
546 }
547
operator string(void) const548 CValueConvert<SSafeSqlCP, CDB_Object>::operator string(void) const
549 {
550 if (m_Value.IsNULL()) {
551 return string();
552 }
553
554 string result;
555
556 const EDB_Type cur_type = m_Value.GetType();
557
558 switch (cur_type) {
559 case eDB_Int:
560 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Int&>(m_Value).Value()), std::string);
561 case eDB_SmallInt:
562 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_SmallInt&>(m_Value).Value()), std::string);
563 case eDB_TinyInt:
564 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_TinyInt&>(m_Value).Value()), std::string);
565 case eDB_BigInt:
566 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_BigInt&>(m_Value).Value()), std::string);
567 case eDB_Bit:
568 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Bit&>(m_Value).Value()), std::string);
569 case eDB_Float:
570 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Float&>(m_Value).Value()), std::string);
571 case eDB_Double:
572 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Double&>(m_Value).Value()), std::string);
573 case eDB_Numeric:
574 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_Numeric&>(m_Value).Value()), std::string);
575 case eDB_Char:
576 case eDB_VarChar:
577 case eDB_LongChar:
578 {
579 const CDB_String& cdb_str = static_cast<const CDB_String&>(m_Value);
580 const string& str = cdb_str.AsString();
581 return ConvertSafe(str);
582 }
583 case eDB_Binary:
584 return ConvertSafe(string(
585 static_cast<const char*>(static_cast<const CDB_Binary&>(m_Value).Value()),
586 static_cast<const CDB_Binary&>(m_Value).Size()
587 ));
588 case eDB_VarBinary:
589 return ConvertSafe(string(
590 static_cast<const char*>(static_cast<const CDB_VarBinary&>(m_Value).Value()),
591 static_cast<const CDB_VarBinary&>(m_Value).Size()
592 ));
593 case eDB_LongBinary:
594 return Convert(string(
595 static_cast<const char*>(static_cast<const CDB_LongBinary&>(m_Value).Value()),
596 static_cast<const CDB_LongBinary&>(m_Value).DataSize()
597 ));
598 case eDB_Text:
599 case eDB_Image:
600 case eDB_VarCharMax:
601 case eDB_VarBinaryMax:
602 {
603 CDB_Stream& strm = const_cast<CDB_Stream&>(static_cast<const CDB_Stream&>(m_Value));
604 result.resize(strm.Size());
605 strm.Read(const_cast<void*>(static_cast<const void*>(result.data())),
606 strm.Size()
607 );
608 }
609 break;
610 case eDB_DateTime:
611 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_DateTime&>(m_Value).Value()), std::string);
612 case eDB_BigDateTime:
613 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_BigDateTime&>(m_Value).GetCTime()), std::string);
614 case eDB_SmallDateTime:
615 return NCBI_CONVERT_TO(ConvertSafe(static_cast<const CDB_SmallDateTime&>(m_Value).Value()), std::string);
616 default:
617 ReportTypeConvError(cur_type, "string");
618 break;
619 }
620
621
622 return Convert(result);
623 }
624
operator const CTime&(void) const625 CValueConvert<SSafeSqlCP, CDB_Object>::operator const CTime&(void) const
626 {
627 static CSafeStatic<CTime> value;
628
629 if (m_Value.IsNULL()) {
630 return value.Get();
631 }
632
633 CheckType(m_Value, eDB_SmallDateTime, eDB_DateTime, eDB_BigDateTime);
634
635 EDB_Type cur_type = m_Value.GetType();
636
637 if (cur_type == eDB_SmallDateTime) {
638 return static_cast<const CDB_SmallDateTime&>(m_Value).Value();
639 } else if (cur_type == eDB_DateTime) {
640 return static_cast<const CDB_DateTime&>(m_Value).Value();
641 } else if (cur_type == eDB_BigDateTime) {
642 return static_cast<const CDB_BigDateTime&>(m_Value).GetCTime();
643 } else {
644 ReportTypeConvError(cur_type, "CTime");
645 }
646
647 return value.Get();
648 }
649
650 ////////////////////////////////////////////////////////////////////////////////
651 template <typename TO>
652 inline
Convert_CDB_Object(const CDB_Object & value)653 TO Convert_CDB_Object(const CDB_Object& value)
654 {
655 CheckNULL(value);
656
657 const EDB_Type cur_type = value.GetType();
658
659 switch (cur_type) {
660 case eDB_BigInt:
661 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_BigInt&>(value).Value()), TO);
662 case eDB_Int:
663 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Int&>(value).Value()), TO);
664 case eDB_SmallInt:
665 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_SmallInt&>(value).Value()), TO);
666 case eDB_TinyInt:
667 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_TinyInt&>(value).Value()), TO);
668 case eDB_Bit:
669 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Bit&>(value).Value()), TO);
670 case eDB_Float:
671 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Float&>(value).Value()), TO);
672 case eDB_Double:
673 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Double&>(value).Value()), TO);
674 case eDB_Numeric:
675 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Numeric&>(value).Value()), TO);
676 case eDB_Char:
677 case eDB_VarChar:
678 case eDB_LongChar:
679 {
680 const CDB_String& cdb_str = static_cast<const CDB_String&>(value);
681 const string& str = cdb_str.AsString();
682 return Convert(str);
683 }
684 case eDB_Binary:
685 return Convert(string(
686 static_cast<const char*>(static_cast<const CDB_Binary&>(value).Value()),
687 static_cast<const CDB_Binary&>(value).Size()
688 ));
689 case eDB_VarBinary:
690 return Convert(string(
691 static_cast<const char*>(static_cast<const CDB_VarBinary&>(value).Value()),
692 static_cast<const CDB_VarBinary&>(value).Size()
693 ));
694 case eDB_LongBinary:
695 return Convert(string(
696 static_cast<const char*>(static_cast<const CDB_LongBinary&>(value).Value()),
697 static_cast<const CDB_LongBinary&>(value).DataSize()
698 ));
699 case eDB_Text:
700 case eDB_Image:
701 case eDB_VarCharMax:
702 case eDB_VarBinaryMax:
703 {
704 string result;
705 CDB_Stream& strm = const_cast<CDB_Stream&>(static_cast<const CDB_Stream&>(value));
706 result.resize(strm.Size());
707 strm.Read(const_cast<void*>(static_cast<const void*>(result.data())),
708 strm.Size()
709 );
710 return Convert(result);
711 }
712 default:
713 ReportTypeConvError(cur_type, "bool");
714 }
715
716 return TO();
717 }
718
719 template <typename TO>
720 inline
Convert_CDB_Object_DT(const CDB_Object & value)721 TO Convert_CDB_Object_DT(const CDB_Object& value)
722 {
723 CheckNULL(value);
724
725 const EDB_Type cur_type = value.GetType();
726
727 switch (cur_type) {
728 case eDB_DateTime:
729 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_DateTime&>(value).Value()), TO);
730 case eDB_BigDateTime:
731 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_BigDateTime&>(value).GetCTime()), TO);
732 case eDB_SmallDateTime:
733 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_SmallDateTime&>(value).Value()), TO);
734 default:
735 ReportTypeConvError(cur_type, "bool");
736 }
737
738 return TO();
739 }
740
741 ////////////////////////////////////////////////////////////////////////////////
CValueConvert(obj_type & value)742 CValueConvert<SRunTimeCP, CDB_Object>::CValueConvert(obj_type& value)
743 : m_Value(value)
744 {
745 }
746
operator bool(void) const747 CValueConvert<SRunTimeCP, CDB_Object>::operator bool(void) const
748 {
749 EDB_Type cur_type = m_Value.GetType();
750
751 if (cur_type == eDB_SmallDateTime || cur_type == eDB_DateTime
752 || cur_type == eDB_BigDateTime) {
753 return Convert_CDB_Object_DT<bool>(m_Value);
754 }
755
756 return Convert_CDB_Object<bool>(m_Value);
757 }
758
operator Uint1(void) const759 CValueConvert<SRunTimeCP, CDB_Object>::operator Uint1(void) const
760 {
761 return Convert_CDB_Object<Uint1>(m_Value);
762 }
763
operator Int2(void) const764 CValueConvert<SRunTimeCP, CDB_Object>::operator Int2(void) const
765 {
766 return Convert_CDB_Object<Int2>(m_Value);
767 }
768
operator Int4(void) const769 CValueConvert<SRunTimeCP, CDB_Object>::operator Int4(void) const
770 {
771 return Convert_CDB_Object<Int4>(m_Value);
772 }
773
operator Int8(void) const774 CValueConvert<SRunTimeCP, CDB_Object>::operator Int8(void) const
775 {
776 return Convert_CDB_Object<Int8>(m_Value);
777 }
778
operator float(void) const779 CValueConvert<SRunTimeCP, CDB_Object>::operator float(void) const
780 {
781 return Convert_CDB_Object<float>(m_Value);
782 }
783
operator double(void) const784 CValueConvert<SRunTimeCP, CDB_Object>::operator double(void) const
785 {
786 return Convert_CDB_Object<double>(m_Value);
787 }
788
operator string(void) const789 CValueConvert<SRunTimeCP, CDB_Object>::operator string(void) const
790 {
791 EDB_Type cur_type = m_Value.GetType();
792
793 if (cur_type == eDB_SmallDateTime || cur_type == eDB_DateTime
794 || cur_type == eDB_BigDateTime) {
795 return Convert_CDB_Object_DT<string>(m_Value);
796 }
797
798 return Convert_CDB_Object<string>(m_Value);
799 }
800
operator const CTime&(void) const801 CValueConvert<SRunTimeCP, CDB_Object>::operator const CTime&(void) const
802 {
803 CheckNULL(m_Value);
804 CheckType(m_Value, eDB_SmallDateTime, eDB_DateTime, eDB_BigDateTime);
805
806 EDB_Type cur_type = m_Value.GetType();
807
808 if (cur_type == eDB_SmallDateTime) {
809 return static_cast<const CDB_SmallDateTime&>(m_Value).Value();
810 } else if (cur_type == eDB_DateTime) {
811 return static_cast<const CDB_DateTime&>(m_Value).Value();
812 } else if (cur_type == eDB_BigDateTime) {
813 return static_cast<const CDB_BigDateTime&>(m_Value).GetCTime();
814 } else {
815 ReportTypeConvError(cur_type, "CTime");
816 }
817
818 static CSafeStatic<CTime> value;
819 return value.Get();
820 }
821
822 ////////////////////////////////////////////////////////////////////////////////
823 template <typename TO>
824 inline
Convert_CDB_ObjectSql(const CDB_Object & value)825 TO Convert_CDB_ObjectSql(const CDB_Object& value)
826 {
827 if (value.IsNULL()) {
828 return TO();
829 }
830
831 const EDB_Type cur_type = value.GetType();
832
833 switch (cur_type) {
834 case eDB_BigInt:
835 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_BigInt&>(value).Value()), TO);
836 case eDB_Int:
837 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Int&>(value).Value()), TO);
838 case eDB_SmallInt:
839 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_SmallInt&>(value).Value()), TO);
840 case eDB_TinyInt:
841 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_TinyInt&>(value).Value()), TO);
842 case eDB_Bit:
843 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Bit&>(value).Value()), TO);
844 case eDB_Float:
845 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Float&>(value).Value()), TO);
846 case eDB_Double:
847 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Double&>(value).Value()), TO);
848 case eDB_Numeric:
849 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_Numeric&>(value).Value()), TO);
850 case eDB_Char:
851 case eDB_VarChar:
852 case eDB_LongChar:
853 {
854 const CDB_String& cdb_str = static_cast<const CDB_String&>(value);
855 const string& str = cdb_str.AsString();
856 return Convert(str);
857 }
858 case eDB_Binary:
859 return Convert(string(
860 static_cast<const char*>(static_cast<const CDB_Binary&>(value).Value()),
861 static_cast<const CDB_Binary&>(value).Size()
862 ));
863 case eDB_VarBinary:
864 return Convert(string(
865 static_cast<const char*>(static_cast<const CDB_VarBinary&>(value).Value()),
866 static_cast<const CDB_VarBinary&>(value).Size()
867 ));
868 case eDB_LongBinary:
869 return Convert(string(
870 static_cast<const char*>(static_cast<const CDB_LongBinary&>(value).Value()),
871 static_cast<const CDB_LongBinary&>(value).DataSize()
872 ));
873 case eDB_Text:
874 case eDB_Image:
875 case eDB_VarCharMax:
876 case eDB_VarBinaryMax:
877 {
878 string result;
879 CDB_Stream& strm = const_cast<CDB_Stream&>(static_cast<const CDB_Stream&>(value));
880 result.resize(strm.Size());
881 strm.Read(const_cast<void*>(static_cast<const void*>(result.data())),
882 strm.Size()
883 );
884 return Convert(result);
885 }
886 default:
887 ReportTypeConvError(cur_type, "bool");
888 }
889
890 return TO();
891 }
892
893 template <typename TO>
894 inline
Convert_CDB_ObjectSql_DT(const CDB_Object & value)895 TO Convert_CDB_ObjectSql_DT(const CDB_Object& value)
896 {
897 if (value.IsNULL()) {
898 return TO();
899 }
900
901 const EDB_Type cur_type = value.GetType();
902
903 switch (cur_type) {
904 case eDB_DateTime:
905 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_DateTime&>(value).Value()), TO);
906 case eDB_BigDateTime:
907 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_BigDateTime&>(value).GetCTime()), TO);
908 case eDB_SmallDateTime:
909 return NCBI_CONVERT_TO(Convert(static_cast<const CDB_SmallDateTime&>(value).Value()), TO);
910 default:
911 ReportTypeConvError(cur_type, "bool");
912 }
913
914 return TO();
915 }
916
917 ////////////////////////////////////////////////////////////////////////////////
CValueConvert(obj_type & value)918 CValueConvert<SRunTimeSqlCP, CDB_Object>::CValueConvert(obj_type& value)
919 : m_Value(value)
920 {
921 }
922
operator bool(void) const923 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator bool(void) const
924 {
925 EDB_Type cur_type = m_Value.GetType();
926
927 if (cur_type == eDB_SmallDateTime || cur_type == eDB_DateTime
928 || cur_type == eDB_BigDateTime) {
929 return Convert_CDB_ObjectSql_DT<bool>(m_Value);
930 }
931
932 return Convert_CDB_ObjectSql<bool>(m_Value);
933 }
934
operator Uint1(void) const935 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator Uint1(void) const
936 {
937 return Convert_CDB_ObjectSql<Uint1>(m_Value);
938 }
939
operator Int2(void) const940 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator Int2(void) const
941 {
942 return Convert_CDB_ObjectSql<Int2>(m_Value);
943 }
944
operator Int4(void) const945 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator Int4(void) const
946 {
947 return Convert_CDB_ObjectSql<Int4>(m_Value);
948 }
949
operator Int8(void) const950 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator Int8(void) const
951 {
952 return Convert_CDB_ObjectSql<Int8>(m_Value);
953 }
954
operator float(void) const955 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator float(void) const
956 {
957 return Convert_CDB_ObjectSql<float>(m_Value);
958 }
959
operator double(void) const960 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator double(void) const
961 {
962 return Convert_CDB_ObjectSql<double>(m_Value);
963 }
964
operator string(void) const965 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator string(void) const
966 {
967 EDB_Type cur_type = m_Value.GetType();
968
969 if (cur_type == eDB_SmallDateTime || cur_type == eDB_DateTime
970 || cur_type == eDB_BigDateTime) {
971 return Convert_CDB_ObjectSql_DT<string>(m_Value);
972 }
973
974 return Convert_CDB_ObjectSql<string>(m_Value);
975 }
976
operator const CTime&(void) const977 CValueConvert<SRunTimeSqlCP, CDB_Object>::operator const CTime&(void) const
978 {
979 CheckNULL(m_Value);
980 CheckType(m_Value, eDB_SmallDateTime, eDB_DateTime, eDB_BigDateTime);
981
982 EDB_Type cur_type = m_Value.GetType();
983
984 if (cur_type == eDB_SmallDateTime) {
985 return static_cast<const CDB_SmallDateTime&>(m_Value).Value();
986 } else if (cur_type == eDB_DateTime) {
987 return static_cast<const CDB_DateTime&>(m_Value).Value();
988 } else if (cur_type == eDB_BigDateTime) {
989 return static_cast<const CDB_BigDateTime&>(m_Value).GetCTime();
990 } else {
991 ReportTypeConvError(cur_type, "CTime");
992 }
993
994 static CSafeStatic<CTime> value;
995 return value.Get();
996 }
997
998 } // namespace value_slice
999
1000 END_NCBI_SCOPE
1001
1002