• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Giorgi / DuckDB.NET / 22921736195

10 Mar 2026 07:24PM UTC coverage: 89.526% (+0.08%) from 89.45%
22921736195

push

github

Giorgi
Update global.json

1255 of 1463 branches covered (85.78%)

Branch coverage included in aggregate %.

2651 of 2900 relevant lines covered (91.41%)

447643.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.03
/DuckDB.NET.Bindings/DuckDBWrapperObjects.cs
1
namespace DuckDB.NET.Native;
2

3
public class DuckDBDatabase() : SafeHandleZeroOrMinusOneIsInvalid(true)
45,803✔
4
{
5
    protected override bool ReleaseHandle()
6
    {
7
        NativeMethods.Startup.DuckDBClose(ref handle);
45,799✔
8
        return true;
45,799✔
9
    }
10
}
11

12
public class DuckDBNativeConnection() : SafeHandleZeroOrMinusOneIsInvalid(true)
64,950✔
13
{
14
    protected override bool ReleaseHandle()
15
    {
16
        NativeMethods.Startup.DuckDBDisconnect(ref handle);
64,946✔
17
        return true;
64,946✔
18
    }
19

20
    public void Interrupt()
21
    {
22
        NativeMethods.Startup.DuckDBInterrupt(this);
12✔
23
    }
12✔
24
}
25

26
public class DuckDBPreparedStatement() : SafeHandleZeroOrMinusOneIsInvalid(true)
158,184✔
27
{
28
    protected override bool ReleaseHandle()
29
    {
30
        NativeMethods.PreparedStatements.DuckDBDestroyPrepare(ref handle);
158,181✔
31
        return true;
158,181✔
32
    }
33
}
34

35
public class DuckDBConfig() : SafeHandleZeroOrMinusOneIsInvalid(true)
45,800✔
36
{
37
    protected override bool ReleaseHandle()
38
    {
39
        NativeMethods.Configuration.DuckDBDestroyConfig(ref handle);
45,800✔
40
        return true;
45,800✔
41
    }
42
}
43

44
public class DuckDBAppender() : SafeHandleZeroOrMinusOneIsInvalid(true)
216✔
45
{
46
    protected override bool ReleaseHandle()
47
    {
48
        return NativeMethods.Appender.DuckDBDestroyAppender(ref handle).IsSuccess();
216✔
49
    }
50
}
51

52
public class DuckDBExtractedStatements() : SafeHandleZeroOrMinusOneIsInvalid(true)
158,076✔
53
{
54
    protected override bool ReleaseHandle()
55
    {
56
        NativeMethods.ExtractStatements.DuckDBDestroyExtracted(ref handle);
158,073✔
57

58
        return true;
158,073✔
59
    }
60
}
61

62
public class DuckDBLogicalType() : SafeHandleZeroOrMinusOneIsInvalid(true)
62,358✔
63
{
64
    protected override bool ReleaseHandle()
65
    {
66
        NativeMethods.LogicalType.DuckDBDestroyLogicalType(ref handle);
62,043✔
67
        return true;
62,043✔
68
    }
69
}
70

71
public class DuckDBDataChunk : SafeHandleZeroOrMinusOneIsInvalid
72
{
73
    public DuckDBDataChunk() : base(true)
40,704✔
74
    {
75
    }
40,704✔
76

77
    public DuckDBDataChunk(IntPtr chunk) : base(false)
471✔
78
    {
79
        SetHandle(chunk);
471✔
80
    }
471✔
81

82
    protected override bool ReleaseHandle()
83
    {
84
        NativeMethods.DataChunks.DuckDBDestroyDataChunk(ref handle);
40,091✔
85
        return true;
40,091✔
86
    }
87
}
88

