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