/* ----------------------------------------------------------------------------
 * Raima Database Manager
 *
 * Copyright (c) 2007-2013 Raima Inc.,  All rights reserved.
 *
 * Use of this software, whether in source code format, or in executable,
 * binary object code form, is governed by the Birdstep LICENSE which
 * is fully described in the LICENSE.TXT file, included within this
 * distribution of files.
 * ----------------------------------------------------------------------------
 */
#if !defined(__LOGCONN_H)
#define __LOGCONN_H

#include "rdm.h"
#include "logfcns.h"

typedef struct _lc_ctxt *LOGCONN_HANDLE;
typedef struct _lf_ctxt *LOGFILE_HANDLE;

typedef RDM_REP_ACTION_TYPE   RDM_LC_ACTION_TYPE;
typedef RDM_REP_ACTION_COLUMN RDM_LC_COLUMN_INFO;
typedef B_SCHEMA_VER          RDM_LC_SCHEMA_VER;
typedef B_REP_IMG_TYPE        RDM_LC_IMG_TYPE;

/* ------------------------------------------------------------------------
   Log connection option flags (bitmap)
*/
#define RDM_LC_DISKLESS     0x00000001
#define RDM_LC_OPTMASK      0xFFFFFFFE

/* ------------------------------------------------------------------------
   Log connection default timeout value (in millisecs)
*/
#define RDM_LC_DEFAULT_TIMEOUT  ((uint32_t) -1)
#define RDM_LC_NO_TIMEOUT       0

#if defined(__cplusplus)
extern "C" {
#endif

/* ------------------------------------------------------------------------
   Log file entry structure for the notification API
*/
typedef struct {
    struct _lc_ctxt        *pCtx;           /* for cross-referencing */
    RDM_REP_ACTION_HEADER   header;
    RDM_REP_TIMESTAMP       timestamp;
    const void             *pvData;
    RDM_LC_COLUMN_INFO     *pCols;
    uint16_t                usColCount;
} RDM_REP_ENTRY;

/* ------------------------------------------------------------------------
   Log file entry attribute structure for the notification API
*/
typedef enum {
    RDM_ACT_ATTRIB_TYPE = 0,
    RDM_ACT_ATTRIB_TIMESTAMP,
    RDM_ACT_ATTRIB_TABLE,
    RDM_ACT_ATTRIB_SET,
    RDM_ACT_ATTRIB_OWNER_TABLE,
    RDM_ACT_ATTRIB_COLUMN
} RDM_LC_ATTRIB_TYPE;

/** \brief Establish a connection with a master-side dbrep.
 *
 *  This function establishes a connection with a master-side replication
 *  utility (dbrep) in order to receive the replication log files. It will
 *  restore the Schema Information from the local file if it exists. If 
 *  the Schema Information is not available on the local file system, the
 *  function will retrieve it directly from the master-side dbrep.
 *
 *  \Returns An RDM status code
 *  \retval S_OKAY           Success
 *  \retval S_INVDB          Invalid database
 *  \retval S_INVNULL        phLC is NULL
 *  \retval S_INVFLAG        Invalid flag specified with optionFlags
 *  \retval S_TX_CONNECT     Unable to connect to the master dbrep
 *  \retval S_NOMEMORY       Unable to allocate sufficient memory
 *  \retval S_REP_NOMASTERDB Specified database is not replicated
 *
 *  \see lc_closeConnection
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_openConnection(
    const char              *dburi,         /**< [IN]  full database URI */
    const char              *docroot,       /**< [IN]  document root */
    uint32_t                 optionFlags,   /**< [IN]  option flags */
    LOGCONN_HANDLE          *phLC);         /**< [OUT] log connection handle */

/** \brief Close an existing connection with a master-side dbrep.
 *
 *  This function closes an existing connection with a master-side
 *  replication utility (dbrep).
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log handle
 *  \retval S_NOMEMORY      Unable to allocate sufficient memory
 *
 *  \see lc_openConnection
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_closeConnection(
    const LOGCONN_HANDLE     hLC);      /**< [IN]  log connection handle */

