I am learning to use the Wt (witty) C++ Library, and tried to improvise on the Dbo::Session with singleton. The following is a snippet from the MySQL Backend Singleton wrapper that I had created.
Failure Case
The program compiles and runs with an exception : MySQL Connect Failure.
On debugging with GDB it revealed that the value of the var dbhost
at //BREAKPOINT
was "localhost"
however, at //STEP1
the value was garbage.
Observations
Wt::Dbo API peculiarly shows that the MySQL class constructor has only one string argument that is not passed by reference const std::string dbhost
. The function signature from the header file is
MySQL(const std::string &db, const std::string &dbuser="root",
const std::string &dbpasswd="", const std::string dbhost="localhost",
unsigned int dbport = 0,
const std::string &dbsocket ="/var/run/mysqld/mysqld.sock",
int fractionalSecondsPart = -1);
Success Case
The same code with only three arguments passed to the super class constructor
MySQL(db, dbuser, dbpasswd) // like this
returns the desired mysql backend object to the code.
Help is solicited in understanding the behaviour and solving the problem.
Following is the code used for compilation
#ifndef CANDBM_MODEL_MYSQL_SINGLETON_H
#define CANDBM_MODEL_MYSQL_SINGLETON_H
#include <Wt/Dbo/Dbo>
#include <Wt/Dbo/backend/MySQL>
namespace dbo = Wt::Dbo;
namespace Candbm { namespace Model {
class MysqlSingleton : public dbo::backend::MySQL
{
private:
static std::string const DB_NAME;
static std::string const DB_USER;
static std::string const DB_PASS;
static std::string const DB_HOST;
static int const DB_PORT;
static MysqlSingleton* mysql;
MysqlSingleton(
const std::string& db,
const std::string& dbuser = "root",
const std::string& dbpass = "",
const std::string dbhost = "localhost",
unsigned int dbport = 0,
const std::string& dbsocket = "/var/run/msyqld/mysqld.sock",
int fractionalSecondsPart = -1
)
: MySQL(db, dbuser, dbpass, dbhost, dbport, dbsocket, // STEP 1
fractionalSecondsPart
) {}
MysqlSingleton(MysqlSingleton const& m) : dbo::backend::MySQL(m) {}
MysqlSingleton operator=(MysqlSingleton const&);
public:
static MysqlSingleton* getBackend() { return instance(); }
static MysqlSingleton* instance();
};
std::string const MysqlSingleton::DB_NAME = "wt_candbm";
std::string const MysqlSingleton::DB_USER = "wtcandbm";
std::string const MysqlSingleton::DB_PASS = "somedummyvalue";
std::string const MysqlSingleton::DB_HOST = "localhost";
int const MysqlSingleton::DB_PORT = 0;
MysqlSingleton* MysqlSingleton::mysql = NULL;
MysqlSingleton* MysqlSingleton::instance()
{
if (!mysql)
{ // BREAKPOINT 1
// EDIT 1: commented the following line
// static std::string dbhost(DB_HOST.begin(), DB_HOST.end());
// EDIT 2: the constant directly passed here ,,,,,,,
mysql = new MysqlSingleton(DB_NAME, DB_USER, DB_PASS, DB_HOST, DB_PORT);
mysql->setProperty("show-queries", "true");
}
return mysql;
}
} }
#endif
Updates:
EDIT 1:2:
The two edits do simplify the code as suggested by @dma. And now the garbage is obtained in the next constructor invocation. i.e. Next step in debugger in the file MySQL.C