// mysqltest.cpp : Defines the entry point for the application. // #include #include #include "mysql.h" void execute_sql(MYSQL *msql, const char *sql); void process_result(MYSQL *mysql); using namespace std; int main() { printf("MySQL multi-statement protocol test.\n"); MYSQL mysql; char host_name[] = "localhost"; char user_name[] = "root"; char password[] = "your-password"; uint port_num = 3306; char db_name[] = ""; char socket_name[] = ""; unsigned long connect_flag = CLIENT_MULTI_STATEMENTS; memset(&mysql, 0, sizeof(mysql)); mysql_init(&mysql); if (mysql_real_connect (&mysql, host_name, user_name, password, db_name, port_num, socket_name, connect_flag) == NULL) { printf("mysql_real_connect() failed: %u - %s", mysql_errno(&mysql), mysql_error(&mysql)); mysql_close(&mysql); exit(1); } // initialize execute_sql(&mysql, "CREATE SCHEMA IF NOT EXISTS protocol_test;\n" "DROP TABLE IF EXISTS protocol_test.table_a;\n" "CREATE TABLE protocol_test.table_a (id INT PRIMARY KEY, info VARCHAR(80) CHARSET Latin1);\n" "SELECT 1"); // execute binlog format description event execute_sql(&mysql, "BINLOG '\n" "8LNlYw8HAAAAegAAAAAAAAAAAAQAOC4wLjI5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" "AAAAAAAAAAAAAAAAAAAAAAAAEwANAAgAAAAABAAEAAAAYgAEGggAAAAICAgCAAAACgoKKioAEjQACigAAXD+Vxg=\n" "';"); // Will print: received 1 rows, 1 fields execute_sql(&mysql, "SELECT 1;"); // insert into protocol_test.table_a values(1, 'record #1'); execute_sql(&mysql, "BINLOG '\n" "vqFpYxMHAAAARAAAALYEAAAAAGgAAAAAAAEADXByb3RvY29sX3Rlc3QAB3RhYmxlX2EAAgMPAlAAAgEBAAIBCC/6kIE=\n" "vqFpYx4HAAAAMgAAAOgEAAAAAGgAAAAAAAEAAgAC/wABAAAACXJlY29yZCAjMSa1VdU=';\n" "COMMIT;"); // The following statement should print that it has received 1 rows, 1 fields, but will print 0 rows affected instead // because it will read wrong paket which belongs to the previous COMMIT above because of the protocol error! // The server does not set SERVER_MORE_RESULTS_EXISTS on the BINLOG result, so the COMMIT result remains unread until // now. This makes it impossible to batch multiple BINLOG statements, and affects the overall performance. execute_sql(&mysql, "SELECT 1;"); mysql_close(&mysql); return 0; } void execute_sql(MYSQL *mysql, const char *sql) { printf("--------------->\n%s\n", sql); int status = mysql_query(mysql, sql); if (status) { printf("mysql_query() failed:\nError: %u - %s\n", mysql_errno(mysql), mysql_error(mysql)); mysql_close(mysql); exit(1); } puts("<-----------------"); process_result(mysql); } void process_result(MYSQL *mysql) { int status = 0; int i = 0; // process each statement result do { // did current statement return data? MYSQL_RES *result = mysql_store_result(mysql); if (result) { // yes; process rows and free the result set printf("Result #%d: received %lu rows, %u fields\n", i, result->row_count, result->field_count); mysql_free_result(result); } else { if (mysql_field_count(mysql) == 0) { printf("Result #%d: %lu rows affected\n", i, mysql_affected_rows(mysql)); } else { printf("Result #%d: Could not retrieve. Error: %u - %s\n", i, mysql_errno(mysql), mysql_error(mysql)); break; } } // more results? -1 = no, >0 = error, 0 = yes (keep looping) if ((status = mysql_next_result(mysql)) > 0) { printf("Could not execute statement #%d. Error: %u - %s\n", i, mysql_errno(mysql), mysql_error(mysql)); } i++; } while (status == 0); }