2010-04-03 18:54:09 +04:00
/* -------------------------------------------------------------------------- */
2018-01-02 20:27:37 +03:00
/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems */
2010-04-03 18:54:09 +04:00
/* */
/* 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 CALLBACKABLE_H_
# define CALLBACKABLE_H_
2010-06-11 18:40:29 +04:00
# include <pthread.h>
2017-05-04 23:56:07 +03:00
# include <sstream>
2018-03-18 01:31:52 +03:00
# include <set>
# include <vector>
2010-06-11 18:40:29 +04:00
2010-04-03 18:54:09 +04:00
using namespace std ;
/**
2018-03-18 01:31:52 +03:00
* This class represents a SQL callback
2010-04-03 18:54:09 +04:00
*/
class Callbackable
{
public :
2018-04-19 16:21:30 +03:00
Callbackable ( ) : cb ( 0 ) , arg ( 0 ) , affected_rows ( 0 )
2010-06-11 18:40:29 +04:00
{
pthread_mutex_init ( & mutex , 0 ) ;
} ;
2010-04-03 18:54:09 +04:00
2010-06-11 18:40:29 +04:00
virtual ~ Callbackable ( )
{
pthread_mutex_destroy ( & mutex ) ;
} ;
2010-04-03 18:54:09 +04:00
/**
* Datatype for call back pointers
*/
2010-04-04 03:11:13 +04:00
typedef int ( Callbackable : : * Callback ) ( void * , int , char * * , char * * ) ;
2010-04-03 18:54:09 +04:00
/**
* Set the callback function and custom arguments to be executed by the
2010-06-11 18:40:29 +04:00
* next SQL command , and locks the mutex until unset_callback is called .
2010-04-03 18:54:09 +04:00
* @ param ptr to the callback function
* @ param arg custom arguments for the callback function
*/
2018-04-23 13:43:29 +03:00
virtual void set_callback ( Callback _cb , void * _arg = 0 )
2010-04-03 18:54:09 +04:00
{
2010-06-11 18:40:29 +04:00
pthread_mutex_lock ( & mutex ) ;
2010-04-03 18:54:09 +04:00
cb = _cb ;
arg = _arg ;
} ;
/**
* Test if the CallBack is set for the object .
* @ return true if the callback is set
*/
2018-04-23 13:43:29 +03:00
virtual bool isCallBackSet ( )
2010-04-03 18:54:09 +04:00
{
return ( cb ! = 0 ) ;
} ;
/**
2010-06-11 18:40:29 +04:00
* Call the callback funcion set . This method must be called only if
* isCallBackSet returns true .
* @ return the callback function return value .
2010-04-03 18:54:09 +04:00
*/
int do_callback ( int num , char * * values , char * * names )
{
2018-06-11 17:57:45 +03:00
+ + affected_rows ;
2010-04-03 18:54:09 +04:00
return ( this - > * cb ) ( arg , num , values , names ) ;
} ;
2010-06-11 18:40:29 +04:00
/**
* Unset the callback function .
*/
void unset_callback ( )
{
cb = 0 ;
arg = 0 ;
pthread_mutex_unlock ( & mutex ) ;
}
2018-04-19 16:21:30 +03:00
/**
* set affected rows variable
*/
void set_affected_rows ( int num_rows )
{
affected_rows = num_rows ;
}
/**
* get affected rows variable
*/
int get_affected_rows ( )
{
return affected_rows ;
}
2010-04-03 18:54:09 +04:00
private :
/**
* SQL callback to be executed for each row result of an SQL statement
*/
2010-04-04 03:11:13 +04:00
Callback cb ;
2010-04-03 18:54:09 +04:00
/**
* Custom arguments for the callback
*/
void * arg ;
2010-06-11 18:40:29 +04:00
2018-04-19 16:21:30 +03:00
/**
* num of affected rows
*/
int affected_rows ;
2010-06-11 18:40:29 +04:00
/**
* Mutex for locking the callback function .
*/
pthread_mutex_t mutex ;
2010-04-03 18:54:09 +04:00
} ;
2017-05-04 23:56:07 +03:00
/* -------------------------------------------------------------------------- */
/* Classes to obtain values from a DB it support concurrent queries using */
/* different objects */
/* -------------------------------------------------------------------------- */
template < class T >
class single_cb : public Callbackable
{
public :
void set_callback ( T * _value )
{
value = _value ;
Callbackable : : set_callback (
static_cast < Callbackable : : Callback > ( & single_cb : : callback ) ) ;
}
virtual int callback ( void * nil , int num , char * * values , char * * names )
{
if ( values = = 0 | | values [ 0 ] = = 0 | | num ! = 1 )
{
return - 1 ;
}
std : : istringstream iss ( values [ 0 ] ) ;
iss > > * value ;
return 0 ;
}
private :
T * value ;
} ;
2018-03-18 01:31:52 +03:00
/* -------------------------------------------------------------------------- */
2017-05-22 19:04:16 +03:00
template < >
class single_cb < std : : string > : public Callbackable
{
public :
void set_callback ( std : : string * _value )
{
value = _value ;
Callbackable : : set_callback (
static_cast < Callbackable : : Callback > ( & single_cb : : callback ) ) ;
}
virtual int callback ( void * nil , int num , char * * values , char * * names )
{
if ( values = = 0 | | values [ 0 ] = = 0 | | num ! = 1 )
{
return - 1 ;
}
* value = values [ 0 ] ;
return 0 ;
}
private :
std : : string * value ;
} ;
2018-03-18 01:31:52 +03:00
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template < class T >
class set_cb : public Callbackable
{
public :
void set_callback ( std : : set < T > * _ids )
{
ids = _ids ;
Callbackable : : set_callback (
static_cast < Callbackable : : Callback > ( & set_cb : : callback ) ) ;
} ;
int callback ( void * nil , int num , char * * values , char * * names )
{
if ( num = = 0 | | values = = 0 | | values [ 0 ] = = 0 )
{
return - 1 ;
}
std : : istringstream iss ( values [ 0 ] ) ;
T value ;
iss > > value ;
ids - > insert ( value ) ;
return 0 ;
} ;
private :
set < T > * ids ;
} ;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template < class T >
class vector_cb : public Callbackable
{
public :
void set_callback ( vector < T > * _oids )
{
oids = _oids ;
Callbackable : : set_callback (
static_cast < Callbackable : : Callback > ( & vector_cb : : callback ) ) ;
} ;
int callback ( void * nil , int num , char * * values , char * * names )
{
if ( num = = 0 | | values = = 0 | | values [ 0 ] = = 0 )
{
return - 1 ;
}
std : : istringstream iss ( values [ 0 ] ) ;
T value ;
iss > > value ;
oids - > push_back ( value ) ;
return 0 ;
} ;
private :
vector < T > * oids ;
} ;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class stream_cb : public Callbackable
{
public :
stream_cb ( int _total ) : total_values ( _total ) { } ;
void set_callback ( ostringstream * _oss )
{
oss = _oss ;
Callbackable : : set_callback (
static_cast < Callbackable : : Callback > ( & stream_cb : : callback ) ) ;
} ;
int callback ( void * nil , int num , char * * values , char * * names )
{
if ( ( ! values [ 0 ] ) | | ( num ! = total_values ) )
{
return - 1 ;
}
for ( int i = 0 ; i < total_values ; i + + )
{
if ( values [ i ] ! = NULL )
{
* oss < < values [ i ] ;
}
}
return 0 ;
} ;
private :
int total_values ;
ostringstream * oss ;
} ;
2018-04-19 16:21:30 +03:00
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class empty_cb : public Callbackable
{
public :
void set_callback ( Callback _cb , void * _arg = 0 ) { } ;
bool isCallBackSet ( )
{
return false ;
} ;
} ;
2010-04-03 18:54:09 +04:00
# endif /*CALLBACKABLE_H_*/