mirror of
https://github.com/getml/sqlgen.git
synced 2025-12-19 16:29:39 -06:00
Minor code beautifications for DuckDB (#94)
This commit is contained in:
committed by
GitHub
parent
b2e4cba591
commit
e85f262f6d
37
.github/workflows/linux-cxx20-vcpkg.yaml
vendored
37
.github/workflows/linux-cxx20-vcpkg.yaml
vendored
@@ -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'
|
||||
|
||||
31
.github/workflows/macos-cxx20-vcpkg.yaml
vendored
31
.github/workflows/macos-cxx20-vcpkg.yaml
vendored
@@ -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
|
||||
|
||||
6
.github/workflows/windows-cxx20-vcpkg.yaml
vendored
6
.github/workflows/windows-cxx20-vcpkg.yaml
vendored
@@ -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: |
|
||||
|
||||
18
README.md
18
README.md
@@ -6,6 +6,7 @@
|
||||
[](https://shields.io/)
|
||||
[](https://shields.io/)
|
||||
[](https://shields.io/)
|
||||
[](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):
|
||||
|
||||
|
||||
@@ -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 @@ class SQLGenConan(ConanFile):
|
||||
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 @@ class SQLGenConan(ConanFile):
|
||||
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()
|
||||
|
||||
|
||||
@@ -17,32 +17,13 @@ class SQLGEN_API DuckDBAppender {
|
||||
static Result<Ref<DuckDBAppender>> make(
|
||||
const std::string& _sql, const ConnPtr& _conn,
|
||||
const std::vector<const char*>& _columns,
|
||||
const std::vector<duckdb_logical_type>& _types) {
|
||||
try {
|
||||
return Ref<DuckDBAppender>::make(_sql, _conn, _columns, _types);
|
||||
} catch (const std::exception& e) {
|
||||
return error(e.what());
|
||||
}
|
||||
}
|
||||
const std::vector<duckdb_logical_type>& _types);
|
||||
|
||||
DuckDBAppender(const std::string& _sql, const ConnPtr& _conn,
|
||||
std::vector<const char*> _columns,
|
||||
std::vector<duckdb_logical_type> _types)
|
||||
: destroy_(false) {
|
||||
if (duckdb_appender_create_query(
|
||||
_conn->conn(), _sql.c_str(), static_cast<idx_t>(_columns.size()),
|
||||
_types.data(), "sqlgen_appended_data", _columns.data(),
|
||||
&appender_) == DuckDBError) {
|
||||
throw std::runtime_error("Could not create appender.");
|
||||
}
|
||||
destroy_ = true;
|
||||
}
|
||||
std::vector<duckdb_logical_type> _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<Nothing> close() {
|
||||
const auto state = duckdb_appender_close(appender_);
|
||||
if (state == DuckDBError) {
|
||||
return error(duckdb_appender_error(appender_));
|
||||
}
|
||||
return Nothing{};
|
||||
}
|
||||
Result<Nothing> close();
|
||||
|
||||
private:
|
||||
bool destroy_;
|
||||
|
||||
@@ -15,27 +15,11 @@ class SQLGEN_API DuckDBResult {
|
||||
|
||||
public:
|
||||
static Result<Ref<DuckDBResult>> make(const std::string& _query,
|
||||
const ConnPtr& _conn) {
|
||||
try {
|
||||
return Ref<DuckDBResult>::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_; }
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
53
src/sqlgen/duckdb/DuckDBAppender.cpp
Normal file
53
src/sqlgen/duckdb/DuckDBAppender.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "sqlgen/duckdb/DuckDBAppender.hpp"
|
||||
|
||||
namespace sqlgen::duckdb {
|
||||
|
||||
Result<Ref<DuckDBAppender>> DuckDBAppender::make(
|
||||
const std::string& _sql, const ConnPtr& _conn,
|
||||
const std::vector<const char*>& _columns,
|
||||
const std::vector<duckdb_logical_type>& _types) {
|
||||
try {
|
||||
return Ref<DuckDBAppender>::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<const char*> _columns,
|
||||
std::vector<duckdb_logical_type> _types)
|
||||
: destroy_(false) {
|
||||
if (duckdb_appender_create_query(
|
||||
_conn->conn(), _sql.c_str(), static_cast<idx_t>(_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<Nothing> DuckDBAppender::close() {
|
||||
const auto state = duckdb_appender_close(appender_);
|
||||
if (state == DuckDBError) {
|
||||
return error(duckdb_appender_error(appender_));
|
||||
}
|
||||
return Nothing{};
|
||||
}
|
||||
|
||||
} // namespace sqlgen::duckdb
|
||||
38
src/sqlgen/duckdb/DuckDBResult.cpp
Normal file
38
src/sqlgen/duckdb/DuckDBResult.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "sqlgen/duckdb/DuckDBResult.hpp"
|
||||
|
||||
namespace sqlgen::duckdb {
|
||||
|
||||
Result<Ref<DuckDBResult>> DuckDBResult::make(const std::string& _query,
|
||||
const ConnPtr& _conn) {
|
||||
try {
|
||||
return Ref<DuckDBResult>::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
|
||||
@@ -1,27 +0,0 @@
|
||||
#include "sqlgen/postgres/exec.hpp"
|
||||
|
||||
#include <ranges>
|
||||
#include <rfl.hpp>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
Result<Ref<PGresult>> exec(const Ref<PGconn>& _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<PGresult>::make(std::shared_ptr<PGresult>(res, PQclear));
|
||||
}
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
@@ -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"
|
||||
|
||||
@@ -46,7 +46,7 @@ TEST(duckdb, test_union_in_select) {
|
||||
const auto united = sqlgen::unite<std::vector<User1>>(s1, s2, s3);
|
||||
|
||||
const auto sel = sqlgen::select_from(united, "name"_c, "age"_c) |
|
||||
sqlgen::to<std::vector<User1>>;
|
||||
sqlgen::order_by("name"_c) | sqlgen::to<std::vector<User1>>;
|
||||
|
||||
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");
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "duckdb",
|
||||
"version>=": "1.4.1"
|
||||
}
|
||||
"version>=": "1.4.2"
|
||||
},
|
||||
{
|
||||
"name":"icu",
|
||||
"version>=":"78.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mysql": {
|
||||
|
||||
Reference in New Issue
Block a user