mysql cpp connector throwing UnknownException while connecting - c++

I am using mysql library to connect to my database (mysql) to retrieve the data after connecting. Checked that my services are running properly.
Following is the part of code that does the connecting task..
// Specify our connection target and credentials
const string server = "tcp://127.0.0.1:3306";
const string username = "root";
const string password = "";// No password - thanks, WAMP Server!
// Try to get a driver to use to connect to our DBMS
try {
driver = get_driver_instance();
if( driver == NULL )
throw SQLException("Null driver instance returned.");
}
catch (SQLException e) {
cout << "Could not get a database driver. Error message: " << e.what() << endl;
return -3;
}
// 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.getSQLStateCStr() << " Error Code: " << e.getErrorCode() << endl;
cout << "Could not connect to database. Error: " << e.what() << endl;
return -1;
}
It compiles well but gives an unknown exception with unknown debug info. Something like this. Please help.

This worked after changing the string to SQLString for all the connection params like server, username and password.
This worked out like a charm.

Related

How to create secure https server in "Qt"?

I am going through the below github source code for implementation of rest server. It has details with respect to http server but when I am trying to create a secure server I am facing problem after adding the certificate and key. Please suggest how to establish a secure https server using Qt.
https://github.com/Tropby/QSimpleRestServer
QFile certFile("demo.cer");
QFile keyFile("demo.key");
QByteArray cert,key;
if(!certFile.open(QIODevice::ReadOnly))
{
qDebug() << "Couldn't Open Resource File.";
qDebug() << "Error: " << certFile.errorString();
}
else {
cert = certFile.readAll();
certFile.close();
}
if(!keyFile.open(QIODevice::ReadOnly))
{
qDebug() << "Couldn't Open Resource File.";
qDebug() << "Error: " << keyFile.errorString();
}
else {
key = keyFile.readAll();
keyFile.close();
}
if(sslSocket->setSocketDescriptor(socket_descriptor)){
qDebug()<<"set passed";
} else {
qDebug()<<"set failed";
}
sslSocket->setProtocol(QSsl::AnyProtocol);
sslSocket->ignoreSslErrors();
QSslKey ssl_key(key,QSsl::Rsa,QSsl::Pem,QSsl::PrivateKey,(QByteArray)"demo.key");
QSslCertificate ssl_cert(cert);
sslSocket->setLocalCertificate(cert);
sslSocket->setPrivateKey(ssl_key);
sslSocket->modeChanged(QSslSocket::SslMode::SslServerMode);
sslSocket->startServerEncryption();

C++ app MySQL odbc database connection error: terminate called after throwing an instance of 'otl_tmpl_exception<>

I am currently debugging a containerized C++ application, it seems like it's throwing exception and complaining about the database connection, error:
terminate called after throwing an instance of 'otl_tmpl_exception<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur>'
Aborted
The code in main() is below:
int main(int ac, char *av[])
{
auto otl_connect = std::make_unique<odbc::otl_connect>("Driver={/usr/local/lib/libmyodbc8a.so};server=xxx.x.x.x;port=xxxx;database=xxxx;user=xxx;password=xxx");
std::stringstream query;
query << "SELECT x FROM xxx.xxxs;";
odbc::otl_stream the_stream(1000, query.str().c_str(), *otl_connect);
std::string
int val;
while(!the_stream.eof())
{
the_stream >> xxx >> val;
std::cout << xxx << " " << val << "\n";
}
the_stream.close();
}
I'm totally new to C++, can someone explain what the codes in main() is doing and how to fix the exception error message, I've been working on this for a whole afternoon, exhausted....help!!!!
I'm not very familiar with the Oracle, ODBC and DB2-CLI Template Library but I had a go using it with a MySql database on my Ubuntu Linux.
This is how I was able to run a simple query. I think the code below is fairly self-explanatory.
As you'll see, it's quite different from your code. The driver is mysql. You have to substitute ... with the real database name, user name and password of your database. You also have to initialise the ODBC environment first and connect to your database using rlogon().
#include <iostream>
#define OTL_ODBC // Compile OTL 4.0/ODBC
#define OTL_ODBC_UNIX
#include "otlv4.h"
int main()
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try {
db.rlogon("DRIVER=mysql;DB=...;UID=...;PWD=..."); // connect to ODBC
otl_stream os(50, "SELECT id FROM task", db);
int id;
// SELECT automatically executes when all input variables are assigned
while (!os.eof())
{
os >> id;
std::cout << "id=" << id << std::endl;
}
}
catch(otl_exception& p) { // intercept OTL exceptions
std::cerr << p.msg << std::endl; // print out error message
std::cerr << p.stm_text << std::endl; // print out SQL that caused the error
std::cerr << p.sqlstate << std::endl; // print out SQLSTATE message
std::cerr << p.var_info << std::endl; // print out the variable that caused the error
}
return 0;
}
Make sure that you have a variable for each field you want to read from the query result. It seems that you can't extract values into std::string variables; you have to use char arrays (e.g. char name[20]) instead.
Hope this helps.

MySQL C++ Not reading results

