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

Giorgi / DuckDB.NET / 21786556530

07 Feb 2026 08:39PM UTC coverage: 89.155% (-0.07%) from 89.223%
21786556530

push

github

Giorgi
Added support for clearing in-progress adapter

Requires DuckDB 1.5

1199 of 1393 branches covered (86.07%)

Branch coverage included in aggregate %.

6 of 8 new or added lines in 1 file covered. (75.0%)

193 existing lines in 43 files now uncovered.

2336 of 2572 relevant lines covered (90.82%)

557295.56 hits per line

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

80.95
/DuckDB.NET.Data/DuckDBMappedAppender.cs
1
using DuckDB.NET.Data.Mapping;
2

3
namespace DuckDB.NET.Data;
4

5
/// <summary>
6
/// A type-safe appender that uses AppenderMap to validate type mappings.
7
/// </summary>
8
/// <typeparam name="T">The type being appended</typeparam>
9
/// <typeparam name="TMap">The AppenderMap type defining the mappings</typeparam>
10
public class DuckDBMappedAppender<T, TMap> : IDisposable where TMap : DuckDBAppenderMap<T>, new()
11
{
12
    private readonly DuckDBAppender appender;
13
    private readonly List<IPropertyMapping<T>> mappings;
14

15
    internal DuckDBMappedAppender(DuckDBAppender appender)
9✔
16
    {
17
        this.appender = appender;
9✔
18
        var classMap = new TMap();
9✔
19

20
        // Get mappings as List<T> to avoid interface enumerator boxing
21
        mappings = classMap.PropertyMappings;
9✔
22

23
        // Validate mappings match the table structure
24
        if (mappings.Count == 0)
9!
25
        {
UNCOV
26
            throw new InvalidOperationException($"AppenderMap {typeof(TMap).Name} has no property mappings defined");
×
27
        }
28

29
        var columnTypes = appender.LogicalTypes;
9✔
30
        if (mappings.Count != columnTypes.Count)
9!
31
        {
UNCOV
32
            throw new InvalidOperationException($"AppenderMap {typeof(TMap).Name} has {mappings.Count} mappings but table has {columnTypes.Count} columns");
×
33
        }
34

35
        for (int index = 0; index < mappings.Count; index++)
78✔
36
        {
37
            var mapping = mappings[index];
33✔
38

39
            if (mapping.MappingType != PropertyMappingType.Property)
33✔
40
            {
41
                continue;
42
            }
43

44
            var columnType = NativeMethods.LogicalType.DuckDBGetTypeId(columnTypes[index]);
27✔
45
            var expectedType = GetExpectedDuckDBType(mapping.PropertyType);
27✔
46

47
            if (expectedType != columnType)
27✔
48
            {
49
                throw new InvalidOperationException(
3✔
50
                    $"Type mismatch at column index {index}: Mapped type is {mapping.PropertyType.Name} (expected DuckDB type: {expectedType}) but actual column type is {columnType}");
3✔
51
            }
52
        }
53
    }
6✔
54

55
    /// <summary>
56
    /// Appends multiple records to the table.
57
    /// </summary>
58
    /// <param name="records">The records to append</param>
59
    public void AppendRecords(IEnumerable<T> records)
60
    {
61
        if (records == null)
6!
62
        {
UNCOV
63
            throw new ArgumentNullException(nameof(records));
×
64
        }
65

66
        foreach (var record in records)
36✔
67
        {
68
            AppendRecord(record);
12✔
69
        }
70
    }
6✔
71

72
    private void AppendRecord(T record)
73
    {
74
        if (record == null)
12!
75
        {
UNCOV
76
            throw new ArgumentNullException(nameof(record));
×
77
        }
78

79
        var row = appender.CreateRow();
12✔
80

81
        foreach (var mapping in mappings)
120✔
82
        {
83
            row = mapping.AppendToRow(row, record);
48✔
84
        }
85

86
        row.EndRow();
12✔
87
    }
12✔
88

89
    private static DuckDBType GetExpectedDuckDBType(Type type)
90
    {
91
        var underlyingType = Nullable.GetUnderlyingType(type) ?? type;
27✔
92

93
        var duckDBType = underlyingType.GetDuckDBType();
27✔
94

95
        return duckDBType switch
27!
96
        {
27✔
UNCOV
97
            DuckDBType.Invalid => throw new NotSupportedException($"Type {type.Name} is not supported for mapping"),
×
98
            _ => duckDBType
27✔
99
        };
27✔
100
    }
101

102
    /// <summary>
103
    /// Closes the appender and flushes any remaining data.
104
    /// </summary>
105
    public void Close()
106
    {
UNCOV
107
        appender.Close();
×
UNCOV
108
    }
×
109

110
    /// <summary>
111
    /// Disposes the appender.
112
    /// </summary>
113
    public void Dispose()
114
    {
115
        appender.Dispose();
6✔
116
    }
6✔
117
}
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