/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/C++ is licensed under the terms of the GPL <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see the FLOSS License Exception <http://www.mysql.com/about/legal/licensing/foss-exception.html>. */ /** * Debug/Tracefile generation * * Two types of debug/trace files are available with Connector/C++. You can make * Connector/C++ write a trace file and/or activate tracing on the level of the * underlying MySQL Client Libarary. * * Connector/C++ is based on the MySQL Client Library (C-API, AKA libmysql). * Connector/C++ is a proxy/wrapper of the MySQL Client Library. * Debug versions of the MySQL Client Library can write a trace file. On the C-level * this is done by passing a string with debug instructions to the C function * mysql_debug(). You can use the Connector/C++ method * setClientOption("libmysql_debug", const string debug) to pass a string to the * C-API function mysql_debug(). See the MySQL C-API documentation * * Example of a libmysql trace: * >mysql_stmt_init * | >_mymalloc * | | enter: Size: 816 * | | exit: ptr: 0x68e7b8 * | <_mymalloc * | >init_alloc_root * | | enter: root: 0x68e7b8 * | | >_mymalloc * | | | enter: Size: 2064 * | | | exit: ptr: 0x68eb28 * [...] * * If you do not have compiled Connector/C++ against a debug version of the MySQL * Client Library but you have compiled Connector/C++ with tracing enabled, then * you may activate the Connector/C++ internal trace using * setClientOption("clientTrace", bool on_off). * * To compile Connector/C++ with tracing enabled, do: * cmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1 * * Example of a Connector/C++ trace: * | INF: Tracing enabled * <MySQL_Connection::setClientOption * >MySQL_Prepared_Statement::setInt * | INF: this=0x69a2e0 * | >MySQL_Prepared_Statement::checkClosed * | <MySQL_Prepared_Statement::checkClosed * | <MySQL_Prepared_Statement::setInt * * Note that the traces will contain your SQL statements. You may not want * to share sensitive SQL statements. * * @link http://dev.mysql.com/doc/refman/5.1/en/mysql-debug.html */ /* Standard C++ includes */ #include <stdlib.h> #include <iostream> #include <sstream> #include <stdexcept> /* Public interface of the MySQL Connector/C++ */ #include <driver/mysql_public_iface.h> /* Connection parameter and sample data */ #include "examples.h" using namespace std; int main(int argc, const char **argv) { const string host(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); sql::Driver *driver; int i; int on_off = 1; cout << boolalpha; cout << "1..1" << endl;; cout << "# Connector/C++ debug / client_options example.." << endl; try { /* Using the Driver to create a connection */ driver = sql::mysql::get_driver_instance(); std::auto_ptr< sql::Connection > con(driver->connect(host, user, pass)); /* Activate debug trace of the MySQL Client Library (C-API) Only available with a debug build of the MySQL Client Library! */ con->setClientOption("libmysql_debug", "d:t:O,client.trace"); con->setSchema(database); std::auto_ptr< sql::Statement > stmt(con->createStatement()); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))"); cout << "#\t Test table created" << endl; std::auto_ptr< sql::PreparedStatement > prep_stmt(con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)")); for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) { prep_stmt->setInt(1, test_data[i].id); prep_stmt->setString(2, test_data[i].label); prep_stmt->executeUpdate(); /* Pointless activity to demo how to activating and de-activating the Connector/C++ internal trace */ on_off = (i + 2) % 2; con->setClientOption("clientTrace", &on_off); } stmt->execute("DROP TABLE IF EXISTS test"); } catch (sql::SQLException &e) { /* The MySQL Connector/C++ throws three different exceptions: - sql::MethodNotImplementedException (derived from sql::SQLException) - sql::InvalidArgumentException (derived from sql::SQLException) - sql::SQLException (derived from std::runtime_error) */ cout << endl; cout << "# ERR: DbcException in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; // Use what(), getErrorCode() and getSQLState() cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; if (e.getErrorCode() == 1047) { /* Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR) Message: Unknown command */ cout << "# ERR: Your server seems not to support PS at all because its MYSQL <4.1" << endl; } cout << "not ok 1 - examples/debug.cpp" << endl; return EXIT_FAILURE; } catch (std::runtime_error &e) { cout << endl; cout << "# ERR: runtime_error in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what() << endl; cout << "not ok 1 - examples/debug.cpp" << endl; return EXIT_FAILURE; } cout << "ok 1 - examples/debug.cpp" << endl; return EXIT_SUCCESS; }