1 ///
2 module dpq2.conv.to_variant;
3 
4 import dpq2.value;
5 import dpq2.oids: OidType;
6 import dpq2.result: ArrayProperties;
7 import dpq2.conv.to_d_types;
8 import dpq2.conv.numeric: rawValueToNumeric;
9 import dpq2.conv.time: TimeStampUTC;
10 static import geom = dpq2.conv.geometric;
11 import std.bitmanip: bigEndianToNative, BitArray;
12 import std.datetime: SysTime, dur, TimeZone, UTC;
13 import std.conv: to;
14 import std.typecons: Nullable;
15 import std.uuid;
16 import std.variant: Variant;
17 import vibe.data.json: VibeJson = Json;
18 
19 ///
20 Variant toVariant(bool isNullablePayload = true)(in Value v) @safe
21 {
22     auto getNative(T)()
23     if(!is(T == Variant))
24     {
25         static if(isNullablePayload)
26         {
27             Nullable!T ret;
28 
29             if (v.isNull)
30                 return ret;
31 
32             ret = v.as!T;
33 
34             return ret;
35         }
36         else
37         {
38             return v.as!T;
39         }
40     }
41 
42     Variant retVariant(T)() @trusted
43     {
44         return Variant(getNative!T);
45     }
46 
47     if(v.format == ValueFormat.TEXT)
48         return retVariant!string;
49 
50     template retArray__(NativeT)
51     {
52         static if(isNullablePayload)
53             alias arrType = Nullable!NativeT[];
54         else
55             alias arrType = NativeT[];
56 
57         alias retArray__ = retVariant!arrType;
58     }
59 
60     with(OidType)
61     switch(v.oidType)
62     {
63         case Bool:      return retVariant!PGboolean;
64         case BoolArray: return retArray__!PGboolean;
65 
66         case Int2:      return retVariant!short;
67         case Int2Array: return retArray__!short;
68 
69         case Int4:      return retVariant!int;
70         case Int4Array: return retArray__!int;
71 
72         case Int8:      return retVariant!long;
73         case Int8Array: return retArray__!long;
74 
75         case Float4:        return retVariant!float;
76         case Float4Array:   return retArray__!float;
77 
78         case Float8:        return retVariant!double;
79         case Float8Array:   return retArray__!double;
80 
81         case Numeric:
82         case Text:
83         case FixedString:
84         case VariableString:
85             return retVariant!string;
86 
87         case NumericArray:
88         case TextArray:
89         case FixedStringArray:
90         case VariableStringArray:
91             return retArray__!string;
92 
93         case ByteArray: return retVariant!PGbytea;
94 
95         case UUID:      return retVariant!PGuuid;
96         case UUIDArray: return retArray__!PGuuid;
97 
98         case Date:      return retVariant!PGdate;
99         case DateArray: return retArray__!PGdate;
100 
101         case Time:      return retVariant!PGtime_without_time_zone;
102         case TimeArray: return retArray__!PGtime_without_time_zone;
103 
104         case TimeWithZone:      return retVariant!PGtime_with_time_zone;
105         case TimeWithZoneArray: return retArray__!PGtime_with_time_zone;
106 
107         case TimeStamp:         return retVariant!PGtimestamp;
108         case TimeStampArray:    return retArray__!PGtimestamp;
109 
110         case TimeStampWithZone:         return retVariant!PGtimestamptz;
111         case TimeStampWithZoneArray:    return retArray__!PGtimestamptz;
112 
113         case TimeInterval:         return retVariant!PGinterval;
114 
115         case Json:
116         case Jsonb:
117             return retVariant!VibeJson;
118 
119         case JsonArray:
120         case JsonbArray:
121             return retArray__!VibeJson;
122 
123         case Line:      return retVariant!(geom.Line);
124         case LineArray: return retArray__!(geom.Line);
125 
126         default:
127             throw new ValueConvException(
128                     ConvExceptionType.NOT_IMPLEMENTED,
129                     "Format of the column ("~to!(immutable(char)[])(v.oidType)~") doesn't supported by Value to Variant converter",
130                     __FILE__, __LINE__
131                 );
132     }
133 }