/** \brief Retrieve the latest transaction ID from the replication master.
 *
 *  This function retrieves the ID of the latest committed transaction
 *  from the replication master.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log handle
 *  \retval S_TX_NETREAD    Unable to read data from the master dbrep
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_latestTransactionID(
    LOGCONN_HANDLE           hLC,           /**< [IN]  log connection handle */
    TXID                    *pTxID);

/** \brief Open the next available replication log file.
 *
 *  This function opens the next available replication log file stored on
 *  the local file system. The handle to the newly opened log file is
 *  returned to phLF. If non-NULL, logFileName will contain the name of
 *  the log file that's opened, up to uFileNameSize - 1 bytes.
 *  
 *  The timeout value specifies the number of milliseconds the function
 *  waits until the next replication log file becomes available. If 
 *  RDM_LC_DEFAULT_TIMEOUT is used, the function will wait for 10,000
 *  milliseconds (10 seconds). If 0 is specified, the function will return
 *  immediately if the next log file is not available.
 *
 *  If the log file contains an updated Schema Information, this function
 *  will copy it to the client cache. It will also be saved to the local
 *  schema file for recovery.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_NOTFOUND      Next log file is not available
 *  \retval S_LOG_INVHANDLE Invalid log file handle
 *  \retval S_LOG_OUTDATED  Log file is outdated
 *  \retval S_LOG_NOSCHEMA  Schema Information missing from the connection
 *  \retval S_NOMEMORY      Unable to allocate sufficient memory
 *
 *  \see lc_openLatestLogFile
 *  \see lc_closeLogFile
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_openNextLogFile(
    LOGCONN_HANDLE           hLC,           /**< [IN]  log connection context */
    uint32_t                 uTimeout,      /**< [IN]  timeout period */
    char                    *logName,       /**< [IN]  log file name */
    uint32_t                 logNameLen,    /**< [IN]  max size of pszLogFIleName */
    LOGFILE_HANDLE          *phLF);         /**< [OUT] log file handle */

/** \brief Open the latest available replication log file.
 *
 *  This function opens the latest available replication log file stored
 *  on the local file system. The handle to the newly opened log file is 
 *  returned to phLF. If non-NULL, logFileName will contain the name of
 *  the log file that's opened, up to uFileNameSize - 1 bytes.
 *
 *  If the log file contains an updated Schema Information, this function
 *  will copy it to the client cache. It will also be saved to the schema
 *  file for recovery.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_NOTFOUND      Next log file is not available
 *  \retval S_LOG_INVHANDLE Invalid log file handle
 *  \retval S_NOMEMORY      Unable to allocate sufficient memory
 *
 *  \see lc_openNextLogFile
 *  \see lc_closeLogFile
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_openLatestLogFile(
    LOGCONN_HANDLE           hLC,           /**< [IN]  log connection handle */
    char                    *logName,       /**< [OUT] log file name */
    uint32_t                 logNameLen,    /**< [IN]  max length of logName */
    LOGFILE_HANDLE          *phLF);         /**< [OUT] log file handle */

/** \brief Close the replication log file stored on the local file system.
 *
 *  This function closes the log file stored on the local file system. The
 *  log file is specified by the input parameter (hLF). If the specified
 *  log file is not open, S_OKAY will be returned.
 *
 *  If RDM_TRUE is passed to bRemove, the function will remove the file
 *  after closing it.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log file handle
 *  \retval S_NOFILE        Log file doesn't exist
 *  \retval S_EACCESS       Sharing violation - file in use
 *
 *  \see lc_openNextLogFile
 *  \see lc_openLatestLogFile
 *  \see lc_removeLogFile
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_closeLogFile(
    LOGFILE_HANDLE           hLF,       /**< [IN]  log file handle */
    RDM_BOOLEAN              bRemove);  /**< [IN]  TRUE to remove the file */

/** \brief Remove the replication log file stored on the local file system.
 *
 *  This function removes the log file stored on the local file system.
 *  The log file is specified by the input parameter (hLF).
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log file handle
 *  \retval S_NOFILE        Log file doesn't exist
 *  \retval S_EACCESS       Sharing violation - file in use
 *
 *  \see lc_openNextLogFile
 *  \see lc_openLatestLogFile
 *  \see lc_closeLogFile
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_removeLogFile(
    LOGFILE_HANDLE           hLF);          /**< [IN]  log file handle */

