#include "CivDbConn.h"
#include "CivCommonUtils.h"
#include <sstream>

CivDbConn::CivDbConn()
{
}

CivDbConn::~CivDbConn()
{
}

bool CivDbConn::isValid() const
{
    return mIsOpen;
}

Str CivDbConn::getLastError() const
{
    return mLastError;
}

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

    char delSql[256] = "delete from \"";
    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))
        return false;

    return true;
}

bool CivDbConn::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))
        return false;

    return true;
}

bool CivDbConn::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))
        return false;

    return true;
}

bool CivDbConn::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))
        return false;


    return true;
}

bool CivDbConn::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))
        return false;

    return true;
}

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

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

    return execSql(finalSql);
}