89
public class DuckDBValue() : SafeHandleZeroOrMinusOneIsInvalid(true), IDuckDBValueReader
11,284✔
90
{
91
    private DuckDBValue[] childValues = [];
11,284✔
92

93
    protected override bool ReleaseHandle()
94
    {
95
        foreach (var value in childValues)
42,580✔
96
        {
97
            value.Dispose();
10,015✔
98
        }
99

100
        NativeMethods.Value.DuckDBDestroyValue(ref handle);
11,275✔
101
        return true;
11,275✔
102
    }
103

104
    internal void SetChildValues(DuckDBValue[] values)
105
    {
106
        childValues = values;
396✔
107
    }
396✔
108

109
    public bool IsNull() => NativeMethods.Value.DuckDBIsNullValue(this);
99✔
110

111
    public T GetValue<T>()
112
    {
113
        var logicalType = NativeMethods.Value.DuckDBGetValueType(this);
156✔
114

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

120
        var duckDBType = NativeMethods.LogicalType.DuckDBGetTypeId(logicalType);
156✔
121

122
        return duckDBType switch
156!
123
        {
156✔
124
            DuckDBType.Boolean => Cast(NativeMethods.Value.DuckDBGetBool(this)),
3✔
125

156✔
126
            DuckDBType.TinyInt => Cast(NativeMethods.Value.DuckDBGetInt8(this)),
3✔
127
            DuckDBType.SmallInt => Cast(NativeMethods.Value.DuckDBGetInt16(this)),
3✔
128
            DuckDBType.Integer => Cast(NativeMethods.Value.DuckDBGetInt32(this)),
63✔
129
            DuckDBType.BigInt => Cast(NativeMethods.Value.DuckDBGetInt64(this)),
3✔
130

156✔
131
            DuckDBType.UnsignedTinyInt => Cast(NativeMethods.Value.DuckDBGetUInt8(this)),
3✔
132
            DuckDBType.UnsignedSmallInt => Cast(NativeMethods.Value.DuckDBGetUInt16(this)),
3✔
133
            DuckDBType.UnsignedInteger => Cast(NativeMethods.Value.DuckDBGetUInt32(this)),
3✔
134
            DuckDBType.UnsignedBigInt => Cast(NativeMethods.Value.DuckDBGetUInt64(this)),
3✔
135

156✔
136
            DuckDBType.Float => Cast(NativeMethods.Value.DuckDBGetFloat(this)),
3✔
137
            DuckDBType.Double => Cast(NativeMethods.Value.DuckDBGetDouble(this)),
9✔
138

156✔
139
            DuckDBType.Decimal => Cast(decimal.Parse(NativeMethods.Value.DuckDBGetVarchar(this), NumberStyles.Any, CultureInfo.InvariantCulture)),
6✔
140

156✔
141
            DuckDBType.Uuid => Cast(new Guid(NativeMethods.Value.DuckDBGetVarchar(this))),
3✔
142

156✔
143
            DuckDBType.HugeInt => Cast(NativeMethods.Value.DuckDBGetHugeInt(this).ToBigInteger()),
3✔
144
            DuckDBType.UnsignedHugeInt => Cast(NativeMethods.Value.DuckDBGetUHugeInt(this).ToBigInteger()),
×
145

156✔
146
            DuckDBType.Varchar => Cast(NativeMethods.Value.DuckDBGetVarchar(this)),
18✔
147

156✔
148
            DuckDBType.Date => Cast((DateOnly)DuckDBDateOnly.FromDuckDBDate(NativeMethods.Value.DuckDBGetDate(this))),
3✔
149
            DuckDBType.Time => Cast((TimeOnly)NativeMethods.DateTimeHelpers.DuckDBFromTime(NativeMethods.Value.DuckDBGetTime(this))),
3✔
150
            DuckDBType.TimeTz => Cast(GetTimeTzValue()),
3✔
151
            DuckDBType.Interval => Cast((TimeSpan)NativeMethods.Value.DuckDBGetInterval(this)),
3✔
152
            DuckDBType.Timestamp => Cast(GetTimestampValue(NativeMethods.Value.DuckDBGetTimestamp(this),DuckDBType.Timestamp)),
3✔
153
            DuckDBType.TimestampS => Cast(GetTimestampValue(NativeMethods.Value.DuckDBGetTimestampS(this), DuckDBType.TimestampS)),
3✔
154
            DuckDBType.TimestampMs => Cast(GetTimestampValue(NativeMethods.Value.DuckDBGetTimestampMs(this), DuckDBType.TimestampMs)),
3✔
155
            DuckDBType.TimestampNs => Cast(GetTimestampValue(NativeMethods.Value.DuckDBGetTimestampNs(this), DuckDBType.TimestampNs)),
3✔
156
            DuckDBType.TimestampTz => Cast(GetTimestampValue(NativeMethods.Value.DuckDBGetTimestamp(this), DuckDBType.TimestampTz)),
3✔
157
            _ => throw new NotImplementedException($"Cannot read value of type {typeof(T).FullName}")
×
158
        };
156✔
159

160
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
161
        static T Cast<TSource>(TSource value) => Unsafe.As<TSource, T>(ref value);
156✔
162
    }
163

164
    private DateTime GetTimestampValue(DuckDBTimestampStruct timestampStruct, DuckDBType duckDBType)
165
    {
166
        var additionalTicks = 0;
15✔
167

168
        // The type-specific getters return values in their native units:
169
        // - TimestampS: seconds
170
        // - TimestampMs: milliseconds
171
        // - TimestampNs: nanoseconds
172
        // We need to convert to microseconds for DuckDBTimestamp.FromDuckDBTimestampStruct()
173
        if (duckDBType == DuckDBType.TimestampNs)
15✔
174
        {
175
            additionalTicks = (int)(timestampStruct.Micros % 1000 / 100);
3✔
176
            timestampStruct.Micros /= 1000;
3✔
177
        }
178
        if (duckDBType == DuckDBType.TimestampMs)
15✔
179
        {
180
            timestampStruct.Micros *= 1000;
3✔
181
        }
182
        if (duckDBType == DuckDBType.TimestampS)
15✔
183
        {
184
            timestampStruct.Micros *= 1000000;
3✔
185
        }
186

187
        var timestamp = DuckDBTimestamp.FromDuckDBTimestampStruct(timestampStruct);
15✔
188
        return timestamp.ToDateTime().AddTicks(additionalTicks);
15✔
189
    }
190

191
    private DateTimeOffset GetTimeTzValue()
192
    {
193
        var timeTzStruct = NativeMethods.Value.DuckDBGetTimeTz(this);
3✔
194
        var timeTz = NativeMethods.DateTimeHelpers.DuckDBFromTimeTz(timeTzStruct);
3✔
195
        return new DateTimeOffset(timeTz.Time.ToDateTime(), TimeSpan.FromSeconds(timeTz.Offset));
3✔
196
    }
197
}
198

199
public class DuckDBClientContext() : SafeHandleZeroOrMinusOneIsInvalid(true)
339✔
200
{
201
    protected override bool ReleaseHandle()
202
    {
203
        NativeMethods.Startup.DuckDBDestroyClientContext(ref handle);
339✔
204
        return true;
339✔
205
    }
206

207
    public ulong ConnectionId => NativeMethods.Startup.DuckDBClientContextGetConnectionId(this);
339✔
208
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc