#include "CivPgConn.h"
#include "CivCommonUtils.h"

CivPgConn::CivPgConn(char* uri)
	:mUri(uri), CivDbConn()
{
	mConn = NULL;
	mResult = NULL;
}

CivPgConn::~CivPgConn()
{

}

bool CivPgConn::open()
{
    mConn = PQconnectdb(mUri);
    if (PQstatus(mConn) == CONNECTION_BAD) {
        mConn = NULL;
        PQfinish(mConn);
        return false;
    }
    mIsOpen = true;
    return true;
}

void CivPgConn::close()
{
    if (mConn != NULL)
        PQfinish(mConn);
    mIsOpen = false;
}

Tables CivPgConn::getTables(StrQuote netName, StrQuote schema)
{
    if (!isValid())
        return Tables();

    std::string utf8NetName = TransUTFCoding(netName); // 中文乱码
    std::string sql = "select \"name\" from public.__layer_info__ where net_code in(select code from public.__layer_net_info__ where \"name\" ='" + utf8NetName + "' and \"schema\" = '" + schema + "')";
    if (!execSql(sql))
        return Tables();

    Tables tables;
    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < columns; j++)
        {
            char* item = PQgetvalue(mResult, i, j);
            std::string ss = UTFTransCoding(item);
            tables.push_back(ss);
        }
    }

    PQclear(mResult);
    return tables;
}

bool CivPgConn::tableExist(StrQuote tableName)
{
    char sql[256] = "select count(*) from pg_class where relname = '";
    strcat_s(sql, tableName.c_str());
    strcat_s(sql, "'");

    if (!execSql(sql))
        return false;

    char* res = PQgetvalue(mResult, 0, 0);
    PQclear(mResult);
    int number = atoi(res);

    return number > 0 ? true : false;
}

bool CivPgConn::execSql(Str sql)
{
    if (sql.empty())
        return false;

    mResult = PQexec(mConn, sql.c_str());
    char* error = PQresultErrorMessage(mResult);
    std::string errorStr = error;

    if (!errorStr.empty())
    {
        mLastError = error;
        PQclear(mResult);
        return false;

    }

    return true;
}

void CivPgConn::clearResult()
{
    PQclear(mResult);
}

void CivPgConn::getData(Componets& comp)
{
    if (mResult == NULL)
        return;

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        Componet node;
        for (int j = 0; j < columns; j++)
        {
            char* item = PQgetvalue(mResult, i, j);
            char* fieldName = PQfname(mResult, j); // 获取列表字段名

            std::string itemStr = UTFTransCoding(item);
            std::string fieldStr = UTFTransCoding(fieldName);

            node.insert(std::pair<std::string, std::string>(fieldStr, itemStr));
        }
        comp.push_back(node);
    }
    PQclear(mResult);
}