#include "PgTriggerContainer.h"
#include "Pgsql_Connection.h"
#include "Pgsql_Col.h"
#include <algorithm>
#include <iterator>

std::string PgTriggerContainer::getLoadQuery() const
{
	std::string q =
		"SELECT oid, tgname, tgrelid, tgfoid, tgtype, tgenabled, tgisinternal, tgconstrrelid, \n"
		"		tgconstrindid, tgconstraint, tgdeferrable, tginitdeferred, tgnargs, tgattr, \n"
        "       tgargs, COALESCE(substring(pg_get_triggerdef(oid), 'WHEN \\(\\((.*)\\)\\) EXECUTE PROCEDURE'), "
        "             substring(pg_get_triggerdef(oid), 'WHEN \\(\\((.*)\\)\\) EXECUTE FUNCTION'),"
        "             substring(pg_get_triggerdef(oid), 'WHEN \\(\\((.*)\\)\\)  \\$trigger')) AS whenclause";
	if (minimumVersion(100000)) {
		q += ", tgoldtable, tgnewtable";
	}
	q +=
		"  FROM pg_trigger \n"
		"  WHERE NOT tgisinternal";
	return q;
}

PgTrigger PgTriggerContainer::loadElem(const Pgsql::Row &row)
{

	Pgsql::Col col(row);
	Oid oid = col.nextValue();
	QString name = col.nextValue();
	PgTrigger v(m_catalog, oid, name, InvalidOid);
	col >> v.relid >> v.foid >> v.type >> v.enabled >> v.isinternal >> v.constrrelid
			>> v.constrindid >> v.constraint >> v.deferrable >> v.initdeferred >> v.nargs >> v.attr;
	const unsigned char * args_bytea = reinterpret_cast<const unsigned char *>(col.nextValue().c_str());
	if (args_bytea) {
		size_t to_length;
		unsigned char *result = PQunescapeBytea(args_bytea, &to_length);
		if (result) {
			v.args = QString::fromUtf8(reinterpret_cast<const char*>(result), static_cast<int>(to_length));
			PQfreemem(result);
		}
	}
	col >> v.whenclause;
	if (minimumVersion(100000)) {
		col >> v.oldtable >> v.newtable;
	}
	return v;
}


std::vector<PgTrigger> PgTriggerContainer::getTriggersForRelation(Oid cls) const
{
	std::vector<PgTrigger> result;
	for (auto e : m_container)
		if (e.relid == cls)
			result.push_back(e);

	return result;
}
