118 lines
3.7 KiB
C++
118 lines
3.7 KiB
C++
/**
|
|
* @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
|