Skip to content

Commit

Permalink
Merge pull request #168 from denizzzka/reduce_code_amount
Browse files Browse the repository at this point in the history
Code deduplication
  • Loading branch information
denizzzka authored Dec 28, 2021
2 parents 33c98b5 + afc1d2b commit dfbfceb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 90 deletions.
40 changes: 7 additions & 33 deletions src/dpq2/conv/geometric.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module dpq2.conv.geometric;

import dpq2.oids: OidType;
import dpq2.value: ConvExceptionType, throwTypeComplaint, Value, ValueConvException, ValueFormat;
import dpq2.conv.to_d_types: checkValue;
import std.bitmanip: bigEndianToNative, nativeToBigEndian;
import std.traits;
import std.typecons : Nullable;
Expand Down Expand Up @@ -272,16 +273,9 @@ private alias ET = ConvExceptionType;
Vec2Ddouble binaryValueAs(Vec2Ddouble)(in Value v)
if(isValidPointType!Vec2Ddouble)
{
if(!(v.oidType == OidType.Point))
throwTypeComplaint(v.oidType, "Point", __FILE__, __LINE__);
v.checkValue(OidType.Point, 16, "Point");

auto data = v.data;

if(!(data.length == 16))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres Point size", __FILE__, __LINE__);

return pointFromBytes!Vec2Ddouble(data[0..16]);
return pointFromBytes!Vec2Ddouble(v.data[0..16]);
}

private Vec2Ddouble pointFromBytes(Vec2Ddouble)(in ubyte[16] data) pure
Expand All @@ -293,25 +287,15 @@ if(isValidPointType!Vec2Ddouble)
T binaryValueAs(T)(in Value v)
if (is(T == Line))
{
if(!(v.oidType == OidType.Line))
throwTypeComplaint(v.oidType, "Line", __FILE__, __LINE__);

if(!(v.data.length == 24))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres Line size", __FILE__, __LINE__);
v.checkValue(OidType.Line, 24, "Line");

return Line((v.data[0..8].bigEndianToNative!double), v.data[8..16].bigEndianToNative!double, v.data[16..24].bigEndianToNative!double);
}

