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.bitmanip : BitArray; 171 import std.datetime.date : StdDate = Date, TimeOfDay, DateTime; 172 import std.datetime.systime : SysTime; 173 import std.traits : Unqual, isSomeString; 174 import std.uuid : StdUUID = UUID; 175 static import dpq2.conv.geometric; 176 static import dpq2.conv.time; 177 import vibe.data.json : VibeJson = Json; 178 179 alias UT = Unqual!T; 180 181 with(OidType) 182 { 183 static if(isSomeString!UT){ return Text; } else 184 static if(is(UT == ubyte[])){ return ByteArray; } else 185 static if(is(UT == bool)){ return Bool; } else 186 static if(is(UT == short)){ return Int2; } else 187 static if(is(UT == int)){ return Int4; } else 188 static if(is(UT == long)){ return Int8; } else 189 static if(is(UT == float)){ return Float4; } else 190 static if(is(UT == double)){ return Float8; } else 191 static if(is(UT == StdDate)){ return Date; } else 192 static if(is(UT == TimeOfDay)){ return Time; } else 193 static if(is(UT == DateTime)){ return TimeStamp; } else 194 static if(is(UT == SysTime)){ return TimeStampWithZone; } else 195 static if(is(UT == dpq2.conv.time.TimeStamp)){ return TimeStamp; } else 196 static if(is(UT == dpq2.conv.time.TimeStampUTC)){ return TimeStampWithZone; } else 197 static if(is(UT == VibeJson)){ return Json; } else 198 static if(is(UT == StdUUID)){ return UUID; } else 199 static if(is(UT == BitArray)){ return VariableBitString; } else 200 static if(dpq2.conv.geometric.isValidPointType!UT){ return Point; } else 201 static if(dpq2.conv.geometric.isValidLineType!UT){ return Line; } else 202 static if(dpq2.conv.geometric.isValidPathType!UT){ return Path; } else 203 static if(dpq2.conv.geometric.isValidPolygon!UT){ return Polygon; } else 204 static if(dpq2.conv.geometric.isValidCircleType!UT){ return Circle; } else 205 static if(dpq2.conv.geometric.isValidLineSegmentType!UT){ return LineSegment; } else 206 static if(dpq2.conv.geometric.isValidBoxType!UT){ return Box; } else 207 208 static assert(false, "Unsupported D type: "~T.stringof); 209 } 210 } 211 212 /// Enum of Oid types defined in PG 213 public enum OidType : Oid 214 { 215 Undefined = 0, /// 216 217 Bool = 16, /// 218 ByteArray = 17, /// 219 Char = 18, /// 220 Name = 19, /// 221 Int8 = 20, /// 222 Int2 = 21, /// 223 Int2Vector = 22, /// 224 Int4 = 23, /// 225 RegProc = 24, /// 226 Text = 25, /// 227 Oid = 26, /// 228 Tid = 27, /// 229 Xid = 28, /// 230 Cid = 29, /// 231 OidVector = 30, /// 232 233 AccessControlList = 1033, /// 234 TypeCatalog = 71, /// 235 AttributeCatalog = 75, /// 236 ProcCatalog = 81, /// 237 ClassCatalog = 83, /// 238 239 Json = 114, /// 240 Jsonb = 3802, /// 241 Xml = 142, /// 242 NodeTree = 194, /// 243 StorageManager = 210, /// 244 245 Point = 600, /// 246 LineSegment = 601, /// 247 Path = 602, /// 248 Box = 603, /// 249 Polygon = 604, /// 250 Line = 628, /// 251 252 Float4 = 700, /// 253 Float8 = 701, /// 254 AbsTime = 702, /// 255 RelTime = 703, /// 256 Interval = 704, /// 257 Unknown = 705, /// 258 259 Circle = 718, /// 260 Money = 790, /// 261 MacAddress = 829, /// 262 HostAddress = 869, /// 263 NetworkAddress = 650, /// 264 265 FixedString = 1042, /// 266 VariableString = 1043, /// 267 268 Date = 1082, /// 269 Time = 1083, /// 270 TimeStamp = 1114, /// 271 TimeStampWithZone = 1184, /// 272 TimeInterval = 1186, /// 273 TimeWithZone = 1266, /// 274 275 FixedBitString = 1560, /// 276 VariableBitString = 1562, /// 277 278 Numeric = 1700, /// 279 RefCursor = 1790, /// 280 RegProcWithArgs = 2202, /// 281 RegOperator = 2203, /// 282 RegOperatorWithArgs = 2204, /// 283 RegClass = 2205, /// 284 RegType = 2206, /// 285 286 UUID = 2950, /// 287 TSVector = 3614, /// 288 GTSVector = 3642, /// 289 TSQuery = 3615, /// 290 RegConfig = 3734, /// 291 RegDictionary = 3769, /// 292 TXidSnapshot = 2970, /// 293 294 Int4Range = 3904, /// 295 NumRange = 3906, /// 296 TimeStampRange = 3908, /// 297 TimeStampWithZoneRange = 3910, /// 298 DateRange = 3912, /// 299 Int8Range = 3926, /// 300 301 // Arrays 302 XmlArray = 143, /// 303 JsonbArray = 3807, /// 304 JsonArray = 199, /// 305 BoolArray = 1000, /// 306 ByteArrayArray = 1001, /// 307 CharArray = 1002, /// 308 NameArray = 1003, /// 309 Int2Array = 1005, /// 310 Int2VectorArray = 1006, /// 311 Int4Array = 1007, /// 312 RegProcArray = 1008, /// 313 TextArray = 1009, /// 314 OidArray = 1028, /// 315 TidArray = 1010, /// 316 XidArray = 1011, /// 317 CidArray = 1012, /// 318 OidVectorArray = 1013, /// 319 FixedStringArray = 1014, /// 320 VariableStringArray = 1015, /// 321 Int8Array = 1016, /// 322 PointArray = 1017, /// 323 LineSegmentArray = 1018, /// 324 PathArray = 1019, /// 325 BoxArray = 1020, /// 326 Float4Array = 1021, /// 327 Float8Array = 1022, /// 328 AbsTimeArray = 1023, /// 329 RelTimeArray = 1024, /// 330 IntervalArray = 1025, /// 331 PolygonArray = 1027, /// 332 AccessControlListArray = 1034, /// 333 MacAddressArray = 1040, /// 334 HostAdressArray = 1041, /// 335 NetworkAdressArray = 651, /// 336 CStringArray = 1263, /// 337 TimeStampArray = 1115, /// 338 DateArray = 1182, /// 339 TimeArray = 1183, /// 340 TimeStampWithZoneArray = 1185, /// 341 TimeIntervalArray = 1187, /// 342 NumericArray = 1231, /// 343 TimeWithZoneArray = 1270, /// 344 FixedBitStringArray = 1561, /// 345 VariableBitStringArray = 1563, /// 346 RefCursorArray = 2201, /// 347 RegProcWithArgsArray = 2207, /// 348 RegOperatorArray = 2208, /// 349 RegOperatorWithArgsArray = 2209, /// 350 RegClassArray = 2210, /// 351 RegTypeArray = 2211, /// 352 UUIDArray = 2951, /// 353 TSVectorArray = 3643, /// 354 GTSVectorArray = 3644, /// 355 TSQueryArray = 3645, /// 356 RegConfigArray = 3735, /// 357 RegDictionaryArray = 3770, /// 358 TXidSnapshotArray = 2949, /// 359 Int4RangeArray = 3905, /// 360 NumRangeArray = 3907, /// 361 TimeStampRangeArray = 3909, /// 362 TimeStampWithZoneRangeArray = 3911, /// 363 DateRangeArray = 3913, /// 364 Int8RangeArray = 3927, /// 365 366 // Pseudo types 367 Record = 2249, /// 368 RecordArray = 2287, /// 369 CString = 2275, /// 370 AnyVoid = 2276, /// 371 AnyArray = 2277, /// 372 Void = 2278, /// 373 Trigger = 2279, /// 374 EventTrigger = 3838, /// 375 LanguageHandler = 2280, /// 376 Internal = 2281, /// 377 Opaque = 2282, /// 378 AnyElement = 2283, /// 379 AnyNoArray = 2776, /// 380 AnyEnum = 3500, /// 381 FDWHandler = 3115, /// 382 AnyRange = 3831, /// 383 }