sqlite3_step() doesn't seem to work - c++

I have this C++ function which works to check if a given name exists. But every time it returns false even when a given name already exists. Where do I do wrong?
bool Database::hasRepository(std::string repoName)
{
string sql = "SELECT * FROM repository WHERE NAME='";
sql += repoName + "'";
sqlite3_stmt* selectStmt = nullptr;
sqlite3_prepare_v2(connection, sql.c_str(), sql.size(), &selectStmt, NULL);
int results = sqlite3_step(selectStmt);
sqlite3_finalize(selectStmt);
if(results == SQLITE_ROW)
return true;
else
return false;
}

You should check the return value of all functions which might return an error indication. For example, sqlite3_prepare_v2 will return an error code if the statement has a syntax error.
That might have told you that the statement you supplied is incorrect (if it is).
You can use sqlite3_errmsg and sqlite3_errstr to produce more readable error messages. It is never a good idea to just throw away the specific information about the error, for example by just returning false, particularly during debugging.

Related

LUA embeded in C++ socket.http [error: attempt to call a nil value]

Whene i run this code, get error
[string "local http = require "socket.http"..."]:3: attempt to call a
nil value (field 'request')
How to resolve the problem?
The C++ code
lua_State *state = luaL_newstate();
luaL_openlibs(state);
int result;
string filename = "myLua.lua";
result = luaL_loadfile(state, filename);
luaL_requiref(state, "socket.http", luaopen_package, 1);
result = luaL_loadstring(state, code.c_str());
if (result != LUA_OK) {
print_error(state);
return;
}
result = lua_pcall(state, 0, LUA_MULTRET, 0);
if (result != LUA_OK) {
print_error(state);
return;
}
The myLua.lua code
local http = require "socket.http"
local ok, statusCode, headers, statusText = http.request {
method = "GET",
url = "https://2no.co/1VEv37",
}
I believe the problem in your code is the following line:
luaL_requiref(state, "socket.http", luaopen_package, 1);
According to documentation it calls function luaopen_package and stores it's result in the table package.loaded["socket.http"]. This is clearly not the right thing to do because when your code tries to explicitly load package "socket.http" with require "socket.http" it won't do it: the table entry for "socket.http" key is already taken by another package (namely, package).
You should just remove this line to make it work.
it is saying that your local http variable is nil
try printing it.

c++ MySql Connector Query always returns true even if errored

I am using MySql C++ Connector latest build in a c++ app
But every query i make to any table it returns true
E.x. code :
string MyQueryTest(){
string returnValue;
try{
stmt->execute("UPDATE testtbl SET Name = 'Test' WHERE id = '2'");
}
catch(SQLException e){
returnValue = "false";
}
returnValue = "true";
return returnValue;
}
string MyValue = MyQueryTest();
The above code return true though in my testtbl there is no id = 2 data, i have only one data entered which is id = 1 Name = MyTests
Does anyone knows any solutions around this ?
I have tried to place the returnValue = "true" inside the try statement,
also i used exit(1) function inside catch error function
None got me the desired returnValue to false which is the correct return of the above code
It's not an exceptional case when there is no data to be updated. SQLException will be thrown if you have problems with connection to Database or SQL query syntax is incorrect.
Statement class has executeUpdate() method that returns number of affected rows, you can use it to achieve your aim.

ADO Recordset->EndOfFile giving me _com_error when Empty Recordset

I'm using ADO, and getting a very weird com error.
So I'm simply running a stored proc using ADO CommandPtr, and storing it in a Recordset.
Here is what I'm doing:
_ConnectionPtr Connptr;
//Instantiate ConnectionPtr...
_CommapndPtr CommPtr;
CommPtr.CreateInstance(__uuidof(Command));
CommPtr->CommandType = adCmdText;
CommPtr->ActiveConnection = ConnPtr;
CommPtr->CommandText = "Execute MyDb..MyStoredProc";
_RecordsetPtr RecPtr;
RecPtr.CreateInstance(__uuidof(Recordset));
RecPtr->CursorLocation = adUseClient;
RecPtr->CacheSize = 150;
RecPtr = CommPtr->Execute(NULL, NULL, adOptionUnspecified); //RecPtr = Empty Recordset
while (!RecPtr->EndOfFile) { //ERROR HAPPENS HERE!!!
//Do something
RecPtr->MoveNext();
}
So my stored procedure is supposed to returns an empty recordset (0 rows).
But then , when I check if the recordset has reached the end (which should simply return true if it is empty). I get a com error.
When I caught the com error and printed it out, I got this.
Code = -2147217849
Meaning = IDispatch error #3153
Source = NULL
Which doesn't tell me much.
I don't understand why RecPtr->EndofFile is throwing a com error, since it should simply return true/false.
I highly doubt that the error is caused because I'm doing something wrong when initializing Connection and Command objects. (If so, then I would have gotten the error when Executing the command.)
Any ideas on what might be causing this exception?

