/*---------------------------------------------------------------
	FILE: CSimpleDatabase.h
	USE: See DOXYGEN doc.

   Part of the MRPT Library
   ISA - Universidad de Malaga - http://www.isa.uma.es
  ---------------------------------------------------------------*/
#ifndef CSimpleDatabase_H
#define CSimpleDatabase_H

#include <MRPT/UTILS/utils_defs.h>
#include <MRPT/UTILS/CSerializable.h>

namespace UTILS
{

	/**  This class implements the tables of databases.
	 * \sa CSimpleDatabase
	 */
	class CSimpleDatabaseTable : public CSerializable
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CSimpleDatabaseTable )
	public:
		/** Default constructor
		  */
		CSimpleDatabaseTable( );

		/** Destructor
		  */
		virtual ~CSimpleDatabaseTable();

		/** Get the count of fields.
		  */
		int  fieldsCount() const;

		/** Append a new and empty record at the end of the table, and return the index of the newly added record.
		  */
		int  appendRecord();

		/** Add a new field to the table. The table is cleared in this operation.
		  */
		void  addField(const char *fieldName);

		/** Get the name of a field by its index
		  * \exception std::exception On index out of bounds
		  */
		std::string  getFieldName(int fieldIndex) const;

		/** Get the index for a given field name
		  * \exception std::exception On field not found
		  */
		int	 fieldIndex(const char *fieldName) const;

		/** Get the records count in the table
		  */
		int	 getRecordCount() const;

		/**  Returns the cell content of the record indicates by its index, and the field indicated in "field".
		  * \exception std::exception On field or record not found
		  */
		std::string  get(int recordIndex, std::string field) const;

		/**  Returns the cell content of the record indicates by its index, and the field indicated by its index.
		  * \exception std::exception On field or record not found
		  */
		std::string  get(int recordIndex, int fieldIndex) const;

		/**  Sets the cell content of the record indicates by its index, and the field indicated in "field".
		  * \exception std::exception On field or record not found
		  */
		void  set(int recordIndex, std::string field, std::string value);

		/**  Sets the cell content of the record indicates by its index, and the field indicated by its index.
		  * \exception std::exception On field or record not found
		  */
		void  set(int recordIndex, int fieldIndex, std::string value);

		/**  Executes a query in the table, returning the record index which a given field has a given value, case insensitive, or -1 if not found.
		  */
		int  query(std::string field, std::string value) const;

	private:
		/** Field names
		  */
		vector_string				field_names;

		/** Cells data
		  */
		std::vector<vector_string>	data;

	}; // end of class definition

	/**  This class impements a very simple database system. A database is
	  *   a collection of tables, each one being a CSimpleDatabaseTable object. Tables are
	  *   a rectangular arrrangement of cells, organized as records of fields.
	  *
	  * <br> (TODO: To make this DB thread-safe)
	  *
	  * \sa CSimpleDatabaseTable
	  */
	class CSimpleDatabase  : public CSerializable
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CSimpleDatabase )

	public:
		/** Default constructor
		  */
		CSimpleDatabase( );

		/** Destructor
		  */
		virtual ~CSimpleDatabase( );

		/** Clears the DB.
		  */
		void  clear();

		/** Creates a new table in the DB, initially empty.
		  */
		CSimpleDatabaseTable *  createTable(char *name);

		/** Returns the table with the indicated name
		  * \exception std::exception On table not found.
		  */
		CSimpleDatabaseTable *  getTable(char *tableName);

		/** Returns the table by index.
		  * \exception std::exception On index out of bounds
		  */
		CSimpleDatabaseTable *  getTable(int tableIndex);

		/** Returns the tables count in the DB.
		  */
		int	 tablesCount() const;

		/** Returns the tables names in the DB.
		  * \exception std::exception On index out of bounds
		  */
		std::string	 tablesName(int tableIndex) const;

	private:
		/** The tables of the DB and their names:
		  */
		std::vector<CSimpleDatabaseTable*>	tables;
		vector_string						table_names;


	}; // end of class definition

} // End of namespace


#endif

