MySQL C++ connector loop - c++

#include <iostream>
#include <sstream>
#include <string>
#include <mysql_connection.h>
#include <mysql_driver.h>
#include <mysql_error.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
using namespace std;
using namespace sql;
using namespace mysql;
int main()
{
Connection* con = nullptr;
MySQL_Driver *driver = get_mysql_driver_instance();
const SQLString server = "server.de";
const SQLString user = "userName";
const SQLString password = "password";
while (1)
{
try {
con = driver->connect(server, user, password);
}
catch (SQLException e) {
printf("Fehler SQL Connect: %s \n", e.getSQLStateCStr());
delete driver;
}
catch (...) {
cerr << "Fehler SQL Connnect" << endl;
}
if (con)
{
con->close();
delete con;
}
boost::detail::Sleep(5000);
}
return 0;
}
I wrote this code and hoped it would run in an endless loop even, if the connect statement failed.
What happens is:
After the first time the connect failes it goes to the first catch statement and writes "Fehler SQL Connect: HY000" as I expect.
The next time the connect failes the program breakes and in VS2017 I see 'te923021119.exe has triggered a breakpoint'
Why doesn't the program try to connect endlessly?
ncb

In your exception handled you call delete driver;
This call destroys the driver object. It is not clear if it the right thing to do - as it is not clear if get_mysql_driver_instance() gives you the ownership of a dynamically allocated object with new.
But regardless - in the next iteration your program attempts to use driver - which has been destroyed.
So - methinks don't call delete driver;. Better yet - use smart pointers to communicate ownership semantic clearly. std::unique_ptr may be a good option.

Related

getlogin_r() and getlogin() do only work on tty

I wrote a test program to check whether getlogin_r() and getlogin() do work or not, because I had problems with them before and could not fix it. In the TTY it works just fine and both functions are returning my username, but executed in the LXDE Terminal, the following error occurs:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
I am running this code an a Raspberry Pi 2 B with Raspbian installed. Here is my code:
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
int main()
{
char user[64];
getlogin_r(user,sizeof(user)-1);
string getlogin_r_str(user);
string getlogin_str(getlogin());
cout << "getlogin_r(): " << getlogin_r_str << endl << "getlogin(): " << getlogin_str << endl;
return 0;
}
This is most likely caused because the LXDE terminal not updating the utmp information which records all logged in users and getlogin determines the username from that information.
You should accept that it is possible for getlogin to return a null pointer and deal with it gracefully, e.g. by using getpwuid if getlogin fails:
#include <pwd.h>
#include <unistd.h>
#include <string>
std::string get_username() {
struct passwd *pwd = getpwuid(getuid());
if (pwd)
return pwd->pw_name;
else
return "(?)";
}

connecting a c++ application to an Oracle database with sqlapi++

I wrote an example application in C++(on Eclipse Luna) using sqlapi++ libraries to connect to an Oracle database I created with sqldeveloper.
The program compiles without errors, but when I run it,nothing appears on the console.
(I am using Windows 7)
Here the Database information:
Database name:"DB Casa Editrice"
Host:localhost
SID:xe
Port:1521
And the code:
#include <iostream>
#include "SQLAPI.h"
using namespace std;
int main() {
SAConnection con; // create connection object
try {
con.Connect( "DB Casa Editrice", // database name
"system", // user name
"shruikan94", // password
SA_Oracle_Client );
cout << "We are connected!\n";
con.Disconnect();
cout << "Disconnected!\n";
}
catch( SAException &x )
{
// SAConnection::Rollback()
// can also throw an exception
// (if a network error for example),
// we will be ready
try {
// on error rollback changes
con.Rollback();
}
catch( SAException & )
{
}
// print error message
cout << "ERROR\n";
}
return 0;
}

Why is my program crashing when MySQL server is unavalibe

