diff --git a/include/sqlgen/postgres/Iterator.hpp b/include/sqlgen/postgres/Iterator.hpp index be34268..660b019 100644 --- a/include/sqlgen/postgres/Iterator.hpp +++ b/include/sqlgen/postgres/Iterator.hpp @@ -1,8 +1,9 @@ #ifndef SQLGEN_POSTGRES_ITERATOR_HPP_ #define SQLGEN_POSTGRES_ITERATOR_HPP_ -#include +#include +#include #include #include #include @@ -15,8 +16,14 @@ namespace sqlgen::postgres { class Iterator : public sqlgen::IteratorBase { + using ConnPtr = Ref; + public: - Iterator(); + Iterator(const std::string& _sql, const ConnPtr& _conn); + + Iterator(const Iterator& _other) = delete; + + Iterator(Iterator&& _other) noexcept; ~Iterator(); @@ -29,7 +36,26 @@ class Iterator : public sqlgen::IteratorBase { Result>>> next( const size_t _batch_size) final; + Iterator& operator=(const Iterator& _other) = delete; + + Iterator& operator=(Iterator&& _other) noexcept; + private: + static std::string make_cursor_name() { + // TODO: Create unique cursor names. + return "sqlgen_cursor"; + } + + private: + /// A unique name to identify the cursor. + std::string cursor_name_; + + /// The underlying postgres connection. We have this in here to prevent its + /// destruction for the lifetime of the iterator. + ConnPtr conn_; + + /// Indicates that the iterator has been moved + bool moved_; }; } // namespace sqlgen::postgres diff --git a/src/sqlgen/postgres/Iterator.cpp b/src/sqlgen/postgres/Iterator.cpp index f1c8fa1..33d6581 100644 --- a/src/sqlgen/postgres/Iterator.cpp +++ b/src/sqlgen/postgres/Iterator.cpp @@ -6,13 +6,29 @@ #include "sqlgen/internal/collect/vector.hpp" #include "sqlgen/internal/strings/strings.hpp" -#include "sqlgen/sqlite/Iterator.hpp" +#include "sqlgen/postgres/exec.hpp" namespace sqlgen::postgres { -Iterator::Iterator() {} +Iterator::Iterator(const std::string& _sql, const ConnPtr& _conn) + : cursor_name_(make_cursor_name()), conn_(_conn), moved_(false) { + exec(conn_, "BEGIN").value(); + exec(conn_, "DECLARE " + cursor_name_ + " CURSOR FOR " + _sql).value(); +} -Iterator::~Iterator() = default; +Iterator::Iterator(Iterator&& _other) noexcept + : cursor_name_(std::move(_other.cursor_name_)), + conn_(std::move(_other.conn_)), + moved_(_other.moved_) { + _other.moved_ = true; +} + +Iterator::~Iterator() { + if (!moved_) { + exec(conn_, "CLOSE " + cursor_name_); + exec(conn_, "END"); + } +} bool Iterator::end() const { return true; } @@ -25,4 +41,15 @@ Result>>> Iterator::next( return error("TODO"); } +Iterator& Iterator::operator=(Iterator&& _other) noexcept { + if (this == &_other) { + return *this; + } + cursor_name_ = _other.cursor_name_; + conn_ = _other.conn_; + moved_ = _other.moved_; + _other.moved_ = true; + return *this; +} + } // namespace sqlgen::postgres