How to Notice Close of MySql Server in Qt - c++

When I closed MySql server, how can I understand that mysql server is gone away from my Qt program?
Edit:
Here my trial:
When I close MySql, I get these results, and I can't catch that MySql is closed.
My Code Snippet is
QSqlQuery query(db);
query.exec("SELECT * From RequestIds");
qDebug()<<query.lastError();
qDebug()<<db.lastError()<<QTime::currentTime();
qDebug()<<db.isOpen();
qDebug()<<db.isValid();
and output is:
QSqlError(2006, "QMYSQL: Unable to execute query", "MySQL server has gone away")
QSqlError(-1, "", "") QTime("14:22:58")
true
true
I don't understand why db.isOpen() returns true.

There is a bug related with QSqlDatabase::isOpen() in Qt.
https://bugreports.qt.io/browse/QTBUG-223

Your program has no idea of its surroundings. If something changes, you may be able to have the OS notify your program, or you'll have to test yourself.
If the database connection closes before your program, the status from the connection should return some kind of error code. You are checking status from the connection functions?
Write a simple program that opens a window and upon the click of a button, writes to the database. After writing to the database, the program should display the status in the window. Run your program. Press button to get the "controlled" response. Close the database then click on the button again.
You may be able to do this with a debugger, depending on the ability of the debugger & OS to queue up messages.

QSqlQuery::lastError() should give you an error if your query via QSqlQuery::exec() has failed. Also QSqlDatabase::isOpen() should report the state of your connection, QSqlDatabase::lastError() is also available

You can use isOpenError to determine whether opening the initial database connection was successfull. I agree that isOpen returning true is confusing.
To monitor the database connection I repeatedly try to open and close a lightweight MySQL connection (e.g. every 3 seconds):
#include <mysql/mysql.h>
mysql_init(&connection);
MYSQL *result = mysql_real_connect(&connection,
host.isNull() ? static_cast<const char *>(0) : host.toLocal8Bit().constData(),
user.isNull() ? static_cast<const char *>(0) : user.toLocal8Bit().constData(),
pass.isNull() ? static_cast<const char *>(0) : pass.toLocal8Bit().constData(),
dbName.isNull() ? static_cast<const char *>(0) : dbName.toLocal8Bit().constData(),
0,
0,
0);
bool currentlyConnected = (result != 0);
In the above example, host, user, pass, and dbName are QString instances containing the connection information. Note that you need the MySQL development headers.

Related

How to use the WinRM C++ API in a simple example

