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

Reply via email to