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