LineSegment binaryValueAs(LineSegment)(in Value v)
if(isValidLineSegmentType!LineSegment)
{
if(!(v.oidType == OidType.LineSegment))
throwTypeComplaint(v.oidType, "LineSegment", __FILE__, __LINE__);

if(!(v.data.length == 32))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres LineSegment size", __FILE__, __LINE__);
v.checkValue(OidType.LineSegment, 32, "LineSegment");

alias Point = ReturnType!(LineSegment.start);

Expand All @@ -324,12 +308,7 @@ if(isValidLineSegmentType!LineSegment)
Box binaryValueAs(Box)(in Value v)
if(isValidBoxType!Box)
{
if(!(v.oidType == OidType.Box))
throwTypeComplaint(v.oidType, "Box", __FILE__, __LINE__);

if(!(v.data.length == 32))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres Box size", __FILE__, __LINE__);
v.checkValue(OidType.Box, 32, "Box");

alias Point = typeof(Box.min);

Expand Down Expand Up @@ -404,12 +383,7 @@ if(isValidPolygon!Polygon)
T binaryValueAs(T)(in Value v)
if(isInstanceOf!(Circle, T))
{
if(!(v.oidType == OidType.Circle))
throwTypeComplaint(v.oidType, "Circle", __FILE__, __LINE__);

if(!(v.data.length == 24))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres Circle size", __FILE__, __LINE__);
v.checkValue(OidType.Circle, 24, "Circle");

alias Point = typeof(T.center);

Expand Down
53 changes: 8 additions & 45 deletions src/dpq2/conv/time.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module dpq2.conv.time;

import dpq2.result;
import dpq2.oids: OidType;
import dpq2.value: throwTypeComplaint;
import dpq2.conv.to_d_types: checkValue;

import core.time;
import std.datetime.date : Date, DateTime, TimeOfDay;
Expand All @@ -32,12 +32,7 @@ import std.conv: to;
SysTime binaryValueAs(T)(in Value v) @trusted
if( is( T == SysTime ) )
{
if(!(v.oidType == OidType.TimeStampWithZone))
throwTypeComplaint(v.oidType, "timestamp with time zone", __FILE__, __LINE__);

if(!(v.data.length == long.sizeof))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres timestamp with time zone type", __FILE__, __LINE__);
v.checkValue(OidType.TimeStampWithZone, long.sizeof, "timestamp with time zone");

auto t = rawTimeStamp2nativeTime!TimeStampUTC(bigEndianToNative!long(v.data.ptr[0..long.sizeof]));
return SysTime(t.dateTime, t.fracSec, UTC());
Expand All @@ -49,12 +44,7 @@ pure:
Date binaryValueAs(T)(in Value v) @trusted
if( is( T == Date ) )
{
if(!(v.oidType == OidType.Date))
throwTypeComplaint(v.oidType, "Date", __FILE__, __LINE__);

if(!(v.data.length == uint.sizeof))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres date type", __FILE__, __LINE__);
v.checkValue(OidType.Date, uint.sizeof, "date type");

int jd = bigEndianToNative!uint(v.data.ptr[0..uint.sizeof]);
int year, month, day;
Expand All @@ -72,12 +62,7 @@ if( is( T == Date ) )
TimeOfDay binaryValueAs(T)(in Value v) @trusted
if( is( T == TimeOfDay ) )
{
if(!(v.oidType == OidType.Time))
throwTypeComplaint(v.oidType, "time without time zone", __FILE__, __LINE__);

if(!(v.data.length == TimeADT.sizeof))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres time without time zone type", __FILE__, __LINE__);
v.checkValue(OidType.Time, TimeADT.sizeof, "time without time zone");

return time2tm(bigEndianToNative!TimeADT(v.data.ptr[0..TimeADT.sizeof]));
}
Expand All @@ -86,12 +71,7 @@ if( is( T == TimeOfDay ) )
TimeStamp binaryValueAs(T)(in Value v) @trusted
if( is( T == TimeStamp ) )
{
if(!(v.oidType == OidType.TimeStamp))
throwTypeComplaint(v.oidType, "timestamp without time zone", __FILE__, __LINE__);

if(!(v.data.length == long.sizeof))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres timestamp without time zone type", __FILE__, __LINE__);
v.checkValue(OidType.TimeStamp, long.sizeof, "timestamp without time zone");

return rawTimeStamp2nativeTime!TimeStamp(
bigEndianToNative!long(v.data.ptr[0..long.sizeof])
Expand All @@ -102,12 +82,7 @@ if( is( T == TimeStamp ) )
TimeStampUTC binaryValueAs(T)(in Value v) @trusted
if( is( T == TimeStampUTC ) )
{
if(!(v.oidType == OidType.TimeStampWithZone))
throwTypeComplaint(v.oidType, "timestamp with time zone", __FILE__, __LINE__);

if(!(v.data.length == long.sizeof))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres timestamp with time zone type", __FILE__, __LINE__);
v.checkValue(OidType.TimeStampWithZone, long.sizeof, "timestamp with time zone");

return rawTimeStamp2nativeTime!TimeStampUTC(
bigEndianToNative!long(v.data.ptr[0..long.sizeof])
Expand Down Expand Up @@ -335,15 +310,10 @@ struct TimeOfDayWithTZ
TimeOfDayWithTZ binaryValueAs(T)(in Value v) @trusted
if( is( T == TimeOfDayWithTZ ) )
{
if(!(v.oidType == OidType.TimeWithZone))
throwTypeComplaint(v.oidType, "time with time zone", __FILE__, __LINE__);

enum recSize = TimeADT.sizeof + TimeTZ.sizeof;
static assert(recSize == 12);

if(v.data.length != recSize)
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres time with time zone type", __FILE__, __LINE__);
v.checkValue(OidType.TimeWithZone, recSize, "time with time zone");

return TimeOfDayWithTZ(
time2tm(bigEndianToNative!TimeADT(v.data.ptr[0 .. TimeADT.sizeof])),
Expand All @@ -363,14 +333,7 @@ struct Interval
Interval binaryValueAs(T)(in Value v) @trusted
if( is( T == Interval ) )
{
immutable typeName = "interval";

if(!(v.oidType == OidType.TimeInterval))
throwTypeComplaint(v.oidType, typeName, __FILE__, __LINE__);

if(v.data.length != long.sizeof * 2)
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
"Value length isn't equal to Postgres "~typeName, __FILE__, __LINE__);
v.checkValue(OidType.TimeInterval, long.sizeof * 2, "interval");

return Interval(
bigEndianToNative!long(v.data.ptr[0 .. 8]),
Expand Down
29 changes: 17 additions & 12 deletions src/dpq2/conv/to_d_types.d
Original file line number Diff line number Diff line change
Expand Up @@ -226,16 +226,26 @@ if( isNumeric!(T) )
assertThrown!ValueConvException(v.binaryValueAs!int);
}

package void checkValue(
in Value v,
in OidType enforceOid,
in size_t enforceSize,
in string typeName
) pure
{
if(!(v.oidType == enforceOid))
throwTypeComplaint(v.oidType, typeName);

if(!(v.data.length == enforceSize))
throw new ValueConvException(ConvExceptionType.SIZE_MISMATCH,
`Value length isn't equal to Postgres `~typeName~` size`);
}

/// Returns UUID as native UUID value
UUID binaryValueAs(T)(in Value v)
if( is( T == UUID ) )
{
if(!(v.oidType == OidType.UUID))
throwTypeComplaint(v.oidType, "UUID", __FILE__, __LINE__);

if(!(v.data.length == 16))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres UUID size", __FILE__, __LINE__);
v.checkValue(OidType.UUID, 16, "UUID");

UUID r;
r.data = v.data;
Expand All @@ -255,12 +265,7 @@ if( is( T == UUID ) )
bool binaryValueAs(T : bool)(in Value v)
if (!is(T == Nullable!R, R))
{
if(!(v.oidType == OidType.Bool))
throwTypeComplaint(v.oidType, "bool", __FILE__, __LINE__);

if(!(v.data.length == 1))
throw new AE(ET.SIZE_MISMATCH,
"Value length isn't equal to Postgres boolean size", __FILE__, __LINE__);
v.checkValue(OidType.Bool, 1, "bool");

return v.data[0] != 0;
}
Expand Down

0 comments on commit dfbfceb

Please sign in to comment.