/** \brief Retrieve the next action entry from the local logfile.
 *
 *  This function retrieves the information stored in the Action Header
 *  and Data Header sections of the Action Record in the pEntryInfo
 *  parameter. All the column data associated with the action will be
 *  read in but wil not be returned to the caller. An application needs
 *  to call lc_entryColumnData()  to retrieve each column data.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log file handle
 *  \retval S_REPLOG_ERR    Error processing the log file
 *  \retval S_INVULL        ppEI is NULL
 *  \retval S_NOMEMORY      Unable to allocate sufficient memory
 *
 *  \see lc_freeEntryInfo
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_nextEntryInfo(
    LOGFILE_HANDLE           hLF,           /**< [IN]  log file handle */
    RDM_REP_ENTRY          **ppEI,          /**< [OUT] pointer to the entry info */
    uint16_t                *pusColCount);  /**< [OUT] number of columns */

/** \brief Free the memory associated with the action entry.
 *
 *  This function frees the memory associated with the action entry. The
 *  memory is originally allocated by lc_nextEntryInfo().
 *
 *  \see lc_nextEntryInfo
 */
RDM_EXPORT void EXTERNAL_FCN lc_freeEntryInfo(
    const RDM_REP_ENTRY     *pEI);          /**< [IN]  action entry info */

/** \brief Retrieve the changed data of the specified column.
 *
 *  This function retrieves the changed data of the specified column in
 *  the transaction entry. The value of usColumnIndex is an index into 
 *  the array of column IDs returned by log_nextEntryInfo().
 *
 *  \returns An RDM status code
 *  \retval S_OKAY         Success
 *  \retval S_INVNULL      pEI is NULL
 *  \retavl S_LOG_INVINDEX usColIndex is out of range
 *
 *  \see lc_entryAttribute
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_entryColumnData(
    const RDM_REP_ENTRY     *pEI,           /**< [IN]  action entry info */
    uint16_t                 usColIndex,    /**< [IN]  column index */
    void                    *pvPreImage,    /**< [OUT] previous image */
    uint32_t                *puPreLen,      /**< [OUT] previous image length */
    void                    *pvPostImage,   /**< [OUT] post image */
    uint32_t                *puPostLen);    /**< [OUT] post image length */

/** \brief Retrieve an attribute of the specified action entry.
 *
 *  This function retrieves an attribute of the specified action entry.
 *  The type of the attribute is specified with the attribType parameter
 *  The value is retrieved into the rgbValue parameter.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY        Success
 *  \retval S_TRUNCATE    String attribute value is truncated
 *  \retval S_INVNULL     ppEI is NULL
 *  \retval S_LOG_INVATTR Entry attribute value is invalid
 *
 *  \see lc_entryColumnData
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_entryAttribute(
    const RDM_REP_ENTRY     *pEI,           /**< [IN]  action entry info */
    RDM_LC_ATTRIB_TYPE       attribType,    /**< [IN]  enumed attribute type */
    void                    *rgbValue,      /**< [OUT] attribute value */
    uint32_t                 valSize,       /**< [IN]  max size of rgbValue */
    uint32_t                *puAvailSize);  /**< [OUT] size of attribute value */

/* ------------------------------------------------------------------------
   Schema Information Access API
*/

/** \brief Retrieve the version number of the current schema information.
 *
 *  This function returns the version number of the current schema 
 *  information. The version number can be used to detect a change in the
 *  Change Criteria. puVersion can be NULL, in which case no useful
 *  information will be returned.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_LOG_INVHANDLE Invalid log connection handle
 *
 *  \see lc_schemaDatabaseInfo
 *  \see lc_schemaTableInfo
 *  \see lc_schemaColumnInfo
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_schemaVersion(
    LOGCONN_HANDLE       hLC,               /**< [IN]  log connection handle */
    RDM_LC_SCHEMA_VER   *pVersion);         /**< [OUT] schema version */

