#ifndef _CSQLITE_STATEMENT_INNER_H
#define _CSQLITE_STATEMENT_INNER_H

#include "sqlite3.h"
#include "CSQLiteException.h"
#include <memory>

/// 封装一对数据库指针和Stmt指针，用于一个共享指针_StatementPtr
class _Statement
{
public:
    _Statement(sqlite3* apSQLite, const char * aQuery)
        : mpSQLite(apSQLite)
        , mpStmt(nullptr)
    {
        const int ret = sqlite3_prepare_v2(apSQLite, aQuery, -1, &mpStmt, nullptr);
        if (SQLITE_OK != ret)
        {
            throw CSQLiteException(apSQLite, ret);
        }
    }

    _Statement(sqlite3* apSQLite, const std::string& aQuery)
        : mpSQLite(apSQLite)
        , mpStmt(nullptr)
    {
        const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, nullptr);
        if (SQLITE_OK != ret)
        {
            throw CSQLiteException(apSQLite, ret);
        }
    }

    ~_Statement()
    {
        // If count reaches zero, finalize the sqlite3_stmt, as no Statement nor Column objet use it anymore.
        // No need to check the return code, as it is the same as the last statement evaluation.
        sqlite3_finalize(mpStmt);
        mpSQLite = nullptr;
        mpStmt = nullptr;
    }

private:
    sqlite3*        mpSQLite;    //!< Pointer to SQLite Database Connection Handle
    sqlite3_stmt*   mpStmt;      //!< Pointer to SQLite Statement Object

public:
    /// Inline cast operator returning the pointer to SQLite Database Connection Handle
    /// for functions like:
    inline operator sqlite3*() const
    {
        return mpSQLite;
    }

    /// Inline cast operator returning the pointer to SQLite Statement Object
    /// for function like: sqlite3_column_xxx()
    inline operator sqlite3_stmt*() const
    {
        return mpStmt;
    }
};

typedef std::shared_ptr<_Statement> _StatementPtr;
#endif // _STATEMENT_H
