Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Giorgi committed Nov 7, 2024
2 parents a2bb658 + c4fd303 commit 1c8cc9b
Show file tree
Hide file tree
Showing 33 changed files with 1,101 additions and 164 deletions.
13 changes: 7 additions & 6 deletions DuckDB.NET.Bindings/Bindings.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
<PropertyGroup>
<Description>DuckDB Bindings for C#.</Description>
<PackageReleaseNotes>
Added support for creating user-defined scalar functions.
Added support for creating user-defined table valued functions.

Added support for Varint type.
Added support for passing LIST parameter types

Added support for writing to Enum columns when using managed Appender.

Updated to DuckDB v1.1.2
Updated to DuckDB v1.1.3
</PackageReleaseNotes>
<RootNamespace>DuckDB.NET.Native</RootNamespace>
<RuntimeIdentifiers>win-x64;win-arm64;linux-x64;linux-arm64;osx</RuntimeIdentifiers>
<DuckDbArtifactRoot Condition=" '$(DuckDbArtifactRoot)' == '' ">https://github.com/duckdb/duckdb/releases/download/v1.1.2</DuckDbArtifactRoot>
<DuckDbArtifactRoot Condition=" '$(DuckDbArtifactRoot)' == '' ">https://github.com/duckdb/duckdb/releases/download/v1.1.3</DuckDbArtifactRoot>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\keyPair.snk</AssemblyOriginatorKeyFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down Expand Up @@ -47,5 +45,8 @@ Updated to DuckDB v1.1.2
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.11.1" PrivateAssets="all" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
<!-- End native lib section -->
</Project>
8 changes: 0 additions & 8 deletions DuckDB.NET.Bindings/DuckDBNativeObjects.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.InteropServices;

namespace DuckDB.NET.Native;
Expand Down Expand Up @@ -143,12 +141,6 @@ public struct DuckDBTimeTz
public struct DuckDBTimestampStruct
{
public long Micros { get; set; }

public readonly DateTime ToDateTime()
{
var ticks = Micros * 10 + Utils.UnixEpochTicks;
return new DateTime(ticks);
}
}

[StructLayout(LayoutKind.Sequential)]
Expand Down
75 changes: 71 additions & 4 deletions DuckDB.NET.Bindings/DuckDBWrapperObjects.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Microsoft.Win32.SafeHandles;
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.CompilerServices;

namespace DuckDB.NET.Native;

Expand Down Expand Up @@ -89,11 +90,77 @@ protected override bool ReleaseHandle()
}
}

public class DuckDBValue() : SafeHandleZeroOrMinusOneIsInvalid(true)
public class DuckDBValue() : SafeHandleZeroOrMinusOneIsInvalid(true), IDuckDBValueReader
{
private DuckDBValue[] childValues = [];

protected override bool ReleaseHandle()
{
foreach (var value in childValues)
{
value.Dispose();
}

NativeMethods.Value.DuckDBDestroyValue(out handle);
return true;
}
}

internal void SetChildValues(DuckDBValue[] values)
{
childValues = values;
}

