#include "PgIndexContainer.h"
#include "PgClassContainer.h"
#include "PgDatabaseCatalog.h"
#include "Pgsql_Col.h"
#include <iterator>

std::string PgIndexContainer::getLoadQuery() const
{
	std::string q =  R"__(
SELECT indexrelid, indrelid, indnatts, indisunique, indisprimary,
	indisexclusion, indimmediate, indisclustered, indisvalid,
	indcheckxmin, indisready, indislive, indkey,
	indcollation, indclass, indoption, indexprs, indpred,
    pg_get_indexdef(indexrelid), pg_total_relation_size(indexrelid))__";

	if (minimumVersion(90400))
		q += ", indisreplident ";
	q += "\nFROM pg_index";
	return q;
}

PgIndex PgIndexContainer::loadElem(const Pgsql::Row &row)
{
	Pgsql::Col col(row);
	Oid indexrelid = col.nextValue();
	auto&& cls = m_catalog.classes()->getByKey(indexrelid);
	auto&& name = cls->objectName();
	auto&& nsoid = cls->nsOid();

	PgIndex v(m_catalog, indexrelid, name, nsoid);
	col >> v.relid >> v.natts >> v.isunique
		>> v.isprimary >> v.isexclusion >> v.immediate >> v.isclustered
		>> v.isvalid >> v.checkxmin >> v.isready >> v.islive;
	col.getAsVector<int16_t>(std::back_inserter(v.key));
	col.getAsVector<Oid>(std::back_inserter(v.collation));
	col.getAsVector<Oid>(std::back_inserter(v.indclass));
	col.getAsVector<int16_t>(std::back_inserter(v.option));
    col >> v.exprs >> v.pred >> v.definition >> v.sizeBytes;
	if (minimumVersion(90400))
		col >> v.isreplident;

	return v;
}

std::vector<PgIndex> PgIndexContainer::getIndexesForTable(Oid table_oid) const
{
	std::vector<PgIndex> result;
	for (const auto &e : m_container)
		if (e.relid == table_oid)
			result.push_back(e);

	return result;
}
