#include "sql.h"
#include <libpq-fe.h>
#include <Text.h>
#include <iostream>

using namespace sql;
using namespace Framework;

// Inhalt ves structs Result aus sql.h
void Result::destroy()
{
	delete[]felder;
	delete[]values;
}

// Inhalt der Datenbank Klasse aus sql.h
// Konstruktor 
Datenbank::Datenbank( const char *user, const char *passwort, const char *dbname, const char *ip, unsigned short port )
{
	Text *txt = new Text( "user=" );
	txt->append( user );
	txt->append( " password=" );
	txt->append( passwort );
	txt->append( " dbname=" );
	txt->append( dbname );
	txt->append( " hostaddr=" );
	txt->append( ip );
	txt->append( " port=" );
	txt->append( port );
	conn = PQconnectdb( txt->getText() );
	txt->release();
	res = 0;
	ref = 1;
	if( PQstatus( conn ) != CONNECTION_OK )
	{
		PQfinish( conn );
		conn = 0;
	}
	else
		PQsetClientEncoding( conn, "WIN1251" );
}

// Destruktor 
Datenbank::~Datenbank()
{
	PQfinish( conn );
}

// nicht constant 
bool Datenbank::befehl( const char *txt )
{
	if( res )
		PQclear( res );
	res = PQexec( conn, txt );
	ExecStatusType t = PQresultStatus( res );
	if( t == PGRES_FATAL_ERROR || t == PGRES_BAD_RESPONSE || t == PGRES_NONFATAL_ERROR )
	{
		std::cout << "Datenbank Error bei Query '" << txt << ";'\n" << PQerrorMessage( conn ) << "\n";
		return 0;
	}
	return 1;
}

// constant
int Datenbank::getZeilenAnzahl() const // Anzahl der betroffenen zeilen
{
	if( res )
		return TextZuInt( PQcmdTuples( res ), 10 );
	return 0;
}

Result Datenbank::getResult() const
{
	Result ret;
	ret.feldAnzahl = PQnfields( res );
	ret.felder = new Text[ ret.feldAnzahl ];
	for( int i = 0; i < ret.feldAnzahl; i++ )
		ret.felder[ i ].setText( PQfname( res, i ) );
	ret.zeilenAnzahl = PQntuples( res );
	ret.values = new Text[ ret.feldAnzahl * ret.zeilenAnzahl ];
	for( int i = 0; i < ret.feldAnzahl * ret.zeilenAnzahl; i++ )
		ret.values[ i ].setText( PQgetvalue( res, i / ret.feldAnzahl, i % ret.feldAnzahl ) );
	return ret;
}

Text *Datenbank::getLetzterFehler() const // gibt den letzten Fehler zurück
{
	Text *ret = new Text( PQerrorMessage( conn ) );
	return ret;
}

bool Datenbank::istOk() const // prüft, ob die Verbindung zur Datenbank besteht
{
	return conn != 0;
}

// Reference Counting 
Datenbank *Datenbank::getThis()
{
	ref++;
	return this;
}

Datenbank *Datenbank::release()
{
	ref--;
	if( ref == 0 )
		delete this;
	return 0;
}