Skip to content

Commit 0c710f6

Browse files
committed
Add test
1 parent 7222612 commit 0c710f6

File tree

3 files changed

+68
-51
lines changed

3 files changed

+68
-51
lines changed

DuckDB.NET.Bindings/DuckDBWrapperObjects.cs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Microsoft.Win32.SafeHandles;
22
using System;
3-
using System.Numerics;
43
using System.Runtime.CompilerServices;
54

65
namespace DuckDB.NET.Native;
@@ -124,35 +123,35 @@ public T GetValue<T>()
124123

125124
return duckDBType switch
126125
{
127-
DuckDBType.Boolean => ReadValue<bool>(NativeMethods.Value.DuckDBGetBool(this)),
128-
129-
DuckDBType.TinyInt => ReadValue<sbyte>(NativeMethods.Value.DuckDBGetInt8(this)),
130-
DuckDBType.SmallInt => ReadValue<short>(NativeMethods.Value.DuckDBGetInt16(this)),
131-
DuckDBType.Integer => ReadValue<int>(NativeMethods.Value.DuckDBGetInt32(this)),
132-
DuckDBType.BigInt => ReadValue<long>(NativeMethods.Value.DuckDBGetInt64(this)),
133-
134-
DuckDBType.UnsignedTinyInt => ReadValue<byte>(NativeMethods.Value.DuckDBGetUInt8(this)),
135-
DuckDBType.UnsignedSmallInt => ReadValue<ushort>(NativeMethods.Value.DuckDBGetUInt16(this)),
136-
DuckDBType.UnsignedInteger => ReadValue<uint>(NativeMethods.Value.DuckDBGetUInt32(this)),
137-
DuckDBType.UnsignedBigInt => ReadValue<ulong>(NativeMethods.Value.DuckDBGetUInt64(this)),
138-
139-
DuckDBType.Float => ReadValue<float>(NativeMethods.Value.DuckDBGetFloat(this)),
140-
DuckDBType.Double => ReadValue<double>(NativeMethods.Value.DuckDBGetDouble(this)),
141-
142-
//DuckDBType.Timestamp => ReadValue<T>(),
143-
//DuckDBType.Interval => ReadValue<T>(),
144-
//DuckDBType.Date => ReadValue<T>(),
145-
//DuckDBType.Time => ReadValue<T>(),
146-
//DuckDBType.TimeTz => ReadValue<T>(),
147-
//DuckDBType.HugeInt => ReadValue<DuckDBHugeInt>(NativeMethods.Value.DuckDBGetHugeInt(this)),
148-
//DuckDBType.UnsignedHugeInt => ReadValue<T>(),
149-
DuckDBType.Varchar => ReadValue<string>(NativeMethods.Value.DuckDBGetVarchar(this)),
150-
//DuckDBType.Decimal => ReadValue<T>(),
151-
//DuckDBType.Uuid => expr,
126+
DuckDBType.Boolean => Cast(NativeMethods.Value.DuckDBGetBool(this)),
127+
128+
DuckDBType.TinyInt => Cast(NativeMethods.Value.DuckDBGetInt8(this)),
129+
DuckDBType.SmallInt => Cast(NativeMethods.Value.DuckDBGetInt16(this)),
130+
DuckDBType.Integer => Cast(NativeMethods.Value.DuckDBGetInt32(this)),
131+
DuckDBType.BigInt => Cast(NativeMethods.Value.DuckDBGetInt64(this)),
132+
133+
DuckDBType.UnsignedTinyInt => Cast(NativeMethods.Value.DuckDBGetUInt8(this)),
134+
DuckDBType.UnsignedSmallInt => Cast(NativeMethods.Value.DuckDBGetUInt16(this)),
135+
DuckDBType.UnsignedInteger => Cast(NativeMethods.Value.DuckDBGetUInt32(this)),
136+
DuckDBType.UnsignedBigInt => Cast(NativeMethods.Value.DuckDBGetUInt64(this)),
137+
138+
DuckDBType.Float => Cast(NativeMethods.Value.DuckDBGetFloat(this)),
139+
DuckDBType.Double => Cast(NativeMethods.Value.DuckDBGetDouble(this)),
140+
141+
DuckDBType.Varchar => Cast(NativeMethods.Value.DuckDBGetVarchar(this)),
142+
DuckDBType.Timestamp => Cast(NativeMethods.DateTimeHelpers.DuckDBFromTimestamp(NativeMethods.Value.DuckDBGetTimestamp(this)).ToDateTime()),
143+
//DuckDBType.Decimal => Cast(decimal.Parse(NativeMethods.Value.DuckDBGetVarchar(this))),
144+
//DuckDBType.Uuid => Cast(new Guid(NativeMethods.Value.DuckDBGetVarchar(this))),
145+
//DuckDBType.TimestampS => expr,
146+
//DuckDBType.TimestampMs => expr,
147+
//DuckDBType.TimestampNs => expr,
148+
//DuckDBType.TimeTz => expr,
149+
//DuckDBType.TimestampTz => expr,
150+
152151
_ => throw new NotImplementedException($"Cannot read value of type {typeof(T).FullName}")
153152
};
154153

155-
T ReadValue<TSource>(TSource value)
154+
T Cast<TSource>(TSource value)
156155
{
157156
return Unsafe.As<TSource, T>(ref value);
158157
}

DuckDB.NET.Bindings/NativeMethods/NativeMethods.Value.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,21 @@ public static class Value
110110
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_double")]
111111
public static extern double DuckDBGetDouble(DuckDBValue value);
112112

