#include "SQLiteModule.h"
#include "../utility/utility.h"
#include "../3rdParty/easylogging/easylogging++.h"

#define BUFFER_SIZE             1024 //缓冲区大小

SQLite::SQLite()
{
    pDB=NULL;
    errMsg=NULL;
}

SQLite::~SQLite()
{

}

bool SQLite::initSQLite()
{
    std::string strDbFileName;      //*.db 名称
    std::string strPath = GetProcDir(); 
    strPath.append("fmdata.db");
    strDbFileName = strPath;

    //打开一个数据库，如果改数据库不存在，则创建一个名字为databaseName的数据库文件
    int res = sqlite3_open(strDbFileName.c_str(), &pDB);
    LOG(INFO)<<"DbFileName:"<<strDbFileName.c_str();
    if(res != SQLITE_OK)
    {
        LOG(ERROR)<<"打开数据库失败:"<<strDbFileName.data();
        return false;
    }
    try
    {
        _createTable(); 
    }
    catch(std::exception &ex)
    {
        LOG(ERROR)<<"创建表异常："<<ex.what();
        return false;
    }
    return true;
}

bool SQLite::_createTable()
{
    //插入一个表，返回值为SQLITE_OK为成功，否则输出出错信息
    //函数参数：第一个为操作数据库的指针，第二句为SQL命令字符串
    //第三个参数为callback函数，这里没有用，第四个参数为callback函数
    //中的第一个参数，第五个为出错信息
    bool rlt=true;
    std::string strTableName="fmOrderFailed";
    if(!isTableExist(pDB,strTableName)){
        char szCreate[1024]={0};
        sprintf(szCreate,"create table %s(id BIGINT NOT NULL,\
                                          msg TEXT,\
                                          logtime TIMESTAMP default (datetime('now', 'localtime')),\
                                          PRIMARY KEY (id))",strTableName.c_str());
        if(!_execSql(szCreate)){
            //执行失败，退出
            exit(0);
        }
    }
    else{
        LOG(INFO)<<strTableName.data()<<"已存在";
    }
    return rlt;

}

void SQLite::closeSQLite()
{
    if(pDB)
        sqlite3_close(pDB); 
}

//查看表是否存在
bool SQLite::isTableExist(sqlite3 *sqDb, std::string strTableName)
{
    char szQuery[1024] = {0};
    sprintf(szQuery, "SELECT count(*) FROM sqlite_master WHERE type=\"table\" AND name=\"%s\"", strTableName.c_str());
    sqlite3_stmt *pstmt;
    sqlite3_prepare(sqDb, szQuery, strlen(szQuery), &pstmt, NULL);
    sqlite3_step(pstmt);
    int count=sqlite3_column_int(pstmt,0);
    sqlite3_finalize(pstmt);
    if(count > 0)
       return true;
    return false;
}

int SQLite::isRecordExist(std::string strTable,std::string strKey)
{
    char* lpSql = new char[BUFFER_SIZE];
    sprintf(lpSql, "select * from %s where id = '%s'",strTable.c_str(),strKey.c_str());    
    char** pResult;  
    int nRow = 0;   
    int nCol = 0;
    int nResult = sqlite3_get_table(pDB,lpSql,&pResult,&nRow,&nCol,&errMsg);  
    delete[] lpSql;
    if (nResult != SQLITE_OK)  
    {
        LOG(ERROR)<<"sqlite3_get_table error:"<<errMsg;
        return -1;
    }
    return nRow;
}

bool SQLite::_execSql(const char* sql)
{
    bool rlt=true;
    int res = sqlite3_exec(pDB,sql, 0, 0, &errMsg); 
    if(res != SQLITE_OK)
    {
        LOG(ERROR)<<"执行sql失败:"<<sql<<"  失败信息："<<errMsg;
        rlt=false;
    }
    return rlt;
}

bool SQLite::insert(const char* sql)
{
    return _execSql(sql);
}

bool SQLite::update(const char* sql)
{
    return _execSql(sql);
}

bool SQLite::remove(const char* sql)
{
    return _execSql(sql);
}

std::vector<orderSendFailedObj> vecOrders;
int callbackQuery(void* data,int n_columns,char** column_values,char** column_names)
{   
    try
    {
        orderSendFailedObj order;
        order.timestamp=atoll(column_values[0]);
        order.order_json=column_values[1];
        vecOrders.push_back(order);
        
    }
    catch(std::exception &ex)
    {
        LOG(ERROR)<<"读取数据失败:"<<ex.what();
        return -1;
    }

    return 0;
}

void SQLite::query(const char* sql,std::vector<orderSendFailedObj> &vecFailedOrders)
{
    vecOrders.clear();
    int rlt = sqlite3_exec(pDB,sql,callbackQuery, 0, &errMsg);
    if(rlt!= SQLITE_OK)
    {
        LOG(ERROR)<<"查询数据执行失败："<<errMsg;
    }
    else{
        vecFailedOrders.assign(vecOrders.begin(), vecOrders.end());
    }
}