List:Commits« Previous MessageNext Message »
From:andrey.hristov Date:November 3 2008 5:42pm
Subject:bzr commit into connector-cpp-bzr branch (andrey.hristov:200)
View as plain text  
#At bzr+ssh://ahristov@stripped/bzrroot/public/connector-cpp-bzr/trunk/

  200 andrey.hristov@stripped	2008-11-03 [merge]
      Merge
modified:
  common/ccppTypes.h
  driver/mysql_prepared_statement.cpp
  examples/connect.cpp
  examples/prepared_statement.cpp
  examples/resultset.cpp
  examples/resultset_meta.cpp
  examples/statement.cpp

=== modified file 'common/ccppTypes.h'
--- a/common/ccppTypes.h	2008-10-17 14:43:14 +0000
+++ b/common/ccppTypes.h	2008-10-31 15:46:28 +0000
@@ -15,7 +15,7 @@
 #define atoll(x) _atoi64((x))
 #endif
 #else
-
+#include <string.h>
 #endif
 
 #include <vector>

=== modified file 'driver/mysql_prepared_statement.cpp'
--- a/driver/mysql_prepared_statement.cpp	2008-11-03 17:38:56 +0000
+++ b/driver/mysql_prepared_statement.cpp	2008-11-03 17:42:54 +0000
@@ -18,6 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
+#include <stdlib.h>
 #include <memory>
 #include "mysql_connection.h"
 #include "mysql_exception.h"

=== modified file 'examples/connect.cpp'
--- a/examples/connect.cpp	2008-10-20 11:49:28 +0000
+++ b/examples/connect.cpp	2008-11-03 17:02:18 +0000
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 
 // Public interface of the MySQL Connector/C++
 #include <driver/mysql_public_iface.h>
@@ -40,7 +41,13 @@ using namespace std;
 /**
 * Usage example for Driver, Connection, (simple) Statement, ResultSet
 */
