Skip to content

Commit

Permalink
feat: complete implementation for all types
Browse files Browse the repository at this point in the history
  • Loading branch information
Seddryck committed Oct 30, 2023
1 parent 402f104 commit 237183d
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 19 deletions.
7 changes: 4 additions & 3 deletions DuckDB.NET.Data/TypeHandlers/BaseTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ public virtual object GetValue(ulong offset, Type type)

var param = Expression.Parameter(typeof(ulong));
var callRef = Expression.Call(Expression.Constant(this), methodInfo, param);
var lambda = Expression.Lambda(callRef, new[] { param });
var convertRef = Expression.Convert(callRef, typeof(object));
var lambda = Expression.Lambda(convertRef, new[] { param });
var compiled = lambda.Compile();
Cache = new(type, compiled);
}
var expression = Cache.Value;
var value = expression.DynamicInvoke(offset);
var expression = (Func<ulong, object>)Cache.Value;
var value = expression.Invoke(offset);
return value!;
}

Expand Down
2 changes: 1 addition & 1 deletion DuckDB.NET.Data/TypeHandlers/BlobTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace DuckDB.NET.Data.TypeHandlers
{
internal class BlobTypeHandler : BaseTypeHandler, IStreamTypeHandler
{
public override Type ClrType => typeof(Stream);
public override Type ClrType { get; } = typeof(Stream);

public unsafe BlobTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand Down
13 changes: 11 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/DateTypeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
{
internal class DateTypeHandler : BaseTypeHandler, IReadDateTimeTypeHandler
{
public override Type ClrType { get => typeof(DuckDBDateOnly); }
public override Type ClrType { get; } = typeof(DuckDBDateOnly);

public unsafe DateTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand All @@ -20,8 +21,10 @@ protected override object Convert(object value, Type type)
return value switch
{
DuckDBDateOnly x when typeof(DateTime).IsAssignableFrom(type) => x.ToDateTime(),
DuckDBDateOnly x when typeof(DateTime?).IsAssignableFrom(type) => x.ToDateTime(),
#if NET6_0_OR_GREATER
DuckDBDateOnly x when typeof(DateOnly).IsAssignableFrom(type) => (DateOnly)x,
DuckDBDateOnly x when typeof(DateOnly?).IsAssignableFrom(type) => (DateOnly)x,
#endif
_ => base.Convert(value, type),
};
Expand All @@ -36,6 +39,12 @@ public DateTime GetDateTime(ulong offset)
=> (DateTime)GetNative(offset);

public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var duckDbDateOnly = GetNative(offset);
if (typeof(T) == typeof(DuckDBDateOnly))
return Unsafe.As<DuckDBDateOnly, T>(ref duckDbDateOnly);
else
return Convert<T>(duckDbDateOnly);
}
}
}
11 changes: 9 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/DecimalTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
Expand All @@ -11,7 +12,7 @@ internal class DecimalTypeHandler : BaseTypeHandler, IReadDecimalTypeHandler
private decimal Power { get; }
private readonly ITypeHandler InternalTypeHandler;

public override Type ClrType { get => typeof(decimal); }
public override Type ClrType { get; } = typeof(decimal);

public unsafe DecimalTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer)
Expand Down Expand Up @@ -74,6 +75,12 @@ decimal processShort(short value, short power)
}
}
public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var dec = GetDecimal(offset);
if (typeof(T) == typeof(decimal))
return Unsafe.As<decimal, T>(ref dec);
else
return Convert<T>(dec);
}
}
}
9 changes: 8 additions & 1 deletion DuckDB.NET.Data/TypeHandlers/EnumTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
Expand Down Expand Up @@ -65,6 +66,12 @@ public override void Dispose()
base.Dispose();
}
public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var enumString = GetString(offset);
if (typeof(T) == typeof(string))
return Unsafe.As<string, T>(ref enumString);
else
return Convert<T>(enumString);
}
}
}
12 changes: 10 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/HugeIntTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
{
internal class HugeIntTypeHandler : BaseTypeHandler
{
public override Type ClrType { get => typeof(BigInteger); }
public override Type ClrType { get; } = typeof(BigInteger);

public unsafe HugeIntTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand All @@ -18,7 +19,14 @@ protected unsafe internal DuckDBHugeInt GetNative(ulong offset)

public BigInteger GetBigInteger(ulong offset)
=> GetNative(offset).ToBigInteger();

public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var bigInteger = GetBigInteger(offset);
if (typeof(T) == typeof(BigInteger))
return Unsafe.As<BigInteger, T>(ref bigInteger);
else
return Convert<T>(bigInteger);
}
}
}
11 changes: 9 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/IntervalTypeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
{
internal class IntervalTypeHandler : BaseTypeHandler
{
public override Type ClrType { get => typeof(DuckDBInterval); }
public override Type ClrType { get; } = typeof(DuckDBInterval);

public unsafe IntervalTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand All @@ -19,6 +20,12 @@ public TimeSpan GetTimeSpan(ulong offset)
=> (TimeSpan)GetNative(offset);

public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var duckDbInterval = GetNative(offset);
if (typeof(T) == typeof(DuckDBInterval))
return Unsafe.As<DuckDBInterval, T>(ref duckDbInterval);
else
return Convert<T>(duckDbInterval);
}
}
}
2 changes: 1 addition & 1 deletion DuckDB.NET.Data/TypeHandlers/NumericTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace DuckDB.NET.Data.TypeHandlers
{
internal class NumericTypeHandler<T> : BaseTypeHandler, IReadDecimalTypeHandler where T : unmanaged
{
public override Type ClrType { get => typeof(T); }
public override Type ClrType { get; } = typeof(T);

private Type[] NumericTypes = new[] {
typeof(bool)
Expand Down
13 changes: 11 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/TimeTypeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
{
internal class TimeTypeHandler : BaseTypeHandler, IReadDateTimeTypeHandler
{
public override Type ClrType { get => typeof(DuckDBTimeOnly); }
public override Type ClrType { get; } = typeof(DuckDBTimeOnly);

public unsafe TimeTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand All @@ -23,8 +24,10 @@ protected override object Convert(object value, Type type)
return value switch
{
DuckDBTimeOnly x when typeof(DateTime).IsAssignableFrom(type) => x.ToDateTime(),
DuckDBTimeOnly x when typeof(DateTime?).IsAssignableFrom(type) => x.ToDateTime(),
#if NET6_0_OR_GREATER
DuckDBTimeOnly x when typeof(TimeOnly).IsAssignableFrom(type) => (TimeOnly)x,
DuckDBTimeOnly x when typeof(TimeOnly?).IsAssignableFrom(type) => (TimeOnly)x,
#endif
_ => base.Convert(value, type),
};
Expand All @@ -39,6 +42,12 @@ public DateTime GetDateTime(ulong offset)
=> (DateTime)GetNative(offset);

public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var duckDbTimeOnly = GetNative(offset);
if (typeof(T) == typeof(DuckDBTimeOnly))
return Unsafe.As<DuckDBTimeOnly, T>(ref duckDbTimeOnly);
else
return Convert<T>(duckDbTimeOnly);
}
}
}
11 changes: 9 additions & 2 deletions DuckDB.NET.Data/TypeHandlers/TimestampTypeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;

namespace DuckDB.NET.Data.TypeHandlers
{
internal class TimestampTypeHandler : BaseTypeHandler, IReadDateTimeTypeHandler
{
public override Type ClrType { get => typeof(DateTime); }
public override Type ClrType { get; } = typeof(DateTime);

public unsafe TimestampTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand All @@ -21,6 +22,12 @@ public DateTime GetDateTime(ulong offset)
=> GetNative(offset).ToDateTime();

public override T GetValue<T>(ulong offset)
=> throw new NotImplementedException();
{
var dateTime = GetDateTime(offset);
if (typeof(T) == typeof(DateTime))
return Unsafe.As<DateTime, T>(ref dateTime);
else
return Convert<T>(dateTime);
}
}
}
2 changes: 1 addition & 1 deletion DuckDB.NET.Data/TypeHandlers/VarcharTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace DuckDB.NET.Data.TypeHandlers
{
internal class VarcharTypeHandler : BaseTypeHandler, IReadStringTypeHandler
{
public override Type ClrType { get => typeof(string); }
public override Type ClrType { get; } = typeof(string);

public unsafe VarcharTypeHandler(IntPtr vector, void* dataPointer, ulong* validityMaskPointer)
: base(vector, dataPointer, validityMaskPointer) { }
Expand Down

0 comments on commit 237183d

Please sign in to comment.