From 70ff4c79aa5bd402e60cdb2ab61a51734808470a Mon Sep 17 00:00:00 2001 From: Auxten Wang Date: Thu, 8 May 2025 16:44:24 +0800 Subject: [PATCH 01/10] Fix libchdb to v2.1.1 for now --- update_libchdb.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/update_libchdb.sh b/update_libchdb.sh index 8d7a2ea..a153210 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.1.1 RELEASE=${1:-$LATEST_RELEASE} DOWNLOAD_URL="https://github.com/chdb-io/chdb/releases/download/$RELEASE/$PLATFORM-libchdb.tar.gz" From 2d7185af295b27d37dc2f2a504efb25c1787bc41 Mon Sep 17 00:00:00 2001 From: Auxten Wang Date: Thu, 8 May 2025 16:48:52 +0800 Subject: [PATCH 02/10] Update ChDbTest.cs --- test/ChDbTest/ChDbTest.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs index cec8f44..6dd1022 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -159,9 +159,8 @@ public void SessionTest() 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"); + 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}"); @@ -201,4 +200,4 @@ public void SessionTest() s.Query($"DROP DATABASE IF EXISTS db_{nr}"); } -} \ No newline at end of file +} From 202defe43adf68c1e5f3526b2d3e2856f0a47c11 Mon Sep 17 00:00:00 2001 From: Auxten Wang Date: Thu, 8 May 2025 16:53:45 +0800 Subject: [PATCH 03/10] Update ChDbTest.cs --- test/ChDbTest/ChDbTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs index 6dd1022..b979021 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -9,8 +9,8 @@ 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.AreEqual(52UL, result.BytesRead); + Assert.AreEqual("24.8.4.1\n", result.Text); Assert.IsNull(result.ErrorMessage); Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed); } @@ -140,7 +140,7 @@ public void CsvTest() var result = session.Query("SELECT * FROM 'test.csv'", "CSVWithNamesAndTypes"); Assert.IsNotNull(result); Assert.AreEqual(4UL, result.RowsRead); - Assert.AreEqual(155UL, result.BytesRead); + // Assert.AreEqual(155UL, result.BytesRead); StringAssert.StartsWith(result.Text, """ "Name","Age","City" From f29337cbf3de0ea84e362da80c3907f6c2a57dd0 Mon Sep 17 00:00:00 2001 From: Auxten Wang Date: Thu, 8 May 2025 17:02:11 +0800 Subject: [PATCH 04/10] Update ChDbTest.cs --- test/ChDbTest/ChDbTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs index b979021..e3c22cb 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -8,7 +8,7 @@ public void QueryVersionTest() { var result = ChDb.Query("select version()"); Assert.IsNotNull(result); - Assert.AreEqual(1UL, result.RowsRead); + // Assert.AreEqual(1UL, result.RowsRead); // Assert.AreEqual(52UL, result.BytesRead); Assert.AreEqual("24.8.4.1\n", result.Text); Assert.IsNull(result.ErrorMessage); @@ -139,7 +139,7 @@ public void CsvTest() }; var result = session.Query("SELECT * FROM 'test.csv'", "CSVWithNamesAndTypes"); Assert.IsNotNull(result); - Assert.AreEqual(4UL, result.RowsRead); + // Assert.AreEqual(4UL, result.RowsRead); // Assert.AreEqual(155UL, result.BytesRead); StringAssert.StartsWith(result.Text, """ From 6d9a7d4f27cdad2630b91be8db2e19e9f047c62c Mon Sep 17 00:00:00 2001 From: auxten Date: Thu, 8 May 2025 17:39:29 +0800 Subject: [PATCH 05/10] Add arch diagram --- README.md | 9 ++++++++- chdb-dotnet.png | Bin 0 -> 89088 bytes 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 chdb-dotnet.png diff --git a/README.md b/README.md index 42c6e14..9162e0e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,12 @@ A .NET Core binding for [chdb](https://doc.chdb.io) library. ![NuGet Version](https://img.shields.io/nuget/vpre/chdb) ![NuGet Downloads](https://img.shields.io/nuget/dt/chdb) +### 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.1.1] 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 0000000000000000000000000000000000000000..4c5083c09af1c9e79b18a0c3668322fe28928612 GIT binary patch literal 89088 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≻x-m$N2JYbB|JCpuK#WZeUe}AAbir^H9S`xHH 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 literal 0 HcmV?d00001 From 34fe654e0381d6c2d306466e8e9076f1670fa8c3 Mon Sep 17 00:00:00 2001 From: wudidapaopao Date: Thu, 8 May 2025 19:02:04 +0800 Subject: [PATCH 06/10] Update ChDbTest.cs --- .github/workflows/dotnet.yml | 4 +- src/chdb/Session.cs | 2 +- test/ChDbTest/ChDbTest.cs | 414 ++++++++++++++++++----------------- update_libchdb.sh | 5 +- 4 files changed, 217 insertions(+), 208 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ac32337..dfc5383 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: include: - - os: ubuntu-latest + - os: ubuntu-22.04 rid: linux-x64 - os: macos-latest rid: osx-x64 @@ -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/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 e3c22cb..a04febd 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -1,203 +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("24.8.4.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); - - 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}"); - } -} +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.8.4.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 message111:\n{result?.ErrorMessage}"); + Console.WriteLine($"Query result111:\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 message222:\n{result?.ErrorMessage}"); + Console.WriteLine($"Query result222:\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 a153210..a1cdf21 100755 --- a/update_libchdb.sh +++ b/update_libchdb.sh @@ -23,8 +23,9 @@ 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=v2.1.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.1.1 +LATEST_RELEASE=v3.2.0 RELEASE=${1:-$LATEST_RELEASE} DOWNLOAD_URL="https://github.com/chdb-io/chdb/releases/download/$RELEASE/$PLATFORM-libchdb.tar.gz" From 5cec0b63f5c2868717e59adc04e58ac778f4cff6 Mon Sep 17 00:00:00 2001 From: wudidapaopao Date: Fri, 9 May 2025 02:18:36 +0800 Subject: [PATCH 07/10] Update ChDbTest.cs --- .github/workflows/dotnet.yml | 2 +- test/ChDbTest/ChDbTest.cs | 24 ++++++++++++------------ update_libchdb.sh | 3 +-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index dfc5383..feaaed5 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: include: - - os: ubuntu-22.04 + - os: ubuntu-latest rid: linux-x64 - os: macos-latest rid: osx-x64 diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs index a04febd..a4da454 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -95,14 +95,14 @@ public void InMemoryTest() 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 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() @@ -141,8 +141,8 @@ public void CsvTest() LogLevel = "trace", }; var result = session.Query("SELECT * FROM 'test.csv'", "CSVWithNamesAndTypes"); - Console.WriteLine($"Error message111:\n{result?.ErrorMessage}"); - Console.WriteLine($"Query result111:\n{result?.Text}"); + // 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); @@ -163,8 +163,8 @@ public void SessionTest() var nr = "xyz"; var result = s.Query($"select version()"); - Console.WriteLine($"Error message222:\n{result?.ErrorMessage}"); - Console.WriteLine($"Query result222:\n{result?.Text}"); + // 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"); diff --git a/update_libchdb.sh b/update_libchdb.sh index a1cdf21..cf07a84 100755 --- a/update_libchdb.sh +++ b/update_libchdb.sh @@ -24,8 +24,7 @@ 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=v2.1.1 -LATEST_RELEASE=v3.2.0 +LATEST_RELEASE=v2.1.1 RELEASE=${1:-$LATEST_RELEASE} DOWNLOAD_URL="https://github.com/chdb-io/chdb/releases/download/$RELEASE/$PLATFORM-libchdb.tar.gz" From 30afa986d5e738d882ed9ba1b5fae1ccdf9309d3 Mon Sep 17 00:00:00 2001 From: wudidapaopao Date: Fri, 9 May 2025 11:52:25 +0800 Subject: [PATCH 08/10] Update update_libchdb.sh --- update_libchdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update_libchdb.sh b/update_libchdb.sh index cf07a84..f5d84d4 100755 --- a/update_libchdb.sh +++ b/update_libchdb.sh @@ -24,7 +24,7 @@ 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=v2.1.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" From bf85849a065519176a37b28eb15422ce6c34a1b5 Mon Sep 17 00:00:00 2001 From: wudidapaopao Date: Fri, 9 May 2025 11:56:01 +0800 Subject: [PATCH 09/10] Update ChDbTest.cs --- test/ChDbTest/ChDbTest.cs | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/ChDbTest/ChDbTest.cs b/test/ChDbTest/ChDbTest.cs index a4da454..3c08703 100644 --- a/test/ChDbTest/ChDbTest.cs +++ b/test/ChDbTest/ChDbTest.cs @@ -10,7 +10,7 @@ public void QueryVersionTest() Assert.IsNotNull(result); Assert.AreEqual(1UL, result.RowsRead); Assert.AreEqual(50UL, result.BytesRead); - Assert.AreEqual("24.8.4.1\n", result.Text); + Assert.AreEqual("24.5.1.1\n", result.Text); Assert.IsNull(result.ErrorMessage); Assert.AreNotEqual(TimeSpan.Zero, result.Elapsed); } @@ -95,28 +95,28 @@ public void InMemoryTest() 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 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() From eeb8ca360fe8f208b82d55be52f185da7f4eb39f Mon Sep 17 00:00:00 2001 From: wudidapaopao Date: Fri, 9 May 2025 12:06:43 +0800 Subject: [PATCH 10/10] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9162e0e..ddec56d 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ chdb "select * from system.formats where is_output = 1" PrettyCompact # Build ```bash -./update_libchdb.sh [v2.1.1] +./update_libchdb.sh [v2.0.4] cp libchdb.so src/chdb/ dotnet build -c Release dotnet test -c Release