#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.hristov | 3 Nov |