Skip to content

Commit

Permalink
Merge branch 'vadz/soci/params2' into upstream
Browse files Browse the repository at this point in the history
Closes pull request #99.
  • Loading branch information
vadz committed Mar 13, 2013
2 parents 2952cff + 4212775 commit 4d5e76a
Show file tree
Hide file tree
Showing 32 changed files with 336 additions and 149 deletions.
8 changes: 7 additions & 1 deletion doc/backends/odbc.html
Expand Up @@ -274,7 +274,13 @@ <h4 id="get_connection_string">get_connection_string()</h4>

<h3 id="options">Configuration options</h3>

<p>None</p>
<p>This backend supports <code>odbc_option_driver_complete</code> option which can be passed to it via <code>connection_parameters</code> class. The value of this option is passed to <code>SQLDriverConnect()</code> function as "driver completion" parameter and so must be one of <code>SQL_DRIVER_XXX</code> values, in the string form. The default value of this option is <code>SQL_DRIVER_PROMPT</code> meaning that the driver will query the user for the user name and/or the password if they are not stored together with the connection. If this is undesirable for some reason, you can use <code>SQL_DRIVER_NOPROMPT</code> value for this option to suppress showing the message box:</p>

<pre class="example">
connection_parameters parameters("odbc", "DSN=mydb");
parameters.set_option(odbc_option_driver_complete, "0" /* SQL_DRIVER_NOPROMPT */);
session sql(parameters);
</pre>

<p class="copyright">Copyright &copy; 2013 Mateusz Loskot</p>
<p class="copyright">Copyright &copy; 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney</p>
Expand Down
12 changes: 12 additions & 0 deletions doc/connections.html
Expand Up @@ -54,6 +54,14 @@ <h3>Connecting to the database</h3>

<p>The last two constructors described above try to locate the shared library with the name <code>libsoci_ABC.so</code> (or <code>libsoci_ABC.dll</code> on Windows), where ABC is the backend name. In the above examples, the expected library name will be <code>libsoci_postgresql.so</code> for Unix-like systems.</p>

<p>The most general form of the constructor takes a single object of <code>connection_parameters</code> type which contains a pointer to the backend to use, the connection string and also any connection options. Using this constructor is the only way to pass any non-default options to the backend. For example, to suppress any interactive prompts when using ODBC backend you could do:</p>
<pre class="example">
connection_parameters parameters("odbc", "DSN=mydb");
parameters.set_option(odbc_option_driver_complete, "0" /* SQL_DRIVER_NOPROMPT */);
session sql(parameters);
</pre>
Notice that you need to <code>#include &lt;soci-odbc.h&gt;</code> to obtain the option name declaration. The existing options are described in the backend-specific part of the documentation.

<div class="note">
<p><span class="note">Environment configuration:</span></p>
<p>The <code>SOCI_BACKENDS_PATH</code> environment variable defines the set of paths where the shared libraries will be searched for. There can be many paths, separated by colons, and they are used from left to right until the library with the appropriate name is found. If this variable is not set or is empty, the current directory is used as a default path for dynamically loaded backends.</p>
Expand Down Expand Up @@ -86,6 +94,10 @@ <h3>Connecting to the database</h3>

// or:
sql.open("postgresql://dbname=mydb");

// or also:
connection_parameters parameters("postgresql", "dbname=mydb");
sql.open(parameters);
</pre>

