Author: wyoung
Date: Fri Jun 22 17:45:34 2007
New Revision: 1583
URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1583&view=rev
Log:
Reworked option handling yet again. Connection::set_option() now takes
effect immediately, pending options list renamed and now used as a list
of options already applied, and added set_option_default() which
consults that list and applies the option only if it hasn't been set
already. The latter is used in Connection::connect() to set defaults
for options that user can override. This redesign was urged by Axel
Schwenke <[EMAIL PROTECTED]> Code's all mine.
Modified:
trunk/lib/connection.cpp
trunk/lib/connection.h
Modified: trunk/lib/connection.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.cpp?rev=1583&r1=1582&r2=1583&view=diff
==============================================================================
--- trunk/lib/connection.cpp (original)
+++ trunk/lib/connection.cpp Fri Jun 22 17:45:34 2007
@@ -172,20 +172,17 @@
disconnect();
}
- // Set defaults for some options. We put these at the front of the
- // queue so that if user sets these, too, that will override these
- // values.
- pending_options_.push_front(OptionInfo(opt_read_default_file, "my"));
- pending_options_.push_front(OptionInfo(opt_connect_timeout,
- connect_timeout));
+ // Set defaults for certain connection options. User can override
+ // these by calling set_option() before connect().
+ set_option_default(opt_read_default_file, "my");
+ set_option_default(opt_connect_timeout, connect_timeout);
if (compress) {
- pending_options_.push_front(OptionInfo(opt_compress));
+ set_option_default(opt_compress);
}
// Establish connection
scoped_var_set<bool> sb(connecting_, true);
- if (apply_pending_options() &&
- mysql_real_connect(&mysql_, host, user, passwd, db,
port,
+ if (mysql_real_connect(&mysql_, host, user, passwd, db, port,
socket_name, client_flag)) {
unlock();
success_ = is_connected_ = true;
@@ -362,19 +359,46 @@
if (connected()) {
// None of the argument-less options can be set once the
// connection is up.
- return bad_option(option, opt_type_none);
- }
- else {
- Option valid_options[] = {
- opt_compress,
- opt_named_pipe,
- opt_use_result,
- opt_use_remote_connection,
- opt_use_embedded_connection,
- opt_guess_connection
- };
- return queue_option(option, valid_options,
- NELEMS(valid_options));
+ return bad_option(option, opt_err_conn);
+ }
+
+ bool success = false;
+ switch (option) {
+ case opt_compress:
+ success = set_option_impl(MYSQL_OPT_COMPRESS);
+ break;
+
+ case opt_named_pipe:
+ success = set_option_impl(MYSQL_OPT_NAMED_PIPE);
+ break;
+
+#if MYSQL_VERSION_ID >= 40101
+ case opt_use_result:
+ success = set_option_impl(MYSQL_OPT_USE_RESULT);
+ break;
+
+ case opt_use_remote_connection:
+ success =
set_option_impl(MYSQL_OPT_USE_REMOTE_CONNECTION);
+ break;
+
+ case opt_use_embedded_connection:
+ success =
set_option_impl(MYSQL_OPT_USE_EMBEDDED_CONNECTION);
+ break;
+
+ case opt_guess_connection:
+ success = set_option_impl(MYSQL_OPT_GUESS_CONNECTION);
+ break;
+#endif
+ default:
+ return bad_option(option, opt_err_type);
+ }
+
+ if (success) {
+ applied_options_.push_back(OptionInfo(option));
+ return true;
+ }
+ else {
+ return bad_option(option, opt_err_value);
}
}
@@ -385,20 +409,51 @@
if (connected()) {
// None of the options taking a char* argument can be set once
// the connection is up.
- return bad_option(option, opt_type_string);
- }
- else {
- Option valid_options[] = {
- opt_init_command,
- opt_read_default_file,
- opt_read_default_group,
- opt_set_charset_dir,
- opt_set_charset_name,
- opt_shared_memory_base_name,
- opt_set_client_ip
- };
- return queue_option(option, valid_options,
- NELEMS(valid_options));
+ return bad_option(option, opt_err_conn);
+ }
+
+ bool success = false;
+ switch (option) {
+ case opt_init_command:
+ success = set_option_impl(MYSQL_INIT_COMMAND, arg);
+ break;
+
+ case opt_read_default_file:
+ success = set_option_impl(MYSQL_READ_DEFAULT_FILE, arg);
+ break;
+
+ case opt_read_default_group:
+ success = set_option_impl(MYSQL_READ_DEFAULT_GROUP,
arg);
+ break;
+
+ case opt_set_charset_dir:
+ success = set_option_impl(MYSQL_SET_CHARSET_DIR, arg);
+ break;
+
+ case opt_set_charset_name:
+ success = set_option_impl(MYSQL_SET_CHARSET_NAME, arg);
+ break;
+
+#if MYSQL_VERSION_ID >= 40100
+ case opt_shared_memory_base_name:
+ success =
set_option_impl(MYSQL_SHARED_MEMORY_BASE_NAME, arg);
+ break;
+#endif
+#if MYSQL_VERSION_ID >= 40101
+ case opt_set_client_ip:
+ success = set_option_impl(MYSQL_SET_CLIENT_IP, arg);
+ break;
+#endif
+ default:
+ return bad_option(option, opt_err_type);
+ }
+
+ if (success) {
+ applied_options_.push_back(OptionInfo(option, arg));
+ return true;
+ }
+ else {
+ return bad_option(option, opt_err_value);
}
}
@@ -409,18 +464,43 @@
if (connected()) {
// None of the options taking an int argument can be set once
// the connection is up.
- return bad_option(option, opt_type_integer);
- }
- else {
- Option valid_options[] = {
- opt_connect_timeout,
- opt_local_infile,
- opt_protocol,
- opt_read_timeout,
- opt_write_timeout
- };
- return queue_option(option, valid_options,
- NELEMS(valid_options));
+ return bad_option(option, opt_err_conn);
+ }
+
+ bool success = false;
+ switch (option) {
+ case opt_connect_timeout:
+ success = set_option_impl(MYSQL_OPT_CONNECT_TIMEOUT,
&arg);
+ break;
+
+ case opt_local_infile:
+ success = set_option_impl(MYSQL_OPT_LOCAL_INFILE, &arg);
+ break;
+
+#if MYSQL_VERSION_ID >= 40100
+ case opt_protocol:
+ success = set_option_impl(MYSQL_OPT_PROTOCOL, &arg);
+ break;
+#endif
+#if MYSQL_VERSION_ID >= 40101
+ case opt_read_timeout:
+ success = set_option_impl(MYSQL_OPT_READ_TIMEOUT, &arg);
+ break;
+
+ case opt_write_timeout:
+ success = set_option_impl(MYSQL_OPT_WRITE_TIMEOUT,
&arg);
+ break;
+#endif
+ default:
+ return bad_option(option, opt_err_type);
+ }
+
+ if (success) {
+ applied_options_.push_back(OptionInfo(option, arg));
+ return true;
+ }
+ else {
+ return bad_option(option, opt_err_value);
}
}
@@ -437,18 +517,68 @@
MYSQL_OPTION_MULTI_STATEMENTS_OFF);
}
else {
- return bad_option(option, opt_type_boolean);
- }
- }
- else {
- Option valid_options[] = {
- opt_secure_auth,
- opt_multi_statements,
- opt_report_data_truncation,
- opt_reconnect
- };
- return queue_option(option, valid_options,
- NELEMS(valid_options));
+ return bad_option(option, opt_err_conn);
+ }
+ }
+
+ bool success = false;
+ switch (option) {
+#if MYSQL_VERSION_ID >= 40101
+ case opt_secure_auth:
+ success = set_option_impl(MYSQL_SECURE_AUTH, &arg);
+ break;
+
+ case opt_multi_statements:
+ success = set_option_impl(arg ?
+ MYSQL_OPTION_MULTI_STATEMENTS_ON :
+ MYSQL_OPTION_MULTI_STATEMENTS_OFF);
+ break;
+#endif
+#if MYSQL_VERSION_ID >= 50003
+ case opt_report_data_truncation:
+ success = set_option_impl(MYSQL_REPORT_DATA_TRUNCATION,
&arg);
+ break;
+#endif
+#if MYSQL_VERSION_ID >= 50013
+ case opt_reconnect:
+ success = set_option_impl(MYSQL_OPT_RECONNECT, &arg);
+ break;
+#endif
+ default:
+ return bad_option(option, opt_err_type);
+ }
+
+ if (success) {
+ applied_options_.push_back(OptionInfo(option, arg));
+ return true;
+ }
+ else {
+ return bad_option(option, opt_err_value);
+ }
+}
+
+
+bool
+Connection::set_option_default(Option option)
+{
+ if (option_set(option)) {
+ return true;
+ }
+ else {
+ return set_option(option);
+ }
+}
+
+
+template <typename T>
+bool
+Connection::set_option_default(Option option, T arg)
+{
+ if (option_set(option)) {
+ return true;
+ }
+ else {
+ return set_option(option, arg);
}
}
@@ -471,50 +601,39 @@
bool
-Connection::bad_option(Option option, OptionArgType type)
-{
- if (option_arg_type(option) == type) {
- return bad_option_value(option);
- }
- else {
- return bad_option_type(option);
- }
-}
-
-
-bool
-Connection::bad_option_type(Option option)
+Connection::bad_option(Option option, OptionError error)
{
if (throw_exceptions()) {
- // Option value is legal, but it was given the wrong argument
- // type.
- OptionArgType type = option_arg_type(option);
ostringstream os;
- os << "option " << option;
- if (type == opt_type_none) {
- os << " does not take an argument";
- }
- else {
- os << " requires an argument of type " << type;
- }
- throw BadOption(os.str(), option);
- }
-
- return false;
-}
-
-
-bool
-Connection::bad_option_value(Option option)
-{
- if (throw_exceptions()) {
- // If we get here, option value is in range and it was given the
- // right argument type, so the reason the option was unhandled
- // must be that it's not supported in the C API we're built
- // against.
- ostringstream os;
- os << "option " << option << " not supported in MySQL C API v";
- api_version(os);
+
+ switch (error) {
+ case opt_err_type: {
+ // Option was set using wrong argument type
+ OptionArgType type = option_arg_type(option);
+ os << "option " << option;
+ if (type == opt_type_none) {
+ os << " does not take an argument";
+ }
+ else {
+ os << " requires an argument of type "
<< type;
+ }
+ break;
+ }
+
+ case opt_err_value:
+ // C API rejected option, which probably
indicates that
+ // you passed a option that it doesn't
understand.
+ os << "option " << option << " not supported in
MySQL "
+ "C API v";
+ api_version(os);
+ break;
+
+ case opt_err_conn:
+ os << "option " << option << " can only be set "
+ "before connection is
established";
+ break;
+ }
+
throw BadOption(os.str(), option);
}
@@ -531,225 +650,24 @@
else {
// Non-optional exception. Something is wrong with the library
// internals if this one is thrown.
- BadOption("bad value given to option_arg_type()", option);
- return opt_type_none; // warning eater
- }
-}
-
-
-bool
-Connection::queue_option(Option option, Option* valid_options,
- size_t num_valid)
-{
- for (size_t i = 0; i < num_valid; ++i) {
- if (valid_options[i] == option) {
- // Option is valid, meaning that it should be okay to
set it
- // once connection comes up, so queue it til then. See
- // apply_pending_options() for despooling logic.
- pending_options_.push_back(OptionInfo(option));
+ throw BadOption("bad value given to option_arg_type()", option);
+ //! return opt_type_none; // warning eater
+ }
+}
+
+
+bool
+Connection::option_set(Option option)
+{
+ for (OptionListIt it = applied_options_.begin();
+ it != applied_options_.end();
+ ++it) {
+ if (it->option == option) {
return true;
}
}
return false;
-}
-
-
-bool
-Connection::apply_pending_options()
-{
- bool success = true;
- OptionListIt it;
- for (it = pending_options_.begin();
- success && (it != pending_options_.end());
- ++it) {
- // Try to set the option
- switch (it->arg_type) {
- case opt_type_none:
- switch (it->option) {
- case opt_compress:
- success =
set_option_impl(MYSQL_OPT_COMPRESS);
- break;
-
- case opt_named_pipe:
- success =
set_option_impl(MYSQL_OPT_NAMED_PIPE);
- break;
-
-#if MYSQL_VERSION_ID >= 40101
- case opt_use_result:
- success =
set_option_impl(MYSQL_OPT_USE_RESULT);
- break;
-
- case opt_use_remote_connection:
- success = set_option_impl(
-
MYSQL_OPT_USE_REMOTE_CONNECTION);
- break;
-
- case opt_use_embedded_connection:
- success = set_option_impl(
-
MYSQL_OPT_USE_EMBEDDED_CONNECTION);
- break;
-
- case opt_guess_connection:
- success = set_option_impl(
-
MYSQL_OPT_GUESS_CONNECTION);
- break;
-#endif
- default:
- success =
bad_option(it->option, opt_type_none);
- }
- break;
-
- case opt_type_string:
- switch (it->option) {
- case opt_init_command:
- success = set_option_impl(
-
MYSQL_INIT_COMMAND, it->str_arg.c_str());
- break;
-
- case opt_read_default_file:
- success = set_option_impl(
-
MYSQL_READ_DEFAULT_FILE,
-
it->str_arg.c_str());
- break;
-
- case opt_read_default_group:
- success = set_option_impl(
-
MYSQL_READ_DEFAULT_GROUP,
-
it->str_arg.c_str());
- break;
-
- case opt_set_charset_dir:
- success = set_option_impl(
-
MYSQL_SET_CHARSET_DIR,
-
it->str_arg.c_str());
- break;
-
- case opt_set_charset_name:
- success = set_option_impl(
-
MYSQL_SET_CHARSET_NAME,
-
it->str_arg.c_str());
- break;
-
-#if MYSQL_VERSION_ID >= 40100
- case opt_shared_memory_base_name:
- success = set_option_impl(
-
MYSQL_SHARED_MEMORY_BASE_NAME,
-
it->str_arg.c_str());
- break;
-#endif
-#if MYSQL_VERSION_ID >= 40101
- case opt_set_client_ip:
- success = set_option_impl(
-
MYSQL_SET_CLIENT_IP,
-
it->str_arg.c_str());
- break;
-#endif
- default:
- success = bad_option(it->option,
-
opt_type_string);
- }
- break;
-
- case opt_type_integer:
- switch (it->option) {
- case opt_connect_timeout:
- success = set_option_impl(
-
MYSQL_OPT_CONNECT_TIMEOUT,
- &it->int_arg);
- break;
-
- case opt_local_infile:
- success = set_option_impl(
-
MYSQL_OPT_LOCAL_INFILE,
- &it->int_arg);
- break;
-
-#if MYSQL_VERSION_ID >= 40100
- case opt_protocol:
- success = set_option_impl(
-
MYSQL_OPT_PROTOCOL,
- &it->int_arg);
- break;
-#endif
-#if MYSQL_VERSION_ID >= 40101
- case opt_read_timeout:
- success = set_option_impl(
-
MYSQL_OPT_READ_TIMEOUT,
- &it->int_arg);
- break;
-
- case opt_write_timeout:
- success = set_option_impl(
-
MYSQL_OPT_WRITE_TIMEOUT,
- &it->int_arg);
- break;
-#endif
- default:
- success = bad_option(it->option,
-
opt_type_integer);
- break;
- }
- break;
-
- case opt_type_boolean:
- switch (it->option) {
-#if MYSQL_VERSION_ID >= 40101
- case opt_secure_auth:
- success = set_option_impl(
-
MYSQL_SECURE_AUTH,
- &it->bool_arg);
- break;
-
- case opt_multi_statements:
- success =
set_option_impl(it->bool_arg ?
-
MYSQL_OPTION_MULTI_STATEMENTS_ON :
-
MYSQL_OPTION_MULTI_STATEMENTS_OFF);
- break;
-#endif
-#if MYSQL_VERSION_ID >= 50003
- case opt_report_data_truncation:
- success = set_option_impl(
-
MYSQL_REPORT_DATA_TRUNCATION,
- &it->bool_arg);
- break;
-#endif
-#if MYSQL_VERSION_ID >= 50013
- case opt_reconnect:
- success = set_option_impl(
-
MYSQL_OPT_RECONNECT,
- &it->bool_arg);
- break;
-#endif
- default:
- success = bad_option(it->option,
-
opt_type_boolean);
- }
- break;
- }
- }
-
- pending_options_.clear();
-
- if (!success && throw_exceptions()) {
- // Failed to set one of the queued options, so throw an
exception
- // to report the problem.
- ostringstream os;
- os << "Failed to set pending option " << it->option;
- if (it->arg_type != opt_type_none) {
- os << " = ";
- switch (it->arg_type) {
- case opt_type_string: os << it->str_arg;
break;
- case opt_type_integer: os << it->int_arg;
break;
- case opt_type_boolean: os << it->bool_arg;
break;
- case opt_type_none: // warning eater
- default: os <<
"unknown"; break;
- }
- }
- throw BadOption(os.str(), it->option);
- }
-
- return success;
}
Modified: trunk/lib/connection.h
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.h?rev=1583&r1=1582&r2=1583&view=diff
==============================================================================
--- trunk/lib/connection.h (original)
+++ trunk/lib/connection.h Fri Jun 22 17:45:34 2007
@@ -423,6 +423,18 @@
/// \brief Sets a connection option, with Boolean argument
bool set_option(Option option, bool arg);
+ /// \brief Same as set_option(), except that it won't override
+ /// a previously-set option.
+ bool set_option_default(Option option);
+
+ /// \brief Same as set_option(), except that it won't override
+ /// a previously-set option.
+ template <typename T>
+ bool set_option_default(Option option, T arg);
+
+ /// \brief Returns true if the given option has been set already
+ bool option_set(Option option);
+
/// \brief Enable SSL-encrypted connection.
///
/// \param key the pathname to the key file
@@ -465,6 +477,13 @@
std::ostream& api_version(std::ostream& os);
protected:
+ /// \brief Types of option setting errors we can diagnose
+ enum OptionError {
+ opt_err_type,
+ opt_err_value,
+ opt_err_conn,
+ };
+
/// \brief Drop the connection to the database server
///
/// This method is protected because it should only be used within
@@ -472,29 +491,11 @@
/// object should always be connected.
void disconnect();
- /// \brief Set all options that have been queued pending connection
- /// establishment.
- ///
- /// Called within connect() method just before we try opening the
- /// database server connection.
- bool apply_pending_options();
-
- /// \brief Generic wrapper for bad_option_*()
- bool bad_option(Option option, OptionArgType type);
-
- /// \brief Handles call of incorrect set_option() overload
- bool bad_option_type(Option option);
-
- /// \brief Handles bad option values sent to set_option()
- bool bad_option_value(Option option);
+ /// \brief Error handling routine for set_option()
+ bool bad_option(Option option, OptionError error);
/// \brief Given option value, return its proper argument type
OptionArgType option_arg_type(Option option);
-
- /// \brief Queues given option if it's in the list of valid options,
- /// to be set during connection establishment proces.
- bool queue_option(Option option, Option* valid_options,
- size_t num_valid);
/// \brief Set MySQL C API connection option
///
@@ -569,7 +570,7 @@
bool is_connected_;
bool connecting_;
bool success_;
- OptionList pending_options_;
+ OptionList applied_options_;
static OptionArgType legal_opt_arg_types_[];
};
_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits