From 6477f0912503833495f0a91eb91517cb95cdc69c Mon Sep 17 00:00:00 2001 From: Mike Neilson Date: Thu, 10 Mar 2022 20:11:30 -0800 Subject: [PATCH] Added additional exception class. Handles the case of user defined exception in pl/pgsql to it can be reported back to the calling application. --- include/sqlpp11/postgresql/exception.h | 24 ++++++++++++++++++++++++ include/sqlpp11/postgresql/result.h | 3 +++ tests/postgresql/usage/Exceptions.cpp | 24 +++++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/sqlpp11/postgresql/exception.h b/include/sqlpp11/postgresql/exception.h index 6179b945..3ea6a455 100644 --- a/include/sqlpp11/postgresql/exception.h +++ b/include/sqlpp11/postgresql/exception.h @@ -125,6 +125,30 @@ namespace sqlpp } }; + /** Any error not covered by standard errors. + * For example custom error code from a user + * defined pl/pgsql function + * + */ + class DLL_PUBLIC sql_user_error : public sql_error + { + std::string m_Code; + + public: + sql_user_error(std::string whatarg, std::string code) : sql_error(std::move(whatarg)), m_Code(std::move(code)) + { + } + sql_user_error(std::string whatarg, std::string query, std::string code) : sql_error(std::move(whatarg),std::move(query)), m_Code(std::move(code)) + { + } + + /// The code so the code raised + const std::string& code() const noexcept + { + return m_Code; + } + }; + // TODO: should this be called statement_completion_unknown!? /// "Help, I don't know whether transaction was committed successfully!" /** Exception that might be thrown in rare cases where the connection to the diff --git a/include/sqlpp11/postgresql/result.h b/include/sqlpp11/postgresql/result.h index d985ce3c..cc56d1f5 100644 --- a/include/sqlpp11/postgresql/result.h +++ b/include/sqlpp11/postgresql/result.h @@ -273,6 +273,9 @@ namespace sqlpp if (strcmp(code, "P0003") == 0) throw plpgsql_too_many_rows(Err, Query); throw plpgsql_error(Err, Query); + break; + default: + throw sql_user_error(Err, Query, code); } throw sql_error(Err, Query); } diff --git a/tests/postgresql/usage/Exceptions.cpp b/tests/postgresql/usage/Exceptions.cpp index 512b5b97..6144918a 100644 --- a/tests/postgresql/usage/Exceptions.cpp +++ b/tests/postgresql/usage/Exceptions.cpp @@ -24,7 +24,10 @@ */ #include +#include #include +#include +#include #include "assertThrow.h" @@ -32,6 +35,8 @@ #include "TabFoo.h" #include "make_test_connection.h" +SQLPP_ALIAS_PROVIDER(returnVal) + namespace sql = sqlpp::postgresql; int Exceptions(int, char*[]) { @@ -57,12 +62,29 @@ int Exceptions(int, char*[]) c_timepoint timestamp with time zone DEFAULT now(), c_day date ))"); + db.execute(R"(create or replace function cause_error() returns int as $$ + begin + raise exception 'User error' USING ERRCODE='ZX123'; + end; + $$ language plpgsql + )"); assert_throw(db(insert_into(foo).set(foo.beta = std::numeric_limits::max() + 1)), sql::data_exception); assert_throw(db(insert_into(foo).set(foo.gamma = "123456")), sql::check_violation); db(insert_into(foo).set(foo.beta = 5)); assert_throw(db(insert_into(foo).set(foo.beta = 5)), sql::integrity_constraint_violation); - assert_throw(db.last_insert_id("tabfoo", "no_such_column"), sqlpp::postgresql::undefined_table); + assert_throw(db.last_insert_id("tabfoo", "no_such_column"), sqlpp::postgresql::undefined_table); + + try + { + db.execute("select cause_error();"); + } + catch( const sql::sql_user_error& e) + { + std::cout << e.code(); + assert( e.code() == "ZX123"); + } + } catch (const sql::failure& e) {