SOCI/soci — pull request #138 by ricardofandrade (2013-04-17 18:25:48+00:00)
Title: Support for logging query parameters (MySQL & PostgreSQL)

Sometimes soci's basic logging support is too basic, this change aims to solve this issue with both performance and usability in mind.

Remarks:
- Direct uses of ```std::stream``` have been replaced with the ```log_stream``` class.
- ```session::get_log_stream()``` returns now a ```log_stream &```, it's the only breaking change on the public API.
- For now ```log_stream``` is implemented inside error.h/cpp, I need suggestions for a better place (log_stream.h/cpp?).
- ```log_stream``` allows conditional logging. Only works if the underlying ```std::ostream *``` is not null. You can test if general logging is available with ```log_stream::is_null()```.
- With ```log_stream::log_params(bool)``` you can enable and disable parameter logging during runtime. You can test if parameter logging is enabled with ```log_stream::for_params().is_null()```.
- With ```log_stream::log_flush(bool)``` you can choose between regular line ending (```\n```) or ```std::endl``` (which is known for causing a flush on some type of streams).
- Parameter logging takes place during ```statement_impl::pre_use()```. For making it work ```pre_use()``` methods down to every existing backend got a new ```log_stream &``` argument. This way what is logged is exactly what the backend will send to the database (before escaping). This is the major change in the backend API.

Regarding the log format for the query parameters:
- If there's no parameter nothing will be logged (not even a blank line).
- Errors occurred during ```statement_impl::prepare()``` (where the query is logged) or ```statement_impl::pre_use()``` (where the params are logged) are marked at the end of the log line with `````` and `````` respectively. The details are still coming with the exceptions thrown.
- Each parameter is logged with its name or position preceded with ':' (e.g. ':1' or ':name'). It's important to say one must set a name with ````soci::use()``` otherwise there will be only positions. Parameters are comma-separated, equal sign before the value.
- ```std::string```/```char``` parameters are logged with single quotes (e.g. :1='x').
- ```std::tm``` parameters are logged using the backend format with braces (e.g. {2006-05-04 03:02:01}).
- ````blob``` and ```rowid``` parameters also get braces in the log (e.g. {1234}) - only PostgreSQL.
- All other supported numeric types are logged directly, according to the format used in the backend.
- ```soci::values``` are preceded in the log with the number of fields (e.g. "(1),:val=1").
- Values of ```std::vector``` of any supported type are enclosed between square brackets (e.g. "[1,2,3]").
- Nulls (pointed by the indicator) are logged as "{NULL}", including the ones inside vectors and values.

Please refer to the MySQL and PostgreSQL tests for more details.

Reviews and suggestions are welcome.