Skip to content

Commit

Permalink
Merge pull request #113 from zussel/feature/dbexception
Browse files Browse the repository at this point in the history
Provide database error information (#107)
  • Loading branch information
zussel committed Jan 6, 2020
2 parents 5d16ad1 + 75653d1 commit 43e109d
Show file tree
Hide file tree
Showing 48 changed files with 488 additions and 400 deletions.
3 changes: 2 additions & 1 deletion include/matador/db/mssql/mssql_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class OOS_MSSQL_API mssql_connection : public connection_impl
void rollback() override;

std::string type() const override;
std::string version() const override;
std::string client_version() const override;
std::string server_version() const override;

bool exists(const std::string &tablename) override;
std::vector<field> describe(const std::string &table) override;
Expand Down
19 changes: 4 additions & 15 deletions include/matador/db/mssql/mssql_exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,13 @@ namespace matador {

namespace mssql {

void throw_error(SQLRETURN ret, SQLSMALLINT htype, SQLHANDLE hndl, const std::string &source, const std::string &sql = "");
void throw_database_error(SQLRETURN ret, SQLSMALLINT htype, SQLHANDLE hndl, const std::string &source, const std::string &sql = "");

void throw_error(const std::string &source, const std::string &sql = "");
//void throw_error(SQLRETURN ret, SQLSMALLINT htype, SQLHANDLE hndl, const std::string &source, const std::string &sql = "");

bool is_success(SQLRETURN ret);

class mssql_exception : public sql_exception
{
public:
mssql_exception(const std::string &source, const std::string &what);
};
//void throw_error(const std::string &source, const std::string &sql = "");

class mssql_stmt_exception : public sql_exception
{
public:
explicit mssql_stmt_exception(const std::string &what);
mssql_stmt_exception(const std::string &source, const std::string &what);
};
bool is_success(SQLRETURN ret);

}

Expand Down
6 changes: 3 additions & 3 deletions include/matador/db/mssql/mssql_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class mssql_result : public detail::result_impl
auto type = (SQLSMALLINT)type2int(matador::data_type_traits<T>::builtin_type());
SQLRETURN ret = SQLGetData(stmt_, (SQLUSMALLINT)(index), type, &val, sizeof(T), &info);
if (!SQL_SUCCEEDED(ret)) {
throw_error(ret, SQL_HANDLE_STMT, stmt_, "mssql", "error on retrieving column value");
throw_database_error(ret, SQL_HANDLE_STMT, stmt_, "mssql");
}
return val;
}
Expand All @@ -79,7 +79,7 @@ class mssql_result : public detail::result_impl
SQLLEN info = 0;
SQLRETURN ret = SQLGetData(stmt_, (SQLUSMALLINT)(index), SQL_C_CHAR, buf, 1024, &info);
if (!SQL_SUCCEEDED(ret)) {
throw_error(ret, SQL_HANDLE_STMT, stmt_, "mssql", "error on retrieving column value");
throw_database_error(ret, SQL_HANDLE_STMT, stmt_, "mssql");
}
return std::string(buf, info);
}
Expand Down Expand Up @@ -117,7 +117,7 @@ class mssql_result : public detail::result_impl
} else {
std::stringstream msg;
msg << "error on retrieving value for column " << id << " (type " << typeid(T).name() << ")";
throw_error(ret, SQL_HANDLE_STMT, stmt_, "mssql", msg.str());
throw_database_error(ret, SQL_HANDLE_STMT, stmt_, "mssql", msg.str());
}
}

Expand Down
18 changes: 18 additions & 0 deletions include/matador/db/mysql/mysql_bool.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Created by sascha on 02.01.20.
//

#ifndef MATADOR_MYSQL_BOOL_HPP
#define MATADOR_MYSQL_BOOL_HPP

#ifdef _MSC_VER
#include <mysql.h>
#else
#include <mysql/mysql.h>
#endif

#if !MARIADB_PACKAGE_VERSION_ID && MYSQL_VERSION_ID >= 80001
typedef bool my_bool;
#endif

#endif //MATADOR_MYSQL_BOOL_HPP
3 changes: 2 additions & 1 deletion include/matador/db/mysql/mysql_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ class OOS_MYSQL_API mysql_connection : public connection_impl
void rollback() override;

std::string type() const override;
std::string version() const override;
std::string client_version() const override;
std::string server_version() const override;

