1 /**
2 *   PostgreSQL major types oids.
3 *
4 *   Copyright: © 2014 DSoftOut
5 *   Authors: NCrashed <ncrashed@gmail.com>
6 */
7 
8 module dpq2.oids;
9 
10 @safe:
11 
12 package OidType oid2oidType(Oid oid) pure
13 {
14     static assert(Oid.sizeof == OidType.sizeof);
15 
16     return cast(OidType)(oid);
17 }
18 
19 /**
20  * Convert between array Oid and element Oid or vice versa
21  *
22  * Params:
23  *  s = "array" or "element"
24  */
25 OidType oidConvTo(string s)(OidType type)
26 {
27     foreach(ref a; appropriateArrOid)
28     {
29         static if(s == "array")
30         {
31             if(a.value == type)
32                 return a.array;
33         }
34         else
35         static if(s == "element")
36         {
37             if(a.array == type)
38                 return a.value;
39         }
40         else
41         static assert(false, "Wrong oidConvTo type "~s);
42     }
43 
44     import dpq2.value: ValueConvException, ConvExceptionType;
45     import std.conv: to;
46 
47     throw new ValueConvException(
48             ConvExceptionType.NOT_IMPLEMENTED,
49             "Conv to "~s~" for type "~type.to!string~" isn't defined",
50             __FILE__, __LINE__
51         );
52 }
53 
54 /// Checks if Oid type can be mapped to native D integer
55 bool isNativeInteger(OidType t) pure
56 {
57     with(OidType)
58     switch(t)
59     {
60         case Int8:
61         case Int2:
62         case Int4:
63             return true;
64         default:
65             break;
66     }
67 
68     return false;
69 }
70 
71 /// Checks if Oid type can be mapped to native D float
72 bool isNativeFloat(OidType t) pure
73 {
74     with(OidType)
75     switch(t)
76     {
77         case Float4:
78         case Float8:
79             return true;
80         default:
81             break;
82     }
83 
84     return false;
85 }
86 
87 package:
88 
89 private struct AppropriateArrOid
90 {
91     OidType value;
92     OidType array;
93 }
94 
95 private static immutable AppropriateArrOid[] appropriateArrOid;
96 
97 shared static this()
98 {
99     alias A = AppropriateArrOid;
100 
101     with(OidType)
102     {
103         immutable AppropriateArrOid[] a =
104         [
105             A(Text, TextArray),
106             A(Bool, BoolArray),
107             A(Int2, Int2Array),
108             A(Int4, Int4Array),
109             A(Int8, Int8Array),
110             A(Float4, Float4Array),
111             A(Float8, Float8Array),
112             A(Date, DateArray),
113             A(Time, TimeArray),
114             A(TimeStampWithZone, TimeStampWithZoneArray),
115             A(TimeStamp, TimeStampArray)
116         ];
117 
118         appropriateArrOid = a;
119     }
120 }
121 
122 import derelict.pq.pq: Oid;
123 
124 bool isSupportedArray(OidType t) pure nothrow @nogc
125 {
126     with(OidType)
127     switch(t)
128     {
129         case BoolArray:
130         case ByteArrayArray:
131         case CharArray:
132         case Int2Array:
133         case Int4Array:
134         case TextArray:
135         case Int8Array:
136         case Float4Array:
137         case Float8Array:
138         case TimeStampArray:
139         case TimeStampWithZoneArray:
140         case DateArray:
141         case TimeArray:
142         case TimeWithZoneArray:
143         case NumericArray:
144         case UUIDArray:
145         case JsonArray:
146         case JsonbArray:
147             return true;
148         default:
149             break;
150     }
151 
152     return false;
153 }
154 
155 OidType detectOidTypeFromNative(T)()
156 {
157     import std.typecons : Nullable;
158 
159     static if(is(T == Nullable!R,R))
160         return detectOidTypeNotCareAboutNullable!(typeof(T.get));
161     else
162         return detectOidTypeNotCareAboutNullable!T;
163 }
164 
165 private OidType detectOidTypeNotCareAboutNullable(T)()
166 {
167     import std.datetime.date : StdDate = Date, TimeOfDay;
168     import std.datetime.systime : SysTime;
169     import std.traits : Unqual;
170     static import dpq2.conv.time;
171     import vibe.data.json : VibeJson = Json;
172 
173     alias UT = Unqual!T;
174 
175     with(OidType)
176     {
177         static if(is(UT == string)){ return Text; } else
178         static if(is(UT == ubyte[])){ return ByteArray; } else
179         static if(is(UT == bool)){ return Bool; } else
180         static if(is(UT == short)){ return Int2; } else
181         static if(is(UT == int)){ return Int4; } else
182         static if(is(UT == long)){ return Int8; } else
183         static if(is(UT == float)){ return Float4; } else
184         static if(is(UT == double)){ return Float8; } else
185         static if(is(UT == StdDate)){ return Date; } else
186         static if(is(UT == TimeOfDay)){ return Time; } else
187         static if(is(UT == SysTime)){ return TimeStampWithZone; } else
188         static if(is(UT == dpq2.conv.time.TimeStamp)){ return TimeStamp; } else
189         static if(is(UT == dpq2.conv.time.TimeStampUTC)){ return TimeStampWithZone; } else
190         static if(is(UT == VibeJson)){ return Json; } else
191 
192         static assert(false, "Unsupported D type: "~T.stringof);
193     }
194 }
195 
196 /// Enum of Oid types defined in PG
197 public enum OidType : Oid
198 {
199     Undefined = 0, ///
200 
201     Bool = 16, ///
202     ByteArray = 17, ///
203     Char = 18, ///
204     Name = 19, ///
205     Int8 = 20, ///
206     Int2 = 21, ///
207     Int2Vector = 22, ///
208     Int4 = 23, ///
209     RegProc = 24, ///
210     Text = 25, ///
211     Oid = 26, ///
212     Tid = 27, ///
213     Xid = 28, ///
214     Cid = 29, ///
215     OidVector = 30, ///
216 
217     AccessControlList = 1033, ///
218     TypeCatalog = 71, ///
219     AttributeCatalog = 75, ///
220     ProcCatalog = 81, ///
221     ClassCatalog = 83, ///
222 
223     Json = 114, ///
224     Jsonb = 3802, ///
225     Xml = 142, ///
226     NodeTree = 194, ///
227     StorageManager = 210, ///
228 
229     Point = 600, ///
230     LineSegment = 601, ///
231     Path = 602, ///
232     Box = 603, ///
233     Polygon = 604, ///
234     Line = 628, ///
235 
236     Float4 = 700, ///
237     Float8 = 701, ///
238     AbsTime = 702, ///
239     RelTime = 703, ///
240     Interval = 704, ///
241     Unknown = 705, ///
242 
243     Circle = 718, ///
244     Money = 790, ///
245     MacAddress = 829, ///
246     HostAddress = 869, ///
247     NetworkAddress = 650, ///
248 
249     FixedString = 1042, ///
250     VariableString = 1043, ///
251 
252     Date = 1082, ///
253     Time = 1083, ///
254     TimeStamp = 1114, ///
255     TimeStampWithZone = 1184, ///
256     TimeInterval = 1186, ///
257     TimeWithZone = 1266, ///
258 
259     FixedBitString = 1560, ///
260     VariableBitString = 1562, ///
261 
262     Numeric = 1700, ///
263     RefCursor = 1790, ///
264     RegProcWithArgs = 2202, ///
265     RegOperator = 2203, ///
266     RegOperatorWithArgs = 2204, ///
267     RegClass = 2205, ///
268     RegType = 2206, ///
269 
270     UUID = 2950, ///
271     TSVector = 3614, ///
272     GTSVector = 3642, ///
273     TSQuery = 3615, ///
274     RegConfig = 3734, ///
275     RegDictionary = 3769, ///
276     TXidSnapshot = 2970, ///
277 
278     Int4Range = 3904, ///
279     NumRange = 3906, ///
280     TimeStampRange = 3908, ///
281     TimeStampWithZoneRange = 3910, ///
282     DateRange = 3912, ///
283     Int8Range = 3926, ///
284 
285     // Arrays
286     XmlArray = 143, ///
287     JsonArray = 3807, ///
288     JsonbArray = 199, ///
289     BoolArray = 1000, ///
290     ByteArrayArray = 1001, ///
291     CharArray = 1002, ///
292     NameArray = 1003, ///
293     Int2Array = 1005, ///
294     Int2VectorArray = 1006, ///
295     Int4Array = 1007, ///
296     RegProcArray = 1008, ///
297     TextArray = 1009, ///
298     OidArray  = 1028, ///
299     TidArray = 1010, ///
300     XidArray = 1011, ///
301     CidArray = 1012, ///
302     OidVectorArray = 1013, ///
303     FixedStringArray = 1014, ///
304     VariableStringArray = 1015, ///
305     Int8Array = 1016, ///
306     PointArray = 1017, ///
307     LineSegmentArray = 1018, ///
308     PathArray = 1019, ///
309     BoxArray = 1020, ///
310     Float4Array = 1021, ///
311     Float8Array = 1022, ///
312     AbsTimeArray = 1023, ///
313     RelTimeArray = 1024, ///
314     IntervalArray = 1025, ///
315     PolygonArray = 1027, ///
316     AccessControlListArray = 1034, ///
317     MacAddressArray = 1040, ///
318     HostAdressArray = 1041, ///
319     NetworkAdressArray = 651, ///
320     CStringArray = 1263, ///
321     TimeStampArray = 1115, ///
322     DateArray = 1182, ///
323     TimeArray = 1183, ///
324     TimeStampWithZoneArray = 1185, ///
325     TimeIntervalArray = 1187, ///
326     NumericArray = 1231, ///
327     TimeWithZoneArray = 1270, ///
328     FixedBitStringArray = 1561, ///
329     VariableBitStringArray = 1563, ///
330     RefCursorArray = 2201, ///
331     RegProcWithArgsArray = 2207, ///
332     RegOperatorArray = 2208, ///
333     RegOperatorWithArgsArray = 2209, ///
334     RegClassArray = 2210, ///
335     RegTypeArray = 2211, ///
336     UUIDArray = 2951, ///
337     TSVectorArray = 3643, ///
338     GTSVectorArray = 3644, ///
339     TSQueryArray = 3645, ///
340     RegConfigArray = 3735, ///
341     RegDictionaryArray = 3770, ///
342     TXidSnapshotArray = 2949, ///
343     Int4RangeArray = 3905, ///
344     NumRangeArray = 3907, ///
345     TimeStampRangeArray = 3909, ///
346     TimeStampWithZoneRangeArray = 3911, ///
347     DateRangeArray = 3913, ///
348     Int8RangeArray = 3927, ///
349 
350     // Pseudo types
351     Record = 2249, ///
352     RecordArray = 2287, ///
353     CString = 2275, ///
354     AnyVoid = 2276, ///
355     AnyArray = 2277, ///
356     Void = 2278, ///
357     Trigger = 2279, ///
358     EventTrigger = 3838, ///
359     LanguageHandler = 2280, ///
360     Internal = 2281, ///
361     Opaque = 2282, ///
362     AnyElement = 2283, ///
363     AnyNoArray = 2776, ///
364     AnyEnum = 3500, ///
365     FDWHandler = 3115, ///
366     AnyRange = 3831, ///
367 }