/** \brief Retrieve the details of the database replicated on this connection.
 *
 *  This function retrieves the information about the database replicated
 *  on this connection. If non-NULL, pszDatabaseName will contain the
 *  basename of the database, and puTableCount will contain the number of
 *  tables replicated under this table. If non-NULL, pbTimestamped will
 *  contain a Boolean value indicating whether or not the log file entries
 *  include the timestamp. 
 *
 *  \returns An RDM status code
 *  \retval S_OKAY         Success
 *  \retval S_TRUNCATE     Database name is truncated
 *  \retval S_LOG_INVHNDLE Invalid log connection handle
 *  \retval S_LOG_NOSCHEMA Schema Information missing from the connection
 *
 *  \see lc_schemaVersion
 *  \see lc_schemaTableInfo
 *  \see lc_schemaColumnInfo
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_schemaDatabaseInfo(
    LOGCONN_HANDLE       hLC,               /**< [IN]  log connection handle */
    char                *pszDatabaseName,   /**< [OUT] database name */
    uint32_t             nameSize,          /**< [IN]  maximum length for db name */
    RDM_BOOLEAN         *pbTimestamped,     /**< [OUT] TRUE if timestamped */
    uint16_t            *pusTableCount);    /**< [OUT] number of tables in the db */

/** \brief Retrieve the details of the table specified by the index.
 *
 *  This function retrieves the information about the replicated table 
 *  for the table index specified in uTableIndex. The table index is
 *  zero-based. If non-NULL, pszTableName will contain the name of the
 *  table, and pusColumnCount will contain the number of columns
 *  replicated under this table.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY         Success
 *  \retval S_TRUNCATE     Database name is truncated
 *  \retval S_LOG_INVHNDLE Invalid log connection handle
 *  \retval S_LOG_NOSCHEMA Schema Information missing from the connection
 *
 *  \see lc_schemaVersion
 *  \see lc_schemaDatabaseInfo
 *  \see lc_schemaColumnInfo
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_schemaTableInfo(
    LOGCONN_HANDLE       hLC,               /**< [IN]  log connection handle */
    uint16_t             usTableIndex,      /**< [IN]  index into the table list */
    char                *pszTableName,      /**< [OUT] name of the table */
    uint32_t             nameSize,          /**< [IN]  max size of the table name */
    uint16_t            *pusColumnCount);   /**< [OUT] # of columns in the table */

/** \brief Retrieve the details of the column specified by the index.
 *
 *  This function retrieves the information about the replicated column
 *  for the column index specified in usColumnIndex. The column index
 *  is zero-based. If non-NULL, each of the output parameters will
 *  contain the specified attribute of the specified column.
 *
 *  \returns An RDM status code
 *  \retval S_OKAY          Success
 *  \retval S_TRUNCATE      Database name is truncated
 *  \retval S_LOG_INVHANDLE Invalid log connection handle
 *  \retval S_LOG_NOSCHEMA  Schema Information missing from the connection
 *
 *  \see lc_schemaVersion
 *  \see lc_schemaDatabaseInfo
 *  \see lc_schemaTableInfo
 */
RDM_EXPORT int32_t EXTERNAL_FCN lc_schemaColumnInfo(
    LOGCONN_HANDLE       hLC,                   /**< [IN]  log connection handle */
    uint16_t             usTableIndex,          /**< [IN]  table index */
    uint16_t             usColumnIndex,         /**< [IN]  column index */
    char                *pszColumnName,         /**< [OUT] column name */
    uint32_t             nameSize,              /**< [IN]  max size of column */
    RDM_TYPE            *pColumnType,           /**< [OUT] RDM column type */
    char                *pszTypeName,           /**< [OUT] RDM column type name */
    uint32_t             typeSize,              /**< [IN]  max size of type */
    uint16_t             usColumnSizeArray[3],  /**< [OUT] column dimension */
    uint8_t             *pPrecision,            /**< [OUT] column precision */
    uint8_t             *pScale,                /**< [OUT] column scale */
    RDM_LC_IMG_TYPE     *pImgOptType);          /**< [OUT] column image option */

#if defined(__cplusplus)
}
#endif

#endif  /* __LOGCONN_H */

