Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
008c5ed
refactor: move the example-aot project to the proper folder
RaphDal Oct 16, 2025
31f2972
feat: add BufferV3 and support for DECIMAL column values in IBuffer i…
RaphDal Oct 16, 2025
e509af7
feat: add support for decimal
RaphDal Oct 17, 2025
af2acea
Merge branch 'main' into rd_decimal
RaphDal Oct 17, 2025
16635e9
fix: update Buffer creation for ProtocolVersion.Auto to use BufferV3
RaphDal Oct 17, 2025
ea890c8
typo: fix typo in readme
RaphDal Oct 17, 2025
cfdb79e
📝 Add docstrings to `rd_decimal`
coderabbitai[bot] Oct 17, 2025
c9492d7
refactor: replace direct byte comparison with WaitAssert for improved…
RaphDal Oct 17, 2025
4850e7f
fix: handle null value in Column method of ISender interface
RaphDal Oct 17, 2025
5319a31
fix: handle null values in DECIMAL case of JsonSpecTestRunner
RaphDal Oct 17, 2025
e85fd36
refactor: remove unused using directive for System.Runtime.InteropSer…
RaphDal Oct 17, 2025
079195e
refactor: improve XML documentation for Buffer and IBuffer interfaces
RaphDal Oct 17, 2025
d9cd6d1
Merge pull request #53 from questdb/coderabbitai/docstrings/ea890c8
RaphDal Oct 17, 2025
92eadc4
fix: handle nullable decimal values in BufferV3
RaphDal Oct 17, 2025
6564091
fix: fix culture in dummy servers.
RaphDal Oct 17, 2025
d2b5163
refactor: enhance XML documentation across Buffer classes and senders
RaphDal Oct 17, 2025
3bf58c8
Update src/net-questdb-client/Senders/ISender.cs
RaphDal Oct 17, 2025
89d923c
Update src/net-questdb-client/Buffers/BufferV3.cs
RaphDal Oct 17, 2025
82a07fc
Update src/net-questdb-client/Senders/HttpSender.cs
RaphDal Oct 17, 2025
81db9f5
fix: correct error message wording for invalid table and column names
RaphDal Oct 17, 2025
c20de68
fix: ensure two's complement conversion is unchecked for negative man…
RaphDal Oct 17, 2025
b59e1ce
fix: improve buffer management in BufferV1 by resetting line start le…
RaphDal Oct 17, 2025
1be64bc
fix: update timestamp in TcpTests to use a specific date for consistency
RaphDal Oct 17, 2025
1495cb1
fix: update TcpTests to use AtNowAsync for current timestamp in test …
RaphDal Oct 20, 2025
bc20a0d
fix: don't write column when the value is null
RaphDal Oct 24, 2025
331083e
test: add BufferTests for decimal negation scenarios
RaphDal Oct 24, 2025
b8900c5
fix: correct expected output for DecimalNegationBoundaryCarry test case
RaphDal Nov 11, 2025
804f855
chore: update subproject commit reference in questdb-client-test
RaphDal Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 34 additions & 33 deletions README.md

Large diffs are not rendered by default.

