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

Giorgi / DuckDB.NET / 12084884944

29 Nov 2024 12:37PM UTC coverage: 89.839% (-0.04%) from 89.881%
12084884944

push

github

Giorgi
Rename conflicting table function

1055 of 1209 branches covered (87.26%)

Branch coverage included in aggregate %.

2075 of 2275 relevant lines covered (91.21%)

824654.22 hits per line

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

97.13
/DuckDB.NET.Data/DuckDBDataReader.cs
1
using DuckDB.NET.Data.Internal.Reader;
2
using DuckDB.NET.Native;
3
using System;
4
using System.Collections;
5
using System.Collections.Generic;
6
using System.Data;
7
using System.Data.Common;
8
using System.IO;
9

10
namespace DuckDB.NET.Data;
11

12
public class DuckDBDataReader : DbDataReader
13
{
14
    private readonly DuckDBCommand command;
15
    private readonly CommandBehavior behavior;
16

17
    private DuckDBResult currentResult;
18
    private DuckDBDataChunk? currentChunk;
19

20
    private int fieldCount;
21

22
    private ulong currentChunkRowCount;
23
    private ulong rowsReadFromCurrentChunk;
24

25
    private bool closed;
26
    private bool hasRows;
27
    private bool streamingResult;
28
    private long currentChunkIndex;
29

30
    private readonly IEnumerator<DuckDBResult> resultEnumerator;
31
    private VectorDataReaderBase[] vectorReaders = [];
63,987✔
32
    private Dictionary<string, int> columnMapping = [];
63,987✔
33

34
    internal DuckDBDataReader(DuckDBCommand command, IEnumerable<DuckDBResult> queryResults, CommandBehavior behavior)
63,987✔
35
    {
36
        this.command = command;
63,987✔
37
        this.behavior = behavior;
63,987✔
38
        resultEnumerator = queryResults.GetEnumerator();
63,987✔
39

40
        InitNextReader();
63,987✔
41
    }
63,975✔
42

43
    private bool InitNextReader()
44
    {
45
        while (resultEnumerator.MoveNext())
64,191✔
46
        {
47
            if (NativeMethods.Query.DuckDBResultReturnType(resultEnumerator.Current) == DuckDBResultType.QueryResult)
63,987✔
48
            {
49
                currentChunkIndex = 0;
63,981✔
50
                currentResult = resultEnumerator.Current;
63,981✔
51

52
                columnMapping = [];
63,981✔
53
                fieldCount = (int)NativeMethods.Query.DuckDBColumnCount(ref currentResult);
63,981✔
54
                streamingResult = NativeMethods.Types.DuckDBResultIsStreaming(currentResult) > 0;
63,981✔
55

56
                hasRows = InitChunkData();
63,981✔
57

58
                return true;
63,981✔
59
            }
60
        }
61

62
        return false;
189✔
63
    }
64

65
    private bool InitChunkData()
66
    {
67
        unsafe
68
        {
69
            foreach (var reader in vectorReaders)
131,358✔
70
            {
71
                reader.Dispose();
1,170✔
72
            }
73

74
            currentChunk?.Dispose();
64,509✔
75
            currentChunk = streamingResult ? NativeMethods.StreamingResult.DuckDBStreamFetchChunk(currentResult) : NativeMethods.Types.DuckDBResultGetChunk(currentResult, currentChunkIndex);
64,509✔
76

77
            rowsReadFromCurrentChunk = 0;
64,509✔
78

79
            currentChunkRowCount = NativeMethods.DataChunks.DuckDBDataChunkGetSize(currentChunk);
64,509✔
80

81
            if (vectorReaders.Length != fieldCount)
64,509✔
82
            {
83
                vectorReaders = new VectorDataReaderBase[fieldCount];
63,972✔
84
            }
85

86
            for (int index = 0; index < fieldCount; index++)
277,272✔
87
            {
88
                var vector = NativeMethods.DataChunks.DuckDBDataChunkGetVector(currentChunk, index);
74,127✔
89

90
                using var logicalType = NativeMethods.Query.DuckDBColumnLogicalType(ref currentResult, index);
74,127✔
91

92
                vectorReaders[index] = VectorDataReaderFactory.CreateReader(vector, logicalType, vectorReaders[index]?.ColumnName ??
74,127✔
93
                                                                            NativeMethods.Query.DuckDBColumnName(ref currentResult, index).ToManagedString(false));
74,127✔
94
            }
95

96
            if (columnMapping.Count == 0)
64,509✔
97
            {
98
                for (var i = 0; i < vectorReaders.Length; i++)
273,894✔
99
                {
100
                    if (!columnMapping.ContainsKey(vectorReaders[i].ColumnName))
72,966✔
101
                    {
102
                        columnMapping.Add(vectorReaders[i].ColumnName, i);
72,963✔
103
                    }
104
                }
105
            }
106

107
            return currentChunkRowCount > 0;
64,509✔
108
        }
109
    }
110

111
    public override bool GetBoolean(int ordinal)
112
    {
113
        return GetFieldValue<bool>(ordinal);
9✔
114
    }
115

116
    public override byte GetByte(int ordinal)
117
    {
118
        return GetFieldValue<byte>(ordinal);
18✔
119
    }
120

121
    public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int bufferOffset, int length)
