#ifndef FBCMetaData__H
#define FBCMetaData__H

#ifndef FBVersion
#define FBVersion 7
#elif FBVersion != 7
#error "The headers for FBCAccess version have been mixed"
#endif

#include "FBCDatatypeMetaData.h"
#include "FBCBlobHandle.h"
#include "FBCColumnMetaData.h"
#include "FBCErrorMetaData.h"
#include "FBCRow.h"
#include "FBCTimeZones.h"

typedef struct FBCMetaData FBCMetaData;

#ifdef __cplusplus
extern "C" {
#endif

char* fbcmdCatalogName(const FBCMetaData* self);

/*!
@function fbcmdMessage
 @discussion A special message area which is sometimes used by the server to return results which don't fit within the normal SQL result set scheme.  For instance, after executing an extract statement, the meta data message will contain a property list describing the result.
 @result The returned string should not be freed by the caller.
 */
char* fbcmdMessage(const FBCMetaData* self);

/*!
@function fbcmdExecutionTime
 @discussion The server execution time for the previous operation.  Please note that the server can choose to evaluate some statements lazily, so deriving the total time required for a given statement can involve the timing the fetch stage.
 @result The returned string should not be freed by the caller.
 */
char* fbcmdExecutionTime(const FBCMetaData* self);

double fbcmdElapsed ( const FBCMetaData* self );
double fbcmdWait ( const FBCMetaData* self );


/*!
@function fbcmdFetchHandle
 @discussion The fetch handle associated with the previous query.  This should be passed to fbcdcFetch().
 @result The returned string should not be freed by the caller.
 */
//char* fbcmdFetchHandle(const FBCMetaData* self);

/*!
@function fbcmdTimeZone
 @discussion The time zone associated with the previous operation.
 @result The returned string should not be freed by the caller.
 */
const char*  fbcmdTimeZone    (const FBCMetaData* self);
FBCTimeZone* fbcmdTZ          (const FBCMetaData* self);

int    fbcmdIsValidTime   ( double time );
double fbcmdAsciiToTime   ( const FBCMetaData* self, const char* ascii);
char*  fbcmdTimeToAscii   ( const FBCMetaData* self, double time, unsigned int precision, char* buffer, unsigned int length );
double fbcmdAsciiToTimeTZ ( const FBCMetaData* self, const char* ascii,  int * gmtOffset );
char*  fbcmdTimeToAsciiTZ ( const FBCMetaData* self, double time, unsigned int precision, int gmtOffset, char* buffer, unsigned int length );
   
const char* fbcmdStatementHandle(const FBCMetaData* self);

const char* fbcmdFetchHandle(const FBCMetaData* self);

/*!
@function fbcmdStatementType
 @discussion The type of SQL statement for the previous block of executed SQL, such as SELECT, UPDATE, DELETE, etc.
 @result The returned string should not be freed by the caller.
 */
const char* fbcmdStatementType(const FBCMetaData* self);

/*!
@function fbcmdErrorClass
 @discussion The class of error for the previous operation.  Assumes that the previous operation failed.
 @result The returned string should not be freed by the caller.
 */
const char* fbcmdErrorClass(const FBCMetaData* self);

FBCBlobHandle* fbcmdBlobHandle(const FBCMetaData* self);

/*!
@function fbcmdErrorsFound
 @discussion Returns True if errors were found during the execution of an SQL statement.
 */
int fbcmdErrorsFound(const FBCMetaData* self);

/*!
@function fbcmdWarningsFound
 @discussion Returns True if warnings were found during the execution of an SQL statement.
 */
int fbcmdWarningsFound(const FBCMetaData* self);

/*!
 @function fbcmdHasRowCount
 @discussion Returns True if the fbcmdRowCount is valid.
 */
int fbcmdHasRowCount(const FBCMetaData* self);

/*!
@function fbcmdRowCount
 @discussion Returns the number of rows fetched by the previous SQL statement.
 */
unsigned long long fbcmdRowCount(const FBCMetaData* self);

extern unsigned long long FBCNilRowIndex;

/*!
@function fbcmdRowIndex
 @discussion Returns the row index of the row just inserted.  This is only valid if the statement executed was an INSERT statement inserting a single row.
 */
unsigned long long fbcmdRowIndex(const FBCMetaData* self);

/*!
@function fbcmdColumnCount
 @discussion Returns the number of columns fetched by the executed SQL statement.
 */
unsigned fbcmdColumnCount(const FBCMetaData* self);

unsigned fbcmdIndexCount(const FBCMetaData* self);

/*!
@function fbcmdErrorCount
 @discussion Returns the number of errors found during execution of an SQL statement.
 */
unsigned fbcmdErrorCount(const FBCMetaData* self);

FBCErrorMetaData* fbcmdErrorMetaData ( FBCMetaData* meta);

/*!
@function fbcmdPlanInfo
 @discussion Returns the query plan information string (NULL if none is available).
 @result The returned string should not be freed by the caller.
 */
const char* fbcmdPlanInfo(const FBCMetaData* self);

unsigned int fbcmdBatchSize(const FBCMetaData* self);

unsigned fbcmdUniqueKey(const FBCMetaData* self);

extern unsigned long long FBCNoVersion;
       unsigned long long fbcmdTransactionVersion(const FBCMetaData* self);

const char* fbcmdVersion ( const FBCMetaData* self );

const char* fbcmdACID ( const FBCMetaData* self );

const char* fbcmdTransactionDescription (const FBCMetaData* self);

/*!
@function fbcmdColumnMetaDataAtIndex
 @discussion Returns the column meta data for the column at the specified index.
 @result The returned FBCColumnMetaData should not be released by the caller.
 */
const FBCColumnMetaData* fbcmdColumnMetaDataAtIndex ( const FBCMetaData* self, unsigned index);

/*!
@function fbcmdDatatypeMetaDataAtIndex
 @discussion Returns the data type meta data for the column at the specified index.
 @result The returned FBCDatatypeMetaData should not be released by the caller.
 */
const FBCDatatypeMetaData* fbcmdDatatypeMetaDataAtIndex(const FBCMetaData* self, unsigned index);

/*!
@function fbcmdTakeFetchMetaDataFrom
 @discussion Internal API.  Not intended for public use.
 */
void fbcmdTakeFetchMetaDataFrom( FBCMetaData* self, FBCMetaData* fetchMetaData);

/*!
@function fbcmdDescription
 @discussion Debugging description of the meta data object.
 @result The returned string should be freed by the caller with fbcmdFreeDescription
 */
char* fbcmdDescription( const FBCMetaData* self);
void  fbcmdFreeDescription (char* description);
/*!
@function fbcmdHasMetaDataArray
 @discussion Returns True if there are multiple meta data objects associated with the previous operation (indicating multiple result sets).  See fbcmdMetaDataAtIndex() for more information.
 */
int fbcmdHasMetaDataArray(const FBCMetaData* self);

/*!
@function fbcmdMetaDataArrayCount
 @discussion Returns the number of meta data objects associated with the previous operation.
 */
unsigned fbcmdMetaDataArrayCount(const FBCMetaData* self);

/*!
@function fbcmdMetaDataAtIndex
 @discussion Returns the meta data object at the given index for the previous operation.  Some operations can return multiple result sets, each of which are accessible by a single meta data.  For instance, executing the SQL, "select * from t0; select * from t1;", will return two result sets.  The result sets need not be similar.
 */
FBCMetaData* fbcmdMetaDataAtIndex(const FBCMetaData* self, unsigned indx);

/*!
@function fbcmdAllRowsFetched
 @discussion Returns a boolean value telling whether all rows of the associated result set has been fetched. The flag is set based on the meta data associated with calls to fbcdcExecuteDirectSQLWithFetch and fbcdcFetch. This is a good way to avoid another call to fbcdcFetch (and fbcdcCancelFetch) just to detect that there are no more rows.
 */
 
int fbcmdAllRowsFetched(const FBCMetaData* self);

int fbcmdAnyRows(const FBCMetaData* self);

FBCMetaData* fbcmdCancelFetch ( FBCMetaData* self );
FBCRow*      fbcmdFetchRow    ( FBCMetaData* self );

FBCMetaData* fbcmdRetain  ( FBCMetaData* self );
void         fbcmdRelease ( FBCMetaData* self );

unsigned long long fbcmdFetchedRows ( FBCMetaData* self );

int                fbcmdHasRowIndexes     ( const FBCMetaData* self );
unsigned           fbcmdRowIndexCount     ( const FBCMetaData* self );
unsigned long long fbcmdRowIndexForColumn ( FBCMetaData* self, FBCRow*  row, unsigned int column );

/*!
 @function fbcmdConnected
 @discussion  Return 1 if the metadata is a result of a request 
              to  valid database connection, otherwise 0 is returned.
 */

int fbcmdConnected ( FBCMetaData* self );

void fbcmdSetFormatResult ( FBCMetaData* self, int flag);
int  fbcmdFormatResult    ( FBCMetaData* self);


/* 
 @function fbcmdConnected
 @discussion Returns the number of clients currently connected to the server
 
 @function fbcmdServerBusyConnectionCount
 @discussion Returns the number of clients currently connected to the server which are busy, ie. executing sql

 @function fbcmdServerBlockedConnectionCount
 @discussion Returns the number of clients currently connected to the server which are busy, but are blocked due
             transaction ependencies.
*/

unsigned fbcmdTransactions        ( FBCMetaData* self );
unsigned fbcmdBusyTransactions    ( FBCMetaData* self );
unsigned fbcmdBlockedTransactions ( FBCMetaData* self );

#ifdef __cplusplus
}
#endif

#endif /* FBCMetaData__H */
