eis/mix_cc/sql/exec.h

118 lines
3.7 KiB
C
Raw Permalink Normal View History

/**
* @file mix_cc/sql/exec.h
* @brief
* @author Cat (null.null.null@qq.com)
* @version 0.1
* @date 2021-09-17
*
* Copyright: Baosight Co. Ltd.
* DO NOT COPY/USE WITHOUT PERMISSION
*
*/
#pragma once
#include "mix_cc/debug.h"
#include "mix_cc/exception.h"
#include "mix_cc/fp.h"
#include "mix_cc/sql/op/cmd.h"
#include "mix_cc/sql/select.h"
#include "mix_cc/sql/sqlapi_warpper.h"
#include "mix_cc/sql/statement.h"
#include <string>
#include <vector>
namespace mix_cc {
namespace sql {
namespace detail {
template <typename Tp>
constexpr auto parse_statement(Tp statement) {
return hana::flatten(
hana::make_tuple(statement.parse_prev(), hana::make_tuple(statement)));
}
template <typename SpeficDB, typename Row, typename Tp>
auto exec_special(Tp statement) -> maybe<std::vector<Row>> {
using row_t = Row;
SpeficDB sql_engine;
std::vector<row_t> results;
try {
if (!sql_engine.connect()) {
return {};
}
std::string statement_str;
hana::for_each(statement,
[&](auto st) { statement_str += st.get_command().c_str(); });
statement_str += ";";
sql_engine.cmd_.execute(_TSA(statement_str.c_str()));
if (sql_engine.cmd_.is_result_set() &&
sql_engine.cmd_.rows_affacted() != 0) {
while (sql_engine.cmd_.fetch_next()) {
row_t row_data;
hana::for_each(
statement[0_c].cols_, [&row_data, &sql_engine](auto col) {
hana::for_each(hana::keys(row_data), [&](auto key) {
if constexpr (col.col_name == key) {
hana::at_key(row_data, key) = sql_engine.cmd_.field(col);
}
});
});
results.emplace_back(row_data);
}
}
} catch (const SAException& e) {
DEBUG_PRINT_MIX_CC(std::string(e.ErrText().GetMultiByteChars()) +
" sql is: " + sql_engine.cmd_.command_text());
} catch (const std::exception& e) {
DEBUG_PRINT_MIX_CC(std::string(e.what()) +
" sql is: " + sql_engine.cmd_.command_text());
} catch (...) {
DEBUG_PRINT_MIX_CC("sql query exec error");
}
return results;
}
template <typename SpeficDB, typename Tp>
constexpr maybe<size_t> exec_general(Tp statement) {
SpeficDB sql_engine;
try {
if (!sql_engine.connect()) {
return {};
}
std::string statement_str;
hana::for_each(statement,
[&](auto st) { statement_str += st.get_command().c_str(); });
statement_str += ";";
sql_engine.cmd_.execute(_TSA(statement_str.c_str()));
return sql_engine.cmd_.rows_affacted();
} catch (const SAException& e) {
DEBUG_PRINT_MIX_CC(std::string(e.ErrText().GetMultiByteChars()) +
" sql is: " + sql_engine.cmd_.command_text());
} catch (const std::exception& e) {
DEBUG_PRINT_MIX_CC(std::string(e.what()) +
" sql is: " + sql_engine.cmd_.command_text());
} catch (...) {
DEBUG_PRINT_MIX_CC("sql query exec error");
}
return {};
}
} // namespace detail
template <typename SpeficDB, typename T, typename Tp,
std::enable_if_t<!std::is_same_v<T, size_t>, bool> = true>
constexpr auto exec(Tp statement)
-> maybe<std::vector<typename T::DataStruct>> {
auto parsed_statement = detail::parse_statement(statement);
return detail::exec_special<SpeficDB, typename T::DataStruct>(
parsed_statement);
}
template <typename SpeficDB, typename T, typename Tp,
std::enable_if_t<std::is_same_v<T, size_t>, bool> = true>
constexpr maybe<size_t> exec(Tp statement) {
auto parsed_statement = detail::parse_statement(statement);
return detail::exec_general<SpeficDB>(parsed_statement);
}
} // namespace sql
} // namespace mix_cc