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


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

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

bool CivPgConn::deleteByField(StrQuote table, StrQuote filedName, StrQuote fieldValue)
{
    if (!isValid())
        return false;

    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)
{
    if (!isValid())
        return false;

    std::stringstream os;
    NodeFieldName filedNames;

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

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

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

    return true;
}

bool CivPgConn::updateLinkByInterval(StrQuote currDate, StrQuote interval)
{
    if (!isValid())
        return false;

    std::stringstream os;
    LinkFiledName filedNames;

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

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

    if (!execSql(updateSql))
    {
        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()
{
    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 (!open())
        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;
}

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);
    int columns = PQnfields(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);
    int columns = PQnfields(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);
    int columns = PQnfields(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);
    int columns = PQnfields(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);
    int columns = PQnfields(mResult);
    std::map<std::string, std::vector<std::string>> typeMap;
    for (int i = 0; i < rows; i++)
    {     
       char* name  = PQgetvalue(mResult, i, 0);
       char* val = PQgetvalue(mResult, i, 1);
       char* type = PQgetvalue(mResult, i, 2);

       typeMap[type].push_back(name);
       typeMap[type].push_back(val);
    }
   
    for (auto iter = typeMap.begin(); iter != typeMap.end(); iter++)
    {
        CivPatterns::PatternTable pTable;
        pTable.name = iter->first;
        
        std::vector<std::string> valVec = iter->second;
        int total = valVec.size();
        // 拼接字符串
        char value[512] = "";
        for (int i = 0; i < total; i++)
        {
            strcat_s(value, valVec[i].c_str());
            strcat_s(value, "  ");
        }
        pTable.val = value;

        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);
    int columns = PQnfields(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 节点");

    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;
}