diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index ac32337..feaaed5 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -72,7 +72,7 @@ jobs:
dotnet build --no-restore --configuration Release
- name: Test
- run: dotnet test -c Release --no-build --logger trx --results-directory "TestResults-${{ matrix.rid }}"
+ run: dotnet test -c Release /p:TestTfmsInParallel=false --logger "console;verbosity=detailed" --no-build --logger trx --results-directory "TestResults-${{ matrix.rid }}"
# - name: Upload dotnet test results
# uses: actions/upload-artifact@v4
diff --git a/README.md b/README.md
index 42c6e14..ddec56d 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,12 @@ A .NET Core binding for [chdb](https://doc.chdb.io) library.


+### Architecture
+
+
+

+
+
### Usage
Running on platforms: linux, osx, windows, and architectures: x64, arm64.
@@ -102,7 +108,7 @@ chdb "select * from system.formats where is_output = 1" PrettyCompact
# Build
```bash
-./update_libchdb.sh [v1.2.1]
+./update_libchdb.sh [v2.0.4]
cp libchdb.so src/chdb/
dotnet build -c Release
dotnet test -c Release
@@ -115,3 +121,4 @@ chdb --version
## Authors
* [Andreas Vilinski](https://github.com/vilinski)
+* [Auxten](https://github.com/auxten)
diff --git a/chdb-dotnet.png b/chdb-dotnet.png
new file mode 100644
index 0000000..4c5083c
Binary files /dev/null and b/chdb-dotnet.png differ
diff --git a/src/chdb/Session.cs b/src/chdb/Session.cs
index fb3c082..5c8bdfb 100644
--- a/src/chdb/Session.cs
+++ b/src/chdb/Session.cs
@@ -21,7 +21,7 @@ public record Session : IDisposable
public void Dispose()
{
- if (!IsTemp && DataPath?.EndsWith("chdb_") == true && Directory.Exists(DataPath))
+ if (IsTemp && DataPath?.EndsWith("chdb_") == true && Directory.Exists(DataPath))
Directory.Delete(DataPath, true);
}
diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs
index cec8f44..3c08703 100644
--- a/test/ChDbTest/ChDbTest.cs
+++ b/test/ChDbTest/ChDbTest.cs
@@ -1,204 +1,211 @@
-namespace ChDb;
-
-[TestClass]
-public class ChDbTest
-{
- [TestMethod]
- public void QueryVersionTest()
- {
- var result = ChDb.Query("select version()");
- Assert.IsNotNull(result);
- Assert.AreEqual(1UL, result.RowsRead);
- Assert.AreEqual(52UL, result.BytesRead);
- Assert.AreEqual("23.10.1.1\n", result.Text);
- Assert.IsNull(result.ErrorMessage);
- Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
- }
-
- [TestMethod]
- public void QueryErrorTest()
- {
- Assert.ThrowsException(() => ChDb.Query(null!));
- // TODO behavior changed in 1.2.1
- var r1 = ChDb.Query("wrong_query");
- Assert.IsNotNull(r1);
- Assert.IsNull(r1.Text);
- Assert.IsNotNull(r1.ErrorMessage);
-
- var r2 = ChDb.Query("wrong_query", "PrettyCompact");
- Assert.IsNotNull(r2);
- Assert.IsNull(r2.Text);
- Assert.IsNotNull(r2.ErrorMessage);
-
- var r3 = ChDb.Query("select version()", "wrong_format");
- Assert.IsNotNull(r3);
- Assert.IsNull(r3.Text);
- StringAssert.Contains(r3.ErrorMessage, "Unknown output format");
- }
-
- [TestMethod]
- public void NoDataTest()
- {
- var result = ChDb.Query("create table x(a UInt8, b UInt8, c UInt8) Engine=Memory");
- Assert.IsNotNull(result);
- Assert.AreEqual(0UL, result.RowsRead);
- Assert.AreEqual(0UL, result.BytesRead);
- Assert.IsNull(result.Text);
- Assert.IsNull(result.ErrorMessage);
- Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
- Assert.IsTrue(0.1 > result.Elapsed.TotalSeconds);
- }
-
- [TestMethod]
- public void EmptyResultTest()
- {
- var result = ChDb.Query("show tables");
- Assert.IsNotNull(result);
- Assert.AreEqual(0UL, result.RowsRead);
- Assert.AreEqual(0UL, result.BytesRead);
- Assert.AreEqual("", result.Text);
- Assert.IsNull(result.ErrorMessage);
- Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
- Assert.IsTrue(0.1 > result.Elapsed.TotalSeconds);
- }
-
- [TestMethod]
- public void RowNumberTest()
- {
- var result = ChDb.Query("SELECT * FROM numbers(10)");
- Assert.IsNotNull(result);
- Assert.AreEqual(10UL, result.RowsRead);
- }
-
- [TestMethod]
- public void FormatTest()
- {
- Assert.AreEqual("1\t2\t3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c")!.Text);
- Assert.AreEqual("1,2,3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSV")!.Text);
- Assert.AreEqual("\"a\",\"b\",\"c\"\n1,2,3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSVWithNames")!.Text);
- StringAssert.Contains(ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSVWithNamesAndTypes")!.Text, "UInt8");
- }
-
- [TestMethod]
- public void InMemoryTest()
- {
- var sql =
- """
- create table test (a UInt8, b UInt8, c UInt8) Engine=Memory;
- insert into test values (1, 2, 3);
- select * from test; show tables;
- drop table test;show tables
- """;
- var result = ChDb.Query(sql);
- Assert.IsNotNull(result);
- Assert.AreEqual("", result.Text);
- Assert.AreEqual(null, result.ErrorMessage);
- }
-
- [TestMethod]
- public void S3ParquetTest()
- {
- var result = ChDb.Query("DESCRIBE s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')");
- Assert.IsNotNull(result);
- Assert.IsNull(result.ErrorMessage);
- StringAssert.StartsWith(result.Text, "price\tNullable(Int64)");
- }
-
- [TestMethod]
- public void S3CountTest()
- {
- var result = ChDb.Query(
- """
- SELECT count()
- FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')
- """);
- Assert.IsNotNull(result);
- Assert.IsNull(result.ErrorMessage);
- Assert.IsTrue(int.TryParse(result.Text, out var count));
- Assert.AreEqual(2772030, count);
- }
-
- [TestMethod]
- public void CsvTest()
- {
- var csv = """
- Name, Age, City
- John, 25, New York
- Alice, 30, London
- Bob, 22, Tokyo
- Eva, 28, Paris
- """;
- var dataPath = "/tmp/chdb/data";
- Directory.CreateDirectory(dataPath);
- File.WriteAllText(Path.Combine(".", "test.csv"), csv);
- var session = new Session
- {
- Format = "PrettyCompact",
- DataPath = dataPath,
- LogLevel = "trace",
- };
- var result = session.Query("SELECT * FROM 'test.csv'", "CSVWithNamesAndTypes");
- Assert.IsNotNull(result);
- Assert.AreEqual(4UL, result.RowsRead);
- Assert.AreEqual(155UL, result.BytesRead);
- StringAssert.StartsWith(result.Text,
- """
- "Name","Age","City"
- """);
- }
-
- [TestMethod]
- public void SessionTest()
- {
- using var s = new Session
- {
- Format = "PrettyCompact",
- LogLevel = "trace",
- };
- var nr = "xyz";
-
- Assert.IsNull(s.Query($"select version()")?.ErrorMessage);
-
- // chdb creates "_local" database instead of "default" in clickhouse
- StringAssert.Contains(s.Query($"SHOW DATABASES")?.Text, "_local");
- StringAssert.Contains(s.Query($"SELECT currentDatabase()")?.Text, "_local");
- Assert.AreEqual("", s.Query($"SHOW TABLES")?.Text);
-
- var r1 = s.Query($"DROP DATABASE IF EXISTS db_{nr}");
- Assert.IsNotNull(r1);
- Assert.IsNull(r1.Text);
- Assert.IsNull(r1.ErrorMessage);
-
- var r2 = s.Query($"CREATE DATABASE IF NOT EXISTS db_{nr} ENGINE = Atomic");
- Assert.IsNotNull(r2);
- Assert.IsNull(r2.Text);
- Assert.IsNull(r2.ErrorMessage);
-
- var r3 = s.Query($"CREATE TABLE IF NOT EXISTS db_{nr}.log_table_{nr} (x String, y Int) ENGINE = Log;");
- Assert.IsNotNull(r3);
- Assert.IsNull(r3.Text);
- Assert.IsNull(r3.ErrorMessage);
-
- var r4 = s.Query($"INSERT INTO db_{nr}.log_table_{nr} VALUES ('a', 1), ('b', 3), ('c', 2), ('d', 5);");
- Assert.IsNotNull(r4);
- Assert.IsNull(r4.Text);
- Assert.IsNull(r4.ErrorMessage);
-
- var r5 = s.Query($"SELECT * FROM db_{nr}.log_table_{nr}", "TabSeparatedWithNames");
- Assert.IsNotNull(r5);
- Assert.AreEqual("x\ty\na\t1\nb\t3\nc\t2\nd\t5\n", r5.Text);
- Assert.IsNull(r5.ErrorMessage);
-
- var r6 = s.Query($"CREATE VIEW db_{nr}.view_{nr} AS SELECT * FROM db_{nr}.log_table_{nr} LIMIT 4;");
- Assert.IsNotNull(r6);
- Assert.IsNull(r6.Text);
- Assert.IsNull(r6.ErrorMessage);
-
- var r7 = s.Query($"SELECT * FROM db_{nr}.view_{nr}", "TabSeparatedWithNames");
- Assert.IsNotNull(r7);
- Assert.AreEqual("x\ty\na\t1\nb\t3\nc\t2\nd\t5\n", r7.Text);
- Assert.IsNull(r7.ErrorMessage);
-
- s.Query($"DROP DATABASE IF EXISTS db_{nr}");
- }
-}
\ No newline at end of file
+namespace ChDb;
+
+[TestClass]
+public class ChDbTest
+{
+ [TestMethod]
+ public void QueryVersionTest()
+ {
+ var result = ChDb.Query("select version()");
+ Assert.IsNotNull(result);
+ Assert.AreEqual(1UL, result.RowsRead);
+ Assert.AreEqual(50UL, result.BytesRead);
+ Assert.AreEqual("24.5.1.1\n", result.Text);
+ Assert.IsNull(result.ErrorMessage);
+ Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
+ }
+
+ [TestMethod]
+ public void QueryErrorTest()
+ {
+ Assert.ThrowsException(() => ChDb.Query(null!));
+ // TODO behavior changed in 1.2.1
+ var r1 = ChDb.Query("wrong_query");
+ Assert.IsNotNull(r1);
+ Assert.IsNull(r1.Text);
+ Assert.IsNotNull(r1.ErrorMessage);
+
+ var r2 = ChDb.Query("wrong_query", "PrettyCompact");
+ Assert.IsNotNull(r2);
+ Assert.IsNull(r2.Text);
+ Assert.IsNotNull(r2.ErrorMessage);
+
+ var r3 = ChDb.Query("select version()", "wrong_format");
+ Assert.IsNotNull(r3);
+ Assert.IsNull(r3.Text);
+ StringAssert.Contains(r3.ErrorMessage, "Unknown output format");
+ }
+
+ [TestMethod]
+ public void NoDataTest()
+ {
+ var result = ChDb.Query("create table x(a UInt8, b UInt8, c UInt8) Engine=Memory");
+ Assert.IsNotNull(result);
+ Assert.AreEqual(0UL, result.RowsRead);
+ Assert.AreEqual(0UL, result.BytesRead);
+ Assert.IsNull(result.Text);
+ Assert.IsNull(result.ErrorMessage);
+ Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
+ Assert.IsTrue(0.1 > result.Elapsed.TotalSeconds);
+ }
+
+ [TestMethod]
+ public void EmptyResultTest()
+ {
+ var result = ChDb.Query("show tables");
+ Assert.IsNotNull(result);
+ Assert.AreEqual(0UL, result.RowsRead);
+ Assert.AreEqual(0UL, result.BytesRead);
+ Assert.AreEqual("", result.Text);
+ Assert.IsNull(result.ErrorMessage);
+ Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed);
+ Assert.IsTrue(0.1 > result.Elapsed.TotalSeconds);
+ }
+
+ [TestMethod]
+ public void RowNumberTest()
+ {
+ var result = ChDb.Query("SELECT * FROM numbers(10)");
+ Assert.IsNotNull(result);
+ Assert.AreEqual(10UL, result.RowsRead);
+ }
+
+ [TestMethod]
+ public void FormatTest()
+ {
+ Assert.AreEqual("1\t2\t3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c")!.Text);
+ Assert.AreEqual("1,2,3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSV")!.Text);
+ Assert.AreEqual("\"a\",\"b\",\"c\"\n1,2,3\n", ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSVWithNames")!.Text);
+ StringAssert.Contains(ChDb.Query("SELECT 1 as a, 2 b, 3 c", "CSVWithNamesAndTypes")!.Text, "UInt8");
+ }
+
+ [TestMethod]
+ public void InMemoryTest()
+ {
+ var sql =
+ """
+ create table test (a UInt8, b UInt8, c UInt8) Engine=Memory;
+ insert into test values (1, 2, 3);
+ select * from test; show tables;
+ drop table test;show tables
+ """;
+ var result = ChDb.Query(sql);
+ Assert.IsNotNull(result);
+ Assert.AreEqual("", result.Text);
+ Assert.AreEqual(null, result.ErrorMessage);
+ }
+
+ [TestMethod]
+ public void S3ParquetTest()
+ {
+ var result = ChDb.Query("DESCRIBE s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')");
+ Assert.IsNotNull(result);
+ Assert.IsNull(result.ErrorMessage);
+ StringAssert.StartsWith(result.Text, "price\tNullable(Int64)");
+ }
+
+ [TestMethod]
+ public void S3CountTest()
+ {
+ var result = ChDb.Query(
+ """
+ SELECT count()
+ FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')
+ """);
+ Assert.IsNotNull(result);
+ Assert.IsNull(result.ErrorMessage);
+ Assert.IsTrue(int.TryParse(result.Text, out var count));
+ Assert.AreEqual(2772030, count);
+ }
+
+ [TestMethod]
+ public void CsvTest()
+ {
+ var csv = """
+ Name, Age, City
+ John, 25, New York
+ Alice, 30, London
+ Bob, 22, Tokyo
+ Eva, 28, Paris
+ """;
+ var dataPath = "/tmp/chdb/data";
+ if (Directory.Exists(dataPath))
+ Directory.Delete(dataPath, true);
+ Directory.CreateDirectory(dataPath);
+ File.WriteAllText(Path.Combine(".", "test.csv"), csv);
+ using var session = new Session
+ {
+ IsTemp = false,
+ Format = "PrettyCompact",
+ DataPath = dataPath,
+ LogLevel = "trace",
+ };
+ var result = session.Query("SELECT * FROM 'test.csv'", "CSVWithNamesAndTypes");
+ // Console.WriteLine($"Error message:\n{result?.ErrorMessage}");
+ // Console.WriteLine($"Query result:\n{result?.Text}");
+ Assert.IsNotNull(result);
+ Assert.AreEqual(4UL, result.RowsRead);
+ Assert.AreEqual(155UL, result.BytesRead);
+ StringAssert.StartsWith(result.Text,
+ """
+ "Name","Age","City"
+ """);
+ }
+
+ [TestMethod]
+ public void SessionTest()
+ {
+ using var s = new Session
+ {
+ Format = "PrettyCompact",
+ LogLevel = "trace",
+ };
+ var nr = "xyz";
+
+ var result = s.Query($"select version()");
+ // Console.WriteLine($"Error message:\n{result?.ErrorMessage}");
+ // Console.WriteLine($"Query result:\n{result?.Text}");
+ Assert.IsNull(s.Query($"select version()")?.ErrorMessage);
+
+ StringAssert.Contains(s.Query($"SHOW DATABASES")?.Text, "default");
+ StringAssert.Contains(s.Query($"SELECT currentDatabase()")?.Text, "default");
+ Assert.AreEqual("", s.Query($"SHOW TABLES")?.Text);
+
+ var r1 = s.Query($"DROP DATABASE IF EXISTS db_{nr}");
+ Assert.IsNotNull(r1);
+ Assert.IsNull(r1.Text);
+ Assert.IsNull(r1.ErrorMessage);
+
+ var r2 = s.Query($"CREATE DATABASE IF NOT EXISTS db_{nr} ENGINE = Atomic");
+ Assert.IsNotNull(r2);
+ Assert.IsNull(r2.Text);
+ Assert.IsNull(r2.ErrorMessage);
+
+ var r3 = s.Query($"CREATE TABLE IF NOT EXISTS db_{nr}.log_table_{nr} (x String, y Int) ENGINE = Log;");
+ Assert.IsNotNull(r3);
+ Assert.IsNull(r3.Text);
+ Assert.IsNull(r3.ErrorMessage);
+
+ var r4 = s.Query($"INSERT INTO db_{nr}.log_table_{nr} VALUES ('a', 1), ('b', 3), ('c', 2), ('d', 5);");
+ Assert.IsNotNull(r4);
+ Assert.IsNull(r4.Text);
+ Assert.IsNull(r4.ErrorMessage);
+
+ var r5 = s.Query($"SELECT * FROM db_{nr}.log_table_{nr}", "TabSeparatedWithNames");
+ Assert.IsNotNull(r5);
+ Assert.AreEqual("x\ty\na\t1\nb\t3\nc\t2\nd\t5\n", r5.Text);
+ Assert.IsNull(r5.ErrorMessage);
+
+ var r6 = s.Query($"CREATE VIEW db_{nr}.view_{nr} AS SELECT * FROM db_{nr}.log_table_{nr} LIMIT 4;");
+ Assert.IsNotNull(r6);
+ Assert.IsNull(r6.Text);
+ Assert.IsNull(r6.ErrorMessage);
+
+ var r7 = s.Query($"SELECT * FROM db_{nr}.view_{nr}", "TabSeparatedWithNames");
+ Assert.IsNotNull(r7);
+ Assert.AreEqual("x\ty\na\t1\nb\t3\nc\t2\nd\t5\n", r7.Text);
+ Assert.IsNull(r7.ErrorMessage);
+
+ s.Query($"DROP DATABASE IF EXISTS db_{nr}");
+ }
+}
diff --git a/update_libchdb.sh b/update_libchdb.sh
index 8d7a2ea..f5d84d4 100755
--- a/update_libchdb.sh
+++ b/update_libchdb.sh
@@ -23,7 +23,8 @@ case "$(uname -s)" in
esac
# Get the newest release version
-LATEST_RELEASE=$(curl --silent "https://api.github.com/repos/chdb-io/chdb/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+# LATEST_RELEASE=$(curl --silent "https://api.github.com/repos/chdb-io/chdb/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+LATEST_RELEASE=v2.0.4
RELEASE=${1:-$LATEST_RELEASE}
DOWNLOAD_URL="https://github.com/chdb-io/chdb/releases/download/$RELEASE/$PLATFORM-libchdb.tar.gz"