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

Giorgi / DuckDB.NET / 12063721251

28 Nov 2024 06:32AM UTC coverage: 88.995% (+0.04%) from 88.958%
12063721251

push

github

Giorgi
Do not throw if parameter index isn't found

1146 of 1326 branches covered (86.43%)

Branch coverage included in aggregate %.

2121 of 2345 relevant lines covered (90.45%)

772904.74 hits per line

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

84.11
/DuckDB.NET.Data/Internal/ClrToDuckDBConverter.cs
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Globalization;
5
using System.Numerics;
6
using DuckDB.NET.Data.Extensions;
7
using DuckDB.NET.Native;
8

9
namespace DuckDB.NET.Data.Internal;
10

11
internal static class ClrToDuckDBConverter
12
{
13
    public static DuckDBValue ToDuckDBValue(this object? value)
14
    {
15
        if (value.IsNull())
7,860✔
16
        {
17
            return NativeMethods.Value.DuckDBCreateNullValue();
3,247✔
18
        }
19

20
        return value switch
4,613!
21
        {
4,613✔
22
            bool val => NativeMethods.Value.DuckDBCreateBool(val),
184✔
23

4,613✔
24
            sbyte val => NativeMethods.Value.DuckDBCreateInt8(val),
177✔
25
            short val => NativeMethods.Value.DuckDBCreateInt16(val),
210✔
26
            int val => NativeMethods.Value.DuckDBCreateInt32(val),
162✔
27
            long val => NativeMethods.Value.DuckDBCreateInt64(val),
243✔
28

4,613✔
29
            byte val => NativeMethods.Value.DuckDBCreateUInt8(val),
156✔
30
            ushort val => NativeMethods.Value.DuckDBCreateUInt16(val),
208✔
31
            uint val => NativeMethods.Value.DuckDBCreateUInt32(val),
141✔
32
            ulong val => NativeMethods.Value.DuckDBCreateUInt64(val),
174✔
33

4,613✔
34
            float val => NativeMethods.Value.DuckDBCreateFloat(val),
238✔
35
            double val => NativeMethods.Value.DuckDBCreateDouble(val),
156✔
36

4,613✔
37
            decimal val => DecimalToDuckDBValue(val),
133✔
38
            BigInteger val => NativeMethods.Value.DuckDBCreateHugeInt(new DuckDBHugeInt(val)),
147✔
39

4,613✔
40
            string val => StringToDuckDBValue(val),
166✔
41
            Guid val => GuidToDuckDBValue(val),
189✔
42
            DateTime val => NativeMethods.Value.DuckDBCreateTimestamp(NativeMethods.DateTimeHelpers.DuckDBToTimestamp(DuckDBTimestamp.FromDateTime(val))),
358✔
43
            TimeSpan val => NativeMethods.Value.DuckDBCreateInterval(val),
283✔
44
            DuckDBDateOnly val => NativeMethods.Value.DuckDBCreateDate(NativeMethods.DateTimeHelpers.DuckDBToDate(val)),
174✔
45
            DuckDBTimeOnly val => NativeMethods.Value.DuckDBCreateTime(NativeMethods.DateTimeHelpers.DuckDBToTime(val)),
168✔
46
#if NET6_0_OR_GREATER
4,613✔
47
            DateOnly val => NativeMethods.Value.DuckDBCreateDate(NativeMethods.DateTimeHelpers.DuckDBToDate(val)),
260✔
48
            TimeOnly val => NativeMethods.Value.DuckDBCreateTime(NativeMethods.DateTimeHelpers.DuckDBToTime(val)),
245✔
49
#endif
4,613✔
50
            DateTimeOffset val => DateTimeOffsetToDuckDBValue(val),
441✔
51
            byte[] val => NativeMethods.Value.DuckDBCreateBlob(val, val.Length),
×
52

4,613✔
53
            ICollection val => CreateCollectionValue(val),
×
54
            _ => throw new InvalidCastException($"Cannot convert value of type {value.GetType().FullName} to DuckDBValue.")
×
55
        };
4,613✔
56
    }
57

58
    private static DuckDBValue DateTimeOffsetToDuckDBValue(DateTimeOffset val)
59
    {
60
        var duckDBToTime = NativeMethods.DateTimeHelpers.DuckDBToTime((DuckDBTimeOnly)val.DateTime);
459✔
61
        var duckDBCreateTimeTz = NativeMethods.DateTimeHelpers.DuckDBCreateTimeTz(duckDBToTime.Micros, (int)val.Offset.TotalSeconds);
459✔
62
        return NativeMethods.Value.DuckDBCreateTimeTz(duckDBCreateTimeTz);
459✔
63
    }
64

65
    private static DuckDBValue GuidToDuckDBValue(Guid value)
66
    {
67
        using var handle = value.ToString().ToUnmanagedString();
210✔
68
        return NativeMethods.Value.DuckDBCreateVarchar(handle);
210✔
69
    }
210✔
70

71
    private static DuckDBValue DecimalToDuckDBValue(decimal value)
72
    {
73
        using var handle = value.ToString(CultureInfo.InvariantCulture).ToUnmanagedString();
181✔
74
        return NativeMethods.Value.DuckDBCreateVarchar(handle);
181✔
75
    }
181✔
76

77
    private static DuckDBValue StringToDuckDBValue(string value)
78
    {
79
        using var handle = value.ToUnmanagedString();
238✔
80
        return NativeMethods.Value.DuckDBCreateVarchar(handle);
238✔
81
    }
238✔
82

83
    private static DuckDBValue CreateCollectionValue(ICollection collection)
84
    {
85
        return collection switch
132!
86
        {
132✔
87
            ICollection<bool> items => CreateCollectionValue(DuckDBType.Boolean, items),
×
88
            ICollection<bool?> items => CreateCollectionValue(DuckDBType.Boolean, items),
6✔
89

132✔
90
            ICollection<sbyte> items => CreateCollectionValue(DuckDBType.TinyInt, items),
×
91
            ICollection<sbyte?> items => CreateCollectionValue(DuckDBType.TinyInt, items),
6✔
92
            ICollection<short> items => CreateCollectionValue(DuckDBType.SmallInt, items),
×
93
            ICollection<short?> items => CreateCollectionValue(DuckDBType.SmallInt, items),
6✔
94
            ICollection<int> items => CreateCollectionValue(DuckDBType.Integer, items),
×
95
            ICollection<int?> items => CreateCollectionValue(DuckDBType.Integer, items),
6✔
96
            ICollection<long> items => CreateCollectionValue(DuckDBType.BigInt, items),
×
97
            ICollection<long?> items => CreateCollectionValue(DuckDBType.BigInt, items),
6✔
98

132✔
99
            ICollection<byte> items => CreateCollectionValue(DuckDBType.UnsignedTinyInt, items),
×
100
            ICollection<byte?> items => CreateCollectionValue(DuckDBType.UnsignedTinyInt, items),
6✔
101
            ICollection<ushort> items => CreateCollectionValue(DuckDBType.UnsignedSmallInt, items),
×
102
            ICollection<ushort?> items => CreateCollectionValue(DuckDBType.UnsignedSmallInt, items),
6✔
103
            ICollection<uint> items => CreateCollectionValue(DuckDBType.UnsignedInteger, items),
×
104
            ICollection<uint?> items => CreateCollectionValue(DuckDBType.UnsignedInteger, items),
6✔
105
            ICollection<ulong> items => CreateCollectionValue(DuckDBType.UnsignedBigInt, items),
×
106
            ICollection<ulong?> items => CreateCollectionValue(DuckDBType.UnsignedBigInt, items),
6✔
107

132✔
108
            ICollection<float> items => CreateCollectionValue(DuckDBType.Float, items),
×
109
            ICollection<float?> items => CreateCollectionValue(DuckDBType.Float, items),
6✔
110
            ICollection<double> items => CreateCollectionValue(DuckDBType.Double, items),
×
111
            ICollection<double?> items => CreateCollectionValue(DuckDBType.Double, items),
6✔
112

132✔
113
            ICollection<decimal> items => CreateCollectionValue(DuckDBType.Varchar, items),
×
114
            ICollection<decimal?> items => CreateCollectionValue(DuckDBType.Varchar, items),
6✔
115
            ICollection<BigInteger> items => CreateCollectionValue(DuckDBType.HugeInt, items),
×
116
            ICollection<BigInteger?> items => CreateCollectionValue(DuckDBType.HugeInt, items),
6✔
117

132✔
118
            ICollection<string> items => CreateCollectionValue(DuckDBType.Varchar, items),
6✔
119
            ICollection<Guid> items => CreateCollectionValue(DuckDBType.Varchar, items),
×
120
            ICollection<Guid?> items => CreateCollectionValue(DuckDBType.Varchar, items),
6✔
121
            ICollection<DateTime> items => CreateCollectionValue(DuckDBType.Date, items),
6✔
122
            ICollection<DateTime?> items => CreateCollectionValue(DuckDBType.Date, items),
×
123
            ICollection<TimeSpan> items => CreateCollectionValue(DuckDBType.Interval, items),
6✔
124
            ICollection<TimeSpan?> items => CreateCollectionValue(DuckDBType.Interval, items),
×
125
            ICollection<DuckDBDateOnly> items => CreateCollectionValue(DuckDBType.Date, items),
×
126
            ICollection<DuckDBDateOnly?> items => CreateCollectionValue(DuckDBType.Date, items),
6✔
127
            ICollection<DuckDBTimeOnly> items => CreateCollectionValue(DuckDBType.Time, items),
×
128
            ICollection<DuckDBTimeOnly?> items => CreateCollectionValue(DuckDBType.Time, items),
6✔
129
#if NET6_0_OR_GREATER
132✔
130
            ICollection<DateOnly> items => CreateCollectionValue(DuckDBType.Date, items),
×
131
            ICollection<DateOnly?> items => CreateCollectionValue(DuckDBType.Date, items),
6✔
132
            ICollection<TimeOnly> items => CreateCollectionValue(DuckDBType.Time, items),
6✔
133
            ICollection<TimeOnly?> items => CreateCollectionValue(DuckDBType.Time, items),
×
134
#endif
132✔
135
            ICollection<DateTimeOffset> items => CreateCollectionValue(DuckDBType.TimeTz, items),
6✔
136
            ICollection<DateTimeOffset?> items => CreateCollectionValue(DuckDBType.TimeTz, items),
×
137
            _ => throw new InvalidOperationException($"Cannot convert collection type {collection.GetType().FullName} to DuckDBValue.")
×
138
        };
132✔
139
    }
140

141
    private static DuckDBValue CreateCollectionValue<T>(DuckDBType duckDBType, ICollection<T> collection)
142
    {
143
        using var listItemType = NativeMethods.LogicalType.DuckDBCreateLogicalType(duckDBType);
132✔
144

145
        var values = new DuckDBValue[collection.Count];
132✔
146

147
        var index = 0;
132✔
148
        foreach (var item in collection)
15,984✔
149
        {
150
            var duckDBValue = item.ToDuckDBValue();
7,860✔
151
            values[index] = duckDBValue;
7,860✔
152
            index++;
7,860✔
153
        }
154

155
        return NativeMethods.Value.DuckDBCreateListValue(listItemType, values, collection.Count);
132✔
156
    }
132✔
157

158
    public static DuckDBValue ToDuckDBValue(this object? item, DuckDBLogicalType logicalType)
159
    {
160
        if (item.IsNull())
699✔
161
        {
162
            return NativeMethods.Value.DuckDBCreateNullValue();
24✔
163
        }
164

165
        var duckDBType = NativeMethods.LogicalType.DuckDBGetTypeId(logicalType);
675✔
166

167
        return (duckDBType, item) switch
675!
168
        {
675✔
169
            (DuckDBType.Boolean, bool value) => NativeMethods.Value.DuckDBCreateBool(value),
3✔
170

675✔
171
            (DuckDBType.TinyInt, _) => NativeMethods.Value.DuckDBCreateInt8(ConvertTo<sbyte>()),
18✔
172
            (DuckDBType.SmallInt, _) => NativeMethods.Value.DuckDBCreateInt16(ConvertTo<short>()),
18✔
173
            (DuckDBType.Integer, _) => NativeMethods.Value.DuckDBCreateInt32(ConvertTo<int>()),
108✔
174
            (DuckDBType.BigInt, _) => NativeMethods.Value.DuckDBCreateInt64(ConvertTo<long>()),
21✔
175

675✔
176
            (DuckDBType.UnsignedTinyInt, _) => NativeMethods.Value.DuckDBCreateUInt8(ConvertTo<byte>()),
18✔
177
            (DuckDBType.UnsignedSmallInt, _) => NativeMethods.Value.DuckDBCreateUInt16(ConvertTo<ushort>()),
18✔
178
            (DuckDBType.UnsignedInteger, _) => NativeMethods.Value.DuckDBCreateUInt32(ConvertTo<uint>()),
18✔
179
            (DuckDBType.UnsignedBigInt, _) => NativeMethods.Value.DuckDBCreateUInt64(ConvertTo<ulong>()),
18✔
180

675✔
181
            (DuckDBType.Float, float value) => NativeMethods.Value.DuckDBCreateFloat(value),
3✔
182
            (DuckDBType.Double, double value) => NativeMethods.Value.DuckDBCreateDouble(value),
3✔
183

675✔
184
            (DuckDBType.Decimal, decimal value) => DecimalToDuckDBValue(value),
48✔
185
            (DuckDBType.HugeInt, BigInteger value) => NativeMethods.Value.DuckDBCreateHugeInt(new DuckDBHugeInt(value)),
6✔
186

675✔
187
            (DuckDBType.Varchar, string value) => StringToDuckDBValue(value),
72✔
188
            (DuckDBType.Uuid, Guid value) => GuidToDuckDBValue(value),
21✔
189

675✔
190
            (DuckDBType.Timestamp, DateTime value) => NativeMethods.Value.DuckDBCreateTimestamp(NativeMethods.DateTimeHelpers.DuckDBToTimestamp(DuckDBTimestamp.FromDateTime(value))),
36✔
191
            (DuckDBType.Interval, TimeSpan value) => NativeMethods.Value.DuckDBCreateInterval(value),
×
192
            (DuckDBType.Date, DuckDBDateOnly value) => NativeMethods.Value.DuckDBCreateDate(NativeMethods.DateTimeHelpers.DuckDBToDate(value)),
18✔
193
            (DuckDBType.Time, DuckDBTimeOnly value) => NativeMethods.Value.DuckDBCreateTime(NativeMethods.DateTimeHelpers.DuckDBToTime(value)),
36✔
194
#if NET6_0_OR_GREATER
675✔
195
            (DuckDBType.Date, DateOnly value) => NativeMethods.Value.DuckDBCreateDate(NativeMethods.DateTimeHelpers.DuckDBToDate(value)),
9✔
196
            (DuckDBType.Time, TimeOnly value) => NativeMethods.Value.DuckDBCreateTime(NativeMethods.DateTimeHelpers.DuckDBToTime(value)),
18✔
197
#endif
675✔
198
            (DuckDBType.TimeTz, DateTimeOffset value) => DateTimeOffsetToDuckDBValue(value),
18✔
199
            (DuckDBType.Blob, byte[] value) => NativeMethods.Value.DuckDBCreateBlob(value, value.Length),
3✔
200
            (DuckDBType.List, ICollection value) => CreateCollectionValue(value),
66✔
201
            (DuckDBType.Array, ICollection value) => CreateCollectionValue(value),
66✔
202
            _ => throw new InvalidOperationException($"Cannot bind parameter type {item.GetType().FullName} to column of type {duckDBType}")
12✔
203
        };
675✔
204

205
        T ConvertTo<T>()
206
        {
207
            try
208
            {
209
                return (T)Convert.ChangeType(item, typeof(T));
237✔
210
            }
211
            catch (Exception)
×
212
            {
213
                throw new ArgumentOutOfRangeException($"Cannot bind parameter type {item.GetType().FullName} to column of type {duckDBType}");
×
214
            }
215
        }
237✔
216
    }
217
}
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