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