<p>The rules for backend naming are the same as with the constructors described above.</p>
Expand Down
2 changes: 1 addition & 1 deletion doc/errors.html
Expand Up @@ -118,7 +118,7 @@ <h2>Errors</h2>
<a href="installation.html">Previous (Installation)</a>
</td>
<td class="foot-link-right">
<a href="basics.html">Next (Connections and simple queries)</a>
<a href="connections.html">Next (Connections and simple queries)</a>
</td>
</tr>
</table>
Expand Down
39 changes: 38 additions & 1 deletion doc/reference.html
Expand Up @@ -14,6 +14,7 @@ <h2>Client interface reference</h2>
<div class="navigation">
<a href="#commontypes">commonly used types</a><br />
<a href="#session">class session</a><br />
<a href="#parameters">class connection_parameters</a><br />
<a href="#pool">class connection_pool</a><br />
<a href="#transaction">class transaction</a><br />
<a href="#into">function into</a><br />
Expand Down Expand Up @@ -75,6 +76,7 @@ <h3 id="session">class session</h3>
{
public:
session();
explicit session(connection_parameters const &amp; parameters);
session(backend_factory const &amp; factory, std::string const &amp; connectString);
session(std::string const &amp; backendName, std::string const &amp; connectString);
explicit session(std::string const &amp; connectString);
Expand Down Expand Up @@ -121,7 +123,9 @@ <h3 id="session">class session</h3>
<ul>
<li>Various constructors. The default one creates the session in the disconnected state.
The others expect the backend factory object, or the backend name, or the URL-like
composed connection string. The last constructor creates a session proxy associated
composed connection string or the special parameters object containing both the backend
and the connection string as well as possibly other connection options.
The last constructor creates a session proxy associated
with the session that is available in the given pool and releases it back to the pool
when its lifetime ends. Example:
<pre class="example">
Expand Down Expand Up @@ -198,6 +202,39 @@ <h3 id="session">class session</h3>
<p>See <a href="basics.html">Connections and simple queries</a> for more
examples.</p>

<h3 id="parameters">class connection_parameters</h3>

<p>The <code>connection_parameters</code> class is a simple container for the backend pointer, connection string and any other connection options. It is used together with <code>session</code> constructor and <code>open()</code> method.</p>

<pre class="example">
class connection_parameters
{
public:
connection_parameters();
connection_parameters(backend_factory const &amp; factory, std::string const &amp; connectString);
connection_parameters(std::string const &amp; backendName, std::string const &amp; connectString);
explicit connection_parameters(std::string const &amp; fullConnectString);

void set_option(const char * name, std::string const &amp; value);
bool get_option(const char * name, std::string &amp; value) const
};
</pre>

<p>The methods of this class are:</p>
<ul>
<li>Default constructor is rarely used as it creates an uninitialized
object and the only way to initialize it later is to assign another, valid,
connection_parameters object to this one.</li>
<li>The other constructors correspond to the similar constructors of the
<code>session</code> class and specify both the backend, either as a
pointer to it or by name, and the connection string.</li>
<li><code>set_option</code> can be used to set the value of an option with
the given name. Currently all option values are strings, so if you need to
set a numeric option you need to convert it to a string first. If an option
with the given name had been already set before, its old value is
overwritten.</li>
</ul>

<h3 id="pool">class connection_pool</h3>

<p>The <code>connection_pool</code> class encapsulates the thread-safe pool of connections
Expand Down
4 changes: 2 additions & 2 deletions src/backends/db2/factory.cpp
Expand Up @@ -16,9 +16,9 @@ using namespace soci::details;

// concrete factory for ODBC concrete strategies
db2_session_backend * db2_backend_factory::make_session(
std::string const &connectString) const
connection_parameters const & parameters) const
{
return new db2_session_backend(connectString);
return new db2_session_backend(parameters);
}

db2_backend_factory const soci::db2;
Expand Down
6 changes: 4 additions & 2 deletions src/backends/db2/session.cpp
Expand Up @@ -8,6 +8,7 @@

#define SOCI_DB2_SOURCE
#include "soci-db2.h"
#include <connection-parameters.h>

#ifdef _MSC_VER
#pragma warning(disable:4355)
Expand Down Expand Up @@ -61,6 +62,7 @@ void db2_session_backend::parseKeyVal(std::string const & keyVal) {
}
}

/* DSN=SAMPLE;Uid=db2inst1;Pwd=db2inst1;AutoCommit=off */
void db2_session_backend::parseConnectString(std::string const & connectString) {
std::string processingString(connectString);
size_t delimiter=processingString.find_first_of(";");
Expand All @@ -76,10 +78,10 @@ void db2_session_backend::parseConnectString(std::string const & connectString)
}

