This commit is contained in:
Scott E. Graves 2024-10-17 18:26:24 -05:00
parent c9f9c2a24c
commit 4a530c4703
14 changed files with 292 additions and 255 deletions

View File

@ -1,15 +1,15 @@
set(BINUTILS_VERSION 2.41)
set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 85)
set(BOOST_PATCH_VERSION 0)
set(BOOST2_MAJOR_VERSION 1)
set(BOOST2_MINOR_VERSION 76)
set(BOOST2_PATCH_VERSION 0)
set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 85)
set(BOOST_PATCH_VERSION 0)
set(CPP_HTTPLIB_VERSION 0.16.3)
set(CURL_VERSION 8.9.1)
set(CURL2_VERSION 8_9_1)
set(EXPAT_VERSION 2.6.2)
set(CURL_VERSION 8.9.1)
set(EXPAT2_VERSION 2_6_2)
set(EXPAT_VERSION 2.6.2)
set(GCC_VERSION 14.2.0)
set(GTEST_VERSION 1.15.2)
set(ICU_VERSION 75-1)
@ -21,7 +21,7 @@ set(OPENSSL_VERSION 3.3.1)
set(PKG_CONFIG_VERSION 0.29.2)
set(PUGIXML_VERSION 1.14)
set(SPDLOG_VERSION 1.14.1)
set(SQLITE_VERSION 3460100)
set(SQLITE2_VERSION 3.46.1)
set(SQLITE_VERSION 3460100)
set(STDUUID_VERSION 1.2.3)
set(ZLIB_VERSION 1.3.1)

View File

