Skip to content

Commit a56edd6

Browse files
More efficient (and more idiomatic) approach to write
1 parent b833423 commit a56edd6

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

include/sqlgen/duckdb/Connection.hpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@ class Connection {
3939
using ConnPtr = Ref<DuckDBConnection>;
4040

4141
public:
42-
Connection(const ConnPtr &_conn) : conn_(_conn) {}
42+
Connection(const ConnPtr &_conn) : appender_(nullptr), conn_(_conn) {}
4343

4444
static rfl::Result<Ref<Connection>> make(
4545
const std::optional<std::string> &_fname) noexcept;
4646

47-
~Connection() = default;
47+
~Connection() {
48+
if (appender_) {
49+
duckdb_appender_destroy(appender_.get());
50+
}
51+
}
4852

4953
Result<Nothing> begin_transaction() noexcept;
5054

@@ -87,25 +91,38 @@ class Connection {
8791
return duckdb::to_sql_impl(_stmt);
8892
}
8993

90-
Result<Nothing> start_write(const dynamic::Write &) { return Nothing{}; }
94+
Result<Nothing> start_write(const dynamic::Write &_write_stmt) {
95+
if (appender_) {
96+
return error(
97+
"Write operation already in progress - you cannot start another.");
98+
}
99+
appender_ = std::make_unique<duckdb_appender>();
100+
if (duckdb_appender_create(
101+
conn_->conn(),
102+
_write_stmt.table.schema ? _write_stmt.table.schema->c_str()
103+
: nullptr,
104+
_write_stmt.table.name.c_str(), appender_.get()) == DuckDBError) {
105+
appender_ = nullptr;
106+
return error("Could not create appender.");
107+
}
108+
return Nothing{};
109+
}
91110

92-
Result<Nothing> end_write() { return Nothing{}; }
111+
Result<Nothing> end_write() {
112+
if (!appender_) {
113+
return error("No write operation in progress - nothing to end.");
114+
}
115+
duckdb_appender_destroy(appender_.get());
116+
appender_ = nullptr;
117+
return Nothing{};
118+
}
93119

94120
template <class ItBegin, class ItEnd>
95121
Result<Nothing> write(ItBegin _begin, ItEnd _end) {
96-
using T =
97-
std::remove_cvref_t<typename std::iterator_traits<ItBegin>::value_type>;
98-
const auto schema = transpilation::get_schema<T>();
99-
const auto table = transpilation::get_tablename<T>();
100-
duckdb_appender appender{};
101-
if (duckdb_appender_create(conn_->conn(),
102-
schema ? schema->c_str() : nullptr,
103-
table.c_str(), &appender) == DuckDBError) {
104-
return error("Could not create appender.");
122+
if (!appender_) {
123+
return error("No write operation in progress - nothing to write.");
105124
}
106-
const auto res = write_to_appender(_begin, _end, appender);
107-
duckdb_appender_destroy(&appender);
108-
return res;
125+
return write_to_appender(_begin, _end, *appender_);
109126
}
110127

111128
private:
@@ -162,6 +179,9 @@ class Connection {
162179
}
163180

164181
private:
182+
/// The appender to be used for the write statements
183+
std::unique_ptr<duckdb_appender> appender_;
184+
165185
/// The underlying duckdb3 connection.
166186
ConnPtr conn_;
167187
};

0 commit comments

Comments
 (0)