c++sqliteauthentication

How to obtain a boolean out of a SQL WHERE condition?


I'm doing an application (only for training, it's been 1.5 years since last time I've practiced) that require a login. I already done this part, the problem is that I'm not able to verify that the user inputs are the same as what's in the DB. The only thing giving me the hint that works is that the sql query show me the result, but I would like to obtain a bool out of it for a switch

#include <iostream>
#include <sqlite3.h>

using namespace std;

static int callback(void *data, int argc, char **argv, char **azColName)
{
    int i;
    fprintf(stderr, "%s: ", (void *)data);
    for (i = 0; i < argc; i++)
    {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");

    return 0;
}

int main(int argc, char *argv[])
{
    string Username = "";
    string Password = "";

    cout << "Please, identify yourself\nUsername : ";
    cin >> Username;

    cout << "Password : ";
    cin >> Password;

    sqlite3 *db;
    char *zErrMsg = 0;
    string data = "Callback function called";
    sqlite3_stmt *res;

    int RC = sqlite3_open("SkyEyes.db", &db);
    if (RC)
    {
        cout << "\nError : ";
        cout << zErrMsg;
    }
    else
    {
        cout << "\nDatabase opened !\n";
    }

    string query = "SELECT * FROM Users WHERE USERNAME LIKE \'" + Username + "\' AND PASSWORD LIKE \'" + Password + "\';";

    sqlite3_exec(db, query.c_str(), callback, (void *)data.c_str(), &zErrMsg);

    cout << data;
}

Solution

  • If you just want to know whether the query produced any results, it suffices to record whether callback was invoked. You can do this by smuggling a bool * as the data argument:

    static int callback(void *data, int argc, char **argv, char **azColName)
    {
        *reinterpret_cast<bool *>(data) = true;
        return 0;
    }
    
    int main() {
        ...
        bool valid = false;
        sqlite3_exec(db, query.c_str(), callback, &valid, &zErrMsg);
    
        // check valid
    }
    

    Alternatively, you can split the sqlite3_exec into a sqlite3_prepare_v3, then check whether sqlite3_step returns SQLITE_ROW exactly once, and finally call sqlite3_finalize.