@ -40,8 +40,8 @@
#include "utils/time.hpp"
namespace {
[[nodiscard]] auto create_resume_entry(const repertory::i_open_file &file)
-> json {
[[nodiscard]] auto
create_resume_entry(const repertory::i_open_file &file) -> json {
return {
{"chunk_size", file.get_chunk_size()},
{"path", file.get_api_path()},
@ -105,7 +105,7 @@ file_manager::file_manager(app_config &config, i_provider &provider)
: config_(config), provider_(provider) {
if (not provider_.is_direct_only()) {
auto db_path =
utils::path::combine(config.get_data_directory(), {"file_manager.db3"});
utils::path::combine(config.get_data_directory(), {"file_manager.db"});
sqlite3 *db3{nullptr};
auto res =
@ -455,11 +455,10 @@ auto file_manager::open(const std::string &api_path, bool directory,
return open(api_path, directory, ofd, handle, file, nullptr);
}
auto file_manager::open(const std::string &api_path, bool directory,
const open_file_data &ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file,
std::shared_ptr<i_closeable_open_file> closeable_file)
-> api_error {
auto file_manager::open(
const std::string &api_path, bool directory, const open_file_data &ofd,
std::uint64_t &handle, std::shared_ptr<i_open_file> &file,
std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error {
const auto create_and_add_handle =
[&](std::shared_ptr<i_closeable_open_file> cur_file) {
handle = get_next_handle();
@ -718,8 +717,8 @@ auto file_manager::rename_directory(const std::string &from_api_path,
}
auto file_manager::rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite)
-> api_error {
const std::string &to_api_path,
bool overwrite) -> api_error {
if (not provider_.is_rename_supported()) {
return api_error::not_implemented;
}

View File

@ -69,10 +69,9 @@ const std::map<std::string, std::string> sql_create_tables = {
namespace repertory {
encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
auto encrypt_provider::create_api_file(const std::string &api_path,
bool directory,
const std::string &source_path)
-> api_file {
auto encrypt_provider::create_api_file(
const std::string &api_path, bool directory,
const std::string &source_path) -> api_file {
auto times = utils::file::get_times(source_path);
if (not times.has_value()) {
throw std::runtime_error("failed to get file times");
@ -98,10 +97,10 @@ auto encrypt_provider::create_api_file(const std::string &api_path,
void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
const api_file &file) {
#if defined(_WIN32)
struct _stat64 buf{};
struct _stat64 buf {};
_stat64(file.source_path.c_str(), &buf);
#else // !defined(_WIN32)
struct stat buf{};
struct stat buf {};
stat(file.source_path.c_str(), &buf);
#endif // defined(_WIN32)
@ -188,9 +187,8 @@ auto encrypt_provider::do_fs_operation(
return callback(cfg, source_path);
}
auto encrypt_provider::get_api_path_from_source(const std::string &source_path,
std::string &api_path) const
-> api_error {
auto encrypt_provider::get_api_path_from_source(
const std::string &source_path, std::string &api_path) const -> api_error {
REPERTORY_USES_FUNCTION_NAME();
try {
@ -255,9 +253,8 @@ auto encrypt_provider::get_directory_item_count(
return count;
}
auto encrypt_provider::get_directory_items(const std::string &api_path,
directory_item_list &list) const
-> api_error {
auto encrypt_provider::get_directory_items(
const std::string &api_path, directory_item_list &list) const -> api_error {
REPERTORY_USES_FUNCTION_NAME();
return do_fs_operation(
@ -430,9 +427,8 @@ auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
return api_error::error;
}
auto encrypt_provider::get_file_size(const std::string &api_path,
std::uint64_t &file_size) const
-> api_error {
auto encrypt_provider::get_file_size(
const std::string &api_path, std::uint64_t &file_size) const -> api_error {
REPERTORY_USES_FUNCTION_NAME();
try {
@ -458,10 +454,9 @@ auto encrypt_provider::get_file_size(const std::string &api_path,
return api_error::error;
}
auto encrypt_provider::get_filesystem_item(const std::string &api_path,
bool directory,
filesystem_item &fsi) const
-> api_error {
auto encrypt_provider::get_filesystem_item(
const std::string &api_path, bool directory,
filesystem_item &fsi) const -> api_error {
auto result = utils::db::sqlite::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
@ -537,10 +532,9 @@ auto encrypt_provider::get_filesystem_item_from_source_path(
return get_filesystem_item(api_path, false, fsi);
}
auto encrypt_provider::get_filesystem_item_and_file(const std::string &api_path,
api_file &file,
filesystem_item &fsi) const
-> api_error {
auto encrypt_provider::get_filesystem_item_and_file(
const std::string &api_path, api_file &file,
filesystem_item &fsi) const -> api_error {
REPERTORY_USES_FUNCTION_NAME();
try {
@ -667,8 +661,8 @@ auto encrypt_provider::is_directory(const std::string &api_path,
return api_error::success;
}
auto encrypt_provider::is_file(const std::string &api_path, bool &exists) const
-> api_error {
auto encrypt_provider::is_file(const std::string &api_path,
bool &exists) const -> api_error {
auto result = utils::db::sqlite::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
@ -1032,7 +1026,7 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
}
auto db_path =
utils::path::combine(config_.get_data_directory(), {"meta.db3"});
utils::path::combine(config_.get_data_directory(), {"meta.db"});
sqlite3 *db3{nullptr};
auto res =

View File

@ -34,7 +34,7 @@ namespace repertory {
meta_db::meta_db(const app_config &cfg) {
REPERTORY_USES_FUNCTION_NAME();
auto db_path = utils::path::combine(cfg.get_data_directory(), {"meta.db3"});
auto db_path = utils::path::combine(cfg.get_data_directory(), {"meta.db"});
sqlite3 *db3{nullptr};
auto res =
@ -108,8 +108,8 @@ auto meta_db::get_api_path_list() -> std::vector<std::string> {
return ret;
}
auto meta_db::get_item_meta(const std::string &api_path, api_meta_map &meta)
-> api_error {
auto meta_db::get_item_meta(const std::string &api_path,
api_meta_map &meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto result = utils::db::sqlite::db_select{*db_, table_name}
@ -292,8 +292,8 @@ auto meta_db::set_item_meta(const std::string &api_path,
return update_item_meta(api_path, existing_meta);
}
auto meta_db::update_item_meta(const std::string &api_path, api_meta_map meta)
-> api_error {
auto meta_db::update_item_meta(const std::string &api_path,
api_meta_map meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto directory = utils::string::to_bool(meta[META_DIRECTORY]);

View File

@ -31,11 +31,7 @@ using db_types_t = std::variant<std::int64_t, std::string>;
struct sqlite3_deleter {
void operator()(sqlite3 *db3) const {
if (db3 != nullptr) {
#if defined(_WIN32)
sqlite3_close(db3);
#else // !defined(_WIN32)
sqlite3_close_v2(db3);
#endif // defined(_WIN32)
}
}
};
@ -123,21 +119,21 @@ public:
template <typename ctx_t> class db_row final {
public:
db_row(std::shared_ptr<ctx_t> context) {
auto column_count = sqlite3_column_count(context->stmt.get());
db_row(std::shared_ptr<ctx_t> ctx) {
auto column_count = sqlite3_column_count(ctx->stmt.get());
for (std::int32_t col = 0; col < column_count; col++) {
std::string name{sqlite3_column_name(context->stmt.get(), col)};
auto column_type = sqlite3_column_type(context->stmt.get(), col);
std::string name{sqlite3_column_name(ctx->stmt.get(), col)};
auto column_type = sqlite3_column_type(ctx->stmt.get(), col);
db_types_t value;
switch (column_type) {
case SQLITE_INTEGER: {
value = sqlite3_column_int64(context->stmt.get(), col);
value = sqlite3_column_int64(ctx->stmt.get(), col);
} break;
case SQLITE_TEXT: {
const auto *text = reinterpret_cast<const char *>(
sqlite3_column_text(context->stmt.get(), col));
sqlite3_column_text(ctx->stmt.get(), col));
value = std::string(text == nullptr ? "" : text);
} break;
@ -180,15 +176,17 @@ public:
};
template <typename ctx_t> struct db_result final {
db_result(std::shared_ptr<ctx_t> context, std::int32_t res)
: context_(std::move(context)), res_(res) {
db_result(std::shared_ptr<ctx_t> ctx, std::int32_t res)
: ctx_(std::move(ctx)), res_(res) {
if (res == SQLITE_OK) {
set_res(sqlite3_step(context_->stmt.get()));
set_res(sqlite3_step(ctx_->stmt.get()));
}
}
~db_result() { ctx_->clear(); }
private:
std::shared_ptr<ctx_t> context_;
std::shared_ptr<ctx_t> ctx_;
mutable std::int32_t res_;
private:
@ -212,8 +210,8 @@ public:
return false;
}
row = db_row{context_};
set_res(sqlite3_step(context_->stmt.get()));
row = db_row{ctx_};
set_res(sqlite3_step(ctx_->stmt.get()));
return true;
}
@ -224,7 +222,7 @@ public:
return;
}
set_res(sqlite3_step(context_->stmt.get()));
set_res(sqlite3_step(ctx_->stmt.get()));
}
};
} // namespace repertory::utils::db::sqlite

View File

@ -46,26 +46,28 @@ public:
using wd_t = where_data_t<w_t>;
std::unique_ptr<wd_t> where_data;
void clear();
};
using row = db_row<context>;
public:
db_delete(sqlite3 &db3, std::string table_name)
: context_(std::make_shared<context>(&db3, table_name)) {}
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_delete(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
db_delete(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> context_;
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result<context>;
[[nodiscard]] auto group(context::w_t::group_func_t func)
-> context::w_t::wn_t;
[[nodiscard]] auto
group(context::w_t::group_func_t func) -> context::w_t::wn_t;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};

View File

@ -34,22 +34,24 @@ public:
bool or_replace{false};
std::map<std::string, db_types_t> values;
void clear();
};
using row = db_row<context>;
public:
db_insert(sqlite3 &db3, std::string table_name)
: context_(std::make_shared<context>(&db3, table_name)) {}
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_insert(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
db_insert(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> context_;
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto or_replace() -> db_insert & {
context_->or_replace = true;
ctx_->or_replace = true;
return *this;
}

View File

@ -44,8 +44,8 @@ public:
[[nodiscard]] auto offset(std::int32_t value) -> db_select_op_t;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_select_op_t;
[[nodiscard]] auto order_by(std::string column_name,
bool ascending) -> db_select_op_t;
};
context(sqlite3 *db3_, std::string table_name_)
@ -63,24 +63,26 @@ public:
std::optional<std::pair<std::string, bool>> order_by;
std::unique_ptr<wd_t> where_data;
void clear();
};
using row = db_row<context>;
public:
db_select(sqlite3 &db3, std::string table_name)
: context_(std::make_shared<context>(&db3, table_name)) {}
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_select(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
db_select(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> context_;
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto column(std::string column_name) -> db_select &;
[[nodiscard]] auto count(std::string column_name, std::string as_column_name)
-> db_select &;
[[nodiscard]] auto count(std::string column_name,
std::string as_column_name) -> db_select &;
[[nodiscard]] auto dump() const -> std::string;
@ -88,15 +90,15 @@ public:
[[nodiscard]] auto group_by(std::string column_name) -> db_select &;
[[nodiscard]] auto group(context::w_t::group_func_t func)
-> context::w_t::wn_t;
[[nodiscard]] auto
group(context::w_t::group_func_t func) -> context::w_t::wn_t;
[[nodiscard]] auto limit(std::int32_t value) -> db_select &;
[[nodiscard]] auto offset(std::int32_t value) -> db_select &;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_select &;
[[nodiscard]] auto order_by(std::string column_name,
bool ascending) -> db_select &;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};

View File

@ -43,8 +43,8 @@ public:
[[nodiscard]] auto limit(std::int32_t value) -> db_update_op_t;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_update_op_t;
[[nodiscard]] auto order_by(std::string column_name,
bool ascending) -> db_update_op_t;
};
using w_t = db_where_t<context, db_update_op_t>;
@ -55,34 +55,36 @@ public:
std::optional<std::pair<std::string, bool>> order_by;
std::unique_ptr<wd_t> where_data;
void clear();
};
using row = db_row<context>;
public:
db_update(sqlite3 &db3, std::string table_name)
: context_(std::make_shared<context>(&db3, table_name)) {}
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_update(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
db_update(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> context_;
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto column_value(std::string column_name, db_types_t value)
-> db_update &;
[[nodiscard]] auto column_value(std::string column_name,
db_types_t value) -> db_update &;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result<context>;
[[nodiscard]] auto group(context::w_t::group_func_t func)
-> context::w_t::wn_t;
[[nodiscard]] auto
group(context::w_t::group_func_t func) -> context::w_t::wn_t;
[[nodiscard]] auto limit(std::int32_t value) -> db_update &;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_update &;
[[nodiscard]] auto order_by(std::string column_name,
bool ascending) -> db_update &;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};

View File

@ -157,8 +157,8 @@ template <typename ctx_t, typename op_t> struct db_where_t final {
using action_t = std::variant<db_comp_data_t, n_t, db_where_t>;
[[nodiscard]] static auto dump(std::int32_t &idx, auto &&actions)
-> std::string {
[[nodiscard]] static auto dump(std::int32_t &idx,
auto &&actions) -> std::string {
std::stringstream stream;
for (auto &&action : actions) {

View File

@ -24,6 +24,11 @@
#if defined(PROJECT_ENABLE_SQLITE)
namespace repertory::utils::db::sqlite {
void db_delete::context::clear() {
stmt.reset();
where_data.reset();
}
auto db_delete::context::db_delete_op_t::dump() const -> std::string {
return db_delete{ctx}.dump();
}
@ -34,11 +39,11 @@ auto db_delete::context::db_delete_op_t::go() const -> db_result<context> {
auto db_delete::dump() const -> std::string {
std::stringstream query;
query << "DELETE FROM \"" << context_->table_name << "\"";
query << "DELETE FROM \"" << ctx_->table_name << "\"";
if (context_->where_data) {
if (ctx_->where_data) {
std::int32_t idx{};
query << " WHERE " << context_->where_data->base.dump(idx);
query << " WHERE " << ctx_->where_data->base.dump(idx);
}
query << ';';
@ -49,61 +54,65 @@ auto db_delete::dump() const -> std::string {
auto db_delete::go() const -> db_result<context> {
sqlite3_stmt *stmt_ptr{nullptr};
auto query_str = dump();
auto res = sqlite3_prepare_v2(context_->db3, query_str.c_str(), -1, &stmt_ptr,
nullptr);
context_->stmt = db3_stmt_t{
auto res =
sqlite3_prepare_v2(ctx_->db3, query_str.c_str(), -1, &stmt_ptr, nullptr);
ctx_->stmt = db3_stmt_t{
stmt_ptr,
sqlite3_statement_deleter(),
};
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
if (not context_->where_data) {
return {context_, res};
if (not ctx_->where_data) {
return {ctx_, res};
}
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->where_data->values.size());
idx < static_cast<std::int32_t>(ctx_->where_data->values.size());
idx++) {
res = std::visit(
overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
return sqlite3_bind_int64(ctx_->stmt.get(), idx + 1, data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
return sqlite3_bind_text(ctx_->stmt.get(), idx + 1, data.c_str(),
-1, nullptr);
},
},
context_->where_data->values.at(static_cast<std::size_t>(idx)));
ctx_->where_data->values.at(static_cast<std::size_t>(idx)));
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
}
return {context_, res};
return {ctx_, res};
}
auto db_delete::group(context::w_t::group_func_t func) -> context::w_t::wn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.group(std::move(func));
return ctx_->where_data->base.group(std::move(func));
}
auto db_delete::where(std::string column_name) const -> context::w_t::cn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.where(column_name);
return ctx_->where_data->base.where(column_name);
}
} // namespace repertory::utils::db::sqlite

View File

@ -24,31 +24,36 @@
#if defined(PROJECT_ENABLE_SQLITE)
namespace repertory::utils::db::sqlite {
void db_insert::context::clear() {
stmt.reset();
values.clear();
}
auto db_insert::column_value(std::string column_name,
db_types_t value) -> db_insert & {
context_->values[column_name] = value;
ctx_->values[column_name] = value;
return *this;
}
auto db_insert::dump() const -> std::string {
std::stringstream query;
query << "INSERT ";
if (context_->or_replace) {
if (ctx_->or_replace) {
query << "OR REPLACE ";
}
query << "INTO \"" << context_->table_name << "\" (";
query << "INTO \"" << ctx_->table_name << "\" (";
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
idx < static_cast<std::int32_t>(ctx_->values.size()); idx++) {
if (idx > 0) {
query << ", ";
}
query << '"' << std::next(context_->values.begin(), idx)->first << '"';
query << '"' << std::next(ctx_->values.begin(), idx)->first << '"';
}
query << ") VALUES (";
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
idx < static_cast<std::int32_t>(ctx_->values.size()); idx++) {
if (idx > 0) {
query << ", ";
}
@ -62,36 +67,36 @@ auto db_insert::dump() const -> std::string {
auto db_insert::go() const -> db_result<context> {
sqlite3_stmt *stmt_ptr{nullptr};
auto query_str = dump();
auto res = sqlite3_prepare_v2(context_->db3, query_str.c_str(), -1, &stmt_ptr,
nullptr);
context_->stmt = db3_stmt_t{
auto res =
sqlite3_prepare_v2(ctx_->db3, query_str.c_str(), -1, &stmt_ptr, nullptr);
ctx_->stmt = db3_stmt_t{
stmt_ptr,
sqlite3_statement_deleter(),
};
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
res = std::visit(
overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
},
},
std::next(context_->values.begin(), idx)->second);
idx < static_cast<std::int32_t>(ctx_->values.size()); idx++) {
res = std::visit(overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(ctx_->stmt.get(), idx + 1,
data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(ctx_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
},
},
std::next(ctx_->values.begin(), idx)->second);
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
}
return {context_, res};
return {ctx_, res};
}
} // namespace repertory::utils::db::sqlite

View File

@ -24,6 +24,17 @@
#if defined(PROJECT_ENABLE_SQLITE)
namespace repertory::utils::db::sqlite {
void db_select::context::clear() {
columns.clear();
count_columns.clear();
group_by.clear();
limit.reset();
offset.reset();
order_by.reset();
stmt.reset();
where_data.reset();
}
auto db_select::context::db_select_op_t::dump() const -> std::string {
return db_select{ctx}.dump();
}
@ -58,13 +69,13 @@ auto db_select::context::db_select_op_t::order_by(std::string column_name,
}
auto db_select::column(std::string column_name) -> db_select & {
context_->columns.push_back(column_name);
ctx_->columns.push_back(column_name);
return *this;
}
auto db_select::count(std::string column_name, std::string as_column_name)
-> db_select & {
context_->count_columns[column_name] = as_column_name;
auto db_select::count(std::string column_name,
std::string as_column_name) -> db_select & {
ctx_->count_columns[column_name] = as_column_name;
return *this;
}
@ -72,59 +83,59 @@ auto db_select::dump() const -> std::string {
std::stringstream query;
query << "SELECT ";
bool has_column{false};
if (context_->columns.empty()) {
if (context_->count_columns.empty()) {
if (ctx_->columns.empty()) {
if (ctx_->count_columns.empty()) {
query << "*";
has_column = true;
}
} else {
has_column = not context_->columns.empty();
for (std::size_t idx = 0U; idx < context_->columns.size(); idx++) {
has_column = not ctx_->columns.empty();
for (std::size_t idx = 0U; idx < ctx_->columns.size(); idx++) {
if (idx > 0U) {
query << ", ";
}
query << context_->columns.at(idx);
query << ctx_->columns.at(idx);
}
}
for (std::int32_t idx = 0U;
idx < static_cast<std::int32_t>(context_->count_columns.size()); idx++) {
idx < static_cast<std::int32_t>(ctx_->count_columns.size()); idx++) {
if (has_column || idx > 0) {
query << ", ";
}
query << "COUNT(\"";
auto &count_column = *std::next(context_->count_columns.begin(), idx);
auto &count_column = *std::next(ctx_->count_columns.begin(), idx);
query << count_column.first << "\") AS \"" << count_column.second << '"';
}
query << " FROM \"" << context_->table_name << "\"";
query << " FROM \"" << ctx_->table_name << "\"";
if (context_->where_data) {
if (ctx_->where_data) {
std::int32_t idx{};
query << " WHERE " << context_->where_data->base.dump(idx);
query << " WHERE " << ctx_->where_data->base.dump(idx);
}
if (not context_->group_by.empty()) {
if (not ctx_->group_by.empty()) {
query << " GROUP BY ";
for (std::size_t idx = 0U; idx < context_->group_by.size(); idx++) {
for (std::size_t idx = 0U; idx < ctx_->group_by.size(); idx++) {
if (idx > 0U) {
query << ", ";
}
query << "\"" << context_->group_by.at(idx) << "\"";
query << "\"" << ctx_->group_by.at(idx) << "\"";
}
}
if (context_->order_by.has_value()) {
query << " ORDER BY \"" << context_->order_by.value().first << "\" ";
query << (context_->order_by.value().second ? "ASC" : "DESC");
if (ctx_->order_by.has_value()) {
query << " ORDER BY \"" << ctx_->order_by.value().first << "\" ";
query << (ctx_->order_by.value().second ? "ASC" : "DESC");
}
if (context_->limit.has_value()) {
query << " LIMIT " << context_->limit.value();
if (ctx_->limit.has_value()) {
query << " LIMIT " << ctx_->limit.value();
}
if (context_->offset.has_value()) {
query << " OFFSET " << context_->offset.value();
if (ctx_->offset.has_value()) {
query << " OFFSET " << ctx_->offset.value();
}
query << ';';
@ -135,82 +146,86 @@ auto db_select::dump() const -> std::string {
auto db_select::go() const -> db_result<context> {
sqlite3_stmt *stmt_ptr{nullptr};
auto query_str = dump();
auto res = sqlite3_prepare_v2(context_->db3, query_str.c_str(), -1, &stmt_ptr,
nullptr);
context_->stmt = db3_stmt_t{
auto res =
sqlite3_prepare_v2(ctx_->db3, query_str.c_str(), -1, &stmt_ptr, nullptr);
ctx_->stmt = db3_stmt_t{
stmt_ptr,
sqlite3_statement_deleter(),
};
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
if (not context_->where_data) {
return {context_, res};
if (not ctx_->where_data) {
return {ctx_, res};
}
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->where_data->values.size());
idx < static_cast<std::int32_t>(ctx_->where_data->values.size());
idx++) {
res = std::visit(
overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
return sqlite3_bind_int64(ctx_->stmt.get(), idx + 1, data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
return sqlite3_bind_text(ctx_->stmt.get(), idx + 1, data.c_str(),
-1, nullptr);
},
},
context_->where_data->values.at(static_cast<std::size_t>(idx)));
ctx_->where_data->values.at(static_cast<std::size_t>(idx)));
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
}
return {context_, res};
return {ctx_, res};
}
auto db_select::group(context::w_t::group_func_t func) -> context::w_t::wn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.group(std::move(func));
return ctx_->where_data->base.group(std::move(func));
}
auto db_select::group_by(std::string column_name) -> db_select & {
context_->group_by.emplace_back(std::move(column_name));
ctx_->group_by.emplace_back(std::move(column_name));
return *this;
}
auto db_select::limit(std::int32_t value) -> db_select & {
context_->limit = value;
ctx_->limit = value;
return *this;
}
auto db_select::offset(std::int32_t value) -> db_select & {
context_->offset = value;
ctx_->offset = value;
return *this;
}
auto db_select::order_by(std::string column_name, bool ascending)
-> db_select & {
context_->order_by = {column_name, ascending};
auto db_select::order_by(std::string column_name,
bool ascending) -> db_select & {
ctx_->order_by = {column_name, ascending};
return *this;
}
auto db_select::where(std::string column_name) const -> context::w_t::cn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.where(column_name);
return ctx_->where_data->base.where(column_name);
}
} // namespace repertory::utils::db::sqlite

View File

@ -24,6 +24,14 @@
#if defined(PROJECT_ENABLE_SQLITE)
namespace repertory::utils::db::sqlite {
void db_update::context::clear() {
column_values.clear();
limit.reset();
order_by.reset();
stmt.reset();
where_data.reset();
}
auto db_update::context::db_update_op_t::dump() const -> std::string {
return db_update{ctx}.dump();
}
@ -45,38 +53,38 @@ auto db_update::context::db_update_op_t::order_by(std::string column_name,
return *this;
}
auto db_update::column_value(std::string column_name, db_types_t value)
-> db_update & {
context_->column_values[column_name] = value;
auto db_update::column_value(std::string column_name,
db_types_t value) -> db_update & {
ctx_->column_values[column_name] = value;
return *this;
}
auto db_update::dump() const -> std::string {
std::stringstream query;
query << "UPDATE \"" << context_->table_name << "\" SET ";
query << "UPDATE \"" << ctx_->table_name << "\" SET ";
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->column_values.size()); idx++) {
idx < static_cast<std::int32_t>(ctx_->column_values.size()); idx++) {
if (idx > 0) {
query << ", ";
}
auto column = std::next(context_->column_values.begin(), idx);
auto column = std::next(ctx_->column_values.begin(), idx);
query << '"' << column->first << "\"=?" + std::to_string(idx + 1);
}
if (context_->where_data) {
auto idx{static_cast<std::int32_t>(context_->column_values.size())};
query << " WHERE " << context_->where_data->base.dump(idx);
if (ctx_->where_data) {
auto idx{static_cast<std::int32_t>(ctx_->column_values.size())};
query << " WHERE " << ctx_->where_data->base.dump(idx);
}
if (context_->order_by.has_value()) {
query << " ORDER BY \"" << context_->order_by.value().first << "\" ";
query << (context_->order_by.value().second ? "ASC" : "DESC");
if (ctx_->order_by.has_value()) {
query << " ORDER BY \"" << ctx_->order_by.value().first << "\" ";
query << (ctx_->order_by.value().second ? "ASC" : "DESC");
}
if (context_->limit.has_value()) {
query << " LIMIT " << context_->limit.value();
if (ctx_->limit.has_value()) {
query << " LIMIT " << ctx_->limit.value();
}
query << ';';
@ -87,100 +95,101 @@ auto db_update::dump() const -> std::string {
auto db_update::go() const -> db_result<context> {
sqlite3_stmt *stmt_ptr{nullptr};
auto query_str = dump();
auto res = sqlite3_prepare_v2(context_->db3, query_str.c_str(), -1, &stmt_ptr,
nullptr);
context_->stmt = db3_stmt_t{
auto res =
sqlite3_prepare_v2(ctx_->db3, query_str.c_str(), -1, &stmt_ptr, nullptr);
ctx_->stmt = db3_stmt_t{
stmt_ptr,
sqlite3_statement_deleter(),
};
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->column_values.size()); idx++) {
res = std::visit(
overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
},
},
std::next(context_->column_values.begin(), idx)->second);
idx < static_cast<std::int32_t>(ctx_->column_values.size()); idx++) {
res = std::visit(overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(ctx_->stmt.get(), idx + 1,
data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(ctx_->stmt.get(), idx + 1,
data.c_str(), -1, nullptr);
},
},
std::next(ctx_->column_values.begin(), idx)->second);
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
}
if (not context_->where_data) {
return {context_, res};
if (not ctx_->where_data) {
return {ctx_, res};
}
for (std::int32_t idx = 0;
idx < static_cast<std::int32_t>(context_->where_data->values.size());
idx < static_cast<std::int32_t>(ctx_->where_data->values.size());
idx++) {
res = std::visit(
overloaded{
[this, &idx](std::int64_t data) -> std::int32_t {
return sqlite3_bind_int64(
context_->stmt.get(),
idx +
static_cast<std::int32_t>(
context_->column_values.size()) +
ctx_->stmt.get(),
idx + static_cast<std::int32_t>(ctx_->column_values.size()) +
1,
data);
},
[this, &idx](const std::string &data) -> std::int32_t {
return sqlite3_bind_text(context_->stmt.get(),
idx +
static_cast<std::int32_t>(
context_->column_values.size()) +
1,
data.c_str(), -1, nullptr);
return sqlite3_bind_text(
ctx_->stmt.get(),
idx + static_cast<std::int32_t>(ctx_->column_values.size()) +
1,
data.c_str(), -1, nullptr);
},
},
context_->where_data->values.at(static_cast<std::size_t>(idx)));
ctx_->where_data->values.at(static_cast<std::size_t>(idx)));
if (res != SQLITE_OK) {
return {context_, res};
return {ctx_, res};
}
}
return {context_, res};
return {ctx_, res};
}
auto db_update::group(context::w_t::group_func_t func) -> context::w_t::wn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.group(std::move(func));
return ctx_->where_data->base.group(std::move(func));
}
auto db_update::limit(std::int32_t value) -> db_update & {
context_->limit = value;
ctx_->limit = value;
return *this;
}
auto db_update::order_by(std::string column_name, bool ascending)
-> db_update & {
context_->order_by = {column_name, ascending};
auto db_update::order_by(std::string column_name,
bool ascending) -> db_update & {
ctx_->order_by = {column_name, ascending};
return *this;
}
auto db_update::where(std::string column_name) const -> context::w_t::cn_t {
if (not context_->where_data) {
context_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, context_},
if (not ctx_->where_data) {
ctx_->where_data = std::make_unique<context::wd_t>(context::wd_t{
context::w_t{0U, ctx_},
{},
{},
});
}
return context_->where_data->base.where(column_name);
return ctx_->where_data->base.where(column_name);
}
} // namespace repertory::utils::db::sqlite