/**
 * save record to database
 */
void IpfixDbWriter::processDataDataRecord(const IpfixRecord::SourceID& sourceID, 
		TemplateInfo& dataTemplateInfo, uint16_t length, 
		IpfixRecord::Data* data)
{
	string rowString;
	time_t flowStartSeconds;

	DPRINTF("Processing data record");

	if (dbError) {
		connectToDB();
		if (dbError) return;
	}

	/* get new insert */
	if(srcId.observationDomainId != 0) {
		// use default source id
		rowString = getInsertString(rowString, flowStartSeconds, srcId, dataTemplateInfo, length, data);
	} else {
		rowString = getInsertString(rowString, flowStartSeconds, sourceID, dataTemplateInfo, length, data);
	}

	// if current table is not ok, write to db and get new table name
	if(!(flowStartSeconds >= currentTable.startTime && flowStartSeconds <= currentTable.endTime)) {
		if(numberOfInserts > 0) {
			msg(MSG_DEBUG, "IpfixDbWriter: Writing buffered records to database");
			writeToDb();
			numberOfInserts = 0;
		}
		if (setCurrentTable(flowStartSeconds) != 0) {
			return;	
		}	
	}


	// start new insert statement if necessary
	if (numberOfInserts == 0) {
		// start insert statement
		insertStatement.str("");
		insertStatement.clear();
		insertStatement << "INSERT INTO " << currentTable.name << " (" << tableColumnsString << ") VALUES " << rowString;
		numberOfInserts = 1;
	} else {
		// append insert statement
		insertStatement << "," << rowString;
		numberOfInserts++;
	}

	// write to db if maxInserts is reached
	if(numberOfInserts == maxInserts) {
		msg(MSG_DEBUG, "IpfixDbWriter: Writing buffered records to database");
		writeToDb();
		numberOfInserts = 0;
	}
}
/**
 * save given elements of record to database
 */
void IpfixDbWriter::processDataDataRecord(IpfixRecord::SourceID* sourceID,
        IpfixRecord::DataTemplateInfo* dataTemplateInfo, uint16_t length,
        IpfixRecord::Data* data)
{
    DPRINTF("Processing data record");

    /** check if statement buffer is not full*/
    if(statements.statemBuffer[statements.maxStatements-1][0] != '\0') {
        THROWEXCEPTION("IpfixDbWriter: Statement buffer is full, this should never happen - drop record");
    }

    /** sourceid null ? use default*/
    /* overwrite sourceid if defined */
    if(srcId.observationDomainId != 0 || sourceID == NULL) {
        sourceID = &srcId;
    }

    /** if statement counter lower as  max count, insert record in statement buffer*/
    if (statements.statemReceived < statements.maxStatements) {
        /** make an sql insert statement from the record data */
        statements.statemBuffer[statements.statemReceived] = getInsertStatement(
                    statements.statemBuffer[statements.statemReceived],
                    sourceID, dataTemplateInfo, length, data, statements.lockTables, statements.maxLocks);
        DPRINTF("Insert statement: %s\n", statements.statemBuffer[statements.statemReceived]);
        /** statemBuffer is filled ->  insert in table*/
        if(statements.statemReceived == statements.maxStatements-1) {
            msg(MSG_INFO, "Writing buffered records to database");
            writeToDb();
        }
        else {
            statements.statemReceived++;
            msg(MSG_DEBUG, "Buffering record. Need %i more records before writing to database.", statements.maxStatements - statements.statemReceived);
        }
    }
}
/**
 * Frees memory used by an ipfixDbWriter
 * @param ipfixDbWriter handle obtained by calling @c createipfixDbWriter()
 */
IpfixDbWriter::~IpfixDbWriter()
{
    int i;

    writeToDb();
    mysql_close(conn);

    for(i=0; i<statements.statemReceived; i++)
        free(statements.statemBuffer[i]);

    free(statements.statemBuffer);
    free(statements.lockTables);
}
/**
 * save record to database
 */
void IpfixDbWriterMongo::processDataDataRecord(const IpfixRecord::SourceID& sourceID,
		TemplateInfo& dataTemplateInfo, uint16_t length,
		IpfixRecord::Data* data)
{
  mongo::BSONObj obj;
	msg(MSG_DEBUG, "IpfixDbWriter: Processing data record");

	if (dbError) {
		msg(MSG_DEBUG, "IpfixDbWriter: reconnecting to DB");
		connectToDB();
		if (dbError) return;
	}

	/* get new insert */
	if(srcId.observationDomainId != 0) {
		// use default source id
		obj = getInsertObj(srcId, dataTemplateInfo, length, data);
	} else {
		obj = getInsertObj(sourceID, dataTemplateInfo, length, data);
	}


	// start new insert statement if necessary
	if (numberOfInserts == 0) {
		// start insert statement
		bufferedObjects.clear();
    bufferedObjects.push_back(obj);
		numberOfInserts = 1;
	} else {
		// append object
    bufferedObjects.push_back(obj);
		numberOfInserts++;
	}

	// write to db if maxInserts is reached
	if(numberOfInserts == maxInserts) {
		msg(MSG_DEBUG, "IpfixDbWriter: Writing buffered records to database");
		writeToDb();
		numberOfInserts = 0;
	}
}
/**
*	function receive the DataRecord or DataDataRecord when callback is started
*/
int  writeDataDataRecord(void* ipfixDbWriter_, SourceID* sourceID, DataTemplateInfo* dataTemplateInfo, uint16_t length, FieldData* data)
{
        IpfixDbWriter *ipfixDbWriter = (IpfixDbWriter*)ipfixDbWriter_;
	Table *tabl = ipfixDbWriter->table;
	Statement* statemen = tabl->statement;

	DPRINTF("Processing data record\n");

	/** if the writeToDb process not ready - drop record*/
	if(statemen->statemBuffer[statemen->maxStatements-1] != NULL) {
		msg(MSG_ERROR,"IpfixDbWriter: Statement buffer is full, writing to DB in progress? - drop record");
		return 1;
	}
	
	/** sourceid null ? use default*/
	/* overwrite sourceid if defined */
	if(ipfixDbWriter->srcId.observationDomainId != 0 || sourceID == NULL) {
		sourceID = &ipfixDbWriter->srcId;
	}

	/** make a sql insert statement from the recors data */
	char* insertTableStr = getRecData(ipfixDbWriter, tabl, sourceID,
					  dataTemplateInfo, length, data);
	DPRINTF("Insert statement: %s\n",insertTableStr);	
	
	/** if statement counter lower as  max count of statement then insert record in statemenBuffer*/
	if(statemen->statemReceived < statemen->maxStatements) {	
		statemen->statemBuffer[statemen->statemReceived] = insertTableStr;
		/** statemBuffer is filled ->  insert in table*/	
		if(statemen->statemReceived == statemen->maxStatements-1) {
                        msg(MSG_INFO, "Writing buffered records to database");
			writeToDb(ipfixDbWriter, tabl, statemen);
		} else {
                        msg(MSG_INFO, "Buffering record. Need %i more records before writing to database.", statemen->maxStatements - statemen->statemReceived);
			statemen->statemReceived++;
		}
	}
	return 0;
}
/**
 * Destructor
 */
IpfixDbWriterMongo::~IpfixDbWriterMongo()
{
	writeToDb();
}
/**
 * Destructor
 */
IpfixDbWriter::~IpfixDbWriter()
{
	writeToDb();
	mysql_close(conn);
}