bool exists(const std::string &tablename) override;
std::vector<field> describe(const std::string &table) override;
Expand Down
25 changes: 2 additions & 23 deletions include/matador/db/mysql/mysql_exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "matador/sql/sql_exception.hpp"

#ifdef _MSC_VER
//#include <winsock2.h>
#include <mysql.h>
#else
#include <mysql/mysql.h>
Expand All @@ -42,29 +41,9 @@ namespace matador {

namespace mysql {

void throw_error(const std::string &source, const std::string &sql = "");
void throw_error(MYSQL *db, const std::string &source, const std::string &sql = "");

void throw_error(int ec, MYSQL *db, const std::string &source, const std::string &sql = "");

void throw_stmt_error(int ec, MYSQL_STMT *stmt, const std::string &source, const std::string &sql = "");

class mysql_exception : public sql_exception
{
public:
mysql_exception(const std::string &source, const std::string &what);
mysql_exception(MYSQL *db, const std::string &source, const std::string &what);

virtual ~mysql_exception() throw();
};

class mysql_stmt_exception : public sql_exception
{
public:
explicit mysql_stmt_exception(const std::string &what);
mysql_stmt_exception(MYSQL_STMT *stmt, const std::string &source, const std::string &what);

virtual ~mysql_stmt_exception() throw();
};
void throw_stmt_error(MYSQL_STMT *stmt, const std::string &source, const std::string &sql = "");

}

Expand Down
10 changes: 9 additions & 1 deletion include/matador/db/mysql/mysql_parameter_binder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "matador/sql/parameter_binder.hpp"

#include "matador/db/mysql/mysql_result_info.hpp"
#include "matador/db/mysql/mysql_bool.hpp"

#ifdef _MSC_VER
#include <mysql.h>
Expand Down Expand Up @@ -55,10 +56,17 @@ class mysql_parameter_binder : public detail::parameter_binder_impl
std::vector<MYSQL_BIND>& bindings();
std::vector<mysql_result_info>& result_infos();


void bind_null(std::size_t index);
private:
struct is_null_t
{
my_bool is_null = false;
};

std::vector<MYSQL_BIND> host_array_;
std::vector<MYSQL_BIND> bind_;
std::vector<my_bool> is_null_vector;
std::vector<is_null_t> is_null_vector;
std::vector<mysql_result_info> info_;

size_t index_ = 0;
Expand Down
1 change: 1 addition & 0 deletions include/matador/db/mysql/mysql_prepared_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "matador/sql/result_impl.hpp"

#include "matador/db/mysql/mysql_result_info.hpp"
#include "matador/db/mysql/mysql_bool.hpp"

#ifdef _MSC_VER
//#include <winsock2.h>
Expand Down
2 changes: 2 additions & 0 deletions include/matador/db/mysql/mysql_result_info.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef MYSQL_RESULT_INFO_HPP
#define MYSQL_RESULT_INFO_HPP

#include "matador/db/mysql/mysql_bool.hpp"

#ifdef _MSC_VER
#include <mysql.h>
#else
Expand Down
4 changes: 0 additions & 4 deletions include/matador/db/mysql/mysql_statement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ class mysql_statement : public matador::detail::statement_impl
protected:
detail::parameter_binder_impl *binder() const override;

private:

// void bind_null(std::size_t index);

private:
MYSQL_STMT *stmt_ = nullptr;

Expand Down
3 changes: 2 additions & 1 deletion include/matador/db/postgresql/postgresql_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class MATADOR_POSTGRESQL_API postgresql_connection : public connection_impl
void rollback() override;

std::string type() const override;
std::string version() const override;
std::string client_version() const override;
std::string server_version() const override;

bool exists(const std::string &table_name) override;
std::vector<field> describe(const std::string &table) override;
Expand Down
28 changes: 1 addition & 27 deletions include/matador/db/postgresql/postgresql_exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,7 @@ namespace matador {

namespace postgresql {

#define THROW_POSTGRESQL_ERROR(db, source, msg) \
do { \
std::stringstream what; \
what << msg; \
throw postgresql_exception(db, source, what.str()); \
} while (false)

void throw_error(const std::string &source, const std::string &sql = "");

void throw_error(int ec, PGconn *db, const std::string &source, const std::string &sql = "");

class postgresql_exception : public sql_exception
{
public:
postgresql_exception(const std::string &source, const std::string &what);
postgresql_exception(PGconn *db, const std::string &source, const std::string &what);

~postgresql_exception() noexcept override = default;
};

class postgresql_stmt_exception : public sql_exception
{
public:
explicit postgresql_stmt_exception(const std::string &what);

~postgresql_stmt_exception() noexcept override = default;
};
void throw_database_error(PGresult *res, PGconn *db, const std::string &source, const std::string &sql = "");

}

Expand Down
3 changes: 2 additions & 1 deletion include/matador/db/sqlite/sqlite_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class OOS_SQLITE_API sqlite_connection : public connection_impl
void rollback() override;

std::string type() const override;
std::string version() const override;
std::string client_version() const override;
std::string server_version() const override;

bool exists(const std::string &table_name) override;
std::vector<field> describe(const std::string &table) override;
Expand Down
12 changes: 1 addition & 11 deletions include/matador/db/sqlite/sqlite_exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,11 @@

#include <sqlite3.h>

#include "matador/sql/sql_exception.hpp"

namespace matador {

namespace sqlite {

void throw_error(int ec, sqlite3 *db, const std::string &source, const std::string &sql = "");

class sqlite_exception : public sql_exception
{
public:
explicit sqlite_exception(const std::string &what);

~sqlite_exception() noexcept override = default;
};
void throw_database_error(int ec, sqlite3 *db, const std::string &source, const std::string &sql = "");

}

Expand Down
3 changes: 2 additions & 1 deletion include/matador/sql/connection_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class OOS_SQL_API connection_impl
virtual void rollback() = 0;

virtual std::string type() const = 0;
virtual std::string version() const = 0;
virtual std::string client_version() const = 0;
virtual std::string server_version() const = 0;

virtual bool exists(const std::string &table_name) = 0;
virtual std::vector<field> describe(const std::string &table) = 0;
Expand Down
112 changes: 112 additions & 0 deletions include/matador/sql/database_error.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//
// Created by sascha on 28.12.19.
//

#ifndef MATADOR_DATABASE_ERROR_HPP
#define MATADOR_DATABASE_ERROR_HPP

#ifdef _MSC_VER
#ifdef matador_sql_EXPORTS
#define OOS_SQL_API __declspec(dllexport)
#define EXPIMP_SQL_TEMPLATE
#else
#define OOS_SQL_API __declspec(dllimport)
#define EXPIMP_SQL_TEMPLATE extern
#endif
#pragma warning(disable: 4251)
#pragma warning(disable: 4355)
#else
#define OOS_SQL_API
#endif

#include <stdexcept>

namespace matador {

/**
* @brief Thrown by db backend containing all available error informations
*
* This exception is thrown by the database backend and contains
* all available error informations provided by the backend
*/
class OOS_SQL_API database_error : public std::runtime_error
{
public:
/**
* Creates a database error exception with error code.
*
* @param what Error message
* @param source Database vendor string
* @param ec Error code
* @param sql Optional sql statement string
*/
database_error(const std::string &what, std::string source, long ec, std::string sql = "");

/**
* Creates a database error exception with sql state and error code.
*
* @param what Error message
* @param source Database vendor string
* @param sqlstate SQL State
* @param ec Error code
* @param sql Optional sql statement string
*/
database_error(const std::string &what, std::string source, std::string sqlstate, long ec, std::string sql = "");

/**
* Creates a database error exception with sql state.
*
* @param what Error message
* @param source Database vendor string
* @param sqlstate SQL State
* @param sql Optional sql statement string
*/
database_error(const std::string &what, std::string source, std::string sqlstate, std::string sql = "");

/**
* Destroy the database error
*/
~database_error() noexcept override = default;

/**
* Returns the database vendor string.
*
* @return Database vendor string
*/
const char* source() const noexcept;

/**
* Returns a proprietary error code depending
* on the database backend.
*
* @return Proprietary database error code
*/
long error_code() const noexcept;

/**
* Returns the sql state according to the SQL standard
* provided by the database backend. It is a 5 char long
* string representing a sql error code.
*
* <a href="https://en.wikipedia.org/wiki/SQLSTATE">SQL States</a>
*
* @return SQL State
*/
const char* sql_state() const noexcept;

/**
* If available it returns a corresponding sql statement.
*
* @return Optional corresponding sql statement
*/
const char* sql_statement() const noexcept;

private:
std::string source_;
long error_code_ = 0;
std::string sqlstate_;
std::string sql_stmt_;
};

}
#endif //MATADOR_DATABASE_ERROR_HPP
Loading

0 comments on commit 43e109d

Please sign in to comment.