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

#define DLLEXPORT __declspec(dllexport)

// 字段过滤
#define FiledFilter std::map<Str,std::set<Str>>
class CivDbConnection;

/**
  数据库连接类，获取数据，写入数据接口
*/
class DLLEXPORT  CivDbConnection
{
public:
	// 表类型
	enum TableType
	{
		NODE_TABLE, // 计算结果点表
		PIPE_TABLE, // 计算结果线表
		PATTERN_TABLE, // 模式表
		CURVE_TABLE
	};

	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(StrQuote tableName, StrQuote schema, TableType tableType);

	/**
	*@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(PGresult* result, Componets& comp);

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

	char* mLastError;

	char mLinkParam[256];
	char mNodeParam[256];

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