I am trying to read data from a database using the 8.0.13 MySQL C++ Connector. I am able to successfully write to a database no problem, but when I try to get the results of the database (using result next) it never runs.
bool outPutBool;
string outPut;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
string test = getTest();
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://ip:port", "root", "password");
/* Connect to the MySQL test database */
con->setSchema("database name");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT `column name` FROM `table name` WHERE `test column` = '" + variable + "'"); //Variable is defined in the function input
while (res->next()) {
outPut = res->getString(1);
cout << outPut << endl;
cout << "Test\n"; //never runs
}
delete res;
delete stmt;
delete con;
}
catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
Sleep(10000); //Temporary delay so I can see if anything comes up before it runs another function
if (test != outPut)
doSomething();
else
doSomethingElse();
The while loop never runs and I am clueless to why this happens as it seems to work for a lot of other people. I have included all libraries and headers in the connector library, but to no help.
Using the SQL Query function in phpmyadmin properly displays the output, so it's not the query's fault.
I would greatly appreciate it if anyone could give me some help here, and if you have any questions or need more of my code just ask. Thanks a lot for the help!
I'm not sure how, but after just simply adding a cout statement between the query and the while loop it suddenly solved itself. I removed the cout and now it's works perfectly no problem. Not sure what caused this error, but I'm happy that it solved itself after I have been trying to fix it for quite a while!
When you concatenate an SQL statement dynamically and when it then does not return the results you are expecting, it is very often that the generated SQL statement is not as you expected to be.
It's hard to tell what's wrong, because we cannot reproduce it without your DBMS, of course.
But usually one will write the SQL statement to stdout, copy it to an interactive SQL console then and see what happens:
std::string query = "SELECT `column name` FROM `table name` WHERE `test column` = '" + variable + "'";
std::cout << query << std::endl; // open console and copy/paste it to your DBMS
res = stmt->executeQuery(query); //Variable is defined in the function input

Error message after inserting to a table in MYSQL db

I have this c++ code that works fine, i can read from the tables and write to the tables:
int main()
{
// 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;
system("pause");
exit(1);
}
// 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;
system("pause");
exit(1);
}
stmt = dbConn->createStatement(); // Specify which connection our SQL statement should be executed on
// Try to query the database
try
{
stmt->execute("USE test"); // Select which database to use. Notice that we use "execute" to perform a command.
res = stmt->executeQuery("INSERT INTO users (fName, lName, age) VALUES ('fname', 'lname', 25)"); // Perform a query and get the results. Notice that we use "executeQuery" to get results back
//res = stmt->executeQuery("SELECT * FROM users");
//return 0;
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
system("pause");
exit(1);
}
sql::ResultSetMetaData *res_meta = res -> getMetaData();
int columns = res_meta -> getColumnCount();
// While there are still results (i.e. rows/records) in our result set...
while (res->next())
{
for (int i = 1; i <= columns; i++) {
cout << res->getString(i) << " | " ;
}
cout << endl;
}
delete res;
delete stmt;
delete dbConn;
//system("pause");
return 0;
}
So, this inserts to the table but then i get this error message
SQL error. Error message: sh: 1: pause: not found
This doesn't happen if i use the "select".
Also i know that this question was already asked here but unfortunately it has no answer so i'm asking again.
Your question looks related to MySQL Query executes but throws exception.
executeQuery() assumes that sql query should return sql::ResultSet but your INSERT INTO query does not. You can use execute() instead, which returns true or false:
try
{
stmt->execute("USE test");
stmt->execute("INSERT INTO users (fName, lName, age) VALUES ('fname', 'lname', 25)");
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
exit(1);
}
An INSERT is not a query. Try using executeUpdate() instead of executeQuery(). Look at the official MySQL example here.
Replace this line
res = stmt->executeQuery("INSERT INTO users (fName, lName, age) VALUES ('fname', 'lname', 25)"); // Perform a query and get the results. Notice that we use "executeQuery" to get results back
with the following lines (you may need a new .h file):
sql::PreparedStatement *pstmt;
pstmt = con->prepareStatement("INSERT INTO users (fName, lName, age)
VALUES ('fname', 'lname', 25)");
res = pstmt->executeUpdate();
delete pstmt;
You may also try using execute(), as shown in this Stackoverflow question. The function execute() is used for generic SQL commands, but may not be as verbose in its return value as more specified functions (it returns a boolean).

MySQL exception "connection lost during query", "MySQL server has gone away" and "command out of sync"

I have a code with c++, which use SQLAPI++ library. In my code I've tried to open connection for mysql, then create two commands, which works with same connection, and call that command from two threads.
During execution of my code I've received exception "Connection lost during query" and "MySQL server has gone away".
Sometime I receive exception "Command out of sync, you can't run this command now".
I've tried to increase wait_timeout տօ 150 and max_allowed_package տօ 64M, but my problem is not solved.
Bellow you can find c++ code.
int main()
{
try
{
SAConnection saConnection;
saConnection.Connect("scada", "root", "123qwerty!##", SA_MySQL_Client);
saConnection.setAutoCommit(SA_AutoCommitOff);
SACommand saCommand1{&saConnection, "select * from Node"};
SACommand saCommand2{&saConnection, "select * from Node limit 1"};
// VM: TODO: saCommand1.setOption("UseStatement") = "TRUE";
// VM: TODO: saCommand2.setOption("UseStatement") = "TRUE";
saCommand1.setOption("HandleResult") = "store";
saCommand2.setOption("HandleResult") = "store";
auto f1 = std::async(std::launch::async, [&]{ saCommand1.Execute(); saConnection.Commit(); });
auto f2 = std::async(std::launch::async, [&]{ saCommand2.Execute(); saConnection.Commit(); });
f1.get();
f2.get();
//saConnection.Commit(); // BOOM!
/*
while (saCommand1.FetchNext())
std::cerr << "======== fetching a record from saCommand1" << std::endl;
while (saCommand2.FetchNext())
std::cerr << "======== fetching a record from saCommand2" << std::endl;
*/
}
catch(const SAException& ex)
{
std::cerr << "==== ex.what() is " << static_cast<const char*>(ex.ErrText()) << std::endl;
}
return 0;
}
You are using one connection from two std::async objects, probably from two threads, which is not supported. Create two connections to the database, one for each std::async.