mercredi 3 mai 2017

C++ / loosing pointer reference outside scope

First of all, this is a newbie question. I've built a basic c++ wrapper class for interacting with sqlite3 in the frame of a small project. Here's a portion of it:

data_wrapper.hpp

#ifndef DATAWRAPPER_H
#define DATAWRAPPER_H

class DataWrapper
{
private:
    sqlite3      *db_;
    const char   *db_file_;
    int          rc_;

    bool prepare ( sqlite3_stmt* statement, const char* query );
    bool check_table ( const char* table_name );

public:
    DataWrapper ( const char* db_file );
    sqlite3* get_database();
};

#endif // DATAWRAPPER_H

data_wrapper.cpp

#include <iostream>
#include <cstring>

#include "data_wrapper.hpp"

using namespace std;

DataWrapper::DataWrapper ( const char* db_file ) : db_ ( nullptr )
{
    db_file_ = db_file;
}

sqlite3* DataWrapper::get_database()
{
    return db_;
}

bool DataWrapper::prepare ( sqlite3_stmt* statement, const char* query )
{
    cout << "preparing: " << query << endl;
    rc_ = sqlite3_prepare_v2 ( db_, query, strlen ( query ), &statement, 0 );
    cout << "statement is: " << &statement << endl;

    return rc_ == SQLITE_OK;
}

/**
 * Checks if a given table is present on the database
 *
 * @param  table_name The name of the table to check.
 * @return bool       True if table exists, false otherwise.
 */
bool DataWrapper::check_table ( const char* table_name )
{
    const char* query = "SELECT name FROM sqlite_master WHERE type='table' AND name=?;";
    sqlite3_stmt* stmt = nullptr;

    if ( !prepare ( stmt, query ) ) {
        cout << "can't prepare query" << endl;

        return false;
    }

    cout << "statement now is: " << stmt << endl;

    if ( !bind ( stmt, 1, table_name ) ) {
        return false;
    }

    step ( stmt );

    return rc_ == SQLITE_ROW;
}

Somewhere, I have an init public method that opens a connection and checks for the presence of a given table. An expert would see the problem, which can be summed up by console output:

preparing: SELECT name FROM sqlite_master WHERE type='table' AND name=?;
done preparing
statement is: 0x7fff6bd121d0
statement now is: 0

Not that the use of sqlite3 is part of the problem here (or is it?), but of course, I won't be able to bind anything on a NULL statement:

(21) API called with NULL prepared statement
(21) misuse at line 76880 of [a65a62893c]

You'll see that I'm losing pointer reference after prepare scope ends. I've been looking around stack for similar problems but none adresses my issue correctly. So how can I prevent that, and possibly modernly, being on a learning curve, I might as well get a grip on actual c++11 techniques.

Aucun commentaire:

Enregistrer un commentaire