From 5a5e1e1273bd627ceaf32086a87d09e77ddf8426 Mon Sep 17 00:00:00 2001 From: Giorgi Date: Thu, 14 Sep 2023 00:22:55 +0400 Subject: [PATCH] DuckDBResult class to struct --- DuckDB.NET.Bindings/DuckDBNativeObjects.cs | 34 +----- .../NativeMethods.PreparedStatements.cs | 2 +- .../NativeMethods/NativeMethods.Query.cs | 24 ++-- .../NativeMethods/NativeMethods.Types.cs | 40 +++---- DuckDB.NET.Data/DuckDBCommand.cs | 5 +- DuckDB.NET.Data/DuckDBDataReader.cs | 18 +-- DuckDB.NET.Data/Internal/PreparedStatement.cs | 5 +- DuckDB.NET.Samples/Program.cs | 23 ++-- DuckDB.NET.Test/AppenderTests.cs | 108 +++++++++--------- DuckDB.NET.Test/QueryTests.cs | 18 ++- 10 files changed, 121 insertions(+), 156 deletions(-) diff --git a/DuckDB.NET.Bindings/DuckDBNativeObjects.cs b/DuckDB.NET.Bindings/DuckDBNativeObjects.cs index ab9ec079..08034a49 100644 --- a/DuckDB.NET.Bindings/DuckDBNativeObjects.cs +++ b/DuckDB.NET.Bindings/DuckDBNativeObjects.cs @@ -55,7 +55,7 @@ public enum DuckDBType } [StructLayout(LayoutKind.Sequential)] - public class DuckDBResult : IDisposable + public struct DuckDBResult : IDisposable { [Obsolete] private long ColumnCount; @@ -74,42 +74,12 @@ public class DuckDBResult : IDisposable private IntPtr internal_data; - public static implicit operator DuckDBResultStruct(DuckDBResult d) => d.ToStruct(); - - private DuckDBResultStruct ToStruct() - { - return new DuckDBResultStruct() - { - internal_data = internal_data - }; - } - public void Dispose() { - NativeMethods.Query.DuckDBDestroyResult(this); + NativeMethods.Query.DuckDBDestroyResult(ref this); } } - public struct DuckDBResultStruct - { - [Obsolete] - internal long ColumnCount; - - [Obsolete] - internal long RowCount; - - [Obsolete] - internal long RowsChanged; - - [Obsolete] - internal IntPtr columns; - - [Obsolete] - internal IntPtr ErrorMessage; - - internal IntPtr internal_data; - } - [StructLayout(LayoutKind.Sequential)] public struct DuckDBDate { diff --git a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.PreparedStatements.cs b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.PreparedStatements.cs index 27c0b37f..5ac11c10 100644 --- a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.PreparedStatements.cs +++ b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.PreparedStatements.cs @@ -80,6 +80,6 @@ public static class PreparedStatements public static extern DuckDBState DuckDBBindTimestamp(DuckDBPreparedStatement preparedStatement, long index, DuckDBTimestampStruct val); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_execute_prepared")] - public static extern DuckDBState DuckDBExecutePrepared(DuckDBPreparedStatement preparedStatement, [In, Out] DuckDBResult result); + public static extern DuckDBState DuckDBExecutePrepared(DuckDBPreparedStatement preparedStatement, out DuckDBResult result); } } \ No newline at end of file diff --git a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Query.cs b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Query.cs index 01feafac..2115f32b 100644 --- a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Query.cs +++ b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Query.cs @@ -8,39 +8,39 @@ public partial class NativeMethods public static class Query { [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_query")] - public static extern DuckDBState DuckDBQuery(DuckDBNativeConnection connection, string query, [In, Out] DuckDBResult result); + public static extern DuckDBState DuckDBQuery(DuckDBNativeConnection connection, string query, out DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_query")] - public static extern DuckDBState DuckDBQuery(DuckDBNativeConnection connection, SafeUnmanagedMemoryHandle query, [In, Out] DuckDBResult result); + public static extern DuckDBState DuckDBQuery(DuckDBNativeConnection connection, SafeUnmanagedMemoryHandle query, out DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_destroy_result")] - public static extern void DuckDBDestroyResult([In, Out] DuckDBResult result); + public static extern void DuckDBDestroyResult([In, Out] ref DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_column_name")] - public static extern IntPtr DuckDBColumnName([In, Out] DuckDBResult result, long col); + public static extern IntPtr DuckDBColumnName([In, Out] ref DuckDBResult result, long col); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_column_type")] - public static extern DuckDBType DuckDBColumnType([In, Out] DuckDBResult result, long col); + public static extern DuckDBType DuckDBColumnType([In, Out] ref DuckDBResult result, long col); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_column_logical_type")] - public static extern DuckDBLogicalType DuckDBColumnLogicalType([In, Out] DuckDBResult result, long col); + public static extern DuckDBLogicalType DuckDBColumnLogicalType([In, Out] ref DuckDBResult result, long col); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_column_count")] - public static extern long DuckDBColumnCount([In, Out] DuckDBResult result); + public static extern long DuckDBColumnCount([In, Out] ref DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_row_count")] - public static extern long DuckDBRowCount([In, Out] DuckDBResult result); + public static extern long DuckDBRowCount([In, Out] ref DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_rows_changed")] - public static extern long DuckDBRowsChanged([In, Out] DuckDBResult result); + public static extern long DuckDBRowsChanged([In, Out] ref DuckDBResult result); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_column_data")] - public static extern IntPtr DuckDBColumnData([In, Out] DuckDBResult result, long col); + public static extern IntPtr DuckDBColumnData([In, Out] ref DuckDBResult result, long col); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_nullmask_data")] - public static extern IntPtr DuckDBNullmaskData([In, Out] DuckDBResult result, long col); + public static extern IntPtr DuckDBNullmaskData([In, Out] ref DuckDBResult result, long col); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_result_error")] - public static extern IntPtr DuckDBResultError([In, Out] DuckDBResult result); + public static extern IntPtr DuckDBResultError([In, Out] ref DuckDBResult result); } } \ No newline at end of file diff --git a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Types.cs b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Types.cs index ea4544a0..193e9c55 100644 --- a/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Types.cs +++ b/DuckDB.NET.Bindings/NativeMethods/NativeMethods.Types.cs @@ -8,63 +8,63 @@ public partial class NativeMethods public static class Types { [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_boolean")] - public static extern bool DuckDBValueBoolean([In, Out] DuckDBResult result, long col, long row); + public static extern bool DuckDBValueBoolean([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_int8")] - public static extern sbyte DuckDBValueInt8([In, Out] DuckDBResult result, long col, long row); + public static extern sbyte DuckDBValueInt8([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_int16")] - public static extern short DuckDBValueInt16([In, Out] DuckDBResult result, long col, long row); + public static extern short DuckDBValueInt16([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_int32")] - public static extern int DuckDBValueInt32([In, Out] DuckDBResult result, long col, long row); + public static extern int DuckDBValueInt32([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_int64")] - public static extern long DuckDBValueInt64([In, Out] DuckDBResult result, long col, long row); + public static extern long DuckDBValueInt64([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_decimal")] - public static extern DuckDBDecimal DuckDBValueDecimal([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBDecimal DuckDBValueDecimal([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_uint8")] - public static extern byte DuckDBValueUInt8([In, Out] DuckDBResult result, long col, long row); + public static extern byte DuckDBValueUInt8([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_uint16")] - public static extern ushort DuckDBValueUInt16([In, Out] DuckDBResult result, long col, long row); + public static extern ushort DuckDBValueUInt16([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_uint32")] - public static extern uint DuckDBValueUInt32([In, Out] DuckDBResult result, long col, long row); + public static extern uint DuckDBValueUInt32([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_uint64")] - public static extern ulong DuckDBValueUInt64([In, Out] DuckDBResult result, long col, long row); + public static extern ulong DuckDBValueUInt64([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_float")] - public static extern float DuckDBValueFloat([In, Out] DuckDBResult result, long col, long row); + public static extern float DuckDBValueFloat([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_double")] - public static extern double DuckDBValueDouble([In, Out] DuckDBResult result, long col, long row); + public static extern double DuckDBValueDouble([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_interval")] - public static extern DuckDBInterval DuckDBValueInterval([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBInterval DuckDBValueInterval([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_varchar")] - public static extern IntPtr DuckDBValueVarchar([In, Out] DuckDBResult result, long col, long row); + public static extern IntPtr DuckDBValueVarchar([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_blob")] - public static extern DuckDBBlob DuckDBValueBlob([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBBlob DuckDBValueBlob([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_date")] - public static extern DuckDBDate DuckDBValueDate([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBDate DuckDBValueDate([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_time")] - public static extern DuckDBTime DuckDBValueTime([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBTime DuckDBValueTime([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_value_timestamp")] - public static extern DuckDBTimestampStruct DuckDBValueTimestamp([In, Out] DuckDBResult result, long col, long row); + public static extern DuckDBTimestampStruct DuckDBValueTimestamp([In, Out] ref DuckDBResult result, long col, long row); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_result_get_chunk")] - public static extern DuckDBDataChunk DuckDBResultGetChunk([In, Out] DuckDBResultStruct result, long chunkIndex); + public static extern DuckDBDataChunk DuckDBResultGetChunk([In, Out] DuckDBResult result, long chunkIndex); [DllImport(DuckDbLibrary, CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_result_chunk_count")] - public static extern long DuckDBResultChunkCount([In, Out] DuckDBResultStruct result); + public static extern long DuckDBResultChunkCount([In, Out] DuckDBResult result); } } \ No newline at end of file diff --git a/DuckDB.NET.Data/DuckDBCommand.cs b/DuckDB.NET.Data/DuckDBCommand.cs index 746e07d6..2f6cd549 100644 --- a/DuckDB.NET.Data/DuckDBCommand.cs +++ b/DuckDB.NET.Data/DuckDBCommand.cs @@ -56,9 +56,10 @@ public override int ExecuteNonQuery() var count = 0; - foreach (var result in results) + for (var index = 0; index < results.Count; index++) { - count += (int)NativeMethods.Query.DuckDBRowsChanged(result); + var result = results[index]; + count += (int)NativeMethods.Query.DuckDBRowsChanged(ref result); result.Dispose(); } diff --git a/DuckDB.NET.Data/DuckDBDataReader.cs b/DuckDB.NET.Data/DuckDBDataReader.cs index f43321f9..0725d489 100644 --- a/DuckDB.NET.Data/DuckDBDataReader.cs +++ b/DuckDB.NET.Data/DuckDBDataReader.cs @@ -48,8 +48,8 @@ private void InitReaderData() { currentRow = -1; - rowCount = NativeMethods.Query.DuckDBRowCount(currentResult); - fieldCount = (int)NativeMethods.Query.DuckDBColumnCount(currentResult); + rowCount = NativeMethods.Query.DuckDBRowCount(ref currentResult); + fieldCount = (int)NativeMethods.Query.DuckDBColumnCount(ref currentResult); chunkCount = NativeMethods.Types.DuckDBResultChunkCount(currentResult); currentChunkIndex = 0; @@ -110,7 +110,7 @@ public override long GetChars(int ordinal, long dataOffset, char[] buffer, int b public override string GetDataTypeName(int ordinal) { - return NativeMethods.Query.DuckDBColumnType(currentResult, ordinal).ToString(); + return NativeMethods.Query.DuckDBColumnType(ref currentResult, ordinal).ToString(); } public override DateTime GetDateTime(int ordinal) @@ -137,7 +137,7 @@ private DuckDBTimeOnly GetTimeOnly(int ordinal) public override decimal GetDecimal(int ordinal) { - using (var logicalType = NativeMethods.Query.DuckDBColumnLogicalType(currentResult, ordinal)) + using (var logicalType = NativeMethods.Query.DuckDBColumnLogicalType(ref currentResult, ordinal)) { var scale = NativeMethods.LogicalType.DuckDBDecimalScale(logicalType); var internalType = NativeMethods.LogicalType.DuckDBDecimalInternalType(logicalType); @@ -180,7 +180,7 @@ public override double GetDouble(int ordinal) public override Type GetFieldType(int ordinal) { - return NativeMethods.Query.DuckDBColumnType(currentResult, ordinal) switch + return NativeMethods.Query.DuckDBColumnType(ref currentResult, ordinal) switch { DuckDBType.DuckdbTypeInvalid => throw new DuckDBException("Invalid type"), DuckDBType.DuckdbTypeBoolean => typeof(bool), @@ -263,15 +263,15 @@ private BigInteger GetBigInteger(int ordinal) public override string GetName(int ordinal) { - return NativeMethods.Query.DuckDBColumnName(currentResult, ordinal).ToManagedString(false); + return NativeMethods.Query.DuckDBColumnName(ref currentResult, ordinal).ToManagedString(false); } public override int GetOrdinal(string name) { - var columnCount = NativeMethods.Query.DuckDBColumnCount(currentResult); + var columnCount = NativeMethods.Query.DuckDBColumnCount(ref currentResult); for (var i = 0; i < columnCount; i++) { - var columnName = NativeMethods.Query.DuckDBColumnName(currentResult, i).ToManagedString(false); + var columnName = NativeMethods.Query.DuckDBColumnName(ref currentResult, i).ToManagedString(false); if (name == columnName) { return i; @@ -305,7 +305,7 @@ public override object GetValue(int ordinal) return DBNull.Value; } - return NativeMethods.Query.DuckDBColumnType(currentResult, ordinal) switch + return NativeMethods.Query.DuckDBColumnType(ref currentResult, ordinal) switch { DuckDBType.DuckdbTypeInvalid => throw new DuckDBException("Invalid type"), DuckDBType.DuckdbTypeBoolean => GetBoolean(ordinal), diff --git a/DuckDB.NET.Data/Internal/PreparedStatement.cs b/DuckDB.NET.Data/Internal/PreparedStatement.cs index ecc69810..d8a82bff 100644 --- a/DuckDB.NET.Data/Internal/PreparedStatement.cs +++ b/DuckDB.NET.Data/Internal/PreparedStatement.cs @@ -123,13 +123,12 @@ void CleanUp() public DuckDBResult Execute(DuckDBParameterCollection parameterCollection) { - var queryResult = new DuckDBResult(); BindParameters(statement, parameterCollection); - var status = NativeMethods.PreparedStatements.DuckDBExecutePrepared(statement, queryResult); + var status = NativeMethods.PreparedStatements.DuckDBExecutePrepared(statement, out var queryResult); if (!status.IsSuccess()) { - var errorMessage = NativeMethods.Query.DuckDBResultError(queryResult).ToManagedString(false); + var errorMessage = NativeMethods.Query.DuckDBResultError(ref queryResult).ToManagedString(false); queryResult.Dispose(); throw new DuckDBException(string.IsNullOrEmpty(errorMessage) ? "DuckDBQuery failed" : errorMessage, status); } diff --git a/DuckDB.NET.Samples/Program.cs b/DuckDB.NET.Samples/Program.cs index 5b638dd7..454860b4 100644 --- a/DuckDB.NET.Samples/Program.cs +++ b/DuckDB.NET.Samples/Program.cs @@ -91,15 +91,14 @@ private static void LowLevelBindingsSample() result = Startup.DuckDBConnect(database, out var connection); using (connection) { - var queryResult = new DuckDBResult(); - result = Query.DuckDBQuery(connection, "CREATE TABLE integers(foo INTEGER, bar INTEGER);", null); - result = Query.DuckDBQuery(connection, "INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);", null); - result = Query.DuckDBQuery(connection, "SELECT foo, bar FROM integers", queryResult); + result = Query.DuckDBQuery(connection, "CREATE TABLE integers(foo INTEGER, bar INTEGER);", out _); + result = Query.DuckDBQuery(connection, "INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);", out _); + result = Query.DuckDBQuery(connection, "SELECT foo, bar FROM integers", out var queryResult); PrintQueryResults(queryResult); // clean up - Query.DuckDBDestroyResult(queryResult); + Query.DuckDBDestroyResult(ref queryResult); result = PreparedStatements.DuckDBPrepare(connection, "INSERT INTO integers VALUES (?, ?)", out var insertStatement); @@ -108,7 +107,7 @@ private static void LowLevelBindingsSample() result = PreparedStatements.DuckDBBindInt32(insertStatement, 1, 42); // the parameter index starts counting at 1! result = PreparedStatements.DuckDBBindInt32(insertStatement, 2, 43); - result = PreparedStatements.DuckDBExecutePrepared(insertStatement, null); + result = PreparedStatements.DuckDBExecutePrepared(insertStatement, out _); } @@ -118,13 +117,13 @@ private static void LowLevelBindingsSample() { result = PreparedStatements.DuckDBBindInt32(selectStatement, 1, 42); - result = PreparedStatements.DuckDBExecutePrepared(selectStatement, queryResult); + result = PreparedStatements.DuckDBExecutePrepared(selectStatement, out queryResult); } PrintQueryResults(queryResult); // clean up - Query.DuckDBDestroyResult(queryResult); + Query.DuckDBDestroyResult(ref queryResult); } } } @@ -159,21 +158,21 @@ private static void PrintQueryResults(DbDataReader queryResult) private static void PrintQueryResults(DuckDBResult queryResult) { - var columnCount = Query.DuckDBColumnCount(queryResult); + var columnCount = Query.DuckDBColumnCount(ref queryResult); for (var index = 0; index < columnCount; index++) { - var columnName = Query.DuckDBColumnName(queryResult, index).ToManagedString(false); + var columnName = Query.DuckDBColumnName(ref queryResult, index).ToManagedString(false); Console.Write($"{columnName} "); } Console.WriteLine(); - var rowCount = Query.DuckDBRowCount(queryResult); + var rowCount = Query.DuckDBRowCount(ref queryResult); for (long row = 0; row < rowCount; row++) { for (long column = 0; column < columnCount; column++) { - var val = Types.DuckDBValueInt32(queryResult, column, row); + var val = Types.DuckDBValueInt32(ref queryResult, column, row); Console.Write(val); Console.Write(" "); } diff --git a/DuckDB.NET.Test/AppenderTests.cs b/DuckDB.NET.Test/AppenderTests.cs index 0fcc4f7a..e0054df8 100644 --- a/DuckDB.NET.Test/AppenderTests.cs +++ b/DuckDB.NET.Test/AppenderTests.cs @@ -1,4 +1,3 @@ -using DuckDB.NET; using Xunit; using FluentAssertions; @@ -6,68 +5,67 @@ namespace DuckDB.NET.Test { public class DuckDBAppenderTests { - [Fact] - public void AppenderTests() - { - var result = NativeMethods.Startup.DuckDBOpen(null, out var database); - result.Should().Be(DuckDBState.DuckDBSuccess); + [Fact] + public void AppenderTests() + { + var result = NativeMethods.Startup.DuckDBOpen(null, out var database); + result.Should().Be(DuckDBState.DuckDBSuccess); - result = NativeMethods.Startup.DuckDBConnect(database, out var connection); - result.Should().Be(DuckDBState.DuckDBSuccess); + result = NativeMethods.Startup.DuckDBConnect(database, out var connection); + result.Should().Be(DuckDBState.DuckDBSuccess); - using (database) - using (connection) - { - var table = "CREATE TABLE appenderTest(a BOOLEAN, b TINYINT, c SMALLINT, d INTEGER, e BIGINT, f UTINYINT, g USMALLINT, h UINTEGER, i UBIGINT, j REAL, k DOUBLE, l VARCHAR);"; - result = NativeMethods.Query.DuckDBQuery(connection, table.ToUnmanagedString(), null); - result.Should().Be(DuckDBState.DuckDBSuccess); + using (database) + using (connection) + { + var table = "CREATE TABLE appenderTest(a BOOLEAN, b TINYINT, c SMALLINT, d INTEGER, e BIGINT, f UTINYINT, g USMALLINT, h UINTEGER, i UBIGINT, j REAL, k DOUBLE, l VARCHAR);"; + result = NativeMethods.Query.DuckDBQuery(connection, table.ToUnmanagedString(), out var queryResult); + result.Should().Be(DuckDBState.DuckDBSuccess); - result = NativeMethods.Appender.DuckDBAppenderCreate(connection, null, "appenderTest", out var appender); - result.Should().Be(DuckDBState.DuckDBSuccess); + result = NativeMethods.Appender.DuckDBAppenderCreate(connection, null, "appenderTest", out var appender); + result.Should().Be(DuckDBState.DuckDBSuccess); - var rows = 10; - using (appender) - { - for (var i = 0; i < rows; i++) - { - NativeMethods.Appender.DuckDBAppendBool(appender, i % 2 == 0); - NativeMethods.Appender.DuckDBAppendInt8(appender, (sbyte)i); - NativeMethods.Appender.DuckDBAppendInt16(appender, (short)i); - NativeMethods.Appender.DuckDBAppendInt32(appender, (int)i); - NativeMethods.Appender.DuckDBAppendInt64(appender, (long)i); - NativeMethods.Appender.DuckDBAppendUInt8(appender, (byte)i); - NativeMethods.Appender.DuckDBAppendUInt16(appender, (ushort)i); - NativeMethods.Appender.DuckDBAppendUInt32(appender, (uint)i); - NativeMethods.Appender.DuckDBAppendUInt64(appender, (ulong)i); - NativeMethods.Appender.DuckDBAppendFloat(appender, (float)i); - NativeMethods.Appender.DuckDBAppendDouble(appender, (double)i); - NativeMethods.Appender.DuckDBAppendVarchar(appender, i.ToString().ToUnmanagedString()); - NativeMethods.Appender.DuckDBAppenderEndRow(appender); - } - } + var rows = 10; + using (appender) + { + for (var i = 0; i < rows; i++) + { + NativeMethods.Appender.DuckDBAppendBool(appender, i % 2 == 0); + NativeMethods.Appender.DuckDBAppendInt8(appender, (sbyte)i); + NativeMethods.Appender.DuckDBAppendInt16(appender, (short)i); + NativeMethods.Appender.DuckDBAppendInt32(appender, (int)i); + NativeMethods.Appender.DuckDBAppendInt64(appender, (long)i); + NativeMethods.Appender.DuckDBAppendUInt8(appender, (byte)i); + NativeMethods.Appender.DuckDBAppendUInt16(appender, (ushort)i); + NativeMethods.Appender.DuckDBAppendUInt32(appender, (uint)i); + NativeMethods.Appender.DuckDBAppendUInt64(appender, (ulong)i); + NativeMethods.Appender.DuckDBAppendFloat(appender, (float)i); + NativeMethods.Appender.DuckDBAppendDouble(appender, (double)i); + NativeMethods.Appender.DuckDBAppendVarchar(appender, i.ToString().ToUnmanagedString()); + NativeMethods.Appender.DuckDBAppenderEndRow(appender); + } + } - var queryResult = new DuckDBResult(); - var query = "SELECT * FROM appenderTest"; - result = NativeMethods.Query.DuckDBQuery(connection, query.ToUnmanagedString(), queryResult); - result.Should().Be(DuckDBState.DuckDBSuccess); + var query = "SELECT * FROM appenderTest"; + result = NativeMethods.Query.DuckDBQuery(connection, query.ToUnmanagedString(), out queryResult); + result.Should().Be(DuckDBState.DuckDBSuccess); - var rowCount = NativeMethods.Query.DuckDBRowCount(queryResult); - rowCount.Should().Be(rows); + var rowCount = NativeMethods.Query.DuckDBRowCount(ref queryResult); + rowCount.Should().Be(rows); - for (var i = 0; i < rows; i++) - { - NativeMethods.Types.DuckDBValueBoolean(queryResult, 0, i).Should().Be(i % 2 == 0); - NativeMethods.Types.DuckDBValueInt8(queryResult, 1, i).Should().Be((sbyte)i); - NativeMethods.Types.DuckDBValueInt16(queryResult, 2, i).Should().Be((short)i); - NativeMethods.Types.DuckDBValueInt32(queryResult, 3, i).Should().Be((int)i); - NativeMethods.Types.DuckDBValueInt64(queryResult, 4, i).Should().Be((long)i); - NativeMethods.Types.DuckDBValueFloat(queryResult, 9, i).Should().Be((float)i); - NativeMethods.Types.DuckDBValueDouble(queryResult, 10, i).Should().Be((double)i); - } + for (var i = 0; i < rows; i++) + { + NativeMethods.Types.DuckDBValueBoolean(ref queryResult, 0, i).Should().Be(i % 2 == 0); + NativeMethods.Types.DuckDBValueInt8(ref queryResult, 1, i).Should().Be((sbyte)i); + NativeMethods.Types.DuckDBValueInt16(ref queryResult, 2, i).Should().Be((short)i); + NativeMethods.Types.DuckDBValueInt32(ref queryResult, 3, i).Should().Be((int)i); + NativeMethods.Types.DuckDBValueInt64(ref queryResult, 4, i).Should().Be((long)i); + NativeMethods.Types.DuckDBValueFloat(ref queryResult, 9, i).Should().Be((float)i); + NativeMethods.Types.DuckDBValueDouble(ref queryResult, 10, i).Should().Be((double)i); + } - NativeMethods.Query.DuckDBDestroyResult(queryResult); - } - } + NativeMethods.Query.DuckDBDestroyResult(ref queryResult); + } + } } } diff --git a/DuckDB.NET.Test/QueryTests.cs b/DuckDB.NET.Test/QueryTests.cs index 5856d058..89ff3f3c 100644 --- a/DuckDB.NET.Test/QueryTests.cs +++ b/DuckDB.NET.Test/QueryTests.cs @@ -18,32 +18,30 @@ public void QueryTest() using (connection) { var table = "CREATE TABLE queryTest(a INTEGER, b BOOLEAN);"; - result = NativeMethods.Query.DuckDBQuery(connection, table.ToUnmanagedString(), null); + result = NativeMethods.Query.DuckDBQuery(connection, table.ToUnmanagedString(), out _); result.Should().Be(DuckDBState.DuckDBSuccess); - - var queryResult = new DuckDBResult(); var insert = "INSERT INTO queryTest VALUES (1, TRUE), (2, FALSE), (3, TRUE);"; - result = NativeMethods.Query.DuckDBQuery(connection, insert.ToUnmanagedString(), queryResult); + result = NativeMethods.Query.DuckDBQuery(connection, insert.ToUnmanagedString(), out var queryResult); result.Should().Be(DuckDBState.DuckDBSuccess); - var rowsChanged = NativeMethods.Query.DuckDBRowsChanged(queryResult); + var rowsChanged = NativeMethods.Query.DuckDBRowsChanged(ref queryResult); rowsChanged.Should().Be(3); - NativeMethods.Query.DuckDBDestroyResult(queryResult); + NativeMethods.Query.DuckDBDestroyResult(ref queryResult); var query = "SELECT * FROM queryTest;"; - result = NativeMethods.Query.DuckDBQuery(connection, query.ToUnmanagedString(), queryResult); + result = NativeMethods.Query.DuckDBQuery(connection, query.ToUnmanagedString(), out queryResult); result.Should().Be(DuckDBState.DuckDBSuccess); - var rowCount = NativeMethods.Query.DuckDBRowCount(queryResult); + var rowCount = NativeMethods.Query.DuckDBRowCount(ref queryResult); rowCount.Should().Be(3); - var columnCount = NativeMethods.Query.DuckDBColumnCount(queryResult); + var columnCount = NativeMethods.Query.DuckDBColumnCount(ref queryResult); columnCount.Should().Be(2); - NativeMethods.Query.DuckDBDestroyResult(queryResult); + NativeMethods.Query.DuckDBDestroyResult(ref queryResult); } } }