db2_session_backend::db2_session_backend(
std::string const & connectString /* DSN=SAMPLE;Uid=db2inst1;Pwd=db2inst1;AutoCommit=off */) :
connection_parameters const & parameters) :
in_transaction(false)
{
parseConnectString(connectString);
parseConnectString(parameters.get_connect_string());
SQLRETURN cliRC = SQL_SUCCESS;

/* Prepare handles */
Expand Down
5 changes: 3 additions & 2 deletions src/backends/db2/soci-db2.h
Expand Up @@ -230,7 +230,7 @@ struct db2_blob_backend : details::blob_backend

struct db2_session_backend : details::session_backend
{
db2_session_backend(std::string const& connectString);
db2_session_backend(connection_parameters const& parameters);

~db2_session_backend();

Expand Down Expand Up @@ -262,7 +262,8 @@ struct db2_session_backend : details::session_backend
struct SOCI_DB2_DECL db2_backend_factory : backend_factory
{
db2_backend_factory() {}
db2_session_backend* make_session(std::string const& connectString) const;
db2_session_backend* make_session(
connection_parameters const & parameters) const;
};

extern SOCI_DB2_DECL db2_backend_factory const db2;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/empty/factory.cpp
Expand Up @@ -18,9 +18,9 @@ using namespace soci::details;

// concrete factory for Empty concrete strategies
empty_session_backend* empty_backend_factory::make_session(
std::string const& connectString) const
connection_parameters const& parameters) const
{
return new empty_session_backend(connectString);
return new empty_session_backend(parameters);
}

empty_backend_factory const soci::empty;
Expand Down
2 changes: 1 addition & 1 deletion src/backends/empty/session.cpp
Expand Up @@ -17,7 +17,7 @@ using namespace soci::details;


empty_session_backend::empty_session_backend(
std::string const & /* connectString */)
connection_parameters const & /* parameters */)
{
// ...
}
Expand Down
6 changes: 3 additions & 3 deletions src/backends/empty/soci-empty.h
Expand Up @@ -154,7 +154,7 @@ struct empty_blob_backend : details::blob_backend

struct empty_session_backend : details::session_backend
{
empty_session_backend(std::string const& connectString);
empty_session_backend(connection_parameters const& parameters);

~empty_session_backend();

Expand All @@ -173,8 +173,8 @@ struct empty_session_backend : details::session_backend

struct SOCI_EMPTY_DECL empty_backend_factory : backend_factory
{
empty_backend_factory() {}
empty_session_backend* make_session(std::string const& connectString) const;
empty_backend_factory() {}
empty_session_backend* make_session(connection_parameters const& parameters) const;
};

extern SOCI_EMPTY_DECL empty_backend_factory const empty;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/firebird/factory.cpp
Expand Up @@ -12,9 +12,9 @@
using namespace soci;

firebird_session_backend * firebird_backend_factory::make_session(
std::string const &connectString) const
connection_parameters const & parameters) const
{
return new firebird_session_backend(connectString);
return new firebird_session_backend(parameters);
}

firebird_backend_factory const soci::firebird;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/firebird/session.cpp
Expand Up @@ -199,12 +199,12 @@ bool getISCConnectParameter(std::map<std::string, std::string> const & m, std::s
} // namespace anonymous

firebird_session_backend::firebird_session_backend(
std::string const & connectString) : dbhp_(0), trhp_(0)
connection_parameters const & parameters) : dbhp_(0), trhp_(0)
, decimals_as_strings_(false)
{
// extract connection parameters
std::map<std::string, std::string>
params(explodeISCConnectString(connectString));
params(explodeISCConnectString(parameters.get_connect_string()));

ISC_STATUS stat[stat_size];
std::string param;
Expand Down
6 changes: 3 additions & 3 deletions src/backends/firebird/soci-firebird.h
Expand Up @@ -291,7 +291,7 @@ struct firebird_blob_backend : details::blob_backend

struct firebird_session_backend : details::session_backend
{
firebird_session_backend(std::string const &connectString);
firebird_session_backend(connection_parameters const & parameters);

~firebird_session_backend();

Expand Down Expand Up @@ -322,9 +322,9 @@ struct firebird_session_backend : details::session_backend

struct firebird_backend_factory : backend_factory
{
firebird_backend_factory() {}
firebird_backend_factory() {}
virtual firebird_session_backend * make_session(
std::string const &connectString) const;
connection_parameters const & parameters) const;
};

extern SOCI_FIREBIRD_DECL firebird_backend_factory const firebird;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/mysql/factory.cpp
Expand Up @@ -21,9 +21,9 @@ using namespace soci::details;

// concrete factory for MySQL concrete strategies
mysql_session_backend * mysql_backend_factory::make_session(
std::string const &connectString) const
connection_parameters const & parameters) const
{
return new mysql_session_backend(connectString);
return new mysql_session_backend(parameters);
}

mysql_backend_factory const soci::mysql;
Expand Down
5 changes: 3 additions & 2 deletions src/backends/mysql/session.cpp
Expand Up @@ -8,6 +8,7 @@

#define SOCI_MYSQL_SOURCE
#include "soci-mysql.h"
#include <connection-parameters.h>
// std
#include <cctype>
#include <cerrno>
Expand Down Expand Up @@ -272,14 +273,14 @@ void parse_connect_string(const string & connectString,
} // namespace anonymous

