#include "CivPgConn.h"
#include "CivCommonUtils.h"
#include "CivSysLog.h"
#include "CivTypes.h"
#include <sstream>


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

CivPgConn::~CivPgConn()
{
    if (mConn != nullptr)
    {
        PQfinish(mConn);
    }
}

bool CivPgConn::deleteByField(StrQuote table, StrQuote filedName, StrQuote fieldValue)
{
    char delSql[256] = "delete from public.\"";
    strcat_s(delSql, table.c_str());
    strcat_s(delSql, "\" where   ");
    strcat_s(delSql, filedName.c_str());
    strcat_s(delSql, "='");
    strcat_s(delSql, fieldValue.c_str());
    strcat_s(delSql, "'");

    std::string utf8Sql = TransUTFCoding(delSql);

    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }
        

    return true;
}

bool CivPgConn::updateNodeByInterval(StrQuote currDate, StrQuote interval)
{
    std::stringstream os;
    NodeFieldName filedNames;

    os << "UPDATE  "
        << PIPENODE << "  AS  tb1 set ("
        << "总水头"<< ","
        << "压力"<< ","
        << "实际需水量"<<","
        <<"水质"
        << ")=( "
        << "tb2." << filedNames.dHead << ","
        << "tb2." << filedNames.dPressure << ","
        << "tb2." << filedNames.dDemand <<","
        << "tb2." << filedNames.dQuality << ")"
        << " from "
        << NODERESULTTABLE<< " AS tb2 where tb1."
        << filedNames.Number << "= tb2."
        <<filedNames.Number << " AND tb2."
        << filedNames.dDate<< "='" << currDate << "'  AND tb2."
        << filedNames.dInterval<< "=" << interval;

    std::string updateSql = os.str();
    os.clear();
    os.str("");

   std::string utfSql = TransUTFCoding(updateSql);
    if (!execSql(utfSql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    return true;
}

bool CivPgConn::updateLinkByInterval(StrQuote currDate, StrQuote interval)
{
    std::stringstream os;
    LinkFiledName filedNames;

    os << "UPDATE  "
        << PIPELINE<< "  AS  tb1 set ("
        << "流量"<< ","
        << "流速"<< ","
        << "单位水头损"<< ","
        << "水头总损失"<< ","
        << "摩擦水头损"<< ","
        << "上点水头"<< ","
        << "本点水头"<< ","
        << "局部水头损"<<","
        <<"水质"
        << ")=( "
        << "tb2." << filedNames.dFlow<< ","
        << "tb2." << filedNames.dVelocity<< ","
        << "tb2." << filedNames.dUnitHeadloss<< ","
        << "tb2." << filedNames.dHeadloss<< ","
        << "tb2." << filedNames.dFrictionHeadloss<< ","
        << "tb2." << filedNames.dFromNodHeadloss<< ","
        << "tb2." << filedNames.dToNodHeadloss<< ","
        << "tb2." << filedNames.dLocalHeadloss<<","
        <<" tb2."<< filedNames.dQuality<< ")" 
        << "  from "
        << PIPERESULTTABLE<< " AS tb2 where tb1."
        << filedNames.szNo<< "= tb2."
        << filedNames.szNo<< " AND tb2."
        << filedNames.dDate<< "='" << currDate << "'  AND tb2."
        << filedNames.dInterval<< "=" << interval;

    std::string updateSql = os.str();
    os.clear();
    os.str("");

    std::string utfSql = TransUTFCoding(updateSql);
    if (!execSql(utfSql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    return true;
}

bool CivPgConn::updateNode(const NodeResultItems& nodeItems)
{
    if (!isValid())
        return false;

    std::stringstream os;
    NodeFieldName filedNames;

    os << "INSERT INTO public." << NODERESULTTABLE << " ( ";
    os << filedNames.Number << ",";
    os << filedNames.dDemand << ",";
    os << filedNames.dHead << ",";
    os << filedNames.dElevation << ",";
    os << filedNames.dPressure << ",";
    os << filedNames.dTankLevel << ",";
    os << filedNames.dTankMaxVolume << ",";
    os << filedNames.dTankVolume << ",";
    os << filedNames.dDate << ",";
    os << filedNames.dInterval << ",";
    os << filedNames.dQuality << ",";
    os << filedNames.dModifyTime;
    os << ") VALUES";

    std::string preSql = os.str();
    os.flush();
    os.clear();
    os.str("");

    // 2, 参数值
    for (auto iter = nodeItems.begin(); iter != nodeItems.end(); iter++)
    {
        NodeResultItem item = iter->second;
        os << "('" << item.szNo << "',";
        os << item.dDemand << ",";
        os << item.dHead << ",";
        os << item.dElevation << ",";
        os << item.dPressure << ",";
        os << item.dTankLevel << ",";
        os << item.dTankMaxVolume << ",";
        os << item.dTankVolume << ",";
        os << "'" << CurrentDate << "',";
        os << item.dInterval << ",";
        os << item.dQuality << ",";
        os << "'" << CurrentTime << "'";

        auto subiter = iter;
        ++subiter;
        if (subiter == nodeItems.end())
        {
            os << ")";
        }
        else
        {
            os << "),";
        }
    }
    std::string sql = TransUTFCoding(preSql) + os.str();
    os.clear();
    os.str("");
    if (!execSql(sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }
    return true;
}

bool CivPgConn::updateLink(const LinkResultItems& lineItems)
{
    if (!isValid())
        return false;

    std::stringstream os;
    LinkFiledName filedNames;
    std::string currData = CurrentDate;

    os << "INSERT INTO public." << PIPERESULTTABLE << "( ";
    os << filedNames.szNo << ",";
    os << filedNames.dFlow << ",";
    os << filedNames.nFlowDirect << ",";
    os << filedNames.dVelocity << ",";
    os << filedNames.dHeadloss << ",";
    os << filedNames.dUnitHeadloss << ",";
    os << filedNames.dFromNodHeadloss << ",";
    os << filedNames.dToNodHeadloss << ",";
    os << filedNames.dLocalHeadloss << ",";
    os << filedNames.dFrictionHeadloss << ",";
    os << filedNames.szStatus << ",";
    os << filedNames.dDate << ",";
    os << filedNames.dInterval << ",";
    os << filedNames.dQuality << ",";
    os << filedNames.dModifyTime;
    os << ") VALUES";

    std::string preSql = os.str();
    os.clear();
    os.str("");

    // 2, 参数值
    for (auto iter = lineItems.begin(); iter != lineItems.end(); iter++)
    {
        LinkResultItem item = iter->second;
        os << "('" << item.szNo << "'" << ",";
        os << item.dFlow << ",";
        os << item.nFlowDirect << ",";
        os << item.dVelocity << ",";
        os << item.dHeadloss << ",";
        os << item.dUnitHeadloss << ",";
        os << item.dFromNodHeadloss << ",";
        os << item.dToNodHeadloss << ",";
        os << item.dLocalHeadloss << ",";
        os << item.dFrictionHeadloss << ",";
        os << "'" << TransUTFCoding(item.szStatus) << "'" << ",";
        os << "'" << CurrentDate << "',";
        os << item.dInterval << ",";
        os << item.dQuality << ",";
        os << "'" << CurrentTime << "'";

        auto subIte = iter;
        ++subIte;
        if (subIte == lineItems.end())
            os << ")";
        else
            os << "),";
    }
    std::string utf8Sql = TransUTFCoding(preSql);
    std::string sql = utf8Sql + os.str();

    os.clear();
    os.str("");

    if (!execSql(sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }
    return true;
}

bool CivPgConn::createTable(CivTableTemp& temp)
{
    if (&temp == NULL)
        return false;

    Str sql = temp.createSql();
    Str finalSql = TransUTFCoding(sql);

    return execSql(finalSql);
}

bool CivPgConn::open()
{
    if (mIsOpen)
        return true;

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

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

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))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }
    char* res = PQgetvalue(mResult, 0, 0);
    PQclear(mResult);
    int number = atoi(res);

    return number > 0 ? true : false;
}

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

    if (!isValid())
        open();
  
    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;
}

bool CivPgConn::getNode(CivNode& node)
{
    
    CivJunctionTableTemp::JunctionTable nodeTable;

    char sql[256] = "select ";
    strcat_s(sql, nodeTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, nodeTable.elev.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, nodeTable.demand.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, nodeTable.pattern.c_str());
    strcat_s(sql, " from public.\"");
    strcat_s(sql, PIPENODE.c_str());
    strcat_s(sql, "\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);

    for (int i = 0; i < rows; i++)
    {
        CivNode::NodeTable nodeTable;
        nodeTable.ID = PQgetvalue(mResult, i, 0);
        nodeTable.Elev = PQgetvalue(mResult, i, 1);
        nodeTable.Demand = PQgetvalue(mResult, i, 2);
        nodeTable.PatternId = PQgetvalue(mResult, i, 3);
        node.addItem(nodeTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getPipe(CivPipe& pipe)
{
    CivPipeTableTemp::PipeTable pipeTable;

    //;ID              	Node1           	Node2           	Length      	Diameter    	Roughness   	MinorLoss   	Status
    char sql[256] = "select ";
    strcat_s(sql, pipeTable.snNo.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.lastPoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.length.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.diameter.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.friction.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.localHeadLoss.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pipeTable.status.c_str());
    strcat_s(sql, " from  管段");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivPipe::PipesTable pipeTable;
        pipeTable.ID = PQgetvalue(mResult, i, 0);
        pipeTable.Node1 = PQgetvalue(mResult, i, 1);
        pipeTable.Node2 = PQgetvalue(mResult, i, 2);
        pipeTable.Length = PQgetvalue(mResult, i, 3);
        pipeTable.Diameter = PQgetvalue(mResult, i, 4);
        pipeTable.Roughness = PQgetvalue(mResult, i, 5);
        pipeTable.MinorLoss = PQgetvalue(mResult, i, 6);
        pipeTable.Status = PQgetvalue(mResult, i, 7);

        pipe.addItem(pipeTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getTank(CivTank& tank)
{
    CivTankTableTemp::TankTable tankTable;

    //;ID              	Elevation   	InitLevel   	MinLevel    	MaxLevel    	Diameter    	MinVol      	VolCurve
    char sql[512] = "select ";
    strcat_s(sql, tankTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.elev.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.initLevel.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.lowLevel.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.highLevel.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.diametor.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.capacity.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, tankTable.volCurve.c_str());
    strcat_s(sql, " from  public.\"");
    strcat_s(sql, TANK.c_str());
    strcat_s(sql, "\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivTank::TankTable tankTable;
        tankTable.ID= PQgetvalue(mResult, i, 0);
        tankTable.Elev = PQgetvalue(mResult, i, 1);
        tankTable.InitLevel= PQgetvalue(mResult, i, 2);
        tankTable.MinLevel= PQgetvalue(mResult, i, 3);
        tankTable.MaxLevel= PQgetvalue(mResult, i, 4);
        tankTable.Diameter= PQgetvalue(mResult, i, 5);
        tankTable.MinVol= PQgetvalue(mResult, i, 6);
        tankTable.VolCurve= PQgetvalue(mResult, i, 7);
     
        tank.addItem(tankTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getValve(CivValve& valve)
{

    CivValveTableTemp::ValveTable vaveTable;

    //;ID              	Node1           	Node2           	Length      	Diameter    	Roughness   	MinorLoss   	Status
    char sql[256] = "select ";
    strcat_s(sql, vaveTable.id.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.startPoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.endPoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.diameter.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.type.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.setting.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, vaveTable.loss.c_str());
    strcat_s(sql, " from  public.\"");
    strcat_s(sql, VALVE.c_str());
    strcat_s(sql, "\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivValve::ValveTable vaveTable;
        vaveTable.ID = PQgetvalue(mResult, i, 0);
        vaveTable.Node1 = PQgetvalue(mResult, i, 1);
        vaveTable.Node2 = PQgetvalue(mResult, i, 2);
        vaveTable.Diameter= PQgetvalue(mResult, i, 3);
        vaveTable.Type = PQgetvalue(mResult, i, 4);
        vaveTable.Setting = PQgetvalue(mResult, i, 5);
        vaveTable.MinorLoss = PQgetvalue(mResult, i, 6);
    
        valve.addItem(vaveTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getPumps(CivPumps& pump)
{

    CivPumpTableTemp::PumpTable pmTable;

    //;ID              	Node1           	Node2           	Length      	Diameter    	Roughness   	MinorLoss   	Status
    char sql[256] = "select ";
    strcat_s(sql, pmTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pmTable.startPoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pmTable.endPoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, pmTable.headCurve.c_str());
    strcat_s(sql, " from  public.\"");
    strcat_s(sql, PUMP.c_str());
    strcat_s(sql, "\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
       /* CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);*/
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivPumps::PumpTable pumpTable;
        pumpTable.ID = PQgetvalue(mResult, i, 0);
        pumpTable.Node1 = PQgetvalue(mResult, i, 1);
        pumpTable.Node2 = PQgetvalue(mResult, i, 2);
        pumpTable.Parameters = PQgetvalue(mResult, i, 3);
      
        pump.addItem(pumpTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getReservoirs(CivReservoirs& reservoirs)
{
    CivResourcesTableTemp::ResourcesTable restemTable;

    //;ID              	Head        	Pattern     
    char sql[512] = "select ";
    strcat_s(sql, restemTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, restemTable.head.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, restemTable.headPattern.c_str());
    strcat_s(sql, " from  public.\"");
    strcat_s(sql, RESIVOIR.c_str());
    strcat_s(sql,"\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivReservoirs::ReservoirsTable resTable;
        resTable.ID = PQgetvalue(mResult, i, 0);
        resTable.Head = PQgetvalue(mResult, i, 1);
        resTable.Pattern = PQgetvalue(mResult, i, 2);
     
        reservoirs.addItem(resTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getEmitters(CivEmitters& emitter)
{
    return true;
}

bool CivPgConn::getCoordinates(CivCoordinates& coord)
{
    CivJunctionTableTemp::JunctionTable nodeTable;

    char sql[512] = "select ";
    strcat_s(sql, TransUTFCoding(nodeTable.thePoint).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.xCoord).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.yCoord).c_str());
    strcat_s(sql, " from public.\"");
    strcat_s(sql, TransUTFCoding(PIPENODE).c_str());
    strcat_s(sql, "\"");

    strcat_s(sql, " UNION  select ");
    strcat_s(sql, TransUTFCoding(nodeTable.thePoint).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.xCoord).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.yCoord).c_str());
    strcat_s(sql, " from public.\"");
    strcat_s(sql, TransUTFCoding(TANK).c_str());
    strcat_s(sql, "\"");

    strcat_s(sql, " UNION  select ");
    strcat_s(sql, TransUTFCoding(nodeTable.thePoint).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.xCoord).c_str());
    strcat_s(sql, ",");
    strcat_s(sql, TransUTFCoding(nodeTable.yCoord).c_str());
    strcat_s(sql, " from public.\"");
    strcat_s(sql, TransUTFCoding(RESIVOIR).c_str());
    strcat_s(sql, "\"");

    if (!execSql(sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivCoordinates::CoordTable coordTable;
        coordTable.ID = PQgetvalue(mResult, i, 0);
        coordTable.XCoord = PQgetvalue(mResult, i, 1);
        coordTable.YCoord = PQgetvalue(mResult, i, 2);
        
        coord.addItem(coordTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getMixing(CivMixing& mixing)
{
    return true;
}

bool CivPgConn::getParameter(std::vector<CivParameter>& params)
{
    CivParametorTableTemp::ParametorTable restemTable;

    char sql[512] = "select ";
    strcat_s(sql, restemTable.name.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, restemTable.val.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, restemTable.type.c_str());
    strcat_s(sql, " from  public.\"__parameter__\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
 
    std::map<std::string, std::vector<CivParameter::ParamTable>> tempMap;
    CivParameter::ParamTable resTable;
    for (int i = 0; i < rows; i++)
    {
        CivParameter::ParamTable pTable;
        pTable.name = PQgetvalue(mResult, i, 0);
        pTable.val = PQgetvalue(mResult, i, 1);

        char* type = PQgetvalue(mResult, i, 2);
        tempMap[type].push_back(pTable);
    }
    // 遍历临时存储的数据拼接参数对象
    for (auto iter = tempMap.begin(); iter != tempMap.end(); iter++)
    {
        CivParameter param;
        std::string type = iter->first;
        std::vector<CivParameter::ParamTable> paramTables = iter->second;

        param.setType(type);

        int total = paramTables.size();
        for (int i = 0; i < total; i++)
            param.addItem(paramTables[i]);
       
        params.push_back(param);
    }
    PQclear(mResult);

    return true;
}

bool CivPgConn::getPatterns(CivPatterns& patterns)
{
    CivPatternTableTemp::PatternTable patternTable;

    char sql[512] = "select ";
    strcat_s(sql, patternTable.modelName.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, patternTable.modelData.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, patternTable.modelType.c_str());
    strcat_s(sql, " from  public.\"__pattern__\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
  
    for (int i = 0; i < rows; i++)
    {     
       char* name  = PQgetvalue(mResult, i, 0);
       char* val = PQgetvalue(mResult, i, 1);
      
       CivPatterns::PatternTable pTable;
       pTable.name = name;
       pTable.val = val;

       patterns.addItem(pTable);
    }

    PQclear(mResult);

    return true;
}

bool CivPgConn::getCurves(CivCurves& curves)
{
    CivCurveTableTemp::CurveTable curveTable;

    char sql[512] = "select ";
    strcat_s(sql, curveTable.CurveName.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, curveTable.CurveType.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, curveTable.CurveData.c_str());
    strcat_s(sql, " from  public.\"__curve__\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivCurves::CurvesTable cTable;
        cTable.ID = PQgetvalue(mResult, i, 0);
        cTable.XCoord = PQgetvalue(mResult, i, 1);
        cTable.YCoord =  PQgetvalue(mResult, i,2);
        curves.addItem(cTable);
    }
    PQclear(mResult);
    return true;
}   

bool CivPgConn::getDemands(CivDemands& demands)
{
    return true;
}

bool CivPgConn::getSources(CivSources& sources)
{
    return true;
}

bool CivPgConn::getStatus(CivStatus& status)
{
    return true;
}

bool CivPgConn::getQuality(CivQuality& quality)
{
    CivJunctionTableTemp::JunctionTable nodeTable;

    char sql[256] = "select ";
    strcat_s(sql, nodeTable.thePoint.c_str());
    strcat_s(sql, ",");
    strcat_s(sql, nodeTable.initQuality.c_str());
    strcat_s(sql, " from ");
    strcat_s(sql, PIPENODE.c_str());

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);
    for (int i = 0; i < rows; i++)
    {
        CivQuality::QualityTable quliTable;
        quliTable.ID = PQgetvalue(mResult, i, 0);
        quliTable.InitQuality = PQgetvalue(mResult, i, 1);
   
        quality.addItem(quliTable);
    }
    PQclear(mResult);
    return true;
}

bool CivPgConn::getLabels(CivLabels& labels)
{
    return true;
}

bool CivPgConn::getTags(CivTags& tags)
{
    return true;
}

bool CivPgConn::getFieldValueFromTable(
    const std::string& table,
    const std::vector<std::string>& fileds, 
    std::vector< std::vector<std::string>>& result)
{
    std::string sql;
    sql.append("select ");

    size_t total = fileds.size();
    for (int i = 0; i < total; i++)
    {
        sql.append(fileds[i]);

        if (i < (total - 1))
            sql.append(",");      
    }
    sql.append(" from public.\"");
    sql.append(table);
    sql.append("\"");

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);

    for (int i = 0; i < rows; i++)
    {
        std::vector<std::string> vecRes;
        for (int j = 0; j < columns; j++)
        {
            std::string res  = PQgetvalue(mResult, i, j);
            vecRes.push_back(res);
        }  
        result.push_back(vecRes);
    }

    PQclear(mResult);

    return true;
}

bool CivPgConn::getValuesFromTableByCondition(
    const std::string& table,
    const std::string& condition,
    const std::vector<std::string>& fileds,
    std::vector< std::map<std::string,std::string>>& result)
{

    std::string sql;
    sql.append("select ");

    size_t total = fileds.size();
    for (int i = 0; i < total; i++)
    {
        sql.append(fileds[i]);
        sql.append(",");      
    }
    sql = sql.substr(0, sql.length() - 1);
    sql.append(" from public.\"");
    sql.append(table);
    sql.append("\"  where ");
    sql.append(condition);

    std::string utf8Sql = TransUTFCoding(sql);
    if (!execSql(utf8Sql))
    {
        CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
        return false;
    }

    int rows = PQntuples(mResult);
    int columns = PQnfields(mResult);

    for (int i = 0; i < rows; i++)
    {
        std::map<std::string, std::string> tempMap;
        for (int j = 0; j < columns; j++)
        {
            std::string res = PQgetvalue(mResult, i, j);
            std::string filedName = UTFTransCoding(PQfname(mResult, j));

            tempMap.insert(std::pair<std::string, std::string>(filedName,res));   
        }
        result.push_back(tempMap);
    }
    PQclear(mResult);

    return true;
}

void  CivPgConn::checkHyDrNetTable()
{
    // 创建曲线表
    CivCurveTableTemp temp;
    if (!tableExist(temp.name()))
    {
        createTable(temp);
    }

    // 参数表
    CivParametorTableTemp paraTemp;
    if (!tableExist(paraTemp.name()))
    {
        createTable(paraTemp);
    }

    // 模式表
    CivPatternTableTemp patternTemp;
    if (!tableExist(patternTemp.name()))
    {
        createTable(patternTemp);
    }

    // 结果点表
    CivNodeResultTableTemp nodeTemp;
    if (!tableExist(nodeTemp.name()))
    {
        createTable(nodeTemp);
    }

    // 结果线表
    CivPipeResultTableTemp pipeTemp;
    if (!tableExist(pipeTemp.name()))
    {
        createTable(pipeTemp);
    }
}