public T GetValue<T>()
{
var logicalType = NativeMethods.Value.DuckDBGetValueType(this);

//Logical type is part of the duckdb_value object and it shouldn't be released separately
//It will get released when the duckdb_value object is destroyed below.
var add = false;
logicalType.DangerousAddRef(ref add);

var duckDBType = NativeMethods.LogicalType.DuckDBGetTypeId(logicalType);

return duckDBType switch
{
DuckDBType.Boolean => Cast(NativeMethods.Value.DuckDBGetBool(this)),

DuckDBType.TinyInt => Cast(NativeMethods.Value.DuckDBGetInt8(this)),
DuckDBType.SmallInt => Cast(NativeMethods.Value.DuckDBGetInt16(this)),
DuckDBType.Integer => Cast(NativeMethods.Value.DuckDBGetInt32(this)),
DuckDBType.BigInt => Cast(NativeMethods.Value.DuckDBGetInt64(this)),

DuckDBType.UnsignedTinyInt => Cast(NativeMethods.Value.DuckDBGetUInt8(this)),
DuckDBType.UnsignedSmallInt => Cast(NativeMethods.Value.DuckDBGetUInt16(this)),
DuckDBType.UnsignedInteger => Cast(NativeMethods.Value.DuckDBGetUInt32(this)),
DuckDBType.UnsignedBigInt => Cast(NativeMethods.Value.DuckDBGetUInt64(this)),

DuckDBType.Float => Cast(NativeMethods.Value.DuckDBGetFloat(this)),
DuckDBType.Double => Cast(NativeMethods.Value.DuckDBGetDouble(this)),

DuckDBType.Decimal => Cast(decimal.Parse(NativeMethods.Value.DuckDBGetVarchar(this))),
DuckDBType.Uuid => Cast(new Guid(NativeMethods.Value.DuckDBGetVarchar(this))),

//DuckDBType.HugeInt => expr,
//DuckDBType.UnsignedHugeInt => expr,

DuckDBType.Varchar => Cast(NativeMethods.Value.DuckDBGetVarchar(this)),

//DuckDBType.Date => expr,
//DuckDBType.Time => expr,
//DuckDBType.TimeTz => expr,
//DuckDBType.Interval => expr,
DuckDBType.Timestamp => Cast(NativeMethods.DateTimeHelpers.DuckDBFromTimestamp(NativeMethods.Value.DuckDBGetTimestamp(this)).ToDateTime()),
//DuckDBType.TimestampS => expr,
//DuckDBType.TimestampMs => expr,
//DuckDBType.TimestampNs => expr,
//DuckDBType.TimestampTz => expr,
_ => throw new NotImplementedException($"Cannot read value of type {typeof(T).FullName}")
};

T Cast<TSource>(TSource value)
{
return Unsafe.As<TSource, T>(ref value);
}
}
}
6 changes: 6 additions & 0 deletions DuckDB.NET.Bindings/IDuckDBValueReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace DuckDB.NET.Native;

