Commit 7e80c683 authored by Vadim Zeitlin's avatar Vadim Zeitlin

Use parameter names from the query, if given, in error messages.

Improve the error messages by using the parameter names used in the query
itself, if any, when the query parameters were bound by position and not by
name.

This means that errors for a query like

            sql << "insert into soci_test(name, age) values (:name, :age)",
                   use(name), use(age));

will now contain "with :name=... :age=..." even though the parameter names
were not passed to use().
parent 8b0c3720
......@@ -184,6 +184,7 @@ struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend
long long get_affected_rows();
int get_number_of_rows();
std::string get_parameter_name(int index) const;
std::string rewrite_for_procedure_call(std::string const& query);
......
......@@ -116,6 +116,7 @@ struct SOCI_EMPTY_DECL empty_statement_backend : details::statement_backend
long long get_affected_rows();
int get_number_of_rows();
std::string get_parameter_name(int index) const;
std::string rewrite_for_procedure_call(std::string const& query);
......
......@@ -185,6 +185,7 @@ struct firebird_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const &query);
......
......@@ -153,6 +153,7 @@ struct mysql_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const &query);
......
......@@ -220,6 +220,7 @@ struct odbc_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const &query);
......
......@@ -188,6 +188,7 @@ struct oracle_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const &query);
......
......@@ -231,6 +231,7 @@ struct postgresql_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const & query);
......
......@@ -170,6 +170,8 @@ public:
virtual long long get_affected_rows() = 0;
virtual int get_number_of_rows() = 0;
virtual std::string get_parameter_name(int index) const = 0;
virtual std::string rewrite_for_procedure_call(std::string const& query) = 0;
virtual int prepare_for_describe() = 0;
......
......@@ -186,6 +186,7 @@ struct sqlite3_statement_backend : details::statement_backend
virtual long long get_affected_rows();
virtual int get_number_of_rows();
virtual std::string get_parameter_name(int index) const;
virtual std::string rewrite_for_procedure_call(std::string const &query);
......
......@@ -211,6 +211,11 @@ int db2_statement_backend::get_number_of_rows()
return numRowsFetched;
}
std::string db2_statement_backend::get_parameter_name(int index) const
{
return names_.at(index);
}
std::string db2_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -63,6 +63,12 @@ int empty_statement_backend::get_number_of_rows()
return 1;
}
std::string empty_statement_backend::get_parameter_name(int /* index */) const
{
// ...
return std::string();
}
std::string empty_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -631,6 +631,19 @@ int firebird_statement_backend::get_number_of_rows()
return rowsFetched_;
}
std::string firebird_statement_backend::get_parameter_name(int index) const
{
for (std::map<std::string, int>::const_iterator i = names_.begin();
i != names_.end();
++i)
{
if (i->second == index)
return i->first;
}
return std::string();
}
std::string firebird_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -380,6 +380,11 @@ int mysql_statement_backend::get_number_of_rows()
return numberOfRows_ - currentRow_;
}
std::string mysql_statement_backend::get_parameter_name(int index) const
{
return names_.at(index);
}
std::string mysql_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -249,6 +249,11 @@ int odbc_statement_backend::get_number_of_rows()
return numRowsFetched_;
}
std::string odbc_statement_backend::get_parameter_name(int index) const
{
return names_.at(index);
}
std::string odbc_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -147,6 +147,12 @@ int oracle_statement_backend::get_number_of_rows()
return rows;
}
std::string oracle_statement_backend::get_parameter_name(int /* index */) const
{
// TODO: How to get the parameter names from the query we prepared?
return std::string();
}
std::string oracle_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -473,6 +473,11 @@ int postgresql_statement_backend::get_number_of_rows()
return numberOfRows_ - currentRow_;
}
std::string postgresql_statement_backend::get_parameter_name(int index) const
{
return names_.at(index);
}
std::string postgresql_statement_backend::rewrite_for_procedure_call(
std::string const & query)
{
......
......@@ -294,6 +294,29 @@ int sqlite3_statement_backend::get_number_of_rows()
return static_cast<int>(dataCache_.size());
}
std::string sqlite3_statement_backend::get_parameter_name(int index) const
{
// Notice that SQLite host parameters are counted from 1, not 0.
char const* name = sqlite3_bind_parameter_name(stmt_, index + 1);
if (!name)
return std::string();
// SQLite returns parameters with the leading colon which is inconsistent
// with the other backends, so get rid of it as well several other
// characters which can be used for named parameters with SQLite.
switch (*name)
{
case ':':
case '?':
case '@':
case '$':
name++;
break;
}
return name;
}
std::string sqlite3_statement_backend::rewrite_for_procedure_call(
std::string const &query)
{
......
......@@ -753,12 +753,19 @@ statement_impl::rethrow_current_exception_with_context(char const* operation)
oss << ", ";
details::use_type_base const& u = *uses_[i];
std::string const& name = u.get_name();
oss << ":";
// Use the name specified in the "use()" call if any,
// otherwise get the name of the matching parameter from
// the query itself, as parsed by the backend.
std::string name = u.get_name();
if (name.empty())
oss << (i + 1);
else
name = backEnd_->get_parameter_name(i);
oss << ":";
if (!name.empty())
oss << name;
else
oss << (i + 1);
oss << "=";
u.dump_value(oss);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment