mirror of
https://github.com/getml/sqlgen.git
synced 2025-12-31 06:30:18 -06:00
Started developing postgres
This commit is contained in:
8
include/sqlgen/postgres.hpp
Normal file
8
include/sqlgen/postgres.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef SQLGEN_POSTGRES_HPP_
|
||||
#define SQLGEN_POSTGRES_HPP_
|
||||
|
||||
#include "../sqlgen.hpp"
|
||||
#include "postgres/Credentials.hpp"
|
||||
#include "postgres/connect.hpp"
|
||||
|
||||
#endif
|
||||
55
include/sqlgen/postgres/Connection.hpp
Normal file
55
include/sqlgen/postgres/Connection.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef SQLGEN_POSTGRES_CONNECTION_HPP_
|
||||
#define SQLGEN_POSTGRES_CONNECTION_HPP_
|
||||
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include <memory>
|
||||
#include <rfl.hpp>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "../Connection.hpp"
|
||||
#include "../IteratorBase.hpp"
|
||||
#include "../Ref.hpp"
|
||||
#include "../Result.hpp"
|
||||
#include "../dynamic/Column.hpp"
|
||||
#include "../dynamic/Statement.hpp"
|
||||
#include "Credentials.hpp"
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
class Connection : public sqlgen::Connection {
|
||||
using ConnPtr = Ref<PGconn>;
|
||||
|
||||
public:
|
||||
Connection(const Credentials& _credentials)
|
||||
: credentials_(_credentials), conn_(make_conn(_credentials.to_str())) {}
|
||||
|
||||
static rfl::Result<Ref<sqlgen::Connection>> make(
|
||||
const Credentials& _credentials) noexcept;
|
||||
|
||||
~Connection() = default;
|
||||
|
||||
Result<Nothing> commit() final { return execute("COMMIT;"); }
|
||||
|
||||
Result<Nothing> execute(const std::string& _sql) noexcept final;
|
||||
|
||||
Result<Ref<IteratorBase>> read(const dynamic::SelectFrom& _query) final;
|
||||
|
||||
std::string to_sql(const dynamic::Statement& _stmt) noexcept final;
|
||||
|
||||
Result<Nothing> start_write(const dynamic::Insert& _stmt) final;
|
||||
|
||||
Result<Nothing> end_write() final;
|
||||
|
||||
Result<Nothing> write(
|
||||
const std::vector<std::vector<std::optional<std::string>>>& _data) final;
|
||||
|
||||
private:
|
||||
static rfl::Result<Ref<sqlgen::Connection>> make_conn(
|
||||
const std::string& _conn_str);
|
||||
};
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
|
||||
#endif
|
||||
23
include/sqlgen/postgres/Credentials.hpp
Normal file
23
include/sqlgen/postgres/Credentials.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef SQLGEN_POSTGRES_CREDENTIALS_HPP_
|
||||
#define SQLGEN_POSTGRES_CREDENTIALS_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
struct Credentials {
|
||||
std::string user;
|
||||
std::string password;
|
||||
std::string host;
|
||||
std::string dbname;
|
||||
int port = 5432;
|
||||
|
||||
std::string to_str() const {
|
||||
return "postgresql://" + user + ":" + password + "@" + host + ":" +
|
||||
std::to_string(port) + "/" + dbname;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
|
||||
#endif
|
||||
37
include/sqlgen/postgres/Iterator.hpp
Normal file
37
include/sqlgen/postgres/Iterator.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef SQLGEN_POSTGRES_ITERATOR_HPP_
|
||||
#define SQLGEN_POSTGRES_ITERATOR_HPP_
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../IteratorBase.hpp"
|
||||
#include "../Ref.hpp"
|
||||
#include "../Result.hpp"
|
||||
#include "Connection.hpp"
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
class Iterator : public sqlgen::IteratorBase {
|
||||
public:
|
||||
Iterator(const StmtPtr& _stmt, const ConnPtr& _conn);
|
||||
|
||||
~Iterator();
|
||||
|
||||
/// Whether the end of the available data has been reached.
|
||||
bool end() const final;
|
||||
|
||||
/// Returns the next batch of rows.
|
||||
/// If _batch_size is greater than the number of rows left, returns all
|
||||
/// of the rows left.
|
||||
Result<std::vector<std::vector<std::optional<std::string>>>> next(
|
||||
const size_t _batch_size) final;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
|
||||
#endif
|
||||
17
include/sqlgen/postgres/connect.hpp
Normal file
17
include/sqlgen/postgres/connect.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef SQLGEN_POSTGRES_CONNECT_HPP_
|
||||
#define SQLGEN_POSTGRES_CONNECT_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Connection.hpp"
|
||||
#include "Credentials.hpp"
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
inline auto connect(const Credentials& _credentials) {
|
||||
return Connection::make(_credentials);
|
||||
}
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
|
||||
#endif
|
||||
36
src/sqlgen/postgres/Connection.cpp
Normal file
36
src/sqlgen/postgres/Connection.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "sqlgen/postgres/Connection.hpp"
|
||||
|
||||
#include <ranges>
|
||||
#include <rfl.hpp>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "sqlgen/internal/collect/vector.hpp"
|
||||
#include "sqlgen/internal/strings/strings.hpp"
|
||||
|
||||
namespace sqlgen::postgres {
|
||||
|
||||
rfl::Result<Ref<sqlgen::Connection>> Connection::make(
|
||||
const Credentials& _credentials) noexcept {
|
||||
try {
|
||||
return Ref<sqlgen::Connection>(Ref<Connection>::make(_credentials));
|
||||
} catch (std::exception& e) {
|
||||
return error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
typename Connection::ConnPtr Connection::make_conn(
|
||||
const std::string& _conn_str) {
|
||||
const auto raw_ptr = PQconnectdb(_conn_str.c_str());
|
||||
|
||||
if (PQstatus(raw_ptr) != CONNECTION_OK) {
|
||||
const auto msg = std::string("Connection to postgres failed: ") +
|
||||
PQerrorMessage(raw_ptr);
|
||||
PQfinish(raw_ptr);
|
||||
throw std::runtime_error(msg.c_str());
|
||||
}
|
||||
|
||||
return ConnPtr::make(std::shared_ptr<PGconn>(raw_ptr, &PQfinish)).value();
|
||||
}
|
||||
|
||||
} // namespace sqlgen::postgres
|
||||
59
src/sqlgen/postgres/Iterator.cpp
Normal file
59
src/sqlgen/postgres/Iterator.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "sqlgen/sqlite/Iterator.hpp"
|
||||
|
||||
#include <ranges>
|
||||
#include <rfl.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include "sqlgen/internal/collect/vector.hpp"
|
||||
#include "sqlgen/internal/strings/strings.hpp"
|
||||
#include "sqlgen/sqlite/Iterator.hpp"
|
||||
|
||||
namespace sqlgen::sqlite {
|
||||
|
||||
Iterator::Iterator(const StmtPtr& _stmt, const ConnPtr& _conn)
|
||||
: end_(false),
|
||||
rownum_(0),
|
||||
num_cols_(sqlite3_column_count(_stmt.get())),
|
||||
stmt_(_stmt),
|
||||
conn_(_conn) {
|
||||
step();
|
||||
}
|
||||
|
||||
Iterator::~Iterator() = default;
|
||||
|
||||
bool Iterator::end() const { return end_; }
|
||||
|
||||
Result<std::vector<std::vector<std::optional<std::string>>>> Iterator::next(
|
||||
const size_t _batch_size) {
|
||||
if (end()) {
|
||||
return error("End is reached.");
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::optional<std::string>>> batch;
|
||||
|
||||
for (size_t i = 0; i < _batch_size; ++i) {
|
||||
std::vector<std::optional<std::string>> new_row;
|
||||
|
||||
for (int j = 0; j < num_cols_; ++j) {
|
||||
auto ptr = sqlite3_column_text(stmt_.get(), j);
|
||||
if (ptr) {
|
||||
new_row.emplace_back(
|
||||
std::string(std::launder(reinterpret_cast<const char*>(ptr))));
|
||||
} else {
|
||||
new_row.emplace_back(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
batch.emplace_back(std::move(new_row));
|
||||
|
||||
step();
|
||||
|
||||
if (end()) {
|
||||
return batch;
|
||||
}
|
||||
}
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
} // namespace sqlgen::sqlite
|
||||
Reference in New Issue
Block a user