// $Id: connection.h,v 1.3 2004/09/06 00:09:46 redi Exp $ /* MyMySQL -- Copyright (C) 2003,2004 Jonathan Wakely Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef MYMYSQL_CONNECTION_H #define MYMYSQL_CONNECTION_H /** @file connection.h * @brief Declares Connection class. */ #include #include /** @namespace mymysql * @brief All components are declared in this namespace. */ namespace mymysql { /** * @class Connection connection.h mymysql/connection.h * @brief Wrapper class for a MySQL database connection. * * Allows implicit conversion to MYSQL*. * * @par Refinement of: * @e DefaultConstructible. */ class Connection { public: /// Create a Connection object and open it using the supplied parameters. explicit Connection( std::string const& host, std::string const& user = "", std::string const& passwd = "", std::string const& database = "", unsigned int port = 0, std::string const& socket = "", unsigned long client_flag = 0 ); /// Create a Connection object but don't open it. Connection(); /// Close the connection. ~Connection(); /// Open the connection using the current parameters and supplied password. bool open(std::string const& passwd = ""); /// Test whether the connection is open. bool is_open() const; /// Conversion operator. operator MYSQL*() const; // parameters and options must be set before opening connection Connection& host(std::string const&); ///< Set the host parameter. Connection& user(std::string const&); ///< Set the user parameter. Connection& database(std::string const&); ///< Set the database parameter. Connection& port(unsigned int); ///< Set the port parameter. Connection& socket(std::string const&); ///< Set the socket parameter. Connection& clientFlag(unsigned long); ///< Set the client flag parameter. std::string const& host() const; ///< The host parameter std::string const& user() const; ///< The user parameter std::string const& database() const; ///< The database parameter unsigned int port() const; ///< The port parameter std::string const& socket() const; ///< The socket parameter unsigned long clientFlag() const; ///< The client flag parameter /** @class Options connection.h mymysql/connection.h * @brief Helper class used to set extra connection options. * * It is not possible to declare instances of this class, they can only * be created by Connection::options() so you must call that function * and call member functions of %Options on the returned object. * * All members return a reference allowing "method-chaining". */ class Options { public: Options& setConnectTimeout(unsigned int seconds); Options& useCompression(); Options& allowLocalInfile(bool = true); Options& useNamedPipe(); Options& setInitCommand(std::string const& sql); Options& readDefaultFile(std::string const& filename); Options& readDefaultGroup(std::string const& group); private: Options(Connection& c) : m_conn(c) {} Options(Options const& o) : m_conn(o.m_conn) {} Options& operator=(Options const&); Connection& m_conn; friend class Connection; }; friend class Options; /// Set extra connect options and affect behaviour for a connection. Options options(); /// Return the error code for the most recent operation that could fail. unsigned int errnum() const; /// Return the error message for the most recent operation that could fail. std::string error() const; /// The thread ID of the current connection. unsigned long id() const; /// Check whether the connection to the server is working. bool ping() const; /// Ask the server to kill the specified thread. bool kill(unsigned long thread_id = 0) const; private: Connection(Connection const&); Connection& operator=(Connection const&); MYSQL* m_db; bool m_opened; unsigned int m_errno; std::string m_error; std::string m_host; std::string m_user; std::string m_database; unsigned int m_port; std::string m_socket; unsigned long m_client_flag; }; inline Connection::Connection() : m_db(mysql_init(0)), m_opened(false), m_errno(0), m_error(), m_host(), m_user(), m_database(), m_port(), m_socket(), m_client_flag() { } inline Connection::Connection( std::string const& host, std::string const& user, std::string const& passwd, std::string const& database, unsigned int port, std::string const& socket, unsigned long client_flag ) : m_db(mysql_init(0)), m_errno(0), m_error(), m_host(host), m_user(user), m_database(database), m_port(port), m_socket(socket), m_client_flag(client_flag) { this->open(passwd); } inline Connection::~Connection() { ::mysql_close(m_db); } inline bool Connection::open(std::string const& passwd) { char const* chost = m_host.size() ? m_host.c_str() : 0; char const* cuser = m_user.size() ? m_user.c_str() : 0; char const* cpasswd = passwd.size() ? passwd.c_str() : 0; char const* cdatabase = m_database.size() ? m_database.c_str() : 0; char const* csocket = m_socket.size() ? m_socket.c_str() : 0; if (::mysql_real_connect(m_db, chost, cuser, cpasswd, cdatabase, m_port, csocket, m_client_flag)) { m_errno = 0; m_error.erase(); } else { m_errno = ::mysql_errno(m_db); m_error = ::mysql_error(m_db); } m_opened = true; return !m_errno; } inline bool Connection::is_open() const { return m_opened && !m_errno; } inline Connection::operator MYSQL*() const { return m_errno ? 0 : m_db; } inline unsigned int Connection::errnum() const { return m_errno; } inline std::string Connection::error() const { return m_error; } inline Connection& Connection::host(std::string const& host) { m_host = host; return *this; } inline Connection& Connection::user(std::string const& user) { m_user = user; return *this; } inline Connection& Connection::database(std::string const& database) { m_database = database; return *this; } inline Connection& Connection::port(unsigned int port) { m_port = port; return *this; } inline Connection& Connection::socket(std::string const& socket) { m_socket = socket; return *this; } inline Connection& Connection::clientFlag(unsigned long client_flag) { m_client_flag = client_flag; return *this; } inline Connection::Options& Connection::Options::setConnectTimeout(unsigned int seconds) { ::mysql_options(m_conn.m_db, MYSQL_OPT_CONNECT_TIMEOUT, reinterpret_cast(&seconds)); return *this; } inline Connection::Options& Connection::Options::useCompression() { ::mysql_options(m_conn.m_db, MYSQL_OPT_COMPRESS, 0); return *this; } inline Connection::Options& Connection::Options::allowLocalInfile(bool allow) { unsigned int uint_allow = allow; ::mysql_options(m_conn.m_db, MYSQL_OPT_CONNECT_TIMEOUT, reinterpret_cast(&uint_allow)); return *this; } inline Connection::Options& Connection::Options::useNamedPipe() { ::mysql_options(m_conn.m_db, MYSQL_OPT_NAMED_PIPE, 0); return *this; } inline Connection::Options& Connection::Options::setInitCommand(std::string const& sql) { ::mysql_options(m_conn.m_db, MYSQL_INIT_COMMAND, sql.c_str()); return *this; } inline Connection::Options& Connection::Options::readDefaultFile(std::string const& filename) { ::mysql_options(m_conn.m_db, MYSQL_READ_DEFAULT_FILE, filename.c_str()); return *this; } inline Connection::Options& Connection::Options::readDefaultGroup(std::string const& group) { ::mysql_options(m_conn.m_db, MYSQL_READ_DEFAULT_GROUP, group.c_str()); return *this; } inline std::string const& Connection::host() const { return m_host; } inline std::string const& Connection::user() const { return m_user; } inline std::string const& Connection::database() const { return m_database; } inline unsigned int Connection::port() const { return m_port; } inline std::string const& Connection::socket() const { return m_socket; } inline unsigned long Connection::clientFlag() const { return m_client_flag; } /** * @return The Options object for the Connection. */ inline Connection::Options Connection::options() { return Options(*this); } inline unsigned long Connection::id() const { return mysql_thread_id(m_db); } /** * If it has gone down, an automatic reconnection is attempted. * This function can be used by clients that remain idle for a long while, * to check whether the server has closed the connection and reconnect * if necessary. * * @return @c true if the server is alive, @c false if an error occurred. */ inline bool Connection::ping() const { return !mysql_ping(m_db); } /** * If @p thread_id is zero then @c this->id() is used. * * @param thread_id The thread to kill. * @return @c true on success, @c false if an error occurred. */ inline bool Connection::kill(unsigned long thread_id) const { return !mysql_kill(m_db, thread_id ? thread_id : id()); } } // namespace mymysql /** * @mainpage * * MyMySQL is a very lightweight wrapper for the MySQL C client API, * which manages all resources internally. * * The overhead due to the wrapper should be very low, as all functions * are inline and most simply forward to the MySQL C API functions. * * No exceptions are thrown by any part of the library, so it is suitable * to use in code that doesn't use exceptions. * * Example of use: @code mymysql::Connection db; db.user("db_user").database("test_db"); db.options().setConnectTimeout(600).readDefaultGroup("my_conf_grp"); if (db.open("my_rubbish_password")) { std::ostringstream sql; sql << "INSERT INTO tbl_name (col_name) ('" << mymysql::escape(db, "This text's going to be escaped") << "'), ('" << mymysql::escape(db, "\\ \" ' \0") << "')"; mymysql::Query q(db, sql.str()); if (q.errnum()) { std::cerr << "Insert failed: " << q.error() << std::endl; } else { if (q.run("SELECT col_name FROM tbl_name")) { for (mymysql::Query::iterator i = q.begin(); i != q.end(); ++i) { std::cout << (*i)[0] << std::endl; } } else { std::cerr << "Select failed: " << q.error() << std::endl; } } } else { std::cerr << "Connect failed: " << db.error() << std::endl; } @endcode */ #endif // MYMYSQL_CONNECTION_H // vim: ts=8 sw=2 expandtab