public interface IDuckDBValueReader
{
T GetValue<T>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ public static class LogicalType
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_logical_type")]
public static extern DuckDBLogicalType DuckDBCreateLogicalType(DuckDBType type);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_decimal_type")]
public static extern DuckDBLogicalType DuckDBCreateDecimalType(byte width, byte scale);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_type_id")]
public static extern DuckDBType DuckDBGetTypeId(DuckDBLogicalType type);

Expand Down
66 changes: 66 additions & 0 deletions DuckDB.NET.Bindings/NativeMethods/NativeMethods.TableFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Runtime.InteropServices;
using System;

namespace DuckDB.NET.Native;

public partial class NativeMethods
{
public static class TableFunction
{
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_table_function")]
public static extern IntPtr DuckDBCreateTableFunction();

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_destroy_table_function")]
public static extern void DuckDBDestroyTableFunction(out IntPtr tableFunction);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_set_name")]
public static extern void DuckDBTableFunctionSetName(IntPtr tableFunction, SafeUnmanagedMemoryHandle name);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_add_parameter")]
public static extern void DuckDBTableFunctionAddParameter(IntPtr tableFunction, DuckDBLogicalType type);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_set_extra_info")]
public static extern unsafe void DuckDBTableFunctionSetExtraInfo(IntPtr tableFunction, IntPtr extraInfo, delegate* unmanaged[Cdecl]<IntPtr, void> destroy);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_set_bind")]
public static extern unsafe void DuckDBTableFunctionSetBind(IntPtr tableFunction, delegate* unmanaged[Cdecl]<IntPtr, void> bind);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_set_init")]
public static extern unsafe void DuckDBTableFunctionSetInit(IntPtr tableFunction, delegate* unmanaged[Cdecl]<IntPtr, void> init);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_table_function_set_function")]
public static extern unsafe void DuckDBTableFunctionSetFunction(IntPtr tableFunction, delegate* unmanaged[Cdecl]<IntPtr, IntPtr, void> callback);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_register_table_function")]
public static extern DuckDBState DuckDBRegisterTableFunction(DuckDBNativeConnection con, IntPtr tableFunction);

#region TableFunctionBind

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_bind_get_extra_info")]
public static extern unsafe IntPtr DuckDBBindGetExtraInfo(IntPtr info);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_bind_add_result_column")]
public static extern unsafe void DuckDBBindAddResultColumn(IntPtr info, SafeUnmanagedMemoryHandle name, DuckDBLogicalType type);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_bind_get_parameter_count")]
public static extern unsafe ulong DuckDBBindGetParameterCount(IntPtr info);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_bind_get_parameter")]
public static extern unsafe DuckDBValue DuckDBBindGetParameter(IntPtr info, ulong index);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_bind_set_bind_data")]
public static extern unsafe void DuckDBBindSetBindData(IntPtr info, IntPtr bindData, delegate* unmanaged[Cdecl]<IntPtr, void> destroy);

#endregion

#region TableFunction

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_function_get_extra_info")]
public static extern unsafe IntPtr DuckDBFunctionGetExtraInfo(IntPtr info);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_function_get_bind_data")]
public static extern unsafe IntPtr DuckDBFunctionGetBindData(IntPtr info);

#endregion
}
}
81 changes: 77 additions & 4 deletions DuckDB.NET.Bindings/NativeMethods/NativeMethods.Value.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace DuckDB.NET.Native;
Expand All @@ -7,6 +8,9 @@ public partial class NativeMethods
{
public static class Value
{
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_destroy_value")]
public static extern void DuckDBDestroyValue(out IntPtr config);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_varchar")]
public static extern DuckDBValue DuckDBCreateVarchar(SafeUnmanagedMemoryHandle value);

Expand Down Expand Up @@ -55,8 +59,8 @@ public static class Value
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_time")]
public static extern DuckDBValue DuckDBCreateTime(DuckDBTime value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_time_tz")]
public static extern DuckDBValue DuckDBCreateTimeTz(DuckDBTimeTz value);
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_time_tz_value")]
public static extern DuckDBValue DuckDBCreateTimeTz(DuckDBTimeTzStruct value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_timestamp")]
public static extern DuckDBValue DuckDBCreateTimestamp(DuckDBTimestampStruct value);
Expand All @@ -67,7 +71,76 @@ public static class Value
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_blob")]
public static extern DuckDBValue DuckDBCreateBlob([In] byte[] value, long length);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_destroy_value")]
public static extern void DuckDBDestroyValue(out IntPtr config);
[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_bool")]
public static extern bool DuckDBGetBool(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_int8")]
public static extern sbyte DuckDBGetInt8(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_uint8")]
public static extern byte DuckDBGetUInt8(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_int16")]
public static extern short DuckDBGetInt16(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_uint16")]
public static extern ushort DuckDBGetUInt16(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_int32")]
public static extern int DuckDBGetInt32(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_uint32")]
public static extern uint DuckDBGetUInt32(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_int64")]
public static extern long DuckDBGetInt64(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_uint64")]
public static extern ulong DuckDBGetUInt64(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_hugeint")]
public static extern DuckDBHugeInt DuckDBGetHugeInt(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_uhugeint")]
public static extern DuckDBUHugeInt DuckDBGetUHugeInt(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_float")]
public static extern float DuckDBGetFloat(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_double")]
public static extern double DuckDBGetDouble(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_date")]
public static extern unsafe DuckDBDate DuckDBGetDate(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_time")]
public static extern unsafe DuckDBTime DuckDBGetTime(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_time_tz")]
public static extern unsafe DuckDBTimeTzStruct DuckDBGetTimeTz(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_timestamp")]
public static extern unsafe DuckDBTimestampStruct DuckDBGetTimestamp(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_interval")]
public static extern unsafe DuckDBInterval DuckDBGetInterval(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_value_type")]
public static extern unsafe DuckDBLogicalType DuckDBGetValueType(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_get_varchar")]
public static extern string DuckDBGetVarchar(DuckDBValue value);

[DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_create_list_value")]
public static extern DuckDBValue DuckDBCreateListValue(DuckDBLogicalType logicalType, IntPtr[] values, long count);

public static DuckDBValue DuckDBCreateListValue(DuckDBLogicalType logicalType, DuckDBValue[] values, int count)
{
var duckDBValue = DuckDBCreateListValue(logicalType, values.Select(item => item.DangerousGetHandle()).ToArray(), count);

duckDBValue.SetChildValues(values);

return duckDBValue;
}
}
}
2 changes: 0 additions & 2 deletions DuckDB.NET.Bindings/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ namespace DuckDB.NET.Native;

public static class Utils
{
internal const long UnixEpochTicks = 621355968000000000;

public static bool IsSuccess(this DuckDBState state)
{
return state == DuckDBState.Success;
Expand Down
8 changes: 3 additions & 5 deletions DuckDB.NET.Data/Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
<PropertyGroup>
<Description>DuckDB ADO.NET Provider for C#.</Description>
<PackageReleaseNotes>
Added support for creating user-defined scalar functions.
Added support for creating user-defined table valued functions.

Added support for Varint type.
Added support for passing LIST parameter types

Added support for writing to Enum columns when using managed Appender.

Updated to DuckDB v1.1.2
Updated to DuckDB v1.1.3
</PackageReleaseNotes>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\keyPair.snk</AssemblyOriginatorKeyFile>
Expand Down
Loading

0 comments on commit 1c8cc9b

Please sign in to comment.