113+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_date")]
114+
public static extern unsafe DuckDBDate DuckDBGetDate(DuckDBValue value);
115+
116+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_time")]
117+
public static extern unsafe DuckDBTime DuckDBGetTime(DuckDBValue value);
118+
119+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_time_tz")]
120+
public static extern unsafe DuckDBTimeTzStruct DuckDBGetTimeTz(DuckDBValue value);
121+
122+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_timestamp")]
123+
public static extern unsafe DuckDBTimestampStruct DuckDBGetTimestamp(DuckDBValue value);
124+
125+
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_interval")]
126+
public static extern unsafe DuckDBInterval DuckDBGetInterval(DuckDBValue value);
127+
113128
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_value_type")]
114129
public static extern unsafe DuckDBLogicalType DuckDBGetValueType(DuckDBValue value);
115130

DuckDB.NET.Test/TableFunctionTests.cs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,56 +33,59 @@ public void RegisterTableFunctionWithOneParameter()
3333
}
3434

3535
[Fact]
36-
public void RegisterTableFunctionWithOneParameterTwoColumns()
36+
public void RegisterTableFunctionWithTwoParameterTwoColumns()
3737
{
38-
var count = 3000;
38+
var count = 50;
3939

40-
Connection.RegisterTableFunction<int>("demo2", (parameters) =>
40+
Connection.RegisterTableFunction<short, string>("demo2", (parameters) =>
4141
{
42-
var value = parameters[0].GetValue<int>();
42+
var start = parameters[0].GetValue<short>();
43+
var prefix = parameters[1].GetValue<string>();
4344

4445
return new TableFunction(new List<ColumnInfo>()
4546
{
4647
new ColumnInfo("foo", typeof(int)),
4748
new ColumnInfo("bar", typeof(string)),
48-
}, Enumerable.Range(0, value));
49+
}, Enumerable.Range(start, count).Select(index => KeyValuePair.Create(index, prefix + index)));
4950
}, (item, writers, rowIndex) =>
5051
{
51-
writers[0].WriteValue((int)item, rowIndex);
52-
writers[1].WriteValue($"string{item}", rowIndex);
52+
var pair = (KeyValuePair<int, string>)item;
53+
writers[0].WriteValue(pair.Key, rowIndex);
54+
writers[1].WriteValue(pair.Value, rowIndex);
5355
});
5456

55-
var data = Connection.Query<(int, string)>($"SELECT * FROM demo2({count});").ToList();
57+
var data = Connection.Query<(int, string)>($"SELECT * FROM demo2(30::SmallInt, 'DuckDB');").ToList();
5658

57-
data.Select(tuple => tuple.Item1).Should().BeEquivalentTo(Enumerable.Range(0, count));
58-
data.Select(tuple => tuple.Item2).Should().BeEquivalentTo(Enumerable.Range(0, count).Select(i => $"string{i}"));
59+
data.Select(tuple => tuple.Item1).Should().BeEquivalentTo(Enumerable.Range(30, count));
60+
data.Select(tuple => tuple.Item2).Should().BeEquivalentTo(Enumerable.Range(30, count).Select(i => $"DuckDB{i}"));
5961
}
6062

6163
[Fact]
62-
public void RegisterTableFunctionWithTwoParameterTwoColumns()
64+
public void RegisterTableFunctionWithThreeParameters()
6365
{
64-
var count = 50;
66+
var count = 30;
67+
var startDate = new DateTime(2024, 11, 6);
68+
var minutesParam= 10;
69+
var secondsParam = 2.5;
6570

66-
Connection.RegisterTableFunction<short, string>("demo3", (parameters) =>
71+
Connection.RegisterTableFunction<DateTime, long, double>("demo3", (parameters) =>
6772
{
68-
var start = parameters[0].GetValue<short>();
69-
var prefix = parameters[1].GetValue<string>();
73+
var date = parameters[0].GetValue<DateTime>();
74+
var minutes = parameters[1].GetValue<long>();
75+
var seconds = parameters[2].GetValue<double>();
7076

7177
return new TableFunction(new List<ColumnInfo>()
7278
{
73-
new ColumnInfo("foo", typeof(int)),
74-
new ColumnInfo("bar", typeof(string)),
75-
}, Enumerable.Range(start, count).Select(index => KeyValuePair.Create(index, prefix + index)));
79+
new ColumnInfo("foo", typeof(DateTime)),
80+
}, Enumerable.Range(0, count).Select(i => date.AddDays(i).AddMinutes(minutes).AddSeconds(seconds)));
7681
}, (item, writers, rowIndex) =>
7782
{
78-
var pair = (KeyValuePair<int, string>)item;
79-
writers[0].WriteValue(pair.Key, rowIndex);
80-
writers[1].WriteValue(pair.Value, rowIndex);
83+
writers[0].WriteValue((DateTime)item, rowIndex);
8184
});
8285

83-
var data = Connection.Query<(int, string)>($"SELECT * FROM demo3(30::SmallInt, 'DuckDB');").ToList();
86+
var data = Connection.Query<DateTime>($"SELECT * FROM demo3('2024-11-06'::TIMESTAMP, 10, 2.5 );").ToList();
8487

85-
data.Select(tuple => tuple.Item1).Should().BeEquivalentTo(Enumerable.Range(30, count));
86-
data.Select(tuple => tuple.Item2).Should().BeEquivalentTo(Enumerable.Range(30, count).Select(i => $"DuckDB{i}"));
88+
var dateTimes = Enumerable.Range(0, count).Select(i => startDate.AddDays(i).AddMinutes(minutesParam).AddSeconds(secondsParam));
89+
data.Select(dateTime => dateTime).Should().BeEquivalentTo(dateTimes);
8790
}
8891
}

0 commit comments

Comments
 (0)