#pragma once
#include "CivTypes.h"
#include <vector>
#include <set>
#include <libpq-fe.h>
#include "CivTableTemp.h"
#include "CivSysLog.h"

#define DLLEXPORT __declspec(dllexport)

class CivDbConnection;

/**
  数据库连接类，获取数据，写入数据接口
*/
class DLLEXPORT  CivDbConnection
{
public:
	CivDbConnection(char* uri);
	~CivDbConnection();

	/**
	 *@brief 获取管网的所有表
	 *@netName: 管网名
	 */
	Tables getTables(StrQuote netName, StrQuote schema = "public");

	/**
	 *@brief 获取管网组件数据：管线，节点，水源等（必须组件）
	 *@tableName： 组件表
	 */
	Componets getComponets(StrQuote tableName);

	Componets getComponetsByWhere(StrQuote tableName, StrQuote where);

	/**
	 *@brief  水泵，阀门 (节点转换为管线)
	 *@tableName： 组件表
	 */
	Componets getLikelyPipes(StrQuote tableName);

	bool tableExist(StrQuote tableName);

	/**
	 *@brief 创建表格
	 *@tableName: 表名
	 *@schema: 
	 *@tableType：表类型，点结果，线结果
	 */
	bool createTable(CivTableTemp& temp);

	bool deleteByDate(StrQuote table, StrQuote filedName, StrQuote fieldValue);

	bool updateNodeByInterval(StrQuote currDate, StrQuote interval);

	bool updateLinkByInterval(StrQuote currDate, StrQuote interval);

	/**
	*@brief 刷新模拟的水质字段值
	*@quality: 水质
	*@currDate: 模拟的日期
	*@StrQuote: 模拟的次数
	*/
	bool updateNodeQuality(const NodeResultItems& nodeItems);
	bool updatePipeQuality(const LinkResultItems& lineItems);
	/**
	 *@brief 更新点表数据
	 *@nodeItems：需要更新的值
	 */
	bool updateNode(const NodeResultItems& nodeItems);

	/**
	 *@brief 更新线表的数据
	 *@lineItems: 线数据
	 */
	bool updateLink(const LinkResultItems& lineItems);

	bool open();
	void close();

	void addFilter(Str type, Str number);

	FiledFilter getFilter() const;

private:
	bool isValid() const;

	/**
	 *@brief 查询与点连接的线
	 *@table: 线表
	 *@code:
	 */
	Componets getLineByCode(StrQuote table, StrQuote code);

	Componets getNodeByCode(StrQuote table, StrQuote code);

	/**
	 *@brief 执行sql语句
	 *@sql: 需要执行的sql语句
	 */
	bool execSql(std::string sql);

	void clearResult();

	/**
	 *@brief 从查询集取出数据
	 *@result: 查询结果集
	 *@comp: 数据容器
	 */
	void getData( Componets& comp);

private:
	PGconn* mConn;
	PGresult* mResult;
	bool mIsOpen = false;
	char* mUri;

	char* mLastError;
	FiledFilter mFilter; // 表名:对应的编号
};