I've been programming in C++ with VS 2010 Professional but I am stuck on this problem:
If the program starts and the connection is good then it loads the "gameactive" loop, and displays the high score of the player.
But when the connection has a error it freezes and crashes. I want to display a error like "error connecting to server" and continue loading the game.
I did use this tutorial:
http://r3dux.org/2010/11/how-to-use-mysql-connectorc-to-connect-to-a-mysql-database-in-windows/
Here is my code:
// Standad C++ includes
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
#include <string.h>
// Include the Connector/C++ headers
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
#include <cgl\cgl.h>
#include <cgl\core.h>
#include <core\corefile.h>
// Link to the Connector/C++ library
#pragma comment(lib, "mysqlcppconn.lib")
// Specify our connection target and credentials
const string server = "tcp://xxx.xxx.xxx.xxx:3306";
const string username = "xxxxxxx";
const string password = "XXxxXXxxXXxx";
char myoutput[1024];
char myoutput1[1024];
char myoutput2[1024];
s_font font;
s_bitmap bmp_background;
int connectsetup()
{
sql::Driver *driver; // Create a pointer to a MySQL driver object
sql::Connection *dbConn; // Create a pointer to a database connection object
sql::Statement *stmt; // Create a pointer to a Statement object to hold our SQL commands
sql::ResultSet *res; // Create a pointer to a ResultSet object to hold the results of any queries we run
// Try to get a driver to use to connect to our DBMS
try
{
driver = get_driver_instance();
}
catch (sql::SQLException e)
{
cout << "Could not get a database driver. Error message: " << e.what() << endl;
}
// Try to connect to the DBMS server
try
{
dbConn = driver->connect(server, username, password);
}
catch (sql::SQLException e)
{
cout << "Could not connect to database. Error message: " << e.what() << endl;
}
stmt = dbConn->createStatement(); // Specify which connection our SQL statement should be executed on
// Try to query the database
try
{
stmt->execute("USE runner"); // Select which database to use. Notice that we use "execute" to perform a command.
res = stmt->executeQuery("SELECT * FROM highscores"); // Perform a query and get the results. Notice that we use "executeQuery" to get results back
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
}
// While there are still results (i.e. rows/records) in our result set...
while (res->next())
{
// ...get each field we want and output it to the screen
// Note: The first field/column in our result-set is field 1 (one) and -NOT- field 0 (zero)
// Also, if we know the name of the field then we can also get it directly by name by using:
// res->getString("TheNameOfTheField");
//printf(myoutput,"%s %s %s",res->getString(1),res->getString(2),res->getString(3));
strcpy(myoutput,res->getString(1).c_str());
strcpy(myoutput1,res->getString(2).c_str());
strcpy(myoutput2,res->getString(3).c_str());
}
// Clean up after ourselves
delete res;
delete stmt;
delete dbConn;
return 0;
}
void coremain()
{
//Fullscreen, windowed of scaled?
corefile_mountimage("res",MOUNT_DIR);
CGL_InitVideo(1280, 720, CGL_VIDEO_NONE);
CGL_SetTitle("CGL - Endless poepert");
CGL_InitFont("font_heat.tga", &font);
CGL_LoadBitmap("track1.tga",&bmp_background);
connectsetup();
int gameactive=1;
int getal=atoi(myoutput);
do {
do {
CGL_WaitRefresh();
CGL_DrawBitmap(0,0,bmp_background);
CGL_DrawCenteredText(100,font, "%s: %d van %s score %s",myoutput,getal,myoutput1,myoutput2);
int key,keytrig;
CGL_GetKeys(&key,&keytrig);
if (keytrig & CGL_INPUT_KEY_EXIT) exit(EXIT_SUCCESS);
CGL_SwapBuffers();
} while(gameactive);
CGL_FlushGraphics();
} while(1);
CGL_CloseVideo();
}
The issue seems to be your connectSetup function. You have try/catch blocks, but you don't do anything if there is an issue. You just keep going as if nothing is wrong.
Also, this is a great time to learn smart pointers. The reason why smart pointers should be used here is in the case where something goes wrong even if the database connection is successful (you have subsequent try/catch blocks). You want to ensure that anything that was allocated is cleaned up, regardless of when or where you issue a return statement.
#include <memory>
#include <string>
std::string myoutput;
std::string myoutput1;
std::string myoutput2;
int connectsetup()
{
sql::Driver* driver;
std::unique_ptr<sql::Connection> dbConn;
std::unique_ptr<sql::Statement> stmt;
std::unique_ptr<sql::ResultSet> res;
try
{
driver = get_driver_instance();
dbConn.reset(driver->connect(server, username, password))
stmt.reset(dbConn->createStatement());
stmt->execute("USE runner");
res.reset(stmt->executeQuery("SELECT * FROM highscores")); // Perform a query
while (res->next())
{
myoutput = res->getString(1);
myoutput1 = res->getString(2);
myoutput2 = res->getString(3);
}
}
catch (const sql::SQLException& e)
{
cout << "Something went wrong with the database stuff. Here it is: " << e.what() << endl;
return -1;
}
return 0;
}
This code was not compiled, but I attempted to extract what your original code was doing and rewrote it using smart pointers.
The code above will throw an exception if any of those statements fail. Note that we catch the exception by reference, not by value. Also note that there is no need for delete, since std::unique_ptr does this work automatically.
Finally, there is no need for char arrays -- why did you introduce them? It only made another part of your function vulnerable to a memory overwrite, namely in the res->next() loop.