122
    {
123
        throw new NotImplementedException();
×
124
    }
125

126
    public override char GetChar(int ordinal)
127
    {
128
        throw new NotSupportedException();
×
129
    }
130

131
    public override long GetChars(int ordinal, long dataOffset, char[]? buffer, int bufferOffset, int length)
132
    {
133
        throw new NotSupportedException();
×
134
    }
135

136
    public override string GetDataTypeName(int ordinal)
137
    {
138
        return vectorReaders[ordinal].DuckDBType.ToString();
6✔
139
    }
140

141
    public override DateTime GetDateTime(int ordinal)
142
    {
143
        return GetFieldValue<DateTime>(ordinal);
27✔
144
    }
145

146
    public override decimal GetDecimal(int ordinal)
147
    {
148
        return GetFieldValue<decimal>(ordinal);
357✔
149
    }
150

151
    public override double GetDouble(int ordinal)
152
    {
153
        return GetFieldValue<double>(ordinal);
3✔
154
    }
155

156
    public override Type GetFieldType(int ordinal)
157
    {
158
        return vectorReaders[ordinal].ClrType;
32,157✔
159
    }
160

161
    public override Type GetProviderSpecificFieldType(int ordinal)
162
    {
163
        return vectorReaders[ordinal].ProviderSpecificClrType;
117✔
164
    }
165

166
    public override float GetFloat(int ordinal)
167
    {
168
        return GetFieldValue<float>(ordinal);
3✔
169
    }
170

171
    public override Guid GetGuid(int ordinal)
172
    {
173
        return GetFieldValue<Guid>(ordinal);
12✔
174
    }
175

176
    public override short GetInt16(int ordinal)
177
    {
178
        return GetFieldValue<short>(ordinal);
18✔
179
    }
180

181
    public override int GetInt32(int ordinal)
182
    {
183
        return GetFieldValue<int>(ordinal);
30,048✔
184
    }
185

186
    public override long GetInt64(int ordinal)
187
    {
188
        return GetFieldValue<long>(ordinal);
18✔
189
    }
190

191
    public override string GetName(int ordinal)
192
    {
193
        return vectorReaders[ordinal].ColumnName;
942✔
194
    }
195

196
    public override int GetOrdinal(string name)
197
    {
198
        if (columnMapping.TryGetValue(name, out var index))
180✔
199
        {
200
            return index;
174✔
201
        }
202

203
        throw new DuckDBException($"Column with name {name} was not found.");
6✔
204
    }
205

206
    public override string GetString(int ordinal)
207
    {
208
        return GetFieldValue<string>(ordinal);
30,042✔
209
    }
210

211
    public override T GetFieldValue<T>(int ordinal)
212
    {
213
        CheckRowRead();
872,463✔
214

215
        return vectorReaders[ordinal].GetValue<T>(rowsReadFromCurrentChunk - 1);
872,460✔
216
    }
217

218
    public override object GetValue(int ordinal)
219
    {
220
        CheckRowRead();
186,234✔
221

222
        return IsDBNull(ordinal) ? DBNull.Value : vectorReaders[ordinal].GetValue(rowsReadFromCurrentChunk - 1);
186,231✔
223
    }
224

225
    public override object GetProviderSpecificValue(int ordinal)
226
    {
227
        CheckRowRead();
132✔
228

229
        return IsDBNull(ordinal) ? DBNull.Value : vectorReaders[ordinal].GetProviderSpecificValue(rowsReadFromCurrentChunk - 1);
132✔
230
    }
231

232
    public override int GetValues(object[] values)
