2017-04-19 21:44:31 +03:00
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
# ifndef LOG_DB_H_
# define LOG_DB_H_
# include <string>
# include <sstream>
# include "SqlDB.h"
2017-04-27 02:03:44 +03:00
/**
* This class represents a log record
*/
struct LogDBRecord
{
/**
* Index for this log entry ( and previous )
*/
unsigned int index ;
unsigned int prev_index ;
/**
* Term where this log ( and previous ) entry was generated
*/
unsigned int term ;
unsigned int prev_term ;
/**
* SQL command to exec in the DB to update ( INSERT , REPLACE , DROP )
*/
std : : string sql ;
/**
* Time when the record has been applied to DB . 0 if not applied
*/
time_t timestamp ;
} ;
/**
* This class implements a generic DB interface with replication . The associated
* DB stores a log to replicate on followers .
*/
2017-04-20 17:13:41 +03:00
class LogDB : public SqlDB , Callbackable
2017-04-19 21:44:31 +03:00
{
public :
2017-04-25 12:49:52 +03:00
LogDB ( SqlDB * _db ) ;
2017-04-21 17:52:54 +03:00
2017-04-25 12:49:52 +03:00
virtual ~ LogDB ( ) ;
2017-04-19 21:44:31 +03:00
2017-04-27 02:03:44 +03:00
// -------------------------------------------------------------------------
// Interface to access Log records
// -------------------------------------------------------------------------
2017-04-20 17:13:41 +03:00
/**
2017-04-27 02:03:44 +03:00
* Loads a log record from the database . Memory is allocated by this class
* and needs to be freed .
2017-04-20 17:13:41 +03:00
* @ param index of the associated logDB entry
2017-04-27 02:03:44 +03:00
* @ return the LogDB record
*/
LogDBRecord * get_log_record ( unsigned int index ) ;
/**
* Applies the SQL command of the given record to the database . The
* timestamp of the record is updated .
* @ param lr the log record
* @ param index of the log record
*/
int apply_log_record ( LogDBRecord * lr ) ;
int apply_log_record ( unsigned int index ) ;
/**
* Inserts a new log record in the database . If the record is successfully
* inserted the index is incremented
* @ param term for the record
* @ param sql command of the record
* @ param timestamp associated to this record
2017-04-20 17:13:41 +03:00
*
2017-04-27 02:03:44 +03:00
* @ return - 1 on failure , index of the inserted record on success
2017-04-20 17:13:41 +03:00
*/
2017-04-27 02:03:44 +03:00
int insert_log_record ( unsigned int term , std : : ostringstream & sql ,
time_t timestamp ) ;
2017-04-19 21:44:31 +03:00
2017-04-20 17:13:41 +03:00
// -------------------------------------------------------------------------
// SQL interface
// -------------------------------------------------------------------------
/**
* This function replicates the DB changes on followers before updating
* the DB state
*/
int exec_wr ( ostringstream & cmd ) ;
2017-04-19 21:44:31 +03:00
2017-04-21 20:16:45 +03:00
int exec_local_wr ( ostringstream & cmd )
2017-04-20 17:13:41 +03:00
{
2017-04-21 20:16:45 +03:00
return db - > exec_local_wr ( cmd ) ;
2017-04-20 17:13:41 +03:00
}
2017-04-19 21:44:31 +03:00
2017-04-21 17:52:54 +03:00
int exec_rd ( ostringstream & cmd , Callbackable * obj )
2017-04-20 17:13:41 +03:00
{
return db - > exec_rd ( cmd , obj ) ;
2017-04-19 21:44:31 +03:00
}
char * escape_str ( const string & str )
{
return db - > escape_str ( str ) ;
}
void free_str ( char * str )
{
db - > free_str ( str ) ;
}
bool multiple_values_support ( )
{
return db - > multiple_values_support ( ) ;
}
2017-04-21 17:52:54 +03:00
// -------------------------------------------------------------------------
// Database methods
// -------------------------------------------------------------------------
2017-04-25 12:49:52 +03:00
static int bootstrap ( SqlDB * _db )
2017-04-21 17:52:54 +03:00
{
2017-04-27 02:03:44 +03:00
std : : ostringstream oss ( db_bootstrap ) ;
2017-04-21 17:52:54 +03:00
2017-04-25 12:49:52 +03:00
return _db - > exec_local_wr ( oss ) ;
2017-04-21 17:52:54 +03:00
}
2017-04-27 02:03:44 +03:00
/**
* This function to get and initialize log related index
* @ param last_applied , highest index applied to the DB
* @ param last_index
*
* @ return 0 on success
*/
int setup_index ( int & last_applied , int & last_index ) ;
2017-04-19 21:44:31 +03:00
protected :
2017-04-27 02:03:44 +03:00
int exec ( std : : ostringstream & cmd , Callbackable * obj , bool quiet )
2017-04-19 21:44:31 +03:00
{
2017-04-20 17:13:41 +03:00
return - 1 ;
2017-04-19 21:44:31 +03:00
}
private :
2017-04-21 17:52:54 +03:00
pthread_mutex_t mutex ;
2017-04-19 21:44:31 +03:00
/**
* Pointer to the underlying DB store
*/
SqlDB * db ;
/**
* Index to be used by the next logDB record
*/
unsigned int next_index ;
2017-04-20 17:13:41 +03:00
/**
2017-04-27 02:03:44 +03:00
* Index of the last log entry applied to the DB state
2017-04-20 17:13:41 +03:00
*/
2017-04-27 02:03:44 +03:00
unsigned int last_applied ;
2017-04-20 17:13:41 +03:00
// -------------------------------------------------------------------------
// DataBase implementation
// -------------------------------------------------------------------------
static const char * table ;
static const char * db_names ;
static const char * db_bootstrap ;
2017-04-25 12:49:52 +03:00
/**
2017-04-27 02:03:44 +03:00
* Callback to initialize the next_index and last_appled varibales .
2017-04-25 12:49:52 +03:00
*/
2017-04-27 02:03:44 +03:00
int setup_index_cb ( void * nil , int num , char * * values , char * * names ) ;
2017-04-25 12:49:52 +03:00
2017-04-20 17:13:41 +03:00
/**
2017-04-27 02:03:44 +03:00
* SQL callback for log record SELECT commands
2017-04-20 17:13:41 +03:00
*/
int select_cb ( void * req , int num , char * * values , char * * names ) ;
/**
* Inserts or update a log record in the database
2017-04-21 23:32:30 +03:00
* @ param index of the log entry
* @ param term for the log entry
* @ param sql command to modify DB state
2017-04-27 02:03:44 +03:00
* @ param timestamp of record application to DB state
2017-04-20 17:13:41 +03:00
* @ param replace true to replace an existing entry
*
* @ return 0 on success
*/
2017-04-21 23:32:30 +03:00
int insert_replace ( int index , int term , const std : : string & sql ,
2017-04-27 02:03:44 +03:00
time_t timestamp , bool replace ) ;
2017-04-19 21:44:31 +03:00
} ;
# endif /*LOG_DB_H_*/