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