• 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

90.59
/DuckDB.NET.Data/DuckDBAppender.cs
1
using DuckDB.NET.Data.Common;
2
using DuckDB.NET.Data.DataChunk.Writer;
3
using System.Diagnostics;
4
using System.Diagnostics.CodeAnalysis;
5

6
namespace DuckDB.NET.Data;
7

8
public class DuckDBAppender : IDisposable
9
{
10
    private bool closed;
11
    private readonly Native.DuckDBAppender nativeAppender;
12
    private readonly string qualifiedTableName;
13

14
    private ulong rowCount;
15

16
    private readonly DuckDBLogicalType[] logicalTypes;
17
    private readonly DuckDBDataChunk dataChunk;
18
    private readonly VectorDataWriterBase[] vectorWriters;
19

20
    internal DuckDBAppender(Native.DuckDBAppender appender, string qualifiedTableName)
195✔
21
    {
22
        nativeAppender = appender;
195✔
23
        this.qualifiedTableName = qualifiedTableName;
195✔
24

25
        var columnCount = NativeMethods.Appender.DuckDBAppenderColumnCount(nativeAppender);
195✔
26

27
        vectorWriters = new VectorDataWriterBase[columnCount];
195✔
28
        logicalTypes = new DuckDBLogicalType[columnCount];
195✔
29
        var logicalTypeHandles = new IntPtr[columnCount];
195✔
30

31
        for (ulong index = 0; index < columnCount; index++)
1,680✔
32
        {
33
            logicalTypes[index] = NativeMethods.Appender.DuckDBAppenderColumnType(nativeAppender, index);
645✔
34
            logicalTypeHandles[index] = logicalTypes[index].DangerousGetHandle();
645✔
35
        }
36

37
        dataChunk = NativeMethods.DataChunks.DuckDBCreateDataChunk(logicalTypeHandles, columnCount);
195✔
38
    }
195✔
39

40
    /// <summary>
41
    /// Gets the logical types of the columns in the appender.
42
    /// </summary>
43
    internal IReadOnlyList<DuckDBLogicalType> LogicalTypes => logicalTypes;
9✔
44

45
    public IDuckDBAppenderRow CreateRow()
46
    {
47
        if (closed)
429,993✔
48
        {
49
            throw new InvalidOperationException("Appender is already closed");
3✔
50
        }
51

52
        if (rowCount % DuckDBGlobalData.VectorSize == 0)
429,990✔
53
        {
54
            AppendDataChunk();
282✔
55

56
            InitVectorWriters();
282✔
57

58
            rowCount = 0;
282✔
59
        }
60

61
        rowCount++;
429,990✔
62
        return new DuckDBAppenderRow(qualifiedTableName, vectorWriters, rowCount - 1, dataChunk, nativeAppender);
429,990✔
63
    }
64

65
    public void Clear()
66
    {
67
        if (closed)
6!
68
        {
NEW
69
            throw new InvalidOperationException("Appender is already closed");
×
70
        }
71
        
72
        var state = NativeMethods.Appender.DuckDBAppenderClear(nativeAppender);
6✔
73
        if (!state.IsSuccess())
6!
74
        {
NEW
75
            ThrowLastError(nativeAppender);
×
76
        }
77

78
        rowCount = 0;
6✔
79
        NativeMethods.DataChunks.DuckDBDataChunkReset(dataChunk);
6✔
80
    }
6✔
81

82
    public void Close()
83
    {
84
        closed = true;
189✔
85

86
        try
87
        {
88
            AppendDataChunk();
189✔
89

90
            foreach (var logicalType in logicalTypes)
1,626✔
91
            {
92
                logicalType.Dispose();
624✔
93
            }
94

95
            foreach (var writer in vectorWriters)
1,626✔
96
            {
97
                writer?.Dispose();
624✔
98
            }
99

100
            dataChunk.Dispose();
189✔
101

102
            var state = NativeMethods.Appender.DuckDBAppenderClose(nativeAppender);
189✔
103
            if (!state.IsSuccess())
189!
104
            {
UNCOV
105
                ThrowLastError(nativeAppender);
×
106
            }
107
        }
189✔
108
        finally
109
        {
110
            nativeAppender.Close();
189✔
111
        }
189✔
112
    }
189✔
113

114
    public void Dispose()
115
    {
116
        if (!closed)
186✔
117
        {
118
            Close();
180✔
119
        }
120
    }
186✔
121

122
    private void InitVectorWriters()
123
    {
124
        for (long index = 0; index < vectorWriters.LongLength; index++)
2,250✔
125
        {
126
            var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(dataChunk, index);
843✔
127

128
            vectorWriters[index]?.Dispose();
843✔
129
            vectorWriters[index] = VectorDataWriterFactory.CreateWriter(vector, logicalTypes[index]);
843✔
130
        }
131
    }
282✔
132

133
    private void AppendDataChunk()
134
    {
135
        NativeMethods.DataChunks.DuckDBDataChunkSetSize(dataChunk, rowCount);
471✔
136
        var state = NativeMethods.Appender.DuckDBAppendDataChunk(nativeAppender, dataChunk);
471✔
137

138
        if (!state.IsSuccess())
471!
139
        {
UNCOV
140
            ThrowLastError(nativeAppender);
×
141
        }
142

143
        NativeMethods.DataChunks.DuckDBDataChunkReset(dataChunk);
471✔
144
    }
471✔
145

146
    [DoesNotReturn]
147
    [StackTraceHidden]
148
    internal static void ThrowLastError(Native.DuckDBAppender appender)
149
    {
150
        var errorMessage = NativeMethods.Appender.DuckDBAppenderError(appender).ToManagedString(false);
3✔
151

152
        throw new DuckDBException(errorMessage);
3✔
153
    }
154
}
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