//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//      RSVC Server All Data Storage Class (Abstract Class)
//
//      This class behaves like a wrapper class that direct
//      all  actions to right components contained inside this class
//
//      All member functions have 3 arguments. The first is the network
//      incoming data, the second is the result of the action in the
//      form of array of network data, and the 3rd argument is size
//      of the array. Callers must free memory for the elements
//      in the array
//
// Author:  Jie Chen
//
//
//
//
#ifndef _RSVC_DATA_STORE_H
#define _RSVC_DATA_STORE_H

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifndef _WIN32
#include <sys/time.h>
#include <unistd.h>
#endif

#include <rsvcData.h>
#include <rsvcTableDef.h>
#include <rsvcHashable.h>
#include <rsvcNetData.h>
#include <rsvcHash.h>


class rsvcVirtualDbase;

class rsvcDataStore : public rsvcHashable
{
public:
  // destrcutor
  virtual ~rsvcDataStore      (void);

  // operations

  // create table definition
  virtual int createDatabase  (rsvcNetData& data,
			       rsvcNetData* outdata[], size_t* num);

  virtual int openDatabase    (rsvcNetData& data,
			       rsvcNetData* outdata[], size_t* num);

  // retrieve table definition and store inside data
  virtual int getTableDef     (rsvcNetData& data,
			       rsvcNetData* outdata[], size_t* num);

  // get data value
  // specified by a key
  virtual int getValue        (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;
  // insert a rsvcData which must have a key inside
  virtual int putValue        (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num,
			       int overwite = 0) = 0;
  // delete a data object pointed by key value
  virtual int delValue        (rsvcNetData& incoming,
			      rsvcNetData* outdata[], size_t* num) = 0;
  // flush all internal buffer to disk
  virtual int flush           (void) = 0;

  // set data value
  // specified either by a key
  virtual int setValue        (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // monitor on incoming database entries
  virtual int monitorIncomingEntries (rsvcNetData& incoming,
				      rsvcNetData* outdata[], size_t* num) = 0;

  // monitor off the above incoming database entries
  virtual int monitorOffIncomingEntries (rsvcNetData& incoming,
					 rsvcNetData* outdata[], size_t* num) = 0;
  // monitor on data values
  // monitor on the whole data 
  virtual int monitorValue    (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // monitor on attribute of a data
  virtual int monitorAttr     (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // monitor off data values
  virtual int monitorOffValue (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // monitor off attribute of a data
  virtual int monitorOffAttr  (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // monitor off value for a single io channel
  virtual int monitorOff      (void* io) = 0;

  // query the data store
  virtual int query           (rsvcNetData& data, char* msg, 
			       rsvcNetData* outdata[], size_t* num) = 0;

  // get every entry in the store
  virtual int getAll          (rsvcNetData& incoming,
			       rsvcNetData* outdata[], size_t* num) = 0;

  // inherited operation from hashable
  unsigned int hash            (void);

  // return name of this data store
  char*        name            (void) const;

  // open and close data store operation
  virtual int  openDatabase    (void);
  virtual int  closeDatabase   (void);

  // handle client close
  virtual void handleClose     (void * /* client */) {}

  // from existing table definition and files 
  // to create a right dataStore object
  static rsvcDataStore* createDataStore (char* name);

protected:
  // constructor
  // construct data store with a unique name
  rsvcDataStore               (char* name);

  // remove all monitors on incoming data
  void        removeAllMonitors (void);


  // update this data store time stamp which is the time when last
  // action was done on the store.
  void        updateTimeStamp (void);

  // notify interested parties about an incoming entry
  int         notifyAnEntryToChannels (rsvcData& entry);

  // data area
  char*             name_;

  // time stamp of this data store
  double             timestamp_;

  // table definition
  rsvcTableDef      tableDef_;

  // data cache handler
  rsvcHash           cache_;

  // insert/deleted data monitor
  rsvcHSlist         idataMonitorList_;
  rsvcHSlist         odataMonitorList_;

  // database handler
  rsvcVirtualDbase* database_;
};
#endif