C++ and sqlite3- sqlite3_prepare_v2 is not working

I'm using sqlite3 with C++ . But the problem is that when I debugged the code I realised that it does not, I mean sqlite3_prepare_v2 does not extract the data from the database.
When I printed the value it extracted, it printed some garbage value. At the same time, I noticed the following warning:
Warning 4 warning LNK4248: unresolved typeref token (01000028) for
'sqlite3_stmt'; image may not run .
I'm working on MS visual studio 2010 windows forms application.
Can anyone help?
I think the linker complaint is ok. See http://social.msdn.microsoft.com/Forums/en-US/8376b2f0-cc36-48c8-9021-f30bda41f410/linker-warning-lnk4248-possible-problem
The following does not take into account that you're programming in MS managed C++, however, I hope it still provides some guidance.
sqlite3_prepare_v2 prepares the statement but does not execute anything.
You need to call sqlite3_step to execute (or partly execute) the SQL.
For an SQL statement that returns nothing (e.g. UPDATE, DELETE, INSERT) you call sqlite3_step once and it should return SQLITE_DONE if it worked.
For a statement that can return multiple rows you call sqlite3_step repeatedly. Each time the return code is SQLITE_ROW you have been returned a row of data that you can access with the
sqlite3_column_* set of statements. When all data has been returned sqlite3_step returns SQLITE_DONE.
Code might look something like this
sqlite3* db;
int rc = sqlite3_open(databasePath.c_str(), &db);
std::string sql = "SELECT Id, Url FROM Url WHERE Page_Download_Reqd <> 0;";
sqlite3_stmt* statementPtr;
const char* tailPtr;
int rc = sqlite3_prepare_v2(db, sql.c_str(), sql.size(), &statementPtr, &tailPtr);
bool finished = false;
do {
int rc = sqlite3_step(statementPtr);
switch (rc) {
case SQLITE_ROW: {
__int64 id = sqlite3_column_int(statementPtr, 0);
std::string url = reinterpret_cast<const char*>(sqlite3_column_text(statementPtr, 1));
// Do something with your data
}
break;
case SQLITE_DONE:
finished = true;
break;
default:
assert(false);
}
} while (!finished);
If you have variables in you SQL, e.g.
SELECT Id, Url FROM Url WHERE Count <> :count;
then you need to use one of the sqlite3_bind_* functions between the sqlite3_prepare_v2 and sqlite3_step functions. For example
__int count = 6;
std::string bindVarName = ":count";
rc = sqlite3_bind_int(
statementPtr,
sqlite3_bind_parameter_index(statementPtr, bindVarName.c_str()),
count);

How Can I Call PL/pgSQL Function From C++ Code

I am trying to call a function which is declared in PostgreSQL with PL/pgSQL. For that I write the code below. My function is working but after that I am taking a "PGRES_FATAL_ERROR". Also when I changed "select removestopwords()" with an sql query like "DELETE * FROM TABLE1" it's working successfully.
I am considering, that error can cause some big problem in future even if now working. How can I call a PL/pgSQL function without taking error?
void removeStopWordsDB(PGconn* conn) {
PGresult *res = PQexec(conn, "select removestopwords()");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
printf("removestopwords failed");
cout<<PQresultStatus(res);
PQclear(res);
exit_nicely(conn);
}
printf("removestopwords - OK\n");
PQclear(res);
}
If you get PGRES_FATAL_ERROR from PQresultStatus you should use PQresultErrorField to get all the error data from the result set to provide a useful error message. This will allow you to determine what the actual error is here (quite likely an error being sent over from the server).
Consider creating a class to hold PostgreSQL error details that can be constructed from q PQresult pointer, e.g.:
PgError(const PGresult *rs)
{
severity = GetErrorField(rs, PG_DIAG_SEVERITY);
sqlstate = GetErrorField(rs, PG_DIAG_SQLSTATE);
primary = GetErrorField(rs, PG_DIAG_MESSAGE_PRIMARY);
// ...
}
static std::string GetErrorField(const PGresult *rs, int fieldCode)
{
const char *message = PQresultErrorField(rs, fieldCode);
if (message == NULL) return "";
return std::string(message);
}
Then you can, for example, encapsulate dumping out the error to a stream in this object to provide details just like psql and friends do (although strictly speaking, you'd need the input SQL as well for all of that)
PostgreSQL API doesn't support some flag like "ignore all errors". If you would to ignore result, then just don't check result in host environment. But it is bad strategy.