11using System ;
2+ using System . Collections ;
23using System . Collections . Generic ;
34using System . Globalization ;
45using System . Numerics ;
@@ -27,19 +28,26 @@ public static DuckDBValue ToDuckDBValue(this object value) =>
2728 Guid val => GuidToDuckDBValue ( val ) ,
2829 BigInteger val => NativeMethods . Value . DuckDBCreateHugeInt ( new DuckDBHugeInt ( val ) ) ,
2930 byte [ ] val => NativeMethods . Value . DuckDBCreateBlob ( val , val . Length ) ,
31+ TimeSpan val => NativeMethods . Value . DuckDBCreateInterval ( val ) ,
3032 DateTime val => NativeMethods . Value . DuckDBCreateTimestamp ( NativeMethods . DateTimeHelpers . DuckDBToTimestamp ( DuckDBTimestamp . FromDateTime ( val ) ) ) ,
33+ DateTimeOffset val => DateTimeOffsetToDuckDBValue ( val ) ,
3134 DuckDBDateOnly val => NativeMethods . Value . DuckDBCreateDate ( NativeMethods . DateTimeHelpers . DuckDBToDate ( val ) ) ,
32- #if NET6_0_OR_GREATER
33- DateOnly val => NativeMethods . Value . DuckDBCreateDate ( NativeMethods . DateTimeHelpers . DuckDBToDate ( val ) ) ,
34- #endif
3535 DuckDBTimeOnly val => NativeMethods . Value . DuckDBCreateTime ( NativeMethods . DateTimeHelpers . DuckDBToTime ( val ) ) ,
3636#if NET6_0_OR_GREATER
37+ DateOnly val => NativeMethods . Value . DuckDBCreateDate ( NativeMethods . DateTimeHelpers . DuckDBToDate ( val ) ) ,
3738 TimeOnly val => NativeMethods. Value . DuckDBCreateTime ( NativeMethods . DateTimeHelpers . DuckDBToTime ( val ) ) ,
3839#endif
39- ICollection< int > val => CreateListValue ( DuckDBType . Integer , val ) ,
40+ ICollection val => CreateCollectionValue ( val ) ,
4041 _ => throw new InvalidCastException( $ "Cannot convert value of type { value . GetType ( ) . FullName } to DuckDBValue.")
4142 } ;
4243
44+ private static DuckDBValue DateTimeOffsetToDuckDBValue( DateTimeOffset val )
45+ {
46+ var duckDBToTime = NativeMethods. DateTimeHelpers . DuckDBToTime ( ( DuckDBTimeOnly ) val . DateTime ) ;
47+ var duckDBCreateTimeTz = NativeMethods. DateTimeHelpers . DuckDBCreateTimeTz ( duckDBToTime . Micros , ( int ) val . Offset . TotalSeconds ) ;
48+ return NativeMethods. Value . DuckDBCreateTimeTz ( duckDBCreateTimeTz ) ;
49+ }
50+
4351 private static DuckDBValue GuidToDuckDBValue( Guid value )
4452 {
4553 using var handle = value. ToString ( ) . ToUnmanagedString ( ) ;
@@ -58,20 +66,53 @@ private static DuckDBValue StringToDuckDBValue(string value)
5866 return NativeMethods. Value . DuckDBCreateVarchar ( handle ) ;
5967 }
6068
61- private static DuckDBValue CreateListValue < T > ( DuckDBType duckDBType , ICollection < T > collection )
69+ private static DuckDBValue CreateCollectionValue( ICollection collection )
70+ {
71+ return collection switch
72+ {
73+ ICollection < bool > items => CreateCollectionValue ( DuckDBType . Boolean , items ) ,
74+
75+ ICollection < sbyte > items => CreateCollectionValue ( DuckDBType . TinyInt , items ) ,
76+ ICollection < byte > items => CreateCollectionValue ( DuckDBType . UnsignedTinyInt , items ) ,
77+ ICollection < short > items => CreateCollectionValue ( DuckDBType . SmallInt , items ) ,
78+ ICollection < ushort > items => CreateCollectionValue ( DuckDBType . UnsignedSmallInt , items ) ,
79+ ICollection < int > items => CreateCollectionValue ( DuckDBType . Integer , items ) ,
80+ ICollection < uint > items => CreateCollectionValue ( DuckDBType . UnsignedInteger , items ) ,
81+ ICollection < long > items => CreateCollectionValue ( DuckDBType . BigInt , items ) ,
82+ ICollection < ulong > items => CreateCollectionValue ( DuckDBType . UnsignedBigInt , items ) ,
83+ ICollection < float > items => CreateCollectionValue ( DuckDBType . Float , items ) ,
84+ ICollection < double > items => CreateCollectionValue ( DuckDBType . Double , items ) ,
85+ ICollection < BigInteger > items => CreateCollectionValue ( DuckDBType . HugeInt , items ) ,
86+ ICollection < decimal > items => CreateCollectionValue ( DuckDBType . Varchar , items ) ,
87+ ICollection < Guid > items => CreateCollectionValue ( DuckDBType . Varchar , items ) ,
88+ ICollection < string > items => CreateCollectionValue ( DuckDBType . Varchar , items ) ,
89+ ICollection < DateTime > items => CreateCollectionValue ( DuckDBType . Date , items ) ,
90+ ICollection < DateTimeOffset > items => CreateCollectionValue ( DuckDBType . TimeTz , items ) ,
91+ ICollection < TimeSpan > items => CreateCollectionValue ( DuckDBType . Interval , items ) ,
92+ ICollection < object > items => CreateCollectionValue ( DuckDBType . List , items ) ,
93+ _ => throw new InvalidOperationException ( $ "Cannot convert collection type { collection . GetType ( ) . FullName } to DuckDBValue.")
94+ } ;
95+ }
96+
97+ private static DuckDBValue CreateCollectionValue< T > ( DuckDBType duckDBType , ICollection < T > collection )
6298 {
63- using var logicalType = NativeMethods . LogicalType . DuckDBCreateLogicalType ( duckDBType ) ;
99+ using var listItemType = NativeMethods. LogicalType. DuckDBCreateLogicalType( duckDBType ) ;
64100
65101 var values = new DuckDBValue[ collection . Count ] ;
66102
67103 var index = 0 ;
68104 foreach ( var item in collection )
69105 {
106+ if ( item == null )
107+ {
108+ throw new InvalidOperationException ( $ "Cannot convert null to DuckDBValue.") ;
109+ }
110+
70111 var duckDBValue = item . ToDuckDBValue ( ) ;
71112 values[ index ] = duckDBValue ;
72113 index++ ;
73114 }
74115
75- return NativeMethods . Value . DuckDBCreateListValue ( logicalType , values , collection . Count ) ;
116+ return NativeMethods. Value . DuckDBCreateListValue ( listItemType , values , collection . Count ) ;
76117 }
77118}
0 commit comments