I have a ODBC wrapper interface that enables me to execute SQL queries in C++. In particular, I use the named parameter idiom for the select statements, for example:
Table.Select("foo").GroupBy("bar").OrderBy("baz");
To achieve this effect, the class Table_t
returns a proxy object Select_t
:
class Table_t
{
// ...
public:
Select_t Select(std::string const &Stmt)
{ return {*this, Stmt}; }
void Execute(std::string const &Stmt);
};
Select_t
combines the basic statement with the additional clauses and executes the actual statement in the destructor:
class Select_t
{
private:
Table_t &Table;
std::string SelectStmt,
OrderStmt,
GroupStmt;
public:
Select_t(Table_t &Table_, std::string const &SelectStmt) :
Table(Table_), SelectStmt(SelectStmt_) {}
~Select_t()
{ /* Combine the statements */ Table.Execute(/* Combined statement */); }
Select_t &OrderBy(std::string const &OrderStmt_)
{ OrderStmt = OrderStmt_; return *this; }
Select_t &GroupBy(std::string const &GroupStmt_)
{ GroupStmt = GroupStmt_; return *this; }
};
The problem is that Table.Execute(Stmt)
may throw and I must not throw in a destructor. Is there a
way I can work around that while retaining the named parameter idiom?
So far the only idea I came up with is to add an Execute
function to Select_t
, but I would prefer not to:
Table.Select("foo").GroupBy("bar").OrderBy("baz").Execute();