-
-
Notifications
You must be signed in to change notification settings - Fork 90
Expand file tree
/
Copy pathTypeExtensions.cs
More file actions
109 lines (90 loc) · 4.17 KB
/
Copy pathTypeExtensions.cs
File metadata and controls
109 lines (90 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace DuckDB.NET.Data.Extensions;
internal static class TypeExtensions
{
private static readonly HashSet<Type> FloatingNumericTypes = [typeof(decimal), typeof(float), typeof(double)];
private static readonly HashSet<Type> IntegralNumericTypes =
[
typeof(byte), typeof(sbyte),
typeof(short), typeof(ushort),
typeof(int), typeof(uint),
typeof(long), typeof(ulong),
typeof(BigInteger)
];
private static readonly Dictionary<Type, DuckDBType> ClrToDuckDBTypeMap = new()
{
{ typeof(bool), DuckDBType.Boolean },
{ typeof(sbyte), DuckDBType.TinyInt },
{ typeof(short), DuckDBType.SmallInt },
{ typeof(int), DuckDBType.Integer },
{ typeof(long), DuckDBType.BigInt },
{ typeof(byte), DuckDBType.UnsignedTinyInt },
{ typeof(ushort), DuckDBType.UnsignedSmallInt },
{ typeof(uint), DuckDBType.UnsignedInteger },
{ typeof(ulong), DuckDBType.UnsignedBigInt },
{ typeof(float), DuckDBType.Float },
{ typeof(double), DuckDBType.Double},
{ typeof(Guid), DuckDBType.Uuid},
{ typeof(DateTime), DuckDBType.Timestamp},
{ typeof(TimeSpan), DuckDBType.Interval},
{ typeof(DateOnly), DuckDBType.Date},
{ typeof(TimeOnly), DuckDBType.Time},
{ typeof(DateTimeOffset), DuckDBType.TimestampTz},
{ typeof(BigInteger), DuckDBType.HugeInt},
{ typeof(string), DuckDBType.Varchar},
{ typeof(byte[]), DuckDBType.Blob},
{ typeof(decimal), DuckDBType.Decimal},
{ typeof(object), DuckDBType.Any},
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNull([NotNullWhen(false)] this object? value) => value is null or DBNull;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Type UnderlyingTypeOrSelf(this Type type) => Nullable.GetUnderlyingType(type) ?? type;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsFloatingNumericType<T>()
{
return typeof(T) == typeof(decimal) || typeof(T) == typeof(float) || typeof(T) == typeof(double);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsIntegralNumericType<T>()
{
return typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte) ||
typeof(T) == typeof(short) || typeof(T) == typeof(ushort) ||
typeof(T) == typeof(int) || typeof(T) == typeof(uint) ||
typeof(T) == typeof(long) || typeof(T) == typeof(ulong) ||
typeof(T) == typeof(BigInteger);
}
public static bool IsNumeric(this Type type)
{
return IntegralNumericTypes.Contains(type) || FloatingNumericTypes.Contains(type);
}
public static bool AllowsNullValue(this Type type, out bool isNullableValueType, out Type? underlyingType)
{
underlyingType = Nullable.GetUnderlyingType(type);
isNullableValueType = underlyingType != null;
var isNullable = isNullableValueType || !type.IsValueType;
return isNullable;
}
public static DuckDBLogicalType GetLogicalType<T>() => typeof(T).GetLogicalType();
public static DuckDBLogicalType GetLogicalType(this Type type)
{
type = type.UnderlyingTypeOrSelf();
if (type == typeof(decimal))
{
return NativeMethods.LogicalType.DuckDBCreateDecimalType(38, 18);
}
if (type.IsAssignableTo(typeof(IList)) && type.IsGenericType)
{
var genericTypeParameter = type.GetGenericArguments()[0];
using var nestedType = genericTypeParameter.GetLogicalType();
return NativeMethods.LogicalType.DuckDBCreateListType(nestedType);
}
if (ClrToDuckDBTypeMap.TryGetValue(type, out var duckDBType))
{
return NativeMethods.LogicalType.DuckDBCreateLogicalType(duckDBType);
}
throw new InvalidOperationException($"Cannot map type {type.FullName} to DuckDBType.");
}
public static DuckDBType GetDuckDBType(this Type type) => ClrToDuckDBTypeMap.TryGetValue(type, out var duckDBType) ? duckDBType : DuckDBType.Invalid;
}