Connect MySQL With C++
Connect MySQL With C++
MySQL Connector/C++
Abstract This manual describes MySQL Connector/C++, the C++ interface for communicating with MySQL servers. Document generated on: 2010-02-05 (revision: 18960)
Copyright 1997-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. All rights reserved. U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its supplements. Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java, Solaris, StarOffice, MySQL Enterprise Monitor 2.0, MySQL logo and MySQL are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd. Copyright 1997-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. Tous droits rservs. L'utilisation est soumise aux termes du contrat de licence.Sun, Sun Microsystems, le logo Sun, Java, Solaris, StarOffice, MySQL Enterprise Monitor 2.0, MySQL logo et MySQL sont des marques de fabrique ou des marques dposes de Sun Microsystems, Inc. aux Etats-Unis et dans d'autres pays. UNIX est une marque dpose aux Etats-Unis et dans d'autres pays et licencie exlusivement par X/Open Company, Ltd. This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the following terms: You may create a printed copy of this documentation solely for your own personal use. Conversion to other formats is allowed as long as the actual content is not altered or edited in any way. You shall not publish or distribute this documentation in any form or on any media, except if you distribute the documentation in a manner similar to how Sun disseminates it (that is, electronically for download on a Web site with the software) or on a CD-ROM or similar medium, provided however that the documentation is disseminated together with the software on the same medium. Any other use, such as any dissemination of printed copies or use of this documentation, in whole or in part, in another publication, requires the prior written consent from an authorized representative of Sun Microsystems, Inc. Sun Microsystems, Inc. and MySQL AB reserve any and all rights to this documentation not expressly granted above. For more information on the terms of this license, for details on how the MySQL documentation is built and produced, or if you are interested in doing a translation, please contact the http://www.mysql.com/company/contact/. For additional licensing information, including licenses for libraries used by MySQL, see Preface, Notes, Licenses. If you want help with using MySQL, please visit either the MySQL Forums or MySQL Mailing Lists where you can discuss your issues with other MySQL users. For additional documentation on MySQL products, including translations of the documentation into other languages, and downloadable versions in variety of formats, including HTML, CHM, and PDF formats, see MySQL Documentation Library.
MySQL Connector/C++
MySQL Connector/C++ is a MySQL database connector for C++. The current version is 1.0.5 GA. The MySQL Connector/C++ is licensed under the terms of the GPL, like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see FLOSS License Exception. If you need a non-GPL license for commercial distribution please contact us. The MySQL Connector/C++ is compatible with the JDBC 4.0 API. However, MySQL Connector/C++ does not implement all of the JDBC 4.0 API. The MySQL Connector/C++ current version features the following classes: Connection DatabaseMetaData Driver PreparedStatement ResultSet ResultSetMetaData Savepoint Statement
The JDBC 4.0 API defines approximately 450 methods for the above mentioned classes. MySQL Connector/C++ implements around 80% of these and makes them available in the current release. The release has been successfully compiled and tested on the following platforms: AIX 5.2 (PPC32, PPC64) 5.3 (PPC32, PPC64)
Linux Debian 3.1 (PPC32, x86) FC4 (x86) RHEL 3 (ia64, x86, x86_64) RHEL 4 (ia64, x86, x86_64) RHEL 5 (ia64, x86, x86_64) iv
MySQL Connector/C++
SLES 9 (ia64, x86, x86_64) SLES 10 (ia64, x86_64) SuSE 10.3, (x86_64) Ubuntu 8.04 (x86) Ubuntu 8.10 (x86_64)
Mac MacOSX 10.3 (PPC32, PPC64) MacOSX 10.4 (PPC32, PPC64, x86) MacOSX 10.5 (PPC32, PPC64, x86, x86_64)
SunOS Solaris 8 (SPARC32, SPARC64, x86) Solaris 9 (SPARC32, SPARC64, x86) Solaris 10 (SPARC32, SPARC64, x86, x86_64)
Future versions will run on all platforms supported by the MySQL Server.
Note
MySQL Connector/C++ supports MySQL 5.1 and later.
Note
MySQL Connector/C++ supports only Microsoft Visual Studio 2003 and above on Windows. MySQL Connector/C++ Download You can download the source code for the MySQL Connector/C++ current release at the MySQL Connector/C++ downloads. MySQL Connector/C++ Source repository The latest development version is also available through Launchpad. Bazaar is used for the MySQL Connector/C++ code repository. You can check out the latest source code using the bzr command line tool:
shell> bzr branch lp:~mysql/mysql-connector-cpp/trunk .
Binary distributions Starting with 1.0.4 Beta, binary distributions were made available in addition to source code releases. The releases available are shown below.
MySQL Connector/C++
Microsoft Windows platform: Without installer, a Zip file MSI installer package
Note
Note that source packages are available for all platforms in the Compressed GNU TAR archive (tar.gz) format. Binary and source packages can be obtained from MySQL Connector/C++ downloads. MySQL Connector/C++ Advantages Using MySQL Connector/C++ instead of the MySQL C API (MySQL Client Library) offers the following advantages for C++ users: Convenience of pure C++, no C function calls required Supports an industry standard API, JDBC 4.0 Supports the object-oriented programming paradigm Reduces development time MySQL Connector/C++ is licensed under the GPL with the FLOSS License Exception MySQL Connector/C++ is available under a commercial license upon request
MySQL Connector/C++ Status MySQL Connector/C++ is available as a GA version. We kindly ask users and developers to try it out and provide us with feedback. Note that MySQL Workbench is successfully using MySQL Connector/C++. If you have any queries please contact us.
vi
You may need to change /usr/local/boost_1_40_0/ to match your installation. See the Section 1.1, Building source on Unix, Solaris and Mac OS X and Section 1.2, Building source on Windows for further details.
On non-Windows systems, CMake first checks to see if the CMake variable MYSQL_CONFIG_EXECUTABLE is set. If it is not found CMake will try to locate mysql_config in the default locations. If you have any problems with the configure process please check the troubleshooting instructions below. 2. Use make to build the libraries. First make sure you have a clean build:
shell> me@host:/path/to/mysql-connector-cpp> make clean
If all goes well, you will find the MySQL Connector/C++ library in /path/to/cppconn/libmysqlcppconn.so. 3. Finally make sure the header and library files are installed to their correct locations:
make install
Unless you have changed this in the configuration step, the header files will be copied to the directory /usr/local/include. The header files copied are mysql_connection.h and mysql_driver.h. Again, unless you have specified otherwise, the library files will be copied to /usr/local/lib. The files copied are libmysqlcppcon.so, the dynamic library, and libmysqlcppconn-static.a, the static library. 1
If you encounter any errors, please first carry out the checks shown below: 1. CMake options: MySQL installation path, debug version and more In case of configure and/or compile problems check the list of CMake options:
shell> me@host:/path/to/mysql-connector-cpp> cmake -L [...] CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4 CMAKE_BUILD_TYPE:STRING= CMAKE_INSTALL_PREFIX:PATH=/usr/local EXECUTABLE_OUTPUT_PATH:PATH= LIBRARY_OUTPUT_PATH:PATH= MYSQLCPPCONN_GCOV_ENABLE:BOOL=0 MYSQLCPPCONN_TRACE_ENABLE:BOOL=0 MYSQL_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/mysql_config
For example, if your MySQL Server installation path is not /usr/local/mysql and you want to build a debug version of the MySQL Connector/C++ use:
shell> me@host:/path/to/mysql-connector-cpp> cmake -D CMAKE_BUILD_TYPE:STRING=Debug -D MYSQL_CONFIG_EXECUTABLE=/path/to/my/mysql/server/bin/mysql_config .
2.
Proceed by carrying out a make clean command followed by a make command, as described above. Once you have installed MySQL Connector/C++ you can carry out a quick test to check the installation. To do this you can compile and run one of the example programs, such as examples/standalone_example.cpp. This example is discussed in more detail later, but for now you can use it to test the connector has been correctly installed. This procedure assumes you have a working MySQL Server that you can connect to. 1. First compile the example. To do this change to the examples directory and type:
2.
You need to make sure the dynamic library which is used in this case can be found at run time. To do this enter:
shell> export LD_LIBRARY_PATH=/usr/local/lib
3.
Now run the program to test your installation, exchanging the host, user, password and database to be accessed given below to match your system:
./test_install localhost root password database
If you see any errors take note of them and go through the troubleshooting procedures discussed earlier. 2
Note
On Windows, mysql_config is not present, so CMake will attempt to retrieve the location of MySQL from the environment variable $ENV{MYSQL_DIR}. If MYSQL_DIR is not set, CMake will then proceed to check for MySQL in the following locations: $ENV{ProgramFiles}/MySQL/*/include, and $ENV{SystemDrive}/MySQL/*/include. CMake makes it easy for you to try out other compilers. However, you may experience compile warnings, compile errors or linking issues not detected by Visual Studio. Patches are gratefully accepted to fix issues with other compilers. Consult the CMake manual or check cmake --help to find out which build systems are supported by your CMake version:
C:\>cmake --help cmake version 2.6-patch 2 Usage [...] Generators The following generators are available on this platform: Borland Makefiles = Generates Borland makefiles. MSYS Makefiles = Generates MSYS makefiles. MinGW Makefiles = Generates a make file for use with mingw32-make. NMake Makefiles = Generates NMake makefiles. Unix Makefiles = Generates standard UNIX makefiles. Visual Studio 6 = Generates Visual Studio 6 project files. Visual Studio 7 = Generates Visual Studio .NET 2002 project files. Visual Studio 7 .NET 2003 = Generates Visual Studio .NET 2003 project files. Visual Studio 8 2005 = Generates Visual Studio .NET 2005 project files. Visual Studio 8 2005 Win64 = Generates Visual Studio .NET 2005 Win64 project files. Visual Studio 9 2008 = Generates Visual Studio 9 2008 project fil Visual Studio 9 2008 Win64 = Generates Visual Studio 9 2008 Win64 proje files. [...]
It is likely that your CMake binary will support more compilers, known by CMake as generators, than supported by MySQL Connector/C++. We have built the connector using the following generators: Microsoft Visual Studio 8 (Visual Studio 2005) Microsoft Visual Studio 9 (Visual Studio 2008, Visual Studio 2008 Express) NMake
Please see the building instructions for Unix, Solaris and Mac OS X for troubleshooting and configuration hints. The steps to build the connector are given below: 1. Run CMake to generate build files for your generator: Visual Studio
C:\path_to_mysql_cpp>cmake -G "Visual Studio 9 2008" -- Check for working C compiler: cl -- Check for working C compiler: cl -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: cl -- Check for working CXX compiler: cl -- works
-- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- ENV{MYSQL_DIR} = -- MySQL Include dir: C:/Programme/MySQL/MySQL Server 5.1/include -- MySQL Library : C:/Progams/MySQL/MySQL Server 5.1/lib/opt/mysqlclient.lib -- MySQL Library dir: C:/Progams/MySQL/MySQL Server 5.1/lib/opt -- MySQL CFLAGS: -- MySQL Link flags: -- MySQL Include dir: C:/Progams/MySQL/MySQL Server 5.1/include -- MySQL Library dir: C:/Progams/MySQL/MySQL Server 5.1/lib/opt -- MySQL CFLAGS: -- MySQL Link flags: -- Configuring cppconn -- Configuring test cases -- Looking for isinf -- Looking for isinf - not found -- Looking for isinf -- Looking for isinf - not found. -- Looking for finite -- Looking for finite - not found. -- Configuring C/J junit tests port -- Configuring examples -- Configuring done -- Generating done -- Build files have been written to: C:\path_to_mysql_cpp C:\path_to_mysql_cpp>dir *.sln *.vcproj [...] 19.11.2008 12:16 23.332 MYSQLCPPCONN.sln [...] 19.11.2008 12:16 27.564 ALL_BUILD.vcproj 19.11.2008 12:16 27.869 INSTALL.vcproj 19.11.2008 12:16 28.073 PACKAGE.vcproj 19.11.2008 12:16 27.495 ZERO_CHECK.vcproj
NMake
C:\path_to_mysql_cpp>cmake -G "NMake Makefiles" -- The C compiler identification is MSVC -- The CXX compiler identification is MSVC [...] -- Build files have been written to: C:\path_to_mysql_cpp
2.
Use your compiler to build MySQL Connector/C++ Visual Studio - GUI Open the newly generated project files in the Visual Studio GUI or use a Visual Studio command line to build the driver. The project files contain a variety of different configurations. Among them debug and nondebug versions. Visual Studio - NMake
C:\path_to_mysql_cpp>nmake Microsoft (R) Program Maintenance Utility Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Scanning dependencies of target mysqlcppconn [ 2%] Building CXX object driver/CMakeFiles/mysqlcppconn.dir/mysql_connection.obj mysql_connection.cpp [...] Linking CXX executable statement.exe [100%] Built target statement
1.3. Dynamically Linking MySQL Connector/C++ against the MySQL Client Library
Note
Note this section refers to dynamic linking of the MySQL Connector/C++ with the client library, not the dynamic linking of the application to MySQL Connector/C++. An application that uses MySQL Connector/C++ can be either statically or dynamically linked to the MySQL Connector/C++ libraries. MySQL Connector/C++ is usually statically linked to the underlying MySQL Client Library (or Connector/C). Note, that unless otherwise stated, reference to the MySQL Client Library is also taken to include Connector/C, which is a separately packaged, stand alone
version of the MySQL Client Library. From MySQL Connector/C++ version 1.1.0 it is possible to also dynamically link to the underlying MySQL Client Library. The ability of MySQL Connector/C++ to dynamically link to MySQL Client Library is not enabled by default, and enabling this feature is done through a compile time option, when compiling the MySQL Connector/C++ source code. To use the ablity to dynamically link the client library to MySQL Connector/C++ the MYSQLCLIENT_STATIC_BINDING:BOOL needs to be defined when building the MySQL Connector/C++ source code:
rm CMakeCache.txt cmake -DMYSQLCLIENT_STATIC_BINDING:BOOL=1 . make clean make make install
Note that pre-compiled binaries of MySQL Connector/C++ use static binding with the client library by default. Now, in your application, when creating a connection, MySQL Connector/C++ will select and load a client library at runtime. It will choose the client library by searching defined locations and environment variables depending on the host operating system. It also possible when creating a connection in an application to define an absolute path to the client library to be loaded at runtime. This can be convenient if you have defined a standard location from which you want the client library to be loaded. This is sometimes done to circumvent possible conflicts with other versions of the client library that may be located on the system.
Using the MSI Installer may be the easiest solution. Running the MSI Installer does not require any administrative permissions as it simply copies files.
The Typical installation consists of all required header files and the Release libraries. The only available Custom installation option allows you to install additional Debug versions of the connector libraries.
The examples cover: Using the Driver class to connect to MySQL Creating tables, inserting rows, fetching rows using (simple) statements Creating tables, inserting rows, fetching rows using prepared statements Hints for working around prepared statement limitations Accessing result set meta data
The examples in this document are only code snippets. The code snippets provide a brief overview on the API. They are not complete programs. Please check the examples/ directory of your MySQL Connector/C++ installation for complete programs. Please also read the README file in the examples/ directory. Note to test the example code you will first need to edit the examples.h file in the examples/ directory, to add your connection information. Then simply rebuild the code by issuing a make command. The examples in the examples/ directory include: examples/connect.cpp: How to create a connection, insert data into MySQL and handle exceptions. examples/connection_meta_schemaobj.cpp: How to obtain meta data associated with a connection object, for example, a list of tables, databases, MySQL version, connector version. examples/debug.cpp: How to activate and deactivate the MySQL Connector/C++ debug protocol. examples/exceptions.cpp: A closer look at the exceptions thrown by the connector and how to fetch error information. examples/prepared_statements.cpp: How to run Prepared Statements including an example how to handle SQL commands that cannot be prepared by the MySQL Server. examples/resultset.cpp: 10
How to fetch data and iterate over the result set (cursor). examples/resultset_meta.cpp: How to obtain meta data associated with a result set, for example, number of columns and column types. examples/resultset_types.cpp: Result sets returned from meta data methods - this is more a test than much of an example. examples/standalone_example.cpp: Simple standalone program not integrated into regular CMake builds. examples/statements.cpp: How to run SQL commands without using Prepared Statements. examples/cpp_trace_analyzer.cpp: This example shows how to filter the output of the debug trace. Please see the inline comments for further documentation. This script is unsupported.
Make sure that you free the sql::Connection object as soon as you do not need it any more. But do not explicitly free the connector object!
Note that you have to free sql::Statement and sql::Connection objects explicitly using delete.
11
// ... sql::Connection *con; sql::Statement *stmt sql::ResultSet *res; // ... stmt = con->createStatement(); // ... res = stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC"); while (res->next()) { // You can use either numeric offsets... cout << "id = " <&;t; res->getInt(0); // ... or column names for accessing results. The latter is recommended. cout << ", label = '" << res->getString("label") << "'" << endl; } delete res; delete stmt; delete con;
Note that you have to free sql::Statement, sql::Connection and sql::ResultSet objects explicitly using delete. The usage of cursors is demonstrated in the examples contained in the download package.
12
#include <cppconn/driver.h> #include <cppconn/exception.h> #include <cppconn/resultset.h> #include <cppconn/statement.h> using namespace std; int main(void) { cout << endl; cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl; try { sql::Driver *driver; sql::Connection *con; sql::Statement *stmt; sql::ResultSet *res; /* Create a connection */ driver = get_driver_instance(); con = driver->connect("tcp://127.0.0.1:3306", "root", "root"); /* Connect to the MySQL test database */ con->setSchema("test"); stmt = con->createStatement(); res = stmt->executeQuery("SELECT 'Hello World!' AS _message"); while (res->next()) { cout << "\t... MySQL replies: "; /* Access column data by alias or column name */ cout << res->getString("_message") << endl; cout << "\t... MySQL says it again: "; /* Access column fata by numeric offset, 1 is the first column */ cout << res->getString(1) << endl; } delete res; delete stmt; delete con; } catch (sql::SQLException &e) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } cout << endl; return EXIT_SUCCESS; }
13
sql::Connection *con; sql::Statement *stmt; sql::ResultSet *res; sql::PreparedStatement *pstmt; /* Create a connection */ driver = get_driver_instance(); con = driver->connect("tcp://127.0.0.1:3306", "root", "root"); /* Connect to the MySQL test database */ con->setSchema("test"); stmt = con->createStatement(); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); delete stmt; /* '?' is the supported placeholder syntax */ pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)"); for (int i = 1; i <= 10; i++) { pstmt->setInt(1, i); pstmt->executeUpdate(); } delete pstmt; /* Select in ascending order */ pstmt = con->prepareStatement("SELECT id FROM test ORDER BY id ASC"); res = pstmt->executeQuery(); /* Fetch in reverse = descending order! */ res->afterLast(); while (res->previous()) cout << "\t... MySQL counts: " << res->getInt("id") << endl; delete res; delete pstmt; delete con; } catch (sql::SQLException &e) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; } cout << endl; return EXIT_SUCCESS; }
14
The first trace file can be generated by the underlying MySQL Client Library (libmysql). To enable this trace the connector will call the C-API function mysql_debug() internally. Only debug versions of the MySQL Client Library are capable of writing a trace file. Therefore you need to compile MySQL Connector/C++ against a debug version of the library, if you want utilize this trace. The trace shows the internal function calls and the addresses of internal objects as you can see below:
>mysql_stmt_init | >_mymalloc | | enter: Size: 816 | | exit: ptr: 0x68e7b8 | <_mymalloc | >init_alloc_root | | enter: root: 0x68e7b8 | | >_mymalloc | | | enter: Size: 2064 | | | exit: ptr: 0x68eb28 [...]
The second trace is the MySQL Connector/C++ internal trace. It is available with debug and nondebug builds of the connector as long as you have enabled the tracing module at compile time using cmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1. By default, the tracing functionality is not available and calls to trace functions are removed by the preprocessor. Compiling the connector with tracing functionality enabled will cause two additional tracing function calls per each connector function call. You will need to run your own benchmark to find out how much this will impact the performance of your application. A simple test using a loop running 30,000 INSERT SQL statements showed no significant real-time impact. The two variants of this application using a trace enabled and trace disabled version of the connector performed equally well. The run time measured in real-time was not significantly impacted as long as writing a debug trace was not enabled. However, there will be a difference in the time spent in the application. When writing a debug trace the IO subsystem may become a bottleneck. In summary, use connector builds with tracing enabled carefully. Trace enabled versions may cause higher CPU usage even if the overall run time of your application is not impacted significantly.
| 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 [...]
The example from examples/debug.cpp demonstrates how to activate the debug traces in your program. Currently they can only be activated through API calls. The traces are controlled on a per-connection basis. You can use the setClientOptions() method of a connection object to activate and deactivate the generation of a trace. The MySQL Client Library trace is always written into a file, whereas the connector's protocol messages are printed to standard out.
sql::Driver *driver; int on_off = 1; /* Using the Driver to create a connection */ driver = 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! */
15
con->setClientOption("libmysql_debug", "d:t:O,client.trace"); /* Tracing is available if you have compiled the driver using cmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1 */ con->setClientOption("client_trace", &on_off);
16
The corresponding getLong() and setLong() methods have been removed. The method DatabaseMetaData::getColumns() has 23 columns in its result set, rather than the 22 columns defined by JDBC. The first 22 columns are as described in the JDBC documentation, but column 23 is new: 23. IS_AUTOINCREMENT: String which is YES if the column is an auto-increment column. Otherwise the string contains NO. MySQL Connector/C++ may return different metadata for the same column. When you have any column that accepts a charset and a collation in its specification and you specify a binary collation, such as:
CHAR(250) CHARACTER SET 'latin1' COLLATE 'latin1_bin'
The server sets the BINARY flag in the result set metadata of this column. The method ResultSetMetadata::getColumnTypeName() uses the metadata and will report, due to the BINARY flag, that the column type name is BINARY. This is illustrated below:
mysql> create table varbin(a varchar(20) character set utf8 collate utf8_bin); Query OK, 0 rows affected (0.00 sec) mysql> select * from varbin; Field 1: `a` Catalog: `def` Database: `test` Table: `varbin` Org_table: `varbin` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 20 Max_length: 0 Decimals: 0 Flags: BINARY 0 rows in set (0.00 sec) mysql> select * from information_schema.columns where table_name='varbin'\G *************************** 1. row *************************** TABLE_CATALOG: NULL TABLE_SCHEMA: test TABLE_NAME: varbin COLUMN_NAME: a ORDINAL_POSITION: 1 COLUMN_DEFAULT: NULL IS_NULLABLE: YES DATA_TYPE: varchar CHARACTER_MAXIMUM_LENGTH: 20 CHARACTER_OCTET_LENGTH: 60 NUMERIC_PRECISION: NULL NUMERIC_SCALE: NULL CHARACTER_SET_NAME: utf8 COLLATION_NAME: utf8_bin COLUMN_TYPE: varchar(20) COLUMN_KEY: EXTRA: PRIVILEGES: select,insert,update,references COLUMN_COMMENT: 1 row in set (0.01 sec)
17
However, INFORMATION_SCHEMA gives no hint in its COLUMNS table that metadata will contain the BINARY flag. DatabaseMetaData::getColumns() uses INFORMATION_SCHEMA. It will report the type name CHAR for the same column. Note, a different type code is also returned. The MySQL Connector/C++ class sql::DataType defines the following JDBC standard data types: UNKNOWN, BIT, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, NUMERIC, CHAR, BINARY, VARCHAR, VARBINARY, LONGVARCHAR, LONGVARBINARY, TIMESTAMP, DATE, TIME, GEOMETRY, ENUM, SET, SQLNULL. However, the following JDBC standard data types are not supported by MySQL Connector/C++: ARRAY, BLOB, CLOB, DISTINCT, FLOAT, OTHER, REF, STRUCT. When inserting or updating BLOB or TEXT columns, MySQL Connector/C++ developers are advised not to use setString(). Instead it is recommended that the dedicated API function setBlob() be used instead. The use of setString() can cause a Packet too large error message. The error will occur if the length of the string passed to the connector using setString() exceeds max_allowed_packet (minus a few bytes reserved in the protocol for control purposes). This situation is not handled in MySQL Connector/C++, as this could lead to security issues, such as extremely large memory allocation requests due to malevolently long strings. However, if setBlob() is used, this problem does not arise. This is because setBlob() takes a streaming approach based on std::istream. When sending the data from the stream to MySQL Server, MySQL Connector/C++ will split the stream into chunks appropriate for MySQL Server and observe the max_allowed_packet setting currently being used.
Caution
When using setString() it is not possible to set max_allowed_packet to a value large enough for the string, prior to passing it to MySQL Connector/C++. The MySQL 5.1 documentation for max_allowed_packet states: As of MySQL 5.1.31, the session value of this variable is read only. Before 5.1.31, setting the session value is allowed but has no effect. This difference with the JDBC specification ensures that MySQL Connector/C++ is not vulnerable to memory flooding attacks. In general MySQL Connector/C++ works with MySQL 5.0, but it is not completely supported. Some methods may not be available when connecting to MySQL 5.0. This is because the Information Schema is used to obtain the requested information. There are no plans to improve the support for 5.0 because the current GA version of MySQL Server is 5.1. As a new product, MySQL Connector/ C++ is primarily targeted at the MySQL Server GA version that was available on its release. The following methods will throw a sql::MethodNotImplemented exception when you connect to MySQL earlier than 5.1.0: DatabaseMetadata::getCrossReference() DatabaseMetadata::getExportedKeys()
MySQL Connector/C++ includes a method Connection::getClientOption() which is not included in the JDBC API specification. The prototype is:
void getClientOption(const std::string & optionName, void * optionValue)
The method can be used to check the value of connection properties set when establishing a database connection. The values are returned through the optionValue argument passed to the method with the type void *. Currently, getClientOption() supports fetching the optionValue of the following options: metadataUseInfoSchema defaultStatementResultType
defaultPreparedStatementResultType The connection option metadataUseInfoSchema controls whether to use the Information_Schemata for returning the meta data of SHOW commands. In the case of metadataUseInfoSchema the optionValue argument should be interpreted as a boolean upon return.
18
In the case of both defaultStatementResultType and defaultPreparedStatementResultType, the optionValue argument should be interpreted as an integer upon return. The connection property can be either set when establishing the connection through the connection property map or using void Connection::setClientOption(const std::string & optionName, const void * optionValue) where optionName is assigned the value metadataUseInfoSchema. Some examples are given below:
int defaultStmtResType; int defaultPStmtResType; conn->getClientOption("defaultStatementResultType", (void *) &defaultStmtResType); conn->getClientOption("defaultPreparedStatementResultType", (void *) &defaultPStmtResType); bool isInfoSchemaUsed; conn->getClientOption("metadataUseInfoSchema", (void *) &isInfoSchemaUsed);
MySQL Connector/C++ also supports the following methods not found in the JDBC API standard:
std::string MySQL_Connection::getSessionVariable(const std::string & varname) void MySQL_Connection::setSessionVariable(const std::string & varname, const std::string & value)
Note that both methods are members of the MySQL_Connection class. The methods get and set MySQL session variables. setSessionVariable() is equivalent to executing:
SET SESSION <varname> = <value>
getSessionVariable() is equivalent to executing the following and fetching the first return value:
SHOW SESSION VARIABLES LIKE "<varname>"
You can use % and other placeholders in <varname>, if the underlying MySQL server supports this. Fetching the value of a column can sometimes return different values depending on whether the call is made from a Statement or Prepared Statement. This is because the protocol used to communicate with the server differs depending on whether a Statement or Prepared Statement is used. To illustrate this, consider the case where a column has been defined as of type BIGINT. The most negative BIGINT value is then inserted into the column. If a Statement and Prepared Statement are created that perform a GetUInt64() call, then the results will be found to be different in each case. The Statement returns the maximum positive value for BIGINT. The Prepared Statement returns 0. The reason for the different results is due to the fact that Statements use a text protocol, and Prepared Statements use a binary protocol. With the binary protocol in this case, a binary value is returned from the server that can be interpreted as an int64. In the above scenario a very large negative value was fetched with GetUInt64(), which fetches unsigned integers. As the large negative value cannot be sensibly converted to an unsigned value 0 is returned. In the case of the Statement, which uses the text protocol, values are returned from the server as strings, and then converted as required. When a string value is returned from the server in the above scenario the large negative value will need to be converted by the runtime library function strtoul(), which GetUInt64() calls. The behavior of strtoul() is dependent upon the specific runtime and host operating system, so the results can be variable. In the case given a large positive value was actually returned. Although it is very rare, there are some cases where Statements and Prepared Statements can return different values unexpectedly, but this usually only happens in extreme cases such as the one mentioned. The JDBC documentation lists many fields for the DatabaseMetaData class. JDBC also appears to define certain values for those fields. However, MySQL Connector/C++ does not define certain values for those fields. Internally enumerations are used and the compiler determines the values to assign to a field. To compare a value with the field, code such as the following should be used, rather than making assumptions about specific values for the attribute:
// dbmeta is an instance of DatabaseMetaData if (myvalue == dbmeta->attributeNoNulls) {
19
... }
Usually myvalue will be a column from a result set holding metadata information. MySQL Connector/C++ does not guarantee that attributeNoNulls is 0. It can be any value. When programming Stored Procedures JDBC has available an extra class, an extra abstraction layer for callable statements, the CallableStatement class. This is not present in MySQL Connector/C++. You therefore need to use the methods from the Statement and Prepared Statement classes to run a Stored Procedure using CALL.
20
See also the MySQL Connector/C++ Changelogs which can be found here Appendix A, MySQL Connector/C++ Change History.
21
22
Instances of std::auto_ptr have been changed to boost::scoped_ptr. Scoped array instances now use boost::scoped_array. Further, boost::shared_ptr and boost::weak_ptr are now used for guarding access around result sets. LDFLAGS, CXXFLAGS and CPPFLAGS are now checked from the environment for every binary generated. Connection map property OPT_RECONNECT was changed to be of type boolean from long long. get_driver_instance() is now only available in dynamic library builds - static builds do not have this symbol. This was done to accommodate loading the DLL with LoadLibrary or dlopen. If you do not use CMake for building the source code you will need to define mysqlcppconn_EXPORTS if you are loading dynamically and want to use the get_driver_instance() entry point. Connection::getClientOption(const sql::SQLString & optionName, void * optionValue) now accepts the optionName values metadataUseInfoSchema, defaultStatementResultType, defaultPreparedStatementResultType, and characterSetResults. In the previous version only metadataUseInfoSchema was allowed. The same options are avalable for Connection::setClientOption().
Bugs fixed: Certain header files were incorrectly present in the source distribution. The fix excludes dynamically generated and platform specific header files from source packages generated using CPack. (Bug#45846) CMake generated an error if configuring an out of source build, that is when CMake not called from the source root directory. (Bug#45843) Using Prepared Statements caused corruption of the heap. (Bug#45048) Missing includes when using GCC 4.4. Note that GCC 4.4 is not yet in use for any official MySQL Connector/C++ builds. (Bug#44931) A bug was fixed in Prepared Statements. The bug occurred when a stored procedure was prepared without any parameters. This led to an exception. (Bug#44931) Fixed a Prepared Statements performance issue. Reading large result sets was slow. Fixed bug in ResultSetMetaData for statements and prepared statements, getScale and getPrecision returned incorrect results.
23
This avoids potential memory leaks that could occur as a result of losing the pointer returned by getMetaData(). Improved memory management. Potential memory leak situations are handled more robustly. Changed the interface of sql::Driver and sql::Connection so they accept the options map by alias instead of by value. Changed the return type of sql::SQLException::getSQLState() from std::string to const char * to be consistent with std::exception::what(). Implemented getResultSetType() and setResultSetType() for Statement. Uses TYPE_FORWARD_ONLY, which means unbuffered result set and TYPE_SCROLL_INSENSITIVE, which means buffered result set. Implemented getResultSetType() for PreparedStatement. The setter is not implemented because currently PreparedStatement cannot do refetching. Storing the result means the bind buffers will be correct. Added the option defaultStatementResultType to MySQL_Connection::setClientOption(). Also, the method now returns sql::Connection *. Added Result::getType(). Implemented for the three result set classes. Enabled tracing functionality when building with Microsoft Visual C++ 8 and later, which corresponds to Microsoft Visual Studio 2005 and later. Added better support for named pipes, on Windows. Use pipe:// and add the path to the pipe. Shared memory connections are currently not supported.
Bugs fixed: A bug was fixed in MySQL_Connection::setSessionVariable(), which had been causing exceptions to be thrown.
Bugs fixed: A bug was fixed in all implementations of ResultSet::relative() which was giving a wrong return value although positioning was working correctly. A leak was fixed in MySQL_PreparedResultSet, which occurred when the result contained a BLOB column.
able to use int64_t. Introduced ResultSet::getUInt() and ResultSet::getUInt64(). Improved the implementation for ResultSetMetaData::isReadOnly(). Values generated from views are read-only. These generated values don't have db in MYSQL_FIELD set, while all normal columns do have. Implemented MySQL_DatabaseMetaData::getExportedKeys(). Implemented MySQL_DatabaseMetaData::getCrossReference().
Bugs fixed: Bug fixed in MySQL_PreparedResultSet::getString(). Returned string that had real data but the length was random. Now, the string is initialized with the correct length and thus is binary safe. Corrected handling of unsigned server types. Now returning correct values. Fixed handling of numeric columns in ResultSetMetaData::isCaseSensitive to return false.
Bugs fixed: Fixed MySQL_PreparedStatementResultSet::getDouble() to return the correct value when the underlying type is MYSQL_TYPE_FLOAT. Fixed bug in MySQL_ConnectionMetaData::getIndexInfo(). The method did not work because the schema name wasn't included in the query sent to the server. Fixed a bug in MySQL_ConnectionMetaData::getColumns() which was performing a cartesian product of the columns in 26
the table times the columns matching columnNamePattern. The example example/connection_meta_schemaobj.cpp was extended to cover the function. Fixed bugs in MySQL_DatabaseMetaData. All supportsCatalogXXXXX methods were incorrectly returning true and all supportsSchemaXXXX methods were incorrectly returning false. Now supportsCatalogXXXXX returns false and supportsSchemaXXXXX returns true. Fixed bugs in the MySQL_PreparedStatements methods setBigInt() and setDatetime(). They decremented the internal column index before forwarding the request. This resulted in a double-decrement and therefore the wrong internal column index. The error message generated was:
setString() ... invalid "parameterIndex"
Fixed a bug in getString(). getString() is now binary safe. A new example was also added. Fixed bug in FLOAT handling. Fixed MySQL_PreparedStatement::setBlob(). In the tests there is a simple example of a class implementing sql::Blob.
or
examples/connect unix:///path/to/mysql.sock user pass database
27
Renamed ConnectionMetaData::getProcedures: PROCEDURE_SCHEMA to PROCEDURE_SCHEM. Renamed ConnectionMetaData::getPrimaryKeys(): COLUMN to COLUMN_NAME, SEQUENCE to KEY_SEQ, and INDEX_NAME to PK_NAME. Renamed ConnectionMetaData::getImportedKeys(): PKTABLE_CATALOG to PKTABLE_CAT, PKTABLE_SCHEMA to PKTABLE_SCHEM, FKTABLE_CATALOG to FKTABLE_CAT, FKTABLE_SCHEMA to FKTABLE_SCHEM. Changed metadata column name TABLE_CATALOG to TABLE_CAT and TABLE_SCHEMA to TABLE_SCHEM to ensure JDBC compliance. Introduced experimental CPack support, see make help. All tests changed to create TAP compliant output. Renamed sql::DbcMethodNotImplemented to sql::MethodNotImplementedException Renamed sql::DbcInvalidArgument to sql::InvalidArgumentException Changed sql::DbcException to implement the interface of JDBC's SQLException. Renamed to sql::SQLException. Converted Connector/J tests added. MySQL Workbench 5.1 changed to use MySQL Connector/C++ for its database connectivity. New directory layout.
28