diff --git a/.github/workflows/linux-cxx20-vcpkg.yaml b/.github/workflows/linux-cxx20-vcpkg.yaml index 6adda0e2..e51347c8 100644 --- a/.github/workflows/linux-cxx20-vcpkg.yaml +++ b/.github/workflows/linux-cxx20-vcpkg.yaml @@ -60,6 +60,22 @@ jobs: - compiler: gcc compiler-version: 14 db: mysql + - compiler: llvm + compiler-version: 16 + db: duckdb + - compiler: llvm + compiler-version: 18 + db: duckdb + - compiler: gcc + compiler-version: 11 + additional-dep: "g++-11" + db: duckdb + - compiler: gcc + compiler-version: 12 + db: duckdb + - compiler: gcc + compiler-version: 14 + db: duckdb name: "${{ github.job }} (${{ matrix.compiler }}-${{ matrix.compiler-version }}-${{ matrix.db }})" concurrency: group: ci-${{ github.ref }}-${{ github.job }}-${{ matrix.compiler }}-${{ matrix.compiler-version }}-${{ matrix.db }} @@ -101,7 +117,22 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF + cmake --build build + - name: Compile + if: matrix.db == 'duckdb' + run: | + if [[ "${{ matrix.compiler }}" == "llvm" ]]; then + export CC=clang-${{ matrix.compiler-version }} + export CXX=clang++-${{ matrix.compiler-version }} + elif [[ "${{ matrix.compiler }}" == "gcc" ]]; then + export CC=gcc-${{ matrix.compiler-version }} + export CXX=g++-${{ matrix.compiler-version }} + fi + sudo ln -s $(which ccache) /usr/local/bin/$CC + sudo ln -s $(which ccache) /usr/local/bin/$CXX + $CXX --version + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_DUCKDB=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF cmake --build build - name: Compile if: matrix.db == 'sqlite' @@ -116,7 +147,7 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_CHECK_HEADERS=ON + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_CHECK_HEADERS=ON cmake --build build - name: Compile if: matrix.db == 'mysql' @@ -131,7 +162,7 @@ jobs: sudo ln -s $(which ccache) /usr/local/bin/$CC sudo ln -s $(which ccache) /usr/local/bin/$CXX $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-linux-dynamic + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-linux-dynamic cmake --build build - name: Set up postgres if: matrix.db == 'postgres' diff --git a/.github/workflows/macos-cxx20-vcpkg.yaml b/.github/workflows/macos-cxx20-vcpkg.yaml index b4e7c376..31b2a936 100644 --- a/.github/workflows/macos-cxx20-vcpkg.yaml +++ b/.github/workflows/macos-cxx20-vcpkg.yaml @@ -18,12 +18,8 @@ jobs: db: sqlite - os: "macos-latest" db: mysql - - os: "macos-13" - db: postgres - - os: "macos-13" - db: sqlite - - os: "macos-13" - db: mysql + - os: "macos-latest" + db: duckdb name: "${{ github.job }} (${{ matrix.os }}-${{ matrix.db }})" concurrency: group: ci-${{ github.ref }}-${{ github.job }}-${{ matrix.os }}-${{ matrix.db }} @@ -50,8 +46,21 @@ jobs: - name: Run vcpkg uses: lukka/run-vcpkg@v11 - name: Install ninja - run: brew install ninja autoconf bison flex + run: brew install ninja autoconf bison flex pkg-config icu4c if: matrix.os == 'macos-latest' + - name: Compile + if: matrix.db == 'duckdb' + env: + CC: clang + CXX: clang++ + run: | + if [[ "${{ matrix.os == 'macos-latest' }}" == "true" ]]; then + export VCPKG_FORCE_SYSTEM_BINARIES=arm + export CMAKE_GENERATOR=Ninja + fi + $CXX --version + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_DUCKDB=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF + cmake --build build -j 4 - name: Compile if: matrix.db == 'postgres' env: @@ -64,7 +73,7 @@ jobs: export MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion)" fi $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_SQLITE3=OFF -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON cmake --build build -j 4 - name: Compile if: matrix.db == 'sqlite' @@ -77,7 +86,7 @@ jobs: export CMAKE_GENERATOR=Ninja fi $CXX --version - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_POSTGRES=OFF cmake --build build -j 4 - name: Compile if: matrix.db == 'mysql' @@ -91,9 +100,9 @@ jobs: fi $CXX --version if [[ "${{ matrix.os == 'macos-latest' }}" == "true" ]]; then - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=arm64-osx-dynamic -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=arm64-osx-dynamic -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON else - cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-osx-dynamic -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON + cmake -S . -B build -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_MYSQL=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF -DBUILD_SHARED_LIBS=ON -DVCPKG_TARGET_TRIPLET=x64-osx-dynamic -DSQLGEN_BUILD_DRY_TESTS_ONLY=ON fi cmake --build build -j 4 - name: Run tests diff --git a/.github/workflows/windows-cxx20-vcpkg.yaml b/.github/workflows/windows-cxx20-vcpkg.yaml index ef97f4af..0bf3043c 100644 --- a/.github/workflows/windows-cxx20-vcpkg.yaml +++ b/.github/workflows/windows-cxx20-vcpkg.yaml @@ -11,6 +11,7 @@ jobs: fail-fast: false matrix: include: + - db: duckdb - db: postgres - db: sqlite - db: mysql @@ -33,6 +34,11 @@ jobs: core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); - uses: ilammy/msvc-dev-cmd@v1 - uses: lukka/run-vcpkg@v11 + - name: Compile + if: matrix.db == 'duckdb' + run: | + cmake -S . -B build -DCMAKE_CXX_STANDARD=20 -DCMAKE_BUILD_TYPE=Release -DSQLGEN_BUILD_TESTS=ON -DSQLGEN_DUCKDB=ON -DSQLGEN_POSTGRES=OFF -DSQLGEN_SQLITE3=OFF + cmake --build build --config Release -j4 - name: Compile if: matrix.db == 'postgres' run: | diff --git a/README.md b/README.md index 2b9d1921..16a019ab 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![Generic badge](https://img.shields.io/badge/gcc-11+-blue.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/clang-14+-blue.svg)](https://shields.io/) [![Generic badge](https://img.shields.io/badge/MSVC-17+-blue.svg)](https://shields.io/) +[![Conan Center](https://img.shields.io/conan/v/sqlgen)](https://conan.io/center/recipes/sqlgen) **📖 Documentation**: [Click here](docs/README.md) @@ -31,14 +32,21 @@ The following table lists the databases currently supported by sqlgen and the un | Database | Library | Version | License | Remarks | |---------------|--------------------------------------------------------------------------|--------------|---------------| -----------------------------------------------------| -| DuckDB | [duckdb](https://github.com/duckdb/duckdb) | >= 1.4.1 | MIT | | +| DuckDB | [duckdb](https://github.com/duckdb/duckdb) | >= 1.4.2 | MIT | | | MySQL/MariaDB | [libmariadb](https://github.com/mariadb-corporation/mariadb-connector-c) | >= 3.4.5 | LGPL | | | PostgreSQL | [libpq](https://github.com/postgres/postgres) | >= 16.4 | PostgreSQL | Will work for all libpq-compatible databases | | sqlite | [sqlite](https://sqlite.org/index.html) | >= 3.49.1 | Public Domain | | ## Quick Start -### Installation using vcpkg +### Install using vcpkg or Conan + +You can install the latest release of sqlgen +using either [vcpkg](https://vcpkg.io/en/package/sqlgen) or [Conan](https://conan.io/center/recipes/sqlgen). + +### Build using vcpkg + +Alternatively, you can build sqlgen from source using vcpkg: 1. Make sure you have the required dependencies installed (skip this step on Windows): ```bash @@ -66,7 +74,7 @@ Run `./vcpkg/vcpkg help triplets` to view all supported triplets. Common triplets for shared libraries are `x64-linux-dynamic`, `arm64-osx-dynamic` or `x64-osx-dynamic`. -Add `-DSQLGEN_MYSQL=ON` to support MySQL/MariaDB. +Add `-DSQLGEN_MYSQL=ON` to support MySQL/MariaDB. Add `-DSQLGEN_DUCKDB=ON` to support DuckDB. 4. Include in your CMake project: ```cmake @@ -74,7 +82,9 @@ find_package(sqlgen REQUIRED) target_link_libraries(your_target PRIVATE sqlgen::sqlgen) ``` -### Installation using Conan +### Build using Conan + +You can also build sqlgen from source using Conan: 1. Install Conan (assuming you have Python and pipx installed): diff --git a/conanfile.py b/conanfile.py index a3fff335..79d3c465 100644 --- a/conanfile.py +++ b/conanfile.py @@ -19,7 +19,7 @@ class SQLGenConan(ConanFile): license = "MIT" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/getml/sqlgen" - topics = ("postgres", "sqlite", "orm") + topics = ("duckdb", "mypy", "postgres", "sqlite", "orm") package_type = "library" settings = "os", "arch", "compiler", "build_type" @@ -29,6 +29,7 @@ class SQLGenConan(ConanFile): "with_mysql": [True, False], "with_postgres": [True, False], "with_sqlite3": [True, False], + "with_duckdb": [True, False], } default_options = { "shared": False, @@ -36,6 +37,7 @@ class SQLGenConan(ConanFile): "with_mysql": False, "with_postgres": True, "with_sqlite3": True, + "with_duckdb": False, } def config_options(self): @@ -54,6 +56,8 @@ def requirements(self): self.requires("libpq/17.5", transitive_headers=True) if self.options.with_sqlite3: self.requires("sqlite3/3.49.1", transitive_headers=True) + if self.options.with_duckdb: + self.requires("duckdb/1.1.3", transitive_headers=True) def build_requirements(self): self.tool_requires("cmake/[>=3.23 <4]") @@ -78,6 +82,7 @@ def generate(self): tc.cache_variables["SQLGEN_MYSQL"] = self.options.with_mysql tc.cache_variables["SQLGEN_POSTGRES"] = self.options.with_postgres tc.cache_variables["SQLGEN_SQLITE3"] = self.options.with_sqlite3 + tc.cache_variables["SQLGEN_DUCKDB"] = self.options.with_duckdb tc.cache_variables["SQLGEN_USE_VCPKG"] = False tc.generate() diff --git a/include/sqlgen/duckdb/DuckDBAppender.hpp b/include/sqlgen/duckdb/DuckDBAppender.hpp index 3f5aa912..b05bca21 100644 --- a/include/sqlgen/duckdb/DuckDBAppender.hpp +++ b/include/sqlgen/duckdb/DuckDBAppender.hpp @@ -17,32 +17,13 @@ class SQLGEN_API DuckDBAppender { static Result> make( const std::string& _sql, const ConnPtr& _conn, const std::vector& _columns, - const std::vector& _types) { - try { - return Ref::make(_sql, _conn, _columns, _types); - } catch (const std::exception& e) { - return error(e.what()); - } - } + const std::vector& _types); DuckDBAppender(const std::string& _sql, const ConnPtr& _conn, std::vector _columns, - std::vector _types) - : destroy_(false) { - if (duckdb_appender_create_query( - _conn->conn(), _sql.c_str(), static_cast(_columns.size()), - _types.data(), "sqlgen_appended_data", _columns.data(), - &appender_) == DuckDBError) { - throw std::runtime_error("Could not create appender."); - } - destroy_ = true; - } + std::vector _types); - ~DuckDBAppender() { - if (destroy_) { - duckdb_appender_destroy(&appender_); - } - } + ~DuckDBAppender(); DuckDBAppender(const DuckDBAppender& _other) = delete; @@ -53,25 +34,11 @@ class SQLGEN_API DuckDBAppender { DuckDBAppender& operator=(const DuckDBAppender& _other) = delete; - DuckDBAppender& operator=(DuckDBAppender&& _other) { - if (this == &_other) { - return *this; - } - destroy_ = _other.destroy_; - appender_ = _other.appender_; - _other.destroy_ = false; - return *this; - } + DuckDBAppender& operator=(DuckDBAppender&& _other); duckdb_appender& appender() { return appender_; } - Result close() { - const auto state = duckdb_appender_close(appender_); - if (state == DuckDBError) { - return error(duckdb_appender_error(appender_)); - } - return Nothing{}; - } + Result close(); private: bool destroy_; diff --git a/include/sqlgen/duckdb/DuckDBResult.hpp b/include/sqlgen/duckdb/DuckDBResult.hpp index 6479e3a0..db22d65d 100644 --- a/include/sqlgen/duckdb/DuckDBResult.hpp +++ b/include/sqlgen/duckdb/DuckDBResult.hpp @@ -15,27 +15,11 @@ class SQLGEN_API DuckDBResult { public: static Result> make(const std::string& _query, - const ConnPtr& _conn) { - try { - return Ref::make(_query, _conn); - } catch (const std::exception& e) { - return error(e.what()); - } - } + const ConnPtr& _conn); - DuckDBResult(const std::string& _query, const ConnPtr& _conn) - : destroy_(false) { - if (duckdb_query(_conn->conn(), _query.c_str(), &res_) == DuckDBError) { - throw std::runtime_error(duckdb_result_error(&res_)); - } - destroy_ = true; - } + DuckDBResult(const std::string& _query, const ConnPtr& _conn); - ~DuckDBResult() { - if (destroy_) { - duckdb_destroy_result(&res_); - } - } + ~DuckDBResult(); DuckDBResult(const DuckDBResult& _other) = delete; @@ -46,15 +30,7 @@ class SQLGEN_API DuckDBResult { DuckDBResult& operator=(const DuckDBResult& _other) = delete; - DuckDBResult& operator=(DuckDBResult&& _other) { - if (this == &_other) { - return *this; - } - destroy_ = _other.destroy_; - res_ = _other.res_; - _other.destroy_ = false; - return *this; - } + DuckDBResult& operator=(DuckDBResult&& _other); duckdb_result& res() { return res_; } diff --git a/sqlgen-config.cmake.in b/sqlgen-config.cmake.in index 2b35e3d3..46d3eeda 100644 --- a/sqlgen-config.cmake.in +++ b/sqlgen-config.cmake.in @@ -1,5 +1,7 @@ @PACKAGE_INIT@ +set(SQLGEN_DUCKDB @SQLGEN_DUCKDB@) +set(SQLGEN_MYSQL @SQLGEN_MYSQL@) set(SQLGEN_POSTGRES @SQLGEN_POSTGRES@) set(SQLGEN_SQLITE3 @SQLGEN_SQLITE3@) @@ -9,6 +11,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/sqlgen-exports.cmake) find_dependency(reflectcpp) +if(SQLGEN_DUCKDB) + find_dependency(DuckDB) +endif() + +if(SQLGEN_MYSQL) + find_dependency(unofficial-libmariadb) +endif() + if(SQLGEN_POSTGRES) find_dependency(PostgreSQL) endif() diff --git a/src/sqlgen/duckdb/DuckDBAppender.cpp b/src/sqlgen/duckdb/DuckDBAppender.cpp new file mode 100644 index 00000000..624bfd22 --- /dev/null +++ b/src/sqlgen/duckdb/DuckDBAppender.cpp @@ -0,0 +1,53 @@ +#include "sqlgen/duckdb/DuckDBAppender.hpp" + +namespace sqlgen::duckdb { + +Result> DuckDBAppender::make( + const std::string& _sql, const ConnPtr& _conn, + const std::vector& _columns, + const std::vector& _types) { + try { + return Ref::make(_sql, _conn, _columns, _types); + } catch (const std::exception& e) { + return error(e.what()); + } +} + +DuckDBAppender::DuckDBAppender(const std::string& _sql, const ConnPtr& _conn, + std::vector _columns, + std::vector _types) + : destroy_(false) { + if (duckdb_appender_create_query( + _conn->conn(), _sql.c_str(), static_cast(_columns.size()), + _types.data(), "sqlgen_appended_data", _columns.data(), + &appender_) == DuckDBError) { + throw std::runtime_error("Could not create appender."); + } + destroy_ = true; +} + +DuckDBAppender::~DuckDBAppender() { + if (destroy_) { + duckdb_appender_destroy(&appender_); + } +} + +DuckDBAppender& DuckDBAppender::operator=(DuckDBAppender&& _other) { + if (this == &_other) { + return *this; + } + destroy_ = _other.destroy_; + appender_ = _other.appender_; + _other.destroy_ = false; + return *this; +} + +Result DuckDBAppender::close() { + const auto state = duckdb_appender_close(appender_); + if (state == DuckDBError) { + return error(duckdb_appender_error(appender_)); + } + return Nothing{}; +} + +} // namespace sqlgen::duckdb diff --git a/src/sqlgen/duckdb/DuckDBResult.cpp b/src/sqlgen/duckdb/DuckDBResult.cpp new file mode 100644 index 00000000..6b486073 --- /dev/null +++ b/src/sqlgen/duckdb/DuckDBResult.cpp @@ -0,0 +1,38 @@ +#include "sqlgen/duckdb/DuckDBResult.hpp" + +namespace sqlgen::duckdb { + +Result> DuckDBResult::make(const std::string& _query, + const ConnPtr& _conn) { + try { + return Ref::make(_query, _conn); + } catch (const std::exception& e) { + return error(e.what()); + } +} + +DuckDBResult::DuckDBResult(const std::string& _query, const ConnPtr& _conn) + : destroy_(false) { + if (duckdb_query(_conn->conn(), _query.c_str(), &res_) == DuckDBError) { + throw std::runtime_error(duckdb_result_error(&res_)); + } + destroy_ = true; +} + +DuckDBResult::~DuckDBResult() { + if (destroy_) { + duckdb_destroy_result(&res_); + } +} + +DuckDBResult& DuckDBResult::operator=(DuckDBResult&& _other) { + if (this == &_other) { + return *this; + } + destroy_ = _other.destroy_; + res_ = _other.res_; + _other.destroy_ = false; + return *this; +} + +} // namespace sqlgen::duckdb diff --git a/src/sqlgen/duckdb/exec.cpp b/src/sqlgen/duckdb/exec.cpp deleted file mode 100644 index 19220f6f..00000000 --- a/src/sqlgen/duckdb/exec.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "sqlgen/postgres/exec.hpp" - -#include -#include -#include -#include - -namespace sqlgen::postgres { - -Result> exec(const Ref& _conn, - const std::string& _sql) noexcept { - const auto res = PQexec(_conn.get(), _sql.c_str()); - - const auto status = PQresultStatus(res); - - if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && - status != PGRES_COPY_IN) { - const auto err = - error("Executing '" + _sql + "' failed: " + PQresultErrorMessage(res)); - PQclear(res); - return err; - } - - return Ref::make(std::shared_ptr(res, PQclear)); -} - -} // namespace sqlgen::postgres diff --git a/src/sqlgen_duckdb.cpp b/src/sqlgen_duckdb.cpp index 1e254aa6..257d8c36 100644 --- a/src/sqlgen_duckdb.cpp +++ b/src/sqlgen_duckdb.cpp @@ -1,5 +1,5 @@ #include "sqlgen/duckdb/Connection.cpp" +#include "sqlgen/duckdb/DuckDBAppender.cpp" #include "sqlgen/duckdb/DuckDBConnection.cpp" -// #include "sqlgen/duckdb/Iterator.cpp" -// #include "sqlgen/duckdb/exec.cpp" +#include "sqlgen/duckdb/DuckDBResult.cpp" #include "sqlgen/duckdb/to_sql.cpp" diff --git a/tests/duckdb/test_union_in_select.cpp b/tests/duckdb/test_union_in_select.cpp index 706ee3ff..5fdea3ae 100644 --- a/tests/duckdb/test_union_in_select.cpp +++ b/tests/duckdb/test_union_in_select.cpp @@ -46,7 +46,7 @@ TEST(duckdb, test_union_in_select) { const auto united = sqlgen::unite>(s1, s2, s3); const auto sel = sqlgen::select_from(united, "name"_c, "age"_c) | - sqlgen::to>; + sqlgen::order_by("name"_c) | sqlgen::to>; const auto result = sel(conn); @@ -56,7 +56,7 @@ TEST(duckdb, test_union_in_select) { EXPECT_EQ( query, - R"(SELECT "name", "age" FROM (SELECT "name", "age" FROM (SELECT "name", "age" FROM "User1") UNION SELECT "name", "age" FROM (SELECT "name", "age" FROM "User2") UNION SELECT "name", "age" FROM (SELECT "name", "age" FROM "User3")))"); + R"(SELECT "name", "age" FROM (SELECT "name", "age" FROM (SELECT "name", "age" FROM "User1") UNION SELECT "name", "age" FROM (SELECT "name", "age" FROM "User2") UNION SELECT "name", "age" FROM (SELECT "name", "age" FROM "User3")) ORDER BY "name")"); EXPECT_EQ(users.size(), 3); EXPECT_EQ(users.at(0).name, "Jane"); diff --git a/vcpkg.json b/vcpkg.json index 42171303..59aa5c2e 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -11,8 +11,12 @@ "dependencies": [ { "name": "duckdb", - "version>=": "1.4.1" - } + "version>=": "1.4.2" + }, + { + "name":"icu", + "version>=":"78.1" + } ] }, "mysql": {