Skip to content

Commit 10c7e82

Browse files
committed
add .NET client test
1 parent 9856e7c commit 10c7e82

7 files changed

Lines changed: 166 additions & 0 deletions

File tree

testing/postgres-client-tests/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ node/node_modules/
44
elixir/postgrex/_build
55
elixir/postgrex/mix.lock
66
elixir/postgrex/dep
7+
dotnet/bin
8+
dotnet/obj
9+
dotnet/out

testing/postgres-client-tests/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ RUN pip3 install --no-cache-dir --target /build/python-deps sqlalchemy==2.0.46
6464
COPY testing/postgres-client-tests/python/ /build/python/
6565
WORKDIR /build/python/
6666

67+
# --- Build .NET Npgsql client ---
68+
FROM mcr.microsoft.com/dotnet/sdk:9.0-bookworm-slim AS dotnet_clients_build
69+
COPY testing/postgres-client-tests/dotnet/ /build/dotnet/
70+
WORKDIR /build/dotnet
71+
RUN dotnet publish -c Release -o /build/output/
72+
6773
# --- Runtime ---
6874
FROM debian:bookworm-slim
6975

@@ -100,10 +106,18 @@ RUN apt-get install -y \
100106
postgresql-client-15 \
101107
nodejs \
102108
elixir \
109+
libicu-dev \
103110
git && \
104111
update-ca-certificates -f && \
105112
rm -rf /var/lib/apt/lists/*
106113

114+
# install .NET
115+
RUN curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh \
116+
&& chmod +x dotnet-install.sh \
117+
&& ./dotnet-install.sh --channel 9.0 --runtime aspnetcore --install-dir /usr/share/dotnet \
118+
&& ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
119+
&& rm dotnet-install.sh
120+
107121
# cpan dependencies
108122
RUN cpanm --force DBD::Pg
109123

@@ -125,6 +139,7 @@ COPY --from=go_clients_build /build/bin/pgx-test /build/bin/go/pgx-test
125139
COPY --from=go_clients_build /build/bin/libpq-test /build/bin/go/libpq-test
126140
COPY --from=rust_clients_build /build/rust/target/release/sqlx_exists_demo /build/bin/rust/sqlx_exists_demo
127141
COPY --from=c_clients_build /build/c/postgres-c-connector-test /build/bin/c/postgres-c-connector-test
142+
COPY --from=dotnet_clients_build /build/output /build/bin/dotnet
128143
COPY --from=node_clients_build /build/node/ /postgres-client-tests/node/
129144
COPY --from=python_clients_build /build/python/ /postgres-client-tests/python/
130145
COPY --from=python_clients_build /build/python-deps/ /usr/local/lib/python-deps/
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using Npgsql;
2+
3+
var user = args[0];
4+
var port = args[1];
5+
6+
var connStr = $"Host=localhost;Port={port};Username={user};Password=password;Database=postgres;SSL Mode=Disable";
7+
await using var conn = new NpgsqlConnection(connStr);
8+
await conn.OpenAsync();
9+
10+
// Basic SELECT
11+
await using (var cmd = new NpgsqlCommand("SELECT pk FROM test_table LIMIT 1", conn))
12+
{
13+
var pk = (int)(await cmd.ExecuteScalarAsync())!;
14+
if (pk != 1)
15+
throw new Exception($"expected pk=1, got {pk}");
16+
}
17+
18+
// INSERT
19+
await using (var cmd = new NpgsqlCommand("INSERT INTO test_table VALUES (2)", conn))
20+
await cmd.ExecuteNonQueryAsync();
21+
22+
// COUNT
23+
await using (var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM test_table", conn))
24+
{
25+
var count = (long)(await cmd.ExecuteScalarAsync())!;
26+
if (count != 2)
27+
throw new Exception($"expected count=2, got {count}");
28+
}
29+
30+
// Prepared SELECT
31+
await using (var cmd = new NpgsqlCommand("SELECT pk FROM test_table WHERE pk = $1", conn))
32+
{
33+
cmd.Parameters.AddWithValue(1);
34+
await cmd.PrepareAsync();
35+
var pk = (int)(await cmd.ExecuteScalarAsync())!;
36+
if (pk != 1)
37+
throw new Exception($"expected pk=1 from prepared stmt, got {pk}");
38+
}
39+
40+
// Dolt workflow: create table, insert, commit, branch, insert, commit, merge
41+
foreach (var q in new[]
42+
{
43+
"DROP TABLE IF EXISTS test",
44+
"CREATE TABLE test (pk int, value int, PRIMARY KEY(pk))",
45+
"INSERT INTO test (pk, value) VALUES (0, 0)",
46+
"SELECT dolt_add('-A')",
47+
"SELECT dolt_commit('-m', 'added table test')",
48+
"SELECT dolt_checkout('-b', 'mybranch')",
49+
"INSERT INTO test VALUES (1, 1)",
50+
"SELECT dolt_commit('-a', '-m', 'updated test')",
51+
"SELECT dolt_checkout('main')",
52+
"SELECT dolt_merge('mybranch')",
53+
})
54+
{
55+
await using var cmd = new NpgsqlCommand(q, conn);
56+
await cmd.ExecuteNonQueryAsync();
57+
}
58+
59+
await RunPreparedQuery(
60+
"SELECT pk, value FROM test WHERE pk = $1",
61+
[0],
62+
async r =>
63+
{
64+
if (!await r.ReadAsync()) throw new Exception("no rows");
65+
var pk = r.GetInt32(0);
66+
var value = r.GetInt32(1);
67+
if (pk != 0 || value != 0)
68+
throw new Exception($"expected pk=0 value=0, got pk={pk} value={value}");
69+
});
70+
71+
await RunPreparedQuery(
72+
"SELECT COUNT(*) FROM dolt_log",
73+
[],
74+
async r =>
75+
{
76+
if (!await r.ReadAsync()) throw new Exception("no rows");
77+
var size = r.GetInt64(0);
78+
if (size != 4)
79+
throw new Exception($"expected 4 dolt_log entries, got {size}");
80+
});
81+
82+
await RunPreparedQuery(
83+
"SELECT COUNT(*) FROM test",
84+
[],
85+
async r =>
86+
{
87+
if (!await r.ReadAsync()) throw new Exception("no rows");
88+
var size = r.GetInt64(0);
89+
if (size != 2)
90+
throw new Exception($"expected 2 rows in test, got {size}");
91+
});
92+
93+
Console.WriteLine("Npgsql test passed");
94+
95+
async Task RunPreparedQuery(string query, object[] queryArgs, Func<NpgsqlDataReader, Task> check)
96+
{
97+
await using var cmd = new NpgsqlCommand(query, conn);
98+
foreach (var arg in queryArgs)
99+
cmd.Parameters.AddWithValue(arg);
100+
await cmd.PrepareAsync();
101+
await using var reader = await cmd.ExecuteReaderAsync();
102+
await check(reader);
103+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<AssemblyName>npgsql-test</AssemblyName>
8+
<InvariantGlobalization>true</InvariantGlobalization>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<PackageReference Include="Npgsql" Version="9.0.3" />
12+
</ItemGroup>
13+
</Project>

testing/postgres-client-tests/go/libpq/main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2026 Dolthub, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package main
216

317
import (

testing/postgres-client-tests/go/pgx/main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2026 Dolthub, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package main
216

317
import (

testing/postgres-client-tests/postgres-client-tests.bats

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,7 @@ teardown() {
110110
@test "go lib/pq client" {
111111
/build/bin/go/libpq-test $USER $PORT
112112
}
113+
114+
@test "dotnet Npgsql client" {
115+
/build/bin/dotnet/npgsql-test $USER $PORT
116+
}

0 commit comments

Comments
 (0)