8 changes: 1 addition & 7 deletions net-questdb-client.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net-questdb-client", "src\net-questdb-client\net-questdb-client.csproj", "{456B1860-0102-48D7-861A-5F9963F3887B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tcp-client-test", "src\tcp-client-test\tcp-client-test.csproj", "{22F903D9-4367-46A2-A25A-F4A6BF9105C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-basic", "src\example-basic\example-basic.csproj", "{121EAA4D-3A73-468C-8CAB-A2A4BEF848CF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-auth-tls", "src\example-auth-tls\example-auth-tls.csproj", "{FBB8181C-6BAB-46C2-A47A-D3566A3997FE}"
Expand All @@ -21,7 +19,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-streaming", "src\ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-auth-http-tls", "src\example-auth-http-tls\example-auth-http-tls.csproj", "{24D93DBB-3783-423F-81CC-6B9BFD33F6CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-aot", "example-aot\example-aot.csproj", "{5341FCF0-F71D-4160-8D6E-B5EFDF92E9E8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-aot", "src\example-aot\example-aot.csproj", "{5341FCF0-F71D-4160-8D6E-B5EFDF92E9E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -36,10 +34,6 @@ Global
{456B1860-0102-48D7-861A-5F9963F3887B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{456B1860-0102-48D7-861A-5F9963F3887B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{456B1860-0102-48D7-861A-5F9963F3887B}.Release|Any CPU.Build.0 = Release|Any CPU
{22F903D9-4367-46A2-A25A-F4A6BF9105C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22F903D9-4367-46A2-A25A-F4A6BF9105C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22F903D9-4367-46A2-A25A-F4A6BF9105C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22F903D9-4367-46A2-A25A-F4A6BF9105C6}.Release|Any CPU.Build.0 = Release|Any CPU
{121EAA4D-3A73-468C-8CAB-A2A4BEF848CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{121EAA4D-3A73-468C-8CAB-A2A4BEF848CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{121EAA4D-3A73-468C-8CAB-A2A4BEF848CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
26 changes: 13 additions & 13 deletions src/dummy-http-server/DummyHttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ public DummyHttpServer(bool withTokenAuth = false, bool withBasicAuth = false, b
.AddConsole();
});

IlpEndpoint.WithTokenAuth = withTokenAuth;
IlpEndpoint.WithBasicAuth = withBasicAuth;
IlpEndpoint.WithTokenAuth = withTokenAuth;
IlpEndpoint.WithBasicAuth = withBasicAuth;
IlpEndpoint.WithRetriableError = withRetriableError;
IlpEndpoint.WithErrorMessage = withErrorMessage;
IlpEndpoint.WithErrorMessage = withErrorMessage;
_withStartDelay = withStartDelay;

if (withTokenAuth)
Expand Down Expand Up @@ -113,7 +113,7 @@ public void Clear()
IlpEndpoint.ReceiveBuffer.Clear();
IlpEndpoint.ReceiveBytes.Clear();
IlpEndpoint.LastError = null;
IlpEndpoint.Counter = 0;
IlpEndpoint.Counter = 0;
}

public async Task StartAsync(int port = 29743, int[]? versions = null)
Expand All @@ -122,10 +122,10 @@ public async Task StartAsync(int port = 29743, int[]? versions = null)
{
await Task.Delay(_withStartDelay.Value);
}
versions ??= new[] { 1, 2, };
SettingsEndpoint.Versions = versions;
_port = port;
_app.RunAsync($"http://localhost:{port}");
versions ??= new[] { 1, 2, 3, };
SettingsEndpoint.Versions = versions;
_port = port;
_ = _app.RunAsync($"http://localhost:{port}");
}

public async Task RunAsync()
Expand All @@ -143,7 +143,7 @@ public StringBuilder GetReceiveBuffer()
return IlpEndpoint.ReceiveBuffer;
}

public List<byte> GetReceiveBytes()
public List<byte> GetReceivedBytes()
{
return IlpEndpoint.ReceiveBytes;
}
Expand All @@ -167,7 +167,7 @@ public async Task<bool> Healthcheck()
var jwtToken = JwtBearer.CreateToken(o =>
{
o.SigningKey = SigningKey;
o.ExpireAt = DateTime.UtcNow.AddDays(1);
o.ExpireAt = DateTime.UtcNow.AddDays(1);
});
return jwtToken;
}
Expand All @@ -182,8 +182,8 @@ public int GetCounter()

public string PrintBuffer()
{
var bytes = GetReceiveBytes().ToArray();
var sb = new StringBuilder();
var bytes = GetReceivedBytes().ToArray();
var sb = new StringBuilder();
var lastAppend = 0;

var i = 0;
Expand Down Expand Up @@ -252,7 +252,7 @@ public string PrintBuffer()
i--;
break;
default:
throw new NotImplementedException();
throw new NotImplementedException($"Type {bytes[i]} not implemented");
}

lastAppend = i + 1;
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\src\net-questdb-client\net-questdb-client.csproj"/>
<ProjectReference Include="..\net-questdb-client\net-questdb-client.csproj"/>
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/net-questdb-client-benchmarks/BenchInserts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
using BenchmarkDotNet.Attributes;
using dummy_http_server;
using QuestDB;
using tcp_client_test;
using net_questdb_client_tests;

#pragma warning disable CS0414 // Field is assigned but its value is never used

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

<ItemGroup>
<ProjectReference Include="..\dummy-http-server\dummy-http-server.csproj"/>
<ProjectReference Include="..\net-questdb-client-tests\net-questdb-client-tests.csproj" />
<ProjectReference Include="..\net-questdb-client\net-questdb-client.csproj"/>
<ProjectReference Include="..\tcp-client-test\tcp-client-test.csproj"/>
</ItemGroup>

<ItemGroup>
Expand Down
71 changes: 71 additions & 0 deletions src/net-questdb-client-tests/DecimalTestHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2024 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/

using System.Text;
using NUnit.Framework;
using QuestDB.Enums;

namespace net_questdb_client_tests;

internal static class DecimalTestHelpers
{
internal static void AssertDecimalField(ReadOnlySpan<byte> buffer,
string columnName,
byte expectedScale,
ReadOnlySpan<byte> expectedMantissa)
{
var payload = ExtractDecimalPayload(buffer, columnName);
Assert.That(payload.Length,
Is.GreaterThanOrEqualTo(4 + expectedMantissa.Length),
$"Decimal field `{columnName}` payload shorter than expected.");
Assert.That(payload[0], Is.EqualTo((byte)'='));
Assert.That(payload[1], Is.EqualTo((byte)BinaryFormatType.DECIMAL));
Assert.That(payload[2], Is.EqualTo(expectedScale), $"Unexpected scale for `{columnName}`.");
Assert.That(payload[3],
Is.EqualTo((byte)expectedMantissa.Length),
$"Unexpected mantissa length for `{columnName}`.");
CollectionAssert.AreEqual(expectedMantissa.ToArray(), payload.Slice(4, expectedMantissa.Length).ToArray(),
$"Mantissa bytes for `{columnName}` did not match expectation.");
}

internal static void AssertDecimalNullField(ReadOnlySpan<byte> buffer, string columnName)
{
var payload = ExtractDecimalPayload(buffer, columnName);
Assert.That(payload.Length,
Is.GreaterThanOrEqualTo(4),
$"Decimal field `{columnName}` payload shorter than expected.");
Assert.That(payload[0], Is.EqualTo((byte)'='));
Assert.That(payload[1], Is.EqualTo((byte)BinaryFormatType.DECIMAL));
Assert.That(payload[2], Is.EqualTo(0), $"Unexpected scale for `{columnName}`.");
Assert.That(payload[3], Is.EqualTo(0), $"Unexpected mantissa length for `{columnName}`.");
}

private static ReadOnlySpan<byte> ExtractDecimalPayload(ReadOnlySpan<byte> buffer, string columnName)
{
var prefix = Encoding.ASCII.GetBytes($"{columnName}=");
var index = buffer.IndexOf(prefix.AsSpan());
Assert.That(index, Is.GreaterThanOrEqualTo(0), $"Column `{columnName}` not found in payload.");
return buffer[(index + prefix.Length)..];
}
}
28 changes: 16 additions & 12 deletions src/net-questdb-client-tests/DummyIlpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class DummyIlpServer : IDisposable

public DummyIlpServer(int port, bool tls)
{
_tls = tls;
_tls = tls;
_server = new TcpListener(IPAddress.Loopback, port);
_server.Start();
}
Expand All @@ -77,7 +77,7 @@ private async Task AcceptConnections()
using var socket = await _server.AcceptSocketAsync();
clientSocket = socket;
await using var connection = new NetworkStream(socket, true);
Stream dataStream = connection;
Stream dataStream = connection;
if (_tls)
{
var sslStream = new SslStream(connection);
Expand Down Expand Up @@ -137,7 +137,7 @@ private async Task RunServerAuth(Stream connection)
var pubKey1 = FromBase64String(_publicKeyX);
var pubKey2 = FromBase64String(_publicKeyY);

var p = SecNamedCurves.GetByName("secp256r1");
var p = SecNamedCurves.GetByName("secp256r1");
var parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);

// Verify the signature
Expand Down Expand Up @@ -168,8 +168,8 @@ private static string Pad(string text)
public static byte[] FromBase64String(string encodedPrivateKey)
{
var replace = encodedPrivateKey
.Replace('-', '+')
.Replace('_', '/');
.Replace('-', '+')
.Replace('_', '/');
return Convert.FromBase64String(Pad(replace));
}

Expand All @@ -178,7 +178,7 @@ private async Task<int> ReceiveUntilEol(Stream connection)
var len = 0;
while (true)
{
var n = await connection.ReadAsync(_buffer.AsMemory(len));
var n = await connection.ReadAsync(_buffer.AsMemory(len));
var inBuffer = len + n;
for (var i = len; i < inBuffer; i++)
{
Expand Down Expand Up @@ -226,13 +226,17 @@ private async Task SaveData(Stream connection, Socket socket)
public string GetTextReceived()
{
return PrintBuffer();
// return Encoding.UTF8.GetString(_received.GetBuffer(), 0, (int)_received.Length);
}

public byte[] GetReceivedBytes()
{
return _received.ToArray();
}

public string PrintBuffer()
{
var bytes = _received.GetBuffer().AsSpan().Slice(0, (int)_received.Length).ToArray();
var sb = new StringBuilder();
var bytes = _received.ToArray();
var sb = new StringBuilder();
var lastAppend = 0;

var i = 0;
Expand All @@ -258,7 +262,7 @@ public string PrintBuffer()
for (var j = 0; j < dims; j++)
{
var lengthBytes = bytes.AsSpan()[i..(i + 4)];
var _length = MemoryMarshal.Cast<byte, uint>(lengthBytes)[0];
var _length = MemoryMarshal.Cast<byte, uint>(lengthBytes)[0];
if (length == 0)
{
length = _length;
Expand Down Expand Up @@ -301,7 +305,7 @@ public string PrintBuffer()
i--;
break;
default:
throw new NotImplementedException();
throw new NotImplementedException("Unknown type: " + bytes[i]);
}

lastAppend = i + 1;
Expand All @@ -315,7 +319,7 @@ public string PrintBuffer()

public void WithAuth(string keyId, string publicKeyX, string publicKeyY)
{
_keyId = keyId;
_keyId = keyId;
_publicKeyX = publicKeyX;
_publicKeyY = publicKeyY;
}
Expand Down
Loading