-int main() {
+int main(int argc, const char **argv) 
+{
+
+	const std::string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
+	const std::string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
+	const std::string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
+
 	// Driver
 	sql::Driver *driver;
 
@@ -52,15 +59,18 @@ int main() {
 	/* sql::ResultSet.rowsCount() returns size_t */
 	size_t row;
 	stringstream sql;
+	stringstream msg;
 	int i, affected_rows;
 
 	cout << boolalpha;
-	cout << "Connector/C++ connect basic usage example.." << endl << endl;
+	cout << "1..1" << endl;
+	cout << "# Connector/C++ connect basic usage example.." << endl;
+	cout << "#" << endl;
 
 	try {
 		// Using the Driver to create a connection
 		driver = get_driver_instance();
-		con = driver->connect(EXAMPLE_HOST, EXAMPLE_USER, EXAMPLE_PASS);
+		con = driver->connect(host, user, pass);
 
 		// Creating a "simple" statement - "simple" = not a prepared statement
 		stmt = con->createStatement();
@@ -69,10 +79,8 @@ int main() {
 		stmt->execute("USE " EXAMPLE_DB);
 		stmt->execute("DROP TABLE IF EXISTS test");
 		stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
-		cout << "\tTest table created" << endl;
-		cout << "stopping tracing" << endl;
-		bool trace = 0;
-		con->setClientOption(std::string("client_trace"), static_cast<const void *> (&trace));
+		cout << "#\t Test table created" << endl;
+		
 		// Populate the test table with data
 		for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) {
 			// KLUDGE: You should take measures against SQL injections!
@@ -82,39 +90,43 @@ int main() {
 			sql << test_data[i].id << ", '" << test_data[i].label << "')";
 			stmt->execute(sql.str());
 		}
-		cout << "\tTest table populated" << endl << endl;
+		cout << "#\t Test table populated" << endl;
 
 		// Run a query which returns exactly one result set like SELECT
 		// Stored procedures (CALL) may return more than one result set
 		res = stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC");
-		cout << "\tRunning 'SELECT id, label FROM test ORDER BY id ASC'" << endl;
+		cout << "#\t Running 'SELECT id, label FROM test ORDER BY id ASC'" << endl;
 
 		// Number of rows in the result set
-		cout << "\t\tNumber of rows\t";
+		cout << "#\t\t Number of rows\t";
 		cout << "res->rowsCount() = " << res->rowsCount() << endl;
+		if (res->rowsCount() != EXAMPLE_NUM_TEST_ROWS) {
+			msg.str("");
+			msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, found " << res->rowsCount();
+			throw runtime_error(msg.str());
+		}
 
 		// Fetching data
 		row = 0;
 		while (res->next()) {
-			cout << "\t\tFetching row " << row << "\t";
+			cout << "#\t\t Fetching row " << row << "\t";
 			// You can use either numeric offsets...
 			cout << "id = " << res->getInt(1);
 			// ... or column names for accessing results. The latter is recommended.
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row++;
-		}
-		cout << endl;
+		}		
 		delete res;
 
 		// Fetching again but using type convertion methods
 		res = stmt->executeQuery("SELECT id FROM test ORDER BY id DESC");
-		cout << "\tFetching 'SELECT id FROM test ORDER BY id DESC' using type conversion" << endl;
+		cout << "#\t Fetching 'SELECT id FROM test ORDER BY id DESC' using type conversion" << endl;
 		row = 0;
 		while (res->next()) {
-			cout << "\t\tFetching row " << row;
-			cout << "\tid (int) = " << res->getInt("id");
-			cout << "\tid (boolean) = " << res->getBoolean("id");
-			cout << "\tid (long) = " << res->getLong("id") << endl;
+			cout << "#\t\t Fetching row " << row;
+			cout << "#\t id (int) = " << res->getInt("id");
+			cout << "#\t id (boolean) = " << res->getBoolean("id");
+			cout << "#\t id (long) = " << res->getLong("id") << endl;
 			row++;
 		}
 		delete res;
@@ -124,17 +136,23 @@ int main() {
 		// Usage of UPDATE
 		stmt->execute("INSERT INTO test(id, label) VALUES (100, 'z')");
 		affected_rows = stmt->executeUpdate("UPDATE test SET label = 'y' WHERE id = 100");
-		cout << endl;
-		cout << "\tUPDATE indicates " << affected_rows << " affected rows" << endl;
+		cout << "#\t UPDATE indicates " << affected_rows << " affected rows" << endl;
+		if (affected_rows != 1) {
+			msg.str("");
+			msg << "Expecting one row to be changed, but " << affected_rows << "change(s) reported";
+			throw runtime_error(msg.str());
+		}
 
 		res = stmt->executeQuery("SELECT id, label FROM test WHERE id = 100");
 
 		res->next();
-		if ((res->getInt("id") != 100) || (res->getString("label") != "y")) {
-			cout << "\t\tFAILURE Update must have failed" << endl;
+		if ((res->getInt("id") != 100) || (res->getString("label") != "y")) {			
+			msg.str("Update must have failed, expecting 100/y got");
+			msg << res->getInt("id") << "/" << res->getString("label");
+			throw runtime_error(msg.str());
 		}
 
-		cout << "\t\tExpecting id = 100, label = 'y' and got id = " << res->getInt("id");
+		cout << "#\t\t Expecting id = 100, label = 'y' and got id = " << res->getInt("id");
 		cout << ", label = '" << res->getString("label") << "'" << endl;
 
 		// Clean up
@@ -142,7 +160,8 @@ int main() {
 		delete stmt;
 		delete con;
 
-		cout << "done!" << endl;
+		cout << "# done!" << endl;
+		cout << "ok" << endl;
 
 	} catch (sql::SQLException &e) {
 		/*
@@ -158,17 +177,25 @@ int main() {
 		All MySQL Server related errors will be reported by throwing a sql::mysql::MySQL_SQLException.
 		All MySQL Client releated errors will be reported by throwing a sql::SQLException
 		*/
-
-		cout << endl;
-		cout << "ERR: SQLException in " << __FILE__;
+		
+		cout << "# ERR: SQLException in " << __FILE__;
 		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
 		// Use what() (derived from std::runtime_error)
-		cout << "ERR: " << e.what();
+		cout << "# ERR: " << e.what();
 		cout << " (MySQL error code: " << e.getErrorCode();
 		cout << ", SQLState: " << e.getSQLState() << " )" << endl;
+		cout << "not ok" << endl;
+
+		return EXIT_FAILURE;
+	} catch (std::runtime_error &e) {
+		
+		cout << "# ERR: runtime_error in " << __FILE__;
+		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;		
+		cout << "# ERR: " << e.what() << endl;
+		cout << "not ok" << endl;
 
 		return EXIT_FAILURE;
-	}
+	} 
 
 	return EXIT_SUCCESS;
 }

=== modified file 'examples/prepared_statement.cpp'
--- a/examples/prepared_statement.cpp	2008-10-20 11:49:28 +0000
+++ b/examples/prepared_statement.cpp	2008-11-03 17:02:18 +0000
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 
 // Public interface of the MySQL Connector/C++
 #include <driver/mysql_public_iface.h>
@@ -71,8 +72,13 @@ using namespace std;
 *
 * @link http://dev.mysql.com/doc/refman/5.1/en/c-api-prepared-statements.html
 */
-int main()
+int main(int argc, const char **argv) 
 {
+
+	const std::string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
+	const std::string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
+	const std::string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
+
 	// Driver Manager
 	sql::Driver *driver;
 
@@ -85,15 +91,17 @@ int main()
 	/* sql::ResultSet.rowsCount() returns size_t */
 	size_t row;
 	stringstream sql;
+	stringstream msg;
 	int i, num_rows;
 
 	cout << boolalpha;
-	cout << "Connector/C++ prepared statement example.." << endl << endl;
+	cout << "1..1" << endl;;
+	cout << "# Connector/C++ prepared statement example.." << endl;
 
 	try {
 		// Using the Driver to create a connection
 		driver = get_driver_instance();
-		con = driver->connect(EXAMPLE_HOST, EXAMPLE_USER, EXAMPLE_PASS);
+		con = driver->connect(host, user, pass);
 
 		// See above - USE is not supported through the prepared statement protocol
 		stmt = con->createStatement();
@@ -125,7 +133,7 @@ int main()
 
 		// Yet another example of *bad* and *slow* code
 		prepare_execute(con, "CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))");
-		cout << "\tTest table created" << endl;
+		cout << "#\t Test table created" << endl;
 
 		/*
 		The first useful example - prepare() once, execute() n + 1 times
@@ -143,25 +151,30 @@ int main()
 		}
 		delete prep_stmt;
 		if (EXAMPLE_NUM_TEST_ROWS != num_rows) {
-			cout << "\tFAILURE executeUpdate() has returned a wrong number of inserted rows" << endl;
+			msg.str("");
+			msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, reported " << num_rows;
+			throw runtime_error(msg.str());
 		}
-
-		cout << "\tTest table populated" << endl << endl;
+		cout << "#\t Test table populated" << endl;
 
 		// We will reuse the SELECT a bit later...
 		prep_select = con->prepareStatement("SELECT id, label FROM test ORDER BY id ASC");
-		cout << "\tRunning 'SELECT id, label FROM test ORDER BY id ASC'" << endl;
+		cout << "#\t Running 'SELECT id, label FROM test ORDER BY id ASC'" << endl;
 		res = prep_select->executeQuery();
 		row = 0;
 		while (res->next()) {
-			cout << "\t\tRow " << row << " - id = " << res->getInt("id");
+			cout << "#\t\t Row " << row << " - id = " << res->getInt("id");
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row++;
-		}
+		}		
 		delete res;
+		if (EXAMPLE_NUM_TEST_ROWS != row) {
+			msg.str("");
+			msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, reported " << row;
+			throw runtime_error(msg.str());
+		}
 
-		cout << endl;
-		cout << "\tSimple PS 'emulation' for USE and another SELECT" << endl;
+		cout << "#\t Simple PS 'emulation' for USE and another SELECT" << endl;
 		stmt = emulate_prepare_execute(con, "USE mysql");
 		delete stmt;
 		stmt = emulate_prepare_execute(con, "USE " EXAMPLE_DB);
@@ -172,47 +185,47 @@ int main()
 		if (res != NULL) {
 			row = 0;
 			while (res->next()) {
-				cout << "\t\tRow " << row << " - id = " << res->getInt("id") << endl;
+				cout << "#\t\t Row " << row << " - id = " << res->getInt("id") << endl;
 				row++;
 			}
 			delete res;
 		}
 		delete stmt;
 
-		// Running the SELECT again but fetching in reverse order
-		cout << endl;
-		cout << "\tSELECT and fetching in reverse order" << endl;
+		// Running the SELECT again but fetching in reverse order		
+		cout << "#\t SELECT and fetching in reverse order" << endl;
 
 		res = prep_select->executeQuery();
 		row = res->rowsCount();
-		cout << "\t\tres->getRowsCount() = " << res->rowsCount() << endl;
-		if (row != EXAMPLE_NUM_TEST_ROWS) {
-			cout << "\tFAILURE Expecting " << EXAMPLE_NUM_TEST_ROWS;
-			cout << " rows; got " << res->rowsCount() << endl;
+		cout << "#\t\t res->getRowsCount() = " << res->rowsCount() << endl;
+		if (res->rowsCount() != EXAMPLE_NUM_TEST_ROWS) {
+			msg.str("");
+			msg << "Expecting " << EXAMPLE_NUM_TEST_ROWS << "rows, found " << res->rowsCount();
+			throw runtime_error(msg.str());
 		}
 
 		// Position the cursor after the last row
-		cout << "\t\tPosition the cursor after the last row\n";
+		cout << "#\t\t Position the cursor after the last row\n";
 		res->afterLast();
-		cout << "\t\tres->isafterLast()\t= " << res->isAfterLast() << endl;
-		cout << "\t\tres->isLast()\t\t= " << res->isLast() << endl;
+		cout << "#\t\t res->isafterLast()\t= " << res->isAfterLast() << endl;
+		cout << "#\t\t res->isLast()\t\t= " << res->isLast() << endl;
 		while (res->previous()) {
-			cout << "\t\tres->previous()\n";
-			cout << "\t\tRow " << row << " - id = " << res->getInt("id");
+			cout << "#\t\t res->previous()\n";
+			cout << "#\t\t Row " << row << " - id = " << res->getInt("id");
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row--;
 		}
-		cout << "\t\tShould be before the first\n";
-		cout << "\t\tres->isFirst()\t\t= " << res->isFirst() << endl;
-		cout << "\t\tres->isBeforeFirst()\t= " << res->isBeforeFirst() << endl;
+		cout << "#\t\t Should be before the first\n";
+		cout << "#\t\t res->isFirst()\t\t= " << res->isFirst() << endl;
+		cout << "#\t\t res->isBeforeFirst()\t= " << res->isBeforeFirst() << endl;
 
 		// Now that the cursor is before the first, fetch the first
-		cout << "\t\tNow that the cursor is before the first, fetch the first\n";
-		cout << "\t\tcalling next() to fetch first row" << endl;
+		cout << "#\t\t Now that the cursor is before the first, fetch the first\n";
+		cout << "#\t\t calling next() to fetch first row" << endl;
 		row++;
 		res->next();
-		cout << "\t\tres->isFirst()\t\t= " << res->isFirst() << endl;
-		cout << "\t\tRow " << row << " - id = " << res->getInt("id");
+		cout << "#\t\t res->isFirst()\t\t= " << res->isFirst() << endl;
+		cout << "#\t\t Row " << row << " - id = " << res->getInt("id");
 		cout << ", label = '" << res->getString("label") << "'" << endl;
 		row--;
 
@@ -224,8 +237,9 @@ int main()
 		// Clean up
 		stmt = con->createStatement();
 		stmt->execute("DROP TABLE IF EXISTS test");
-		cout << "done!" << endl;
-		cout << endl;
+		cout << "#done!" << endl;
+		
+		cout << "ok" << endl;
 
 		delete stmt;
 		delete con;
@@ -246,15 +260,25 @@ int main()
 		*/
 
 		cout << endl;
-		cout << "ERR: DbcException in " << __FILE__;
+		cout << "# ERR: DbcException in " << __FILE__;
 		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
 		// Use what(), getErrorCode() and getSQLState()
-		cout << "ERR: " << e.what();
+		cout << "# ERR: " << e.what();
 		cout << " (MySQL error code: " << e.getErrorCode();
 		cout << ", SQLState: " << e.getSQLState() << " )" << endl;
+		cout << "not ok" << 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" << endl;
+
+		return EXIT_FAILURE;
+	} 
 
 	return EXIT_SUCCESS;
 }
@@ -277,13 +301,13 @@ sql::Statement* emulate_prepare_execute(
 	sql::PreparedStatement *prep_stmt;
 	sql::Statement *stmt = NULL;
 
-	cout << "\t\t'emulation': " << sql << endl;
+	cout << "#\t\t 'emulation': " << sql << endl;
 
 	try {
 
 		prep_stmt = con->prepareStatement(sql);
 		prep_stmt->execute();
-		cout << "\t\t'emulation': use of sql::PreparedStatement possible" << endl;
+		cout << "#\t\t 'emulation': use of sql::PreparedStatement possible" << endl;
 		// safe upcast - PreparedStatement is derived from Statement
 		stmt = prep_stmt;
 
@@ -302,7 +326,7 @@ sql::Statement* emulate_prepare_execute(
 			// but something went wrong. Let the caller handle the error.
 			throw ;
 		}
-		cout << "\t\t'emulation': ER_UNSUPPORTED_PS and fallback to sql::Statement" << endl;
+		cout << "#\t\t 'emulation': ER_UNSUPPORTED_PS and fallback to sql::Statement" << endl;
 
 		stmt = con->createStatement();
 		stmt->execute(sql);

=== modified file 'examples/resultset.cpp'
--- a/examples/resultset.cpp	2008-10-20 11:49:28 +0000
+++ b/examples/resultset.cpp	2008-11-03 17:02:18 +0000
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 
 // Public interface of the MySQL Connector/C++
 #include <driver/mysql_public_iface.h>
@@ -41,8 +42,13 @@ using namespace std;
 /**
 * Example how to scroll through a result set
 */
-int main()
+int main(int argc, const char **argv) 
 {
+
+	const std::string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
+	const std::string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
+	const std::string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
+
 	// Driver Manager
 	sql::Driver *driver;
 
@@ -58,12 +64,13 @@ int main()
 	struct _test_data min, max;
 
 	cout << boolalpha;
-	cout << "Connector/C++ result set.." << endl << endl;
+	cout << "1..1" << endl;
+	cout << "# Connector/C++ result set.." << endl;
 
 	try {
 		// Using the Driver to create a connection
 		driver = get_driver_instance();
-		con = driver->connect(EXAMPLE_HOST, EXAMPLE_USER, EXAMPLE_PASS);
+		con = driver->connect(host, user, pass);
 
 		// Creating a "simple" statement - "simple" = not a prepared statement
 		stmt = con->createStatement();
@@ -72,7 +79,7 @@ int main()
 		stmt->execute("USE " EXAMPLE_DB);
 		stmt->execute("DROP TABLE IF EXISTS test");
 		stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
-		cout << "\tTest table created" << endl;
+		cout << "#\t Test table created" << endl;
 
 		// Populate the test table with data
 		min = max = test_data[0];
@@ -92,7 +99,7 @@ int main()
 			sql << test_data[i].id << ", '" << test_data[i].label << "')";
 			stmt->execute(sql.str());
 		}
-		cout << "\tTest table populated" << endl << endl;
+		cout << "#\t Test table populated" << endl;
 
 		/*
 		This is an example how to fetch in reverse order using the ResultSet cursor.
@@ -103,78 +110,89 @@ int main()
 		always fetch all data no matter how big the result set is!
 		*/
 		res = stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC");
-		cout << "\tSelecting in ascending order but fetching in descending (reverse) order" << endl;
+		cout << "#\t Selecting in ascending order but fetching in descending (reverse) order" << endl;
 
 		// Move the cursor after the last row - n + 1
 		res->afterLast();
 		row = res->rowsCount() - 1;
 		// Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available.
 		while (res->previous()) {
-			cout << "\t\tRow " << row << " id = " << res->getInt("id");
+			cout << "#\t\t Row " << row << " id = " << res->getInt("id");
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row--;
 		}
 		// The last call to res->previous() has moved the cursor before the first row
 		// Cursor position is 0, recall: rows are from 1 ... n
-		cout << "\t\tisBeforeFirst() = " << res->isBeforeFirst() << endl;
-		cout << endl;
+		cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl;
+		if (false != res->isBeforeFirst()) {			
+			throw runtime_error("Position should be 0 = first row");
+		}
 
 		// Move the cursor forward again to position 1 - the first row
 		res->next();
-		cout << "\tPositioning cursor to 1 using next(), isFirst() = " << res->isFirst() << endl;
+		cout << "#\t Positioning cursor to 1 using next(), isFirst() = " << res->isFirst() << endl;
 		validateRow(res, &min);
 
 		// Move the cursor to position 0 = before the first row
-		if (false != res->absolute(0)) {
-			cout << "FAILURE Cannot position cursor before first row" << endl;
+		if (false != res->absolute(0)) {			
+			throw runtime_error("Call did not fail although its not allowed to move the cursor before the first row");
 		}
-		cout << "\tPositioning before first row using absolute(0), isFirst() = " << res->isFirst() << endl;
+		cout << "#\t Positioning before first row using absolute(0), isFirst() = " << res->isFirst() << endl;
 		// Move the cursor forward to position 1 = the first row
 		res->next();
 		validateRow(res, &min);
 
 		// Move the cursor to position 0 = before the first row
 		res->beforeFirst();
-		cout << "\tPositioning cursor using beforeFirst(), isFirst() = " << res->isFirst() << endl;
+		cout << "#\t Positioning cursor using beforeFirst(), isFirst() = " << res->isFirst() << endl;
 		// Move the cursor forward to position 1 = the first row
 		res->next();
-		cout << "\t\tMoving cursor forward using next(), isFirst() = " << res->isFirst() << endl;
+		cout << "#\t\t Moving cursor forward using next(), isFirst() = " << res->isFirst() << endl;
 		validateRow(res, &min);
-
-		cout << endl;
-		cout << "\tFinally, reading in descending (reverse) order again" << endl;
+		
+		cout << "#\t Finally, reading in descending (reverse) order again" << endl;
 		// Move the cursor after the last row - n + 1
 		res->afterLast();
 		row = res->rowsCount() - 1;
 		// Move the cursor backwards to: n, n - 1, ... 1, 0. Return true if rows are available.
 		while (res->previous()) {
-			cout << "\t\tRow " << row << " id = " << res->getInt("id");
+			cout << "#\t\t Row " << row << " id = " << res->getInt("id");
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row--;
 		}
 		// The last call to res->previous() has moved the cursor before the first row
 		// Cursor position is 0, recall: rows are from 1 ... n
-		cout << "\t\tisBeforeFirst() = " << res->isBeforeFirst() << endl;
-		cout << endl;
-
-		cout << "\tAnd in regular order..." << endl;
+		cout << "#\t\t isBeforeFirst() = " << res->isBeforeFirst() << endl;
+		if (false != res->isBeforeFirst()) {			
+			throw runtime_error("Position should be 0 = first row");
+		}
+		
+		cout << "#\t And in regular order..." << endl;
 		res->beforeFirst();
 		row = 0;
 		while (res->next()) {
-			cout << "\t\tRow " << row << " id = " << res->getInt("id");
+			cout << "#\t\t Row " << row << " id = " << res->getInt("id");
 			cout << ", label = '" << res->getString("label") << "'" << endl;
 			row++;
 		}
-		cout << "\t\tisAfterLast() = " << res->isAfterLast() << endl;
+		cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl;
+		if (true != res->isAfterLast()) {			
+			throw runtime_error("next() has returned false and the cursor should be after the last row");
+		}
 
-		// Move to the last entry using a negative offset for absolute()
-		cout << endl;
-		cout << "\tTrying absolute(-1) to fetch last entry..." << endl;
+		// Move to the last entry using a negative offset for absolute()	
+		cout << "#\t Trying absolute(-1) to fetch last entry..." << endl;
 		if (true != res->absolute(-1)) {
-			cout << "FAILURE absolute(-1) should return true" << endl;
+			throw runtime_error("Call did fail although -1 is valid");
+		}
+		cout << "#\t\t isAfterLast() = " << res->isAfterLast() << endl;
+		if (false != res->isAfterLast()) {			
+			throw runtime_error("Cursor should be positioned to the last row and  not faster the last row");
+		}
+		cout << "#\t\t isLast() = " << res->isLast() << endl;
+		if (true != res->isLast()) {			
+			throw runtime_error("Cursor should be positioned to the last row");
 		}
-		cout << "\t\tisAfterLast() = " << res->isAfterLast() << endl;
-		cout << "\t\tisLast() = " << res->isLast() << endl;
 		validateRow(res, &max);
 
 		delete res;
@@ -184,7 +202,7 @@ int main()
 		delete stmt;
 		delete con;
 
-		cout << "done!" << endl;
+		cout << "# done!" << endl;
 
 	} catch (sql::SQLException &e) {
 		/*
@@ -201,29 +219,41 @@ int main()
 		All MySQL Client releated errors will be reported by throwing a sql::SQLException
 		*/
 
-		cout << endl;
-		cout << "ERR: SQLException in " << __FILE__;
+		cout << "# ERR: SQLException in " << __FILE__;
 		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
 		// Use what(), getErrorCode() and getSQLState()
-		cout << "ERR: " << e.what();
+		cout << "# ERR: " << e.what();
 		cout << " (MySQL error code: " << e.getErrorCode();
 		cout << ", SQLState: " << e.getSQLState() << " )" << endl;
+		cout << "not ok" << endl;
 
 		return EXIT_FAILURE;
-	}
+	} catch (std::runtime_error &e) {
+
+		cout << "# ERR: runtime_error in " << __FILE__;
+		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;		
+		cout << "# ERR: " << e.what() << endl;
+		cout << "not ok" << endl;
 
+		return EXIT_FAILURE;
+	} 
+
+	cout << "ok" << endl;
 	return EXIT_SUCCESS;
 }
 
 static void validateRow(sql::ResultSet *res, struct _test_data *exp)
 {
-	cout << "\t\tFetching the first row, id = " << res->getInt("id");
-	cout << "\t\tlabel = '" << res->getString("label") << "'" << endl;
+	stringstream msg;
+
+	cout << "#\t\t Fetching the first row, id = " << res->getInt("id");
+	cout << ", label = '" << res->getString("label") << "'" << endl;
 
 	if ((res->getInt("id") != exp->id) || (res->getString("label") != exp->label)) {
-		cout << "\t\tFAILURE Wrong results"	<< "; expected (" << exp->id;
-		cout << "," << exp->label << ") got (" << res->getInt("id");
-		cout <<", " << res->getString("label") << ")" << endl;
+		msg.str("Wrong results");
+		msg << "Expected (" << exp->id << "," << exp->label << ")";
+		msg << " got (" << res->getInt("id") <<", " << res->getString("label") << ")";
+		throw runtime_error(msg.str());
 	}
 }
 

=== modified file 'examples/resultset_meta.cpp'
--- a/examples/resultset_meta.cpp	2008-10-20 11:49:28 +0000
+++ b/examples/resultset_meta.cpp	2008-11-03 17:02:18 +0000
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 
 // Public interface of the MySQL Connector/C++
 #include <driver/mysql_public_iface.h>
@@ -42,8 +43,13 @@ using namespace std;
 /**
 * Meta data of a (simple) statements result set - not prepared statements
 */
-int main()
+int main(int argc, const char **argv) 
 {
+
+	const std::string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
+	const std::string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
+	const std::string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
+
 	// Driver Manager
 	sql::Driver *driver;
 
@@ -54,15 +60,16 @@ int main()
 
 	/* sql::ResultSet.rowsCount() returns size_t */
 	stringstream sql;
-int i;
+	int i;
 
 	cout << boolalpha;
-	cout << "Connector/C++ connect basic usage example.." << endl << endl;
+	cout << "1..1" << endl;
+	cout << "# Connector/C++ connect basic usage example.." << endl;
 
 	try {
 		// Using the Driver to create a connection
 		driver = get_driver_instance();
-		con = driver->connect(EXAMPLE_HOST, EXAMPLE_USER, EXAMPLE_PASS);
+		con = driver->connect(host, user, pass);
 
 		// Creating a "simple" statement - "simple" = not a prepared statement
 		stmt = con->createStatement();
@@ -71,7 +78,7 @@ int i;
 		stmt->execute("USE " EXAMPLE_DB);
 		stmt->execute("DROP TABLE IF EXISTS test");
 		stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))");
-		cout << "\tTest table created" << endl;
+		cout << "#\t Test table created" << endl;
 
 		// Populate the test table with data
 		for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) {
@@ -82,27 +89,26 @@ int i;
 			sql << test_data[i].id << ", '" << test_data[i].label << "')";
 			stmt->execute(sql.str());
 		}
-		cout << "\tTest table populated" << endl << endl;
+		cout << "#\t Test table populated" << endl;
 
 		res = stmt->executeQuery("SELECT id AS column_alias, label FROM test AS table_alias LIMIT 1");
-		cout << "\tSELECT id AS column_alias, label FROM test AS table_alias LIMIT 1" << endl;
+		cout << "#\t SELECT id AS column_alias, label FROM test AS table_alias LIMIT 1" << endl;
 		printResultSetMetaData(res);
 		delete res;
 
 		res = stmt->executeQuery("SELECT 1.01, 'Hello world!'");
-		cout << "\tSELECT 1.01, 'Hello world!'" << endl;
+		cout << "#\t SELECT 1.01, 'Hello world!'" << endl;
 		printResultSetMetaData(res);
 		delete res;
 
 		res = stmt->executeQuery("DESCRIBE test");
-		cout << "\tDESCRIBE test" << endl;
+		cout << "# \tDESCRIBE test" << endl;
 		printResultSetMetaData(res);
 		delete res;
 
 		// Clean up
 		stmt->execute("DROP TABLE IF EXISTS test");
-		cout << "done!" << endl;
-		cout << endl;
+		cout << "# done!" << endl;
 
 		delete stmt;
 		delete con;
@@ -121,18 +127,29 @@ int i;
 		All MySQL Server related errors will be reported by throwing a sql::mysql::MySQL_SQLException.
 		All MySQL Client releated errors will be reported by throwing a sql::SQLException
 		*/
-
-		cout << endl;
-		cout << "ERR: SQLException in " << __FILE__;
+		
+		cout << "# ERR: SQLException in " << __FILE__;
 		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
 		// Use what(), getErrorCode() and getSQLState()
-		cout << "ERR: " << e.what();
+		cout << "# ERR: " << e.what();
 		cout << " (MySQL error code: " << e.getErrorCode();
 		cout << ", SQLState: " << e.getSQLState() << " )" << endl;
+		
+		cout << "not ok" << endl;
+
+		return EXIT_FAILURE;
+
+	} catch (std::runtime_error &e) {
+
+		cout << "# ERR: runtime_error in " << __FILE__;
+		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;		
+		cout << "# ERR: " << e.what() << endl;
+		cout << "not ok" << endl;
 
 		return EXIT_FAILURE;
 	}
 
+	cout << "ok" << endl;
 	return EXIT_SUCCESS;
 }
 
@@ -147,44 +164,40 @@ static void printResultSetMetaData(sql::
 	unsigned int column;
 
 	if (res->rowsCount() == 0) {
-		cout << "FAILURE - no rows" << endl;
+		throw runtime_error("FAILURE - no rows");
 		return;
 	}
 
 	// Get the meta data - we leave all the exception handling to the caller...
 	meta = res->getMetaData();
-
-	cout << endl;
-	cout << "\tPrinting result set meta data" << endl;
-	cout << "\tres->rowsCount() = " << res->rowsCount() << endl;
-	cout << "\tmeta->getColumnCount() = " << meta->getColumnCount() << endl;
+	
+	cout << "#\t Printing result set meta data" << endl;
+	cout << "#\t res->rowsCount() = " << res->rowsCount() << endl;
+	cout << "#\t meta->getColumnCount() = " << meta->getColumnCount() << endl;
 
 	// Dump information for every column
 	// NOTE: column indexing is 1-based not zero-based!
 	for (column = 1; column <= meta->getColumnCount(); column++) {
-		cout << "\t\tColumn " << column << "\t\t\t= " << meta->getColumnName(column)<< endl;
-		cout << "\t\tmeta->getCatalogName()\t\t= " << meta->getCatalogName(column) << endl;
-		// Not implemented
-		// cout << "\t\tmeta->getColumnDisplaySize() = " << meta->getColumnDisplaySize(column) << endl;
-		cout << "\t\tmeta->getColumnLabel()\t\t= " << meta->getColumnLabel(column) << endl;
-		cout << "\t\tmeta->getColumnName()\t\t= " << meta->getColumnName(column) << endl;
-		cout << "\t\tmeta->getColumnType()\t\t= " << meta->getColumnType(column) << endl;
-		cout << "\t\tmeta->getColumnTypeName()\t= " << meta->getColumnTypeName(column) << endl;
-		// Not implemented
-		// cout << "\t\tmeta->getPrecision()\t\t= " << meta->getPrecision(column) << endl;
-		// cout << "\t\tmeta->getScale()\t\t= " << meta->getScale(column) << endl;
-		cout << "\t\tmeta->getSchemaName()\t\t= " << meta->getSchemaName(column) << endl;
-		cout << "\t\tmeta->getTableName()\t\t= " << meta->getTableName(column) << endl;
-		cout << "\t\tmeta->isAutoIncrement()\t\t= " << meta->isAutoIncrement(column) << endl;
-		cout << "\t\tmeta->isCaseSensitive()\t\t= " << meta->isCaseSensitive(column) << endl;
-		cout << "\t\tmeta->isCurrency()\t\t= " << meta->isCurrency(column) << endl;
-		cout << "\t\tmeta->isDefinitelyWritable()\t= " << meta->isDefinitelyWritable(column) << endl;
-		cout << "\t\tmeta->isNullable()\t\t= " << meta->isNullable(column) << endl;
-		cout << "\t\tmeta->isReadOnly()\t\t= " << meta->isReadOnly(column) << endl;
-		cout << "\t\tmeta->isSearchable()\t\t= " << meta->isSearchable(column) << endl;
-		cout << "\t\tmeta->isSigned()\t\t= " << meta->isSigned(column) << endl;
-		cout << "\t\tmeta->isWritable()\t\t= " << meta->isWritable(column) << endl;
-		cout << endl;
+		cout << "#\t\tColumn " << column << "\t\t\t= " << meta->getColumnName(column)<< endl;
+		cout << "#\t\tmeta->getCatalogName()\t\t= " << meta->getCatalogName(column) << endl;		
+		cout << "#\t\t meta->getColumnDisplaySize() = " << meta->getColumnDisplaySize(column) << endl;
+		cout << "#\t\t meta->getColumnLabel()\t\t= " << meta->getColumnLabel(column) << endl;
+		cout << "#\t\t meta->getColumnName()\t\t= " << meta->getColumnName(column) << endl;
+		cout << "#\t\t meta->getColumnType()\t\t= " << meta->getColumnType(column) << endl;
+		cout << "#\t\t meta->getColumnTypeName()\t= " << meta->getColumnTypeName(column) << endl;		
+		// Not implemented: cout << "#\t\t meta->getPrecision()\t\t= " << meta->getPrecision(column) << endl;
+		cout << "#\t\t meta->getScale()\t\t= " << meta->getScale(column) << endl;
+		cout << "#\t\t meta->getSchemaName()\t\t= " << meta->getSchemaName(column) << endl;
+		cout << "#\t\t meta->getTableName()\t\t= " << meta->getTableName(column) << endl;
+		cout << "#\t\t meta->isAutoIncrement()\t\t= " << meta->isAutoIncrement(column) << endl;
+		cout << "#\t\t meta->isCaseSensitive()\t\t= " << meta->isCaseSensitive(column) << endl;
+		cout << "#\t\t meta->isCurrency()\t\t= " << meta->isCurrency(column) << endl;
+		cout << "#\t\t meta->isDefinitelyWritable()\t= " << meta->isDefinitelyWritable(column) << endl;
+		cout << "#\t\t meta->isNullable()\t\t= " << meta->isNullable(column) << endl;
+		cout << "#\t\t meta->isReadOnly()\t\t= " << meta->isReadOnly(column) << endl;
+		cout << "#\t\t meta->isSearchable()\t\t= " << meta->isSearchable(column) << endl;
+		cout << "#\t\t meta->isSigned()\t\t= " << meta->isSigned(column) << endl;
+		cout << "#\t\t meta->isWritable()\t\t= " << meta->isWritable(column) << endl;		
 	}
 }
 

=== modified file 'examples/statement.cpp'
--- a/examples/statement.cpp	2008-10-23 17:17:12 +0000
+++ b/examples/statement.cpp	2008-11-03 17:02:18 +0000
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 
 // Public interface of the MySQL Connector/C++
 #include <driver/mysql_public_iface.h>
@@ -39,8 +40,13 @@ using namespace std;
 /**
 * Example of statements - not to be confused with prepared statements
 */
-int main()
+int main(int argc, const char **argv) 
 {
+
+	const std::string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
+	const std::string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
+	const std::string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
+
 	// Driver Manager
 	sql::Driver *driver;
 
@@ -56,12 +62,13 @@ int main()
 	bool ok;
 
 	cout << boolalpha;
-	cout << "Connector/C++ (simple) statement example.." << endl << endl;
+	cout << "1..1" << endl;
+	cout << "# Connector/C++ (simple) statement example.." << endl;
 
 	try {
 		// Using the Driver to create a connection
 		driver = get_driver_instance();
-		con = driver->connect(EXAMPLE_HOST, EXAMPLE_USER, EXAMPLE_PASS);
+		con = driver->connect(host, user, pass);
 
 		// Creating a "simple" statement - "simple" = not a prepared statement
 		stmt = con->createStatement();
@@ -70,7 +77,7 @@ int main()
 		stmt->execute("USE " EXAMPLE_DB);
 		stmt->execute("DROP TABLE IF EXISTS test");
 		stmt->execute("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label CHAR(1))");
-		cout << "\tTest table created" << endl;
+		cout << "#\t Test table created" << endl;
 
 		// Populate the test table with data
 		for (i = 0; i < EXAMPLE_NUM_TEST_ROWS; i++) {
@@ -81,23 +88,23 @@ int main()
 			sql << test_data[i].id << ", '" << test_data[i].label << "')";
 			stmt->execute(sql.str());
 		}
-		cout << "\tTest table populated" << endl << endl;
+		cout << "#\t Test table populated" << endl;
 
 		// NOTE: Use execute() instead of the more convenient executeQuery()
 		// See the other example file for executeQuery() and executeUpdate() examples
 		// However, if you are executing SQL dynamically, you might have to use execute()
 		ok = stmt->execute("SELECT id, label FROM test ORDER BY id ASC");
-		cout << "\tstmt->execute('SELECT id, label FROM test ORDER BY id ASC') = ";
-		cout << ok << endl;
+		cout << "#\t stmt->execute('SELECT id, label FROM test ORDER BY id ASC') = ";
+		cout << ok << endl;	
 		if (ok == true) {
 			// The first result is a result set
-			cout << "\t\tFetching results" << endl;
+			cout << "#\t\t Fetching results" << endl;
 			// NOTE: If stmt.getMoreResults() would be implemented already one
 			// KLUDGE: would use a do { ... } while (stmt.getMoreResults()) loop
 			res = stmt->getResultSet();
 			row = 0;
 			while (res->next()) {
-				cout << "\t\tRow " << row << " - id = " << res->getInt("id");
+				cout << "#\t\t Row " << row << " - id = " << res->getInt("id");
 				cout << ", label = '" << res->getString("label") << "'" << endl;
 				row++;
 			}
@@ -105,14 +112,13 @@ int main()
 
 		} else if (ok == false) {
 			// The first result is an update count
-			cout << "FAILURE Expecting regular result set." << endl;
+			throw runtime_error("Expecting regular result set.");
 		}
 
 		// Clean up
 		stmt->execute("DROP TABLE IF EXISTS test");
-		cout << "done!" << endl;
-		cout << endl;
-
+		cout << "# done!" << endl;
+		
 		delete stmt;
 		delete con;
 
@@ -131,17 +137,26 @@ int main()
 		All MySQL Client releated errors will be reported by throwing a sql::SQLException
 		*/
 
-		cout << endl;
-		cout << "ERR: SQLException in " << __FILE__;
+		cout << "# ERR: SQLException in " << __FILE__;
 		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
 		// Use what(), getErrorCode() and getSQLState()
-		cout << "ERR: " << e.what();
+		cout << "# ERR: " << e.what();
 		cout << " (MySQL error code: " << e.getErrorCode();
 		cout << ", SQLState: " << e.getSQLState() << " )" << endl;
+		cout << "not ok" << endl;
+
+		return EXIT_FAILURE;
+	} catch (std::runtime_error &e) {
+
+		cout << "# ERR: runtime_error in " << __FILE__;
+		cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;		
+		cout << "# ERR: " << e.what() << endl;
+		cout << "not ok" << endl;
 
 		return EXIT_FAILURE;
 	}
 
+	cout << "ok" << endl;
 	return EXIT_SUCCESS;
 }
 

Thread
bzr commit into connector-cpp-bzr branch (andrey.hristov:200) andrey.hristov3 Nov