I am learning to write C++ code to access data in a MySQL database. My goal is to use a separate class to control the database access so I can use this class elsewhere. To facilitate my learning, I'm working on simple code to connect to a database (success!) and return all rows in a simple and small table (failing!).
The connection is OK through the class constructor but I'm getting a segmentation fault in the queryResults = query.store()
in the class method. The backtrace, as I read it, says the failure is in a MySQL routine. (PS: The gtkmm.h is because I eventually want this class to be used by a GUI written in gtkmm.)
Any suggestions would be greatly appreciated!
Dave
[program messages and backtrace of gdb:]
Starting program: /home/dave/Code/mysql/main
[Thread debugging using libthread_db enabled]
main: Trying to instantiate db class...
database: Trying to connect to test...
database: Connection was successful.
main: After instantiation of db class
main: Calling dbselect using:SELECT * FROM SourceType ORDER BY SourceTypeId
database: Do query using SELECT * FROM SourceType ORDER BY SourceTypeId
database: Did 'query << selectsql'
Program received signal SIGSEGV, Segmentation fault.
0x00f15e94 in mysql_send_query () from /usr/lib/libmysqlclient.so.16
(gdb) bt
#0 0x00f15e94 in mysql_send_query () from /usr/lib/libmysqlclient.so.16
#1 0x00f15f30 in mysql_real_query () from /usr/lib/libmysqlclient.so.16
#2 0x00e8445f in mysqlpp::Query::store(char const*, unsigned int) ()
from /usr/lib/libmysqlpp.so.3
#3 0x00e86e05 in mysqlpp::Query::store(mysqlpp::SQLTypeAdapter const&) ()
from /usr/lib/libmysqlpp.so.3
#4 0x0804b2ae in mysqlpp::Query::store (this=0xbffff250)
at /usr/include/mysql++/query.h:467
#5 0x0804a9b7 in DataBase::dbselect (this=0xbffff238, selectsql=...)
at database.cc:31
#6 0x0804c74f in main ()
(gdb)
[end backtrace]
my main C++ code
#include <gtkmm.h>
#include <iostream>
#include <mysql++.h>
#include <stdlib.h>
#include "database.h"
using namespace std;
using namespace mysqlpp;
int main() {
//Variables
Glib::ustring SQLstring;
size_t rows = 0;
StoreQueryResult results;
//Connect
cout << "main: Trying to instantiate db class...\n";
DataBase wwdb("test");
cout << "main: After instantiation of db class\n";
//SELECT
SQLstring = "SELECT * FROM SourceType ORDER BY SourceTypeId";
cout << "main: Calling dbselect using:" << SQLstring <<"\n";
if (wwdb.dbselect(SQLstring)) {
cout << "main: Successful!";
rows = wwdb.returnRows();
results = wwdb.returnResults();
cout << "Rows=" << rows << "\n";
for (size_t i = 0; i < rows; i++)
cout << "main: ID: " << results[i]["SourceTypeId"] << " - Name: " << results[i]["SourceTypeName"] << endl;
cout << "main: Select done.\n";
}
else {
cout << "main: FAILED\n";
return -1;
}
my class header:
#ifndef DATABASE_H
#define DATABASE_H
#include <gtkmm.h>
#include <stdlib.h>
#include <mysql++.h>
using namespace std;
using namespace mysqlpp;
class DataBase
{
public:
DataBase(Glib::ustring db);
virtual ~DataBase();
bool dbselect(const Glib::ustring&);
size_t returnRows();
StoreQueryResult returnResults();
bool dbinsert(Glib::ustring&);
protected:
Connection conn;
Query query;
StoreQueryResult queryResults;
size_t rows;
};
#endif //DATABASE_H
my database class methods:
#include <iostream>
#include <mysql++.h>
#include <stdlib.h>
#include <string>
#include "database.h"
using namespace std;
using namespace mysqlpp;
//Constructor - Connect to DB
DataBase::DataBase(Glib::ustring db) : query(&conn, true) {
cout << "database: Trying to connect to " << db <<"...\n";
conn = new Connection("wwindextest", "localhost", "guest");
if (!conn) {
cout << "FAILED due to: " << conn.error() << "\n";
}
cout << "database: Connection was successful.\n";
query = conn.query();
}
//Destructor - disconnect from DB
DataBase::~DataBase() {
}
//Methods
//SELECT
bool DataBase::dbselect(const Glib::ustring& selectsql) {
cout << "database: Do query using " << selectsql << "\n";
query << selectsql;
cout << "database: Did 'query << selectsql' \n";
if (queryResults = query.store()) {
cout << "Successful! Rows=";
rows = queryResults.num_rows();
cout << rows << "\n";
return true;
}
else {
cout << "FAILED due to " << query.error() << "\n";
return false;
}
}
size_t DataBase::returnRows() {
return rows;
}
StoreQueryResult DataBase::returnResults() {
return queryResults;
}
bool DataBase::dbinsert(Glib::ustring& insertsql)
{
cout << "Do Insert here\n";
return true;
}
/* To insert stuff with escaping */
/*cout << "Trying to insert...\n";
query << "INSERT INTO table " <<
"VALUES (" <<
"\"" << escape << insertData << "\"" <<
");";
query.execute();
cout << "insert done.\n";
*/
return 0;
}