统一SQLException

This commit is contained in:
fasiondog 2021-06-30 02:01:16 +08:00
parent 55d5f7cdc1
commit f04c8dbec3
10 changed files with 81 additions and 103 deletions

View File

@ -11,6 +11,7 @@
#define HIKYUU_DB_CONNECT_H
#include "DBConnectBase.h"
#include "SQLException.h"
#include "DBCondition.h"
#include "SQLStatementBase.h"
#include "TransAction.h"

View File

@ -14,6 +14,7 @@
#include "../../utilities/Parameter.h"
#include "DBCondition.h"
#include "SQLStatementBase.h"
#include "SQLException.h"
namespace hku {
@ -275,6 +276,13 @@ void DBConnectBase::save(T& item, bool autotrans) {
if (autotrans) {
commit();
}
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "failed save! sql: {}! {}", st->getSqlString(), e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
@ -312,6 +320,12 @@ void DBConnectBase::batchSave(InputIterator first, InputIterator last, bool auto
commit();
}
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "failed batch save! sql: {}! {}", st->getSqlString(), e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
@ -390,11 +404,17 @@ void DBConnectBase::batchUpdate(InputIterator first, InputIterator last, bool au
commit();
}
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "failed batch update! sql: {}! {}", st->getSqlString(), e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
}
HKU_THROW("failed batch save! sql: {}! {}", st->getSqlString(), e.what());
HKU_THROW("failed batch update! sql: {}! {}", st->getSqlString(), e.what());
} catch (...) {
if (autotrans) {
@ -439,6 +459,13 @@ void DBConnectBase::remove(T& item, bool autotrans) {
if (autotrans) {
commit();
}
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "failed delete! sql: {}! {}", st->getSqlString(), e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
@ -472,6 +499,13 @@ void DBConnectBase::batchRemove(InputIterator first, InputIterator last, bool au
if (autotrans) {
commit();
}
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "failed batch delete! {}", e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
@ -496,11 +530,16 @@ inline void DBConnectBase::remove(const std::string& tablename, const std::strin
try {
exec(sql);
} catch (hku::SQLException& e) {
if (autotrans) {
rollback();
}
SQL_THROW(e.errcode(), "Failed exec sql: {}! {}", sql, e.what());
} catch (std::exception& e) {
if (autotrans) {
rollback();
}
HKU_THROW(R"(Failed exec sql: {}! {})", sql, e.what());
HKU_THROW("Failed exec sql: {}! {}", sql, e.what());
} catch (...) {
if (autotrans) {
rollback();

View File

@ -12,25 +12,24 @@
namespace hku {
/** SQLite 处理异常 */
class SQLiteException : public hku::exception {
/** SQL 数据库引擎处理异常 */
class SQLException : public hku::exception {
public:
SQLiteException() = delete;
SQLException() = delete;
/**
* SQLite
* @param errcode SQLite错误码
* @param msg SQLite错误信息
*/
SQLiteException(int errcode, const std::string& msg)
: hku::exception(msg), m_errcode(errcode) {}
SQLException(int errcode, const std::string& msg) : hku::exception(msg), m_errcode(errcode) {}
/**
* SQLite
* @param errcode SQLite错误码
* @param msg SQLite错误信息
*/
SQLiteException(int errcode, const char* msg) : hku::exception(msg), m_errcode(errcode) {}
SQLException(int errcode, const char* msg) : hku::exception(msg), m_errcode(errcode) {}
/** 获取 SQLite 错误码 */
int errcode() const {
@ -41,20 +40,20 @@ private:
int m_errcode;
};
#define SQLITE_CHECK(expr, errcode, ...) \
#define SQL_CHECK(expr, errcode, ...) \
do { \
if (!(expr)) { \
throw SQLiteException( \
throw SQLException( \
errcode, fmt::format("CHECK({}) {} [{}] ({}:{})", #expr, fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} \
} while (0)
#define SQLITE_THROW(errcode, ...) \
do { \
throw SQLiteException(errcode, \
fmt::format("EXCEPTION: {} [{}] ({}:{})", fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
#define SQL_THROW(errcode, ...) \
do { \
throw SQLException(errcode, \
fmt::format("EXCEPTION: {} [{}] ({}:{})", fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} while (0)
} // namespace hku

View File

@ -73,14 +73,14 @@ void MySQLConnect::exec(const string& sql_string) {
if (ping()) {
ret = mysql_query(m_mysql, sql_string.c_str());
} else {
MYSQL_THROW(ret, "SQL error{}! error code{}, error msg: {}", sql_string, ret,
mysql_error(m_mysql));
SQL_THROW(ret, "SQL error{}! error code{}, error msg: {}", sql_string, ret,
mysql_error(m_mysql));
}
}
if (ret) {
MYSQL_THROW(ret, "SQL error{}! error code{}, error msg: {}", sql_string, ret,
mysql_error(m_mysql));
SQL_THROW(ret, "SQL error{}! error code{}, error msg: {}", sql_string, ret,
mysql_error(m_mysql));
}
do {
@ -98,8 +98,8 @@ void MySQLConnect::exec(const string& sql_string) {
HKU_TRACE("num_rows: {}", num_rows);
#endif
} else {
MYSQL_THROW(ret, "mysql_field_count error{}! error code{}, error msg: {}",
sql_string, ret, mysql_error(m_mysql));
SQL_THROW(ret, "mysql_field_count error{}! error code{}, error msg: {}",
sql_string, ret, mysql_error(m_mysql));
}
}
} while (!mysql_next_result(m_mysql));

View File

@ -13,7 +13,6 @@
#include "../DBConnectBase.h"
#include "MySQLStatement.h"
#include "MySQLException.h"
#if defined(_MSC_VER)
#include <mysql.h>

View File

@ -1,59 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-06-26
* Author: fasiondog
*/
#pragma once
#include <fmt/format.h>
#include "hikyuu/exception.h"
namespace hku {
/** MYSQL 处理异常 */
class MySQLException : public hku::exception {
public:
MySQLException() = delete;
/**
* MYSQL
* @param errcode MYSQL
* @param msg MYSQL
*/
MySQLException(int errcode, const std::string& msg) : hku::exception(msg), m_errcode(errcode) {}
/**
* MYSQL
* @param errcode MYSQL
* @param msg MYSQL
*/
MySQLException(int errcode, const char* msg) : hku::exception(msg), m_errcode(errcode) {}
/** 获取 MYSQL 错误码 */
int errcode() const {
return m_errcode;
}
private:
int m_errcode;
};
#define MYSQL_CHECK(expr, errcode, ...) \
do { \
if (!(expr)) { \
throw MySQLException( \
errcode, fmt::format("CHECK({}) {} [{}] ({}:{})", #expr, fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} \
} while (0)
#define MYSQL_THROW(errcode, ...) \
do { \
throw MySQLException(errcode, \
fmt::format("EXCEPTION: {} [{}] ({}:{})", fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} while (0)
} // namespace hku

View File

@ -26,8 +26,8 @@ MySQLStatement::MySQLStatement(DBConnectBase* driver, const string& sql_statemen
std::string stmt_errorstr(mysql_stmt_error(m_stmt));
mysql_stmt_close(m_stmt);
m_stmt = nullptr;
MYSQL_THROW(ret, "Failed prepare sql statement: {}! error msg: {}!", sql_statement,
stmt_errorstr);
SQL_THROW(ret, "Failed prepare sql statement: {}! error msg: {}!", sql_statement,
stmt_errorstr);
}
auto param_count = mysql_stmt_param_count(m_stmt);
@ -57,7 +57,7 @@ MySQLStatement::~MySQLStatement() {
void MySQLStatement::_reset() {
if (m_needs_reset) {
int ret = mysql_stmt_reset(m_stmt);
MYSQL_CHECK(ret == 0, ret, "Failed reset statement! {}", mysql_stmt_error(m_stmt));
SQL_CHECK(ret == 0, ret, "Failed reset statement! {}", mysql_stmt_error(m_stmt));
// m_param_bind.clear();
// m_result_bind.clear();
// m_param_buffer.clear();
@ -73,10 +73,10 @@ void MySQLStatement::sub_exec() {
int ret = 0;
if (m_param_bind.size() > 0) {
ret = mysql_stmt_bind_param(m_stmt, m_param_bind.data());
MYSQL_CHECK(ret == 0, ret, "Failed mysql_stmt_bind_param! {}", mysql_stmt_error(m_stmt));
SQL_CHECK(ret == 0, ret, "Failed mysql_stmt_bind_param! {}", mysql_stmt_error(m_stmt));
}
ret = mysql_stmt_execute(m_stmt);
MYSQL_CHECK(ret == 0, ret, "Failed mysql_stmt_execute: {}", mysql_stmt_error(m_stmt));
SQL_CHECK(ret == 0, ret, "Failed mysql_stmt_execute: {}", mysql_stmt_error(m_stmt));
}
void MySQLStatement::_bindResult() {
@ -148,17 +148,17 @@ bool MySQLStatement::sub_moveNext() {
m_has_bind_result = true;
ret = mysql_stmt_bind_result(m_stmt, m_result_bind.data());
MYSQL_CHECK(ret == 0, ret, "Failed mysql_stmt_bind_result! {}", mysql_stmt_error(m_stmt));
SQL_CHECK(ret == 0, ret, "Failed mysql_stmt_bind_result! {}", mysql_stmt_error(m_stmt));
ret = mysql_stmt_store_result(m_stmt);
MYSQL_CHECK(ret == 0, ret, "Failed mysql_stmt_store_result! {}", mysql_stmt_error(m_stmt));
SQL_CHECK(ret == 0, ret, "Failed mysql_stmt_store_result! {}", mysql_stmt_error(m_stmt));
}
ret = mysql_stmt_fetch(m_stmt);
if (ret == 0) {
return true;
} else if (ret == 1) {
MYSQL_THROW(ret, "Error occurred in mysql_stmt_fetch! {}", mysql_stmt_error(m_stmt));
SQL_THROW(ret, "Error occurred in mysql_stmt_fetch! {}", mysql_stmt_error(m_stmt));
}
return false;
}

View File

@ -32,14 +32,14 @@ SQLiteConnect::SQLiteConnect(const Parameter& param) : DBConnectBase(param), m_d
flags = getParam<int>("flags");
}
int rc = sqlite3_open_v2(m_dbname.c_str(), &m_db, flags, NULL);
SQLITE_CHECK(rc == SQLITE_OK, rc, sqlite3_errmsg(m_db));
SQL_CHECK(rc == SQLITE_OK, rc, sqlite3_errmsg(m_db));
sqlite3_busy_handler(m_db, sqlite_busy_call_back, (void*)m_db);
} catch (std::out_of_range& e) {
HKU_FATAL("Can't get database name! {}", e.what());
close();
throw;
} catch (SQLiteException& e) {
} catch (SQLException& e) {
HKU_FATAL("Failed open database: {})! SQLite3 errcode: {}, errmsg: {}", m_dbname,
e.errcode(), e.what());
close();
@ -72,7 +72,7 @@ bool SQLiteConnect::ping() {
void SQLiteConnect::exec(const string& sql_string) {
int rc = sqlite3_exec(m_db, sql_string.c_str(), NULL, NULL, NULL);
SQLITE_CHECK(rc == SQLITE_OK, rc, "SQL error: {}! ({})", sqlite3_errmsg(m_db), sql_string);
SQL_CHECK(rc == SQLITE_OK, rc, "SQL error: {}! ({})", sqlite3_errmsg(m_db), sql_string);
}
SQLStatementPtr SQLiteConnect::getStatement(const string& sql_statement) {

View File

@ -13,7 +13,6 @@
#include <sqlite3.h>
#include "../DBConnectBase.h"
#include "SQLiteStatement.h"
#include "SQLiteException.h"
namespace hku {

View File

@ -23,8 +23,8 @@ SQLiteStatement::SQLiteStatement(DBConnectBase* driver, const string& sql_statem
sqlite3_prepare_v2(m_db, m_sql_string.c_str(), m_sql_string.size() + 1, &m_stmt, NULL);
if (status != SQLITE_OK) {
sqlite3_finalize(m_stmt);
SQLITE_THROW(status, "Failed prepare sql statement: {}! error msg: {}", m_sql_string,
sqlite3_errmsg(m_db));
SQL_THROW(status, "Failed prepare sql statement: {}! error msg: {}", m_sql_string,
sqlite3_errmsg(m_db));
}
HKU_CHECK(m_stmt != 0, "Invalid SQL statement: {}", m_sql_string);
@ -39,7 +39,7 @@ void SQLiteStatement::_reset() {
int status = sqlite3_reset(m_stmt);
if (status != SQLITE_OK) {
m_step_status = SQLITE_DONE;
SQLITE_THROW(status, sqlite3_errmsg(m_db));
SQL_THROW(status, sqlite3_errmsg(m_db));
}
m_needs_reset = false;
m_step_status = SQLITE_DONE;
@ -52,7 +52,7 @@ void SQLiteStatement::sub_exec() {
m_step_status = sqlite3_step(m_stmt);
m_needs_reset = true;
if (m_step_status != SQLITE_DONE && m_step_status != SQLITE_ROW) {
SQLITE_THROW(m_step_status, sqlite3_errmsg(m_db));
SQL_THROW(m_step_status, sqlite3_errmsg(m_db));
}
}
@ -68,7 +68,7 @@ bool SQLiteStatement::sub_moveNext() {
} else if (m_step_status == SQLITE_ROW) {
return true;
} else {
SQLITE_THROW(m_step_status, sqlite3_errmsg(m_db));
SQL_THROW(m_step_status, sqlite3_errmsg(m_db));
}
}
} else {
@ -85,31 +85,31 @@ int SQLiteStatement::sub_getNumColumns() const {
void SQLiteStatement::sub_bindNull(int idx) {
_reset();
int status = sqlite3_bind_null(m_stmt, idx + 1);
SQLITE_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
}
void SQLiteStatement::sub_bindInt(int idx, int64_t value) {
_reset();
int status = sqlite3_bind_int64(m_stmt, idx + 1, value);
SQLITE_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
}
void SQLiteStatement::sub_bindText(int idx, const string& item) {
_reset();
int status = sqlite3_bind_text(m_stmt, idx + 1, item.c_str(), -1, SQLITE_TRANSIENT);
SQLITE_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
}
void SQLiteStatement::sub_bindDouble(int idx, double item) {
_reset();
int status = sqlite3_bind_double(m_stmt, idx + 1, item);
SQLITE_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
}
void SQLiteStatement::sub_bindBlob(int idx, const string& item) {
_reset();
int status = sqlite3_bind_blob(m_stmt, idx + 1, item.data(), item.size(), SQLITE_TRANSIENT);
SQLITE_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
SQL_CHECK(status == SQLITE_OK, status, sqlite3_errmsg(m_db));
}
void SQLiteStatement::sub_getColumnAsInt64(int idx, int64_t& item) {