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