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

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