Connection attempt failed MySQL poco

Another question on a Mysql connection failing:
I'm using the Poco library (1.5.2) and I would like to know why, when I try to open a MySQL connection, I got this message:
Connection attempt failed
Whereas, when I try a connection via console (mysql -u root -p ...), it works.
Maybe I forget an important step in the MySQL configuration ?
Here is my code :
#include <iostream>
#include <string>
#include <Poco/Data/MySQL/MySQLException.h>
#include <Poco/Data/MySQL/Connector.h>
#include <Poco/Data/SessionFactory.h>
using namespace std;
int main()
{
Poco::Data::MySQL::Connector::registerConnector();
try
{
string str = "host=localhost;user=root;password=mypassword;compress=true;auto-reconnect=true";
Poco::Data::Session test(Poco::Data::SessionFactory::instance().create(Poco::Data::MySQL::Connector::KEY, str ));
}
catch (Poco::Data::MySQL::ConnectionException& e)
{
cout << e.what() << endl;
return -1;
}
catch(Poco::Data::MySQL::StatementException& e)
{
cout << e.what() << endl;
return -1;
}
return 0;
}
Thank you !!
ok the problem was the "localhost" value for "host" doesn't work on my linux (I don't know why). For fixing the bug, I had to change my string to:
string str = "host=127.0.0.1;user=root;password=mypassword;compress=true;auto-reconnect=true";

Release build says SQL is invalid. Is this a configuration issue?

I am using the following code and I get this error
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '??]?j?X?0' at line 1
My code is as follows this works perfectly in the debug build
#include <iostream>
#include <vector>
//#define CPPCONN_PUBLIC_FUNC
/* MySQL Connector/C++ specific headers */
#include <driver.h>
#include <connection.h>
#include <statement.h>
#include <prepared_statement.h>
#include <resultset.h>
#include <metadata.h>
#include <resultset_metadata.h>
#include <exception.h>
int main()
{
sql::Driver *driver;
sql::Statement *stmt;
sql::ResultSet *res;
sql::Connection *con;
sql::PreparedStatement *prep_stmt;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("server", "user", "pass");
/* Connect to the MySQL database */
con->setSchema("MySchema");
std::vector<std::string> SymbolList;
std::string SQL = "SELECT `MyList`.`Symbol` FROM `MySchema`.`MasterList`;";
try
{
stmt = con->createStatement();
res = stmt->executeQuery(SQL);
while(res->next()) //If object exists
{
std::string symbol = res->getString("Symbol");
SymbolList.push_back(symbol);
std::cout << symbol;
}
}
catch(std::exception &ex)
{
std::string d = ex.what();
}
std::cin.get();
return 0;
}//end method
I am still confused by the error I am getting the code seems to work fine in debug mode but in release mode it gives this error out. Any suggestions on what I should try and what I might be doing wrong. I am using VS2010.I can also upload a small project that I created