why is my code failing to run a simple executable using WinRM's C++ API?
//main.cpp
int main()
{
ShellClient *shellClient = new ShellClient();
//Set up the shell client here and connect to the localhost.
//This seems to be working fine because I'm handling every
//possible error code, and none of them are being triggered
PCWSTR commandLine = L"\"MyExampleExecutable.exe\"";
isOk = shellClient->RunCommand(commandLine);
if (!isOk)
return 1;
return 0;
}
//ShellClient.cpp
bool ShellClient::RunCommand(PCWSTR command)
{
WSMAN_SHELL_ASYNC createCommandAsync;
ZeroMemory(&createCommandAsync, sizeof(createCommandAsync));
createCommandAsync.operationContext = this;
createCommandAsync.completionFunction = (WSMAN_SHELL_COMPLETION_FUNCTION)CommandCreatedCallback;
WSManRunShellCommand(shellHandle, 0, command, NULL, NULL, &createCommandAsync, &commandHandle);
if (commandHandle == NULL)//It is *always* NULL
{
std::cout << "command handle null" << std::endl;
system("pause");
return false;
}
return true;
}
One possible clue is that my C++ code thinks the shell gets created fine, but in the Event Viewer for my machine, there is this:
WSMan operation CreateShell failed, error code 2150859250
At the time of writing, this lovely error code gives precisely zero results when put into Google, making it rather difficult to know what it means.
Background and common solutions which I have already checked
As documented here and explaned in this video by the same author, most WinRM issues boil down to either connection or authentication problems. In my case, if I deliberately enter incorrect user credentials, I get an authentication error, so I know that my program is connecting and authenticating fine when the correct username and password are supplied. Also:
From the command line, I can connect to my local machine and pretend it's a remote server, for example the following command works fine:
winrs -r:http://localhost:5985 -u:COMPUTERNAME\Jeremy "dir"
winrm quickconfig shows the service is working (which we already know otherwise the winrs command wouldn't work)
winrm get winrm/config shows TrustedHosts = localhost, AllowUnencrypted = true, and all authentication methods are set to true
Following this advice, I have set the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy = 1
Working in Windows 10
Thank you in advance!
I wasn't aware of this so can't comment on whether it's common knowledge but Microsoft have a nifty error lookup tool where you can enter an error code (after converting it from a normal number to hexadecimal) and it tells you what it means.
In this case, 2150859250 (803381F2 in hex) corresponds to:
ERROR_WINRS_IDLETIMEOUT_OUTOFBOUNDS wsmerror.h
# The WS-Management service cannot process the request. The
# requested IdleTimeout is outside the allowed range.
When setting up the WinRM shell, I was doing the following:
WSMAN_SHELL_STARTUP_INFO startupInfo;
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.idleTimeoutMs = 1000;//not large enough!
startupInfo.workingDirectory = L"C:\\";
//other parameters of startupInfo set here
WSManCreateShell(session, 0, shellUri, &startupInfo, NULL, NULL, &createShellAsync, &shellHandle);
Changing idleTimeoutMs from 1000 to a much larger number like 100000 solved the error and my program now works fine.
Since the official docs for this parameter say anything between 0 and 0xFFFFFFFF are valid, it remains a mystery why a value of 1000 is throwing this error. I leave this for somebody more knowledgable than myself to answer, on the off chance that they come across this question.

SQLite C++ 'database is locked' when multiple processes access db in readonly mode

I have an sqlite database that doesn't change.
Multiple processes that open a database connection each in SQLITE_OPEN_READONLY mode using sqlite3_open_v2. Each process is single threaded
The connections are made from an MSVC project using the official C/C++ Interface's single amalgamated C source file.
According to the SQLite FAQ multiple processes running SELECTs is fine
Each process after opening the database creates 4 prepared SELECT statements each with 2 bindable values.
Over the course of the execution the statements (one at a time) have the following called on them repeatedly as required
sqlite3_bind_int
sqlite3_bind_int
sqlite3_step (while SQLITE_ROW is returned)
sqlite3_column_int (while there was a row)
sqlite3_reset
The prepared statements are reused so finalize isn't called on each of them until near the end of the program. Finally the database is closed at the very end of execution.
The problem is any of these operations can fail with error code = 5: 'database is locked'
Error code 5 is SQLITE_BUSY and the website states that
"indicates a conflict with a separate database connection, probably in a separate process"
The rest of the internet seems to agree that multiple READONLY connections is fine. I've gone over and over the source and can't see that anything is wrong (I can't post it here sadly, I know, not helpful)
So I'm turning it to you guys, what could I possibly be missing?
EDIT 1:
Database is on a local drive, File system is NTFS, OS is Windows 7.
EDIT 2:
Wrapping all sqlite3 calls in infinite loops that check if SQLITE_BUSY was returned and then remake the call alleviates the problem. I don't consider this a fix but if that truly is the right thing to do then I'll do that.
So the working answer I have used is to wrap all the calls to sqlite in functions that loop that function while SQLITE_BUSY is returned. There doesn't seem to be a simple alternative.
const int bindInt(sqlite3_stmt* stmt, int parameterIndex, int value)
{
int ret;
do
ret = sqlite3_bind_int(stmt, parameterIndex, value);
while (ret == SQLITE_BUSY)
return ret;
}

ora-24399- Invalid number of connections specified -OCCI program

I am using following simple code to connect to database and I am getting error as ORA-24399 which says invalid number of connections specified. I have googled enough but not clue. This is a CPP program.
Following is code Snippet:
try
{
Environment *env = Environment::createEnvironment(Environment::DEFAULT);
Connection *con= env->createConnection("test","test","testdb");
}
catch(SQLException ex)
{
cout<<ex.getMessage().c_str();
}
P.S Using SQL Plus I am able to connect to the database where this code is being run. There are no issues there. Only through program there is a failure seen.
P.P.S Tried using connectionpool as well but still no luck...
Looking at your error, it seems that the problem is somewhere else in your code: you should fix the parameters (related to connection numbers) in the call to OCIConnectionPoolCreate.

Application crash after using mysql_fetch_row

I got a problem regarding simple MySQL function which is mysql_fetch_row when ever I use it, my application will crash with it will go to the point when its executing.
No matter what query I would run it will crash. The core dump says following:
(gdb) bt full
#0 0x2866397f in mysql_store_result () from /usr/home/ld/application
#1 0x28637905 in main () from /usr/home/ld/application
#2 0x08441d3a in CRC_GetCodeSize20 ()
The code looks simple:
int main()
{
MYSQL *conn; // the connection
MYSQL_RES *res; // the results
MYSQL_ROW row; // the results row (line by line)
struct connection_details mysqlD;
mysqlD.server = "localhost"; // where the mysql database is
mysqlD.user = "mysqlusername"; // the root user of mysql
mysqlD.password = "mysqlpassword"; // the password of the root user in mysql
mysqlD.database = "mysql"; // the databse to pick
conn = mysql_connection_setup(mysqlD);
res = mysql_perform_query(conn, "select 1, 2");
printf("Result:\n");
while ((row = mysql_fetch_row(res)) !=NULL)
printf("%s\n", row[0]);
mysql_free_result(res);
mysql_close(conn);
return 0;
}
What is the problem?
edit
mysql_perform_query:
MYSQL_RES* mysql_perform_query(MYSQL *connection, char *sql_query)
{
if (mysql_query(connection, sql_query))
{
printf("MySQL query error : %s\n", mysql_error(connection));
exit(1);
}
return mysql_use_result(connection);
}
Ok. So I have spent quite some time to reproduce this problem. I assume you took the example from this tutorial: http://www.codingfriends.com/index.php/2010/02/17/mysql-connection-example/ since it's exactly the same.
Steps taken:
cd /usr/ports/databases/mysql56-client && make install
Copy pasted the exact code from the above tutorial to test.cpp
g++ -I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient test.cpp
./a.out
Output:
Mysql tables in database:
entry
old
I used my remote mysql server and a test account. First I made sure I can connect to it via console mysql -h mydomain.com -u test -p
The program seems to work normally. The only thing I noticed is that sometimes it takes 1 second to execute while other times it takes up to 10 seconds for whatever reason.
Built on PC-BSD Isotope Edition (9.1 RELEASE) with up to date port tree.
So now there are 2 people with successful build (me and your friend). Code being the same the only thing I can think of going wrong is the libmysqlclient.so library. Try to update your port tree and do a fresh build. Or maybe try a different version.
You could try viewing the registered *port* using the netstat command , because the reason it might be crashing is, you are using an already registered port for your dbase. Check for that.
Also if you find out working on an already registered port, try changing the port number in the S/w along with that you have to remove the value from the registry as well(regedit) .(Sometimes it uses the shadow port , so need to do that).
Also check for null in your "conn", Somehow maybe you arn't able to initiate a connection. (connection pool exhaustion?? Very doubtful ).

Interop exception with VC++ and MySQL C++ Connector

I am helping a friend with his bachelor thesis project. It is a program that calculates bending moments for various materials. One of the extra requirements that the client desires is database functionality to store and retrieve various pieces of data being used in the program.
The program is a forms application written in managed C++. I jumped on board to help with writing the database functionality. I am using MySQL Server 5.5 and the MySQL Connector/C++ to bridge the program and the database. Everything has been going pretty well and all the functionality we need works just fine, but only in debug. As soon as we put the program into release mode there is undefined behavior occurring at runtime. Below is the function that is used to open a connection to the database:
try
{
m_driver = get_driver_instance();
m_conn = m_driver->connect(m_dbHost, m_dbUser, m_dbPwd);
m_conn->setSchema(m_dbSchema);
}
catch(sql::SQLException &e)
{
int a = e.getErrorCode();
MessageBoxA(NULL, e.what(), "DB Error", MB_OK);
}
The values passed into the connect function are all std::string. In debug mode the connection is made with no issues. In release mode an exception is caught after the connect function is called, and displays the message "Unknown MySQL Server Host '####' (0)" where the #### is always some garbage text. I also notice that in the output window another exception is being thrown, this one is the type System.Runtime.InteropServices.SEHException.
I have been doing some research and have seen numerous cases of this exception on many forums (and here on stack exchange) but no one seems to be having this issue with the MySQL connector. My assumption is that the memory is being corrupted because the program is mixed mode, with the main program code being written in Managed C++ and my database helper code being in native C++ (as required by the connector).
Is there something I can change in my code to try and fix this issue to that the strings aren't being corrupted at run time. I have tried many different hacks to try and solve the problem but nothing has worked.
Thanks,
Tom
Update: I am now seeing this error in debug mode. I added code to retrieve values from the database and populate some text boxes on the form. The code is as follows:
// Populate the form with material details
String^ selectedMaterial = (String^)(comboBox1->SelectedItem);
string selectedMaterial_ = "";
MarshalString(selectedMaterial, selectedMaterial_);
sql::ResultSet* results = dbHelper.GetData("matname", selectedMaterial_);
if (results->rowsCount() == 1)
{
// Outdim
string outdim_ = "";
outdim_ = results->getString("outdim");
String^ outdim = gcnew String(outdim_.c_str());
textBox1->Text = outdim;
}
else
{
// !!!! Duplicate materials in list
}
When it tries to read outdim from the result set the SEHException is thrown, and the only other piece of information given is that it was thrown in an external component.
Update 2: I ran Application Verifier against the debug executable and then launched the program from VS2010. However the form window never loads so somewhere along the line the program must be getting halted. Strangely there is absolutely no information in the log files in Application Verifier. I also tried with the release version and I didnt get any useful information from that either.