mysql_session_backend::mysql_session_backend(
std::string const & connectString)
connection_parameters const & parameters)
{
string host, user, password, db, unix_socket, ssl_ca, ssl_cert, ssl_key,
charset;
int port, local_infile;
bool host_p, user_p, password_p, db_p, unix_socket_p, port_p,
ssl_ca_p, ssl_cert_p, ssl_key_p, local_infile_p, charset_p;
parse_connect_string(connectString, &host, &host_p, &user, &user_p,
parse_connect_string(parameters.get_connect_string(), &host, &host_p, &user, &user_p,
&password, &password_p, &db, &db_p,
&unix_socket, &unix_socket_p, &port, &port_p,
&ssl_ca, &ssl_ca_p, &ssl_cert, &ssl_cert_p, &ssl_key, &ssl_key_p,
Expand Down
6 changes: 3 additions & 3 deletions src/backends/mysql/soci-mysql.h
Expand Up @@ -228,7 +228,7 @@ struct mysql_blob_backend : details::blob_backend

struct mysql_session_backend : details::session_backend
{
mysql_session_backend(std::string const &connectString);
mysql_session_backend(connection_parameters const & parameters);

~mysql_session_backend();

Expand All @@ -250,9 +250,9 @@ struct mysql_session_backend : details::session_backend

struct mysql_backend_factory : backend_factory
{
mysql_backend_factory() {}
mysql_backend_factory() {}
virtual mysql_session_backend * make_session(
std::string const &connectString) const;
connection_parameters const & parameters) const;
};

extern SOCI_MYSQL_DECL mysql_backend_factory const mysql;
Expand Down
4 changes: 2 additions & 2 deletions src/backends/odbc/factory.cpp
Expand Up @@ -15,9 +15,9 @@ using namespace soci::details;

// concrete factory for ODBC concrete strategies
odbc_session_backend * odbc_backend_factory::make_session(
std::string const &connectString) const
connection_parameters const & parameters) const
{
return new odbc_session_backend(connectString);
return new odbc_session_backend(parameters);
}

odbc_backend_factory const soci::odbc;
Expand Down
38 changes: 34 additions & 4 deletions src/backends/odbc/session.cpp
Expand Up @@ -9,10 +9,15 @@
#include "soci-odbc.h"
#include "session.h"

#include <cstdio>

using namespace soci;
using namespace soci::details;

odbc_session_backend::odbc_session_backend(std::string const & connectString)
char const * soci::odbc_option_driver_complete = "odbc.driver_complete";

odbc_session_backend::odbc_session_backend(
connection_parameters const & parameters)
: henv_(0), hdbc_(0), product_(prod_uninitialized)
{
SQLRETURN rc;
Expand Down Expand Up @@ -43,11 +48,36 @@ odbc_session_backend::odbc_session_backend(std::string const & connectString)
SQLCHAR outConnString[1024];
SQLSMALLINT strLength;

rc = SQLDriverConnect(hdbc_, NULL, // windows handle
// Prompt the user for any missing information (typically UID/PWD) in the
// connection string by default but allow overriding this using "prompt"
// option.
SQLHWND hwnd_for_prompt = NULL;
unsigned completion = SQL_DRIVER_COMPLETE;
std::string completionString;
if (parameters.get_option(odbc_option_driver_complete, completionString))
{
// The value of the option is supposed to be just the integer value of
// one of SQL_DRIVER_XXX constants but don't check for the exact value in
// case more of them are added in the future, the ODBC driver will return
// an error if we pass it an invalid value anyhow.
if (std::sscanf(completionString.c_str(), "%u", &completion) != 1)
{
throw soci_error("Invalid non-numeric driver completion option value \"" +
completionString + "\".");
}
}

#ifdef _WIN32
if (completion != SQL_DRIVER_NOPROMPT)
hwnd_for_prompt = ::GetDesktopWindow();
#endif // _WIN32

std::string const & connectString = parameters.get_connect_string();
rc = SQLDriverConnect(hdbc_, hwnd_for_prompt,
(SQLCHAR *)connectString.c_str(),
(SQLSMALLINT)connectString.size(),
outConnString, 1024,
&strLength, SQL_DRIVER_NOPROMPT);
outConnString, 1024, &strLength,
static_cast<SQLUSMALLINT>(completion));

if (is_odbc_error(rc))
{
Expand Down

0 comments on commit 4d5e76a

Please sign in to comment.