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