233
    {
234
        for (var i = 0; i < FieldCount; i++)
3,546✔
235
        {
236
            values[i] = GetValue(i);
1,242✔
237
        }
238

239
        return FieldCount;
531✔
240
    }
241

242
    public override Stream GetStream(int ordinal)
243
    {
244
        return GetFieldValue<Stream>(ordinal);
27✔
245
    }
246

247
    public override bool IsDBNull(int ordinal)
248
    {
249
        CheckRowRead();
246,588✔
250

251
        return !vectorReaders[ordinal].IsValid(rowsReadFromCurrentChunk - 1);
246,585✔
252
    }
253

254
    public override int FieldCount => fieldCount;
2,994✔
255

256
    public override object this[int ordinal] => GetValue(ordinal);
46,932✔
257

258
    public override object this[string name] => GetValue(GetOrdinal(name));
3✔
259

260
    public override int RecordsAffected => -1;
×
261

262
    public override bool HasRows => hasRows;
18✔
263

264
    public override bool IsClosed => closed;
81✔
265

266
    public override bool NextResult()
267
    {
268
        return InitNextReader();
198✔
269
    }
270

271
    public override bool Read()
272
    {
273
        if (rowsReadFromCurrentChunk == currentChunkRowCount)
510,498✔
274
        {
275
            currentChunkIndex++;
528✔
276
            var hasData = InitChunkData();
528✔
277

278
            if (hasData)
528✔
279
            {
280
                rowsReadFromCurrentChunk++;
111✔
281
            }
282

283
            return hasData;
528✔
284
        }
285
        else
286
        {
287
            rowsReadFromCurrentChunk++;
509,970✔
288

289
            return true;
509,970✔
290
        }
291
    }
292

293
    public override int Depth { get; }
×
294

295
    public override IEnumerator GetEnumerator()
296
    {
297
        return new DbEnumerator(this, behavior == CommandBehavior.CloseConnection);
3✔
298
    }
299

300
    public override DataTable GetSchemaTable()
301
    {
302
        var table = new DataTable
45✔
303
        {
45✔
304
            Columns =
45✔
305
            {
45✔
306
                { SchemaTableColumn.ColumnName, typeof(string) },
45✔
307
                { SchemaTableColumn.ColumnOrdinal, typeof(int) },
45✔
308
                { SchemaTableColumn.ColumnSize, typeof(int) },
45✔
309
                { SchemaTableColumn.NumericPrecision, typeof(byte)},
45✔
310
                { SchemaTableColumn.NumericScale, typeof(byte) },
45✔
311
                { SchemaTableColumn.DataType, typeof(Type) },
45✔
312
                { SchemaTableColumn.AllowDBNull, typeof(bool)  }
45✔
313
            }
45✔
314
        };
45✔
315

316
        var rowData = new object[7];
45✔
317

318
        for (var i = 0; i < FieldCount; i++)
636✔
319
        {
320
            rowData[0] = GetName(i);
273✔
321
            rowData[1] = i;
273✔
322
            rowData[2] = -1;
273✔
323
            rowData[5] = GetFieldType(i);
273✔
324
            rowData[6] = true;
273✔
325

326
            if (vectorReaders[i] is DecimalVectorDataReader decimalVectorDataReader)
273✔
327
            {
328
                rowData[4] = decimalVectorDataReader.Scale;
6✔
329
                rowData[3] = decimalVectorDataReader.Precision;
6✔
330
            }
331
            else
332
            {
333
                rowData[3] = rowData[4] = DBNull.Value;
267✔
334
            }
335

336
            table.Rows.Add(rowData);
273✔
337
        }
338

339
        return table;
45✔
340
    }
341

342
    public override void Close()
343
    {
344
        if (closed) return;
63,489✔
345

346
        foreach (var reader in vectorReaders)
254,748✔
347
        {
348
            reader.Dispose();
63,963✔
349
        }
350

351
        currentChunk?.Dispose();
63,411✔
352

353
        if (behavior == CommandBehavior.CloseConnection)
63,411✔
354
        {
355
            command.CloseConnection();
6✔
356
        }
357

358
        closed = true;
63,411✔
359
        resultEnumerator.Dispose();
63,411✔
360
    }
63,411✔
361

362
    private void CheckRowRead()
363
    {
364
        if (rowsReadFromCurrentChunk <= 0)
1,305,417✔
365
        {
366
            throw new InvalidOperationException("No row has been read");
9✔
367
        }
368
    }
1,305,408✔
369
}
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