2008-06-17 20:27:32 +04:00
/* -------------------------------------------------------------------------- */
2012-01-12 15:29:18 +04:00
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
2008-06-17 20:27:32 +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 POOL_SQL_H_
# define POOL_SQL_H_
# include <map>
# include <string>
# include <queue>
2010-04-03 18:54:54 +04:00
# include "SqlDB.h"
2008-06-17 20:27:32 +04:00
# include "PoolObjectSQL.h"
# include "Log.h"
2009-03-27 03:32:02 +03:00
# include "Hook.h"
2008-06-17 20:27:32 +04:00
using namespace std ;
/**
* PoolSQL class . Provides a base class to implement persistent generic pools .
2010-04-03 18:54:54 +04:00
* The PoolSQL provides a synchronization mechanism ( mutex ) to operate in
* multithreaded applications . Any modification or access function to the pool
2008-06-17 20:27:32 +04:00
* SHOULD block the mutex .
*/
2010-04-11 00:19:16 +04:00
class PoolSQL : public Callbackable , public Hookable
2008-06-17 20:27:32 +04:00
{
public :
/**
* Initializes the oid counter . This function sets lastOID to
* the last used Object identifier by querying the corresponding database
* table . This function SHOULD be called before any pool related function .
* @ param _db a pointer to the database
2012-04-20 12:23:51 +04:00
* @ param _table the name of the table supporting the pool ( to set the oid
2008-06-17 20:27:32 +04:00
* counter ) . If null the OID counter is not updated .
2012-04-20 12:23:51 +04:00
* @ param cache_by_name True if the objects can be retrieved by name
2008-06-17 20:27:32 +04:00
*/
2012-04-20 12:23:51 +04:00
PoolSQL ( SqlDB * _db , const char * _table , bool cache_by_name ) ;
2008-06-17 20:27:32 +04:00
virtual ~ PoolSQL ( ) ;
/**
* Allocates a new object , writting it in the pool database . No memory is
* allocated for the object .
* @ param objsql an initialized ObjectSQL
* @ return the oid assigned to the object or - 1 in case of failure
*/
virtual int allocate (
2010-08-05 21:28:28 +04:00
PoolObjectSQL * objsql ,
string & error_str ) ;
2008-06-17 20:27:32 +04:00
/**
2010-04-03 18:54:54 +04:00
* Gets an object from the pool ( if needed the object is loaded from the
2008-06-17 20:27:32 +04:00
* database ) .
* @ param oid the object unique identifier
* @ param lock locks the object if true
2010-04-03 18:54:54 +04:00
*
2008-06-17 20:27:32 +04:00
* @ return a pointer to the object , 0 in case of failure
*/
2011-03-05 05:24:11 +03:00
PoolObjectSQL * get ( int oid , bool lock ) ;
2008-06-17 20:27:32 +04:00
2012-01-25 18:54:57 +04:00
/**
* Updates the cache name index . Must be called when the owner of an object
* is changed
*
* @ param old_name Object ' s name before the change
* @ param old_uid Object ' s owner ID before the change
* @ param new_name Object ' s name after the change
* @ param new_uid Object ' s owner ID after the change
*/
void update_cache_index ( string & old_name ,
int old_uid ,
string & new_name ,
int new_uid ) ;
2008-06-17 20:27:32 +04:00
/**
* Finds a set objects that satisfies a given condition
* @ param oids a vector with the oids of the objects .
* @ param the name of the DB table .
* @ param where condition in SQL format .
2010-04-03 18:54:54 +04:00
*
* @ return 0 on success
2008-06-17 20:27:32 +04:00
*/
virtual int search (
vector < int > & oids ,
const char * table ,
const string & where ) ;
2010-04-03 18:54:54 +04:00
2008-06-17 20:27:32 +04:00
/**
* Updates the object ' s data in the data base . The object mutex SHOULD be
* locked .
* @ param objsql a pointer to the object
2010-04-03 18:54:54 +04:00
*
2008-06-17 20:27:32 +04:00
* @ return 0 on success .
*/
virtual int update (
PoolObjectSQL * objsql )
{
2009-03-27 03:32:02 +03:00
int rc ;
2010-04-03 18:54:54 +04:00
2009-03-27 03:32:02 +03:00
rc = objsql - > update ( db ) ;
2010-04-03 18:54:54 +04:00
2009-03-27 03:32:02 +03:00
if ( rc = = 0 )
{
2009-03-30 01:34:37 +04:00
do_hooks ( objsql , Hook : : UPDATE ) ;
2009-03-27 03:32:02 +03:00
}
2010-04-03 18:54:54 +04:00
2009-03-27 03:32:02 +03:00
return rc ;
2008-06-17 20:27:32 +04:00
} ;
2010-04-03 18:54:54 +04:00
2010-04-06 01:34:09 +04:00
/**
* Drops the object ' s data in the data base . The object mutex SHOULD be
* locked .
* @ param objsql a pointer to the object
2011-06-08 21:18:12 +04:00
* @ param error_msg Error reason , if any
* @ return 0 on success , - 1 DB error
2010-04-06 01:34:09 +04:00
*/
2011-06-08 21:18:12 +04:00
virtual int drop ( PoolObjectSQL * objsql , string & error_msg )
2010-04-06 01:34:09 +04:00
{
2011-06-08 21:18:12 +04:00
int rc = objsql - > drop ( db ) ;
if ( rc ! = 0 )
{
error_msg = " SQL DB error " ;
return - 1 ;
}
2012-10-08 01:33:19 +04:00
else
{
do_hooks ( objsql , Hook : : REMOVE ) ;
}
2011-06-08 21:18:12 +04:00
return 0 ;
2010-04-06 01:34:09 +04:00
} ;
2008-06-17 20:27:32 +04:00
/**
* Removes all the elements from the pool
*/
void clean ( ) ;
2010-04-03 18:54:54 +04:00
2010-04-21 17:06:26 +04:00
/**
* Dumps the pool in XML format . A filter can be also added to the
* query
* @ param oss the output stream to dump the pool contents
* @ param where filter for the objects , defaults to all
*
* @ return 0 on success
*/
virtual int dump ( ostringstream & oss , const string & where ) = 0 ;
2012-05-05 05:18:25 +04:00
// -------------------------------------------------------------------------
// Function to generate dump filters
// -------------------------------------------------------------------------
2012-05-04 19:27:57 +04:00
/**
2012-10-08 01:33:19 +04:00
* Creates a filter for those objects ( oids ) or objects owned by a given
2012-05-05 05:18:25 +04:00
* group that an user can access based on the ACL rules
* @ param uid the user id
* @ param gid the group id
* @ param auth_object object type
* @ param all returns if the user can access all objects
* @ param filter the resulting filter string
2012-05-04 19:27:57 +04:00
*/
2012-10-08 01:33:19 +04:00
static void acl_filter ( int uid ,
int gid ,
2012-05-05 05:18:25 +04:00
PoolObjectSQL : : ObjectType auth_object ,
bool & all ,
string & filter ) ;
/**
* Creates a filter for the objects owned by a given user / group
* @ param uid the user id
* @ param gid the group id
* @ param filter_flag query type ( ALL , MINE , GROUP )
* @ param all user can access all objects
* @ param filter the resulting filter string
*/
2012-10-08 01:33:19 +04:00
static void usr_filter ( int uid ,
int gid ,
2012-05-05 05:18:25 +04:00
int filter_flag ,
bool all ,
const string & acl_str ,
string & filter ) ;
/**
* Creates a filter for a given set of objects based on their id
* @ param start_id first id
* @ param end_id last id
* @ param filter the resulting filter string
*/
static void oid_filter ( int start_id ,
int end_id ,
string & filter ) ;
2008-06-17 20:27:32 +04:00
protected :
2012-10-09 13:56:01 +04:00
/**
* Register on " CREATE " and on " REMOVE " hooks for the pool . The hooks are
* meant to be executed locally by the generic AllocateHook and RemoveHook
* classes .
* @ param hook_mads , array of HOOKs to be installed
* @ param remotes_location , path to remotes in the front - end where the
* hooks are installed
*/
void register_hooks ( vector < const Attribute * > hook_mads ,
const string & remotes_location ) ;
2012-04-20 12:23:51 +04:00
/**
* Gets an object from the pool ( if needed the object is loaded from the
* database ) .
* @ param name of the object
* @ param uid id of owner
* @ param lock locks the object if true
*
* @ return a pointer to the object , 0 in case of failure
*/
PoolObjectSQL * get ( const string & name , int uid , bool lock ) ;
2008-06-17 20:27:32 +04:00
/**
* Pointer to the database .
*/
2010-04-03 18:54:54 +04:00
SqlDB * db ;
2011-03-09 13:23:58 +03:00
/**
* Dumps the pool in XML format . A filter can be also added to the
* query
* @ param oss the output stream to dump the pool contents
* @ param elem_name Name of the root xml pool name
* @ param table Pool table name
* @ param where filter for the objects , defaults to all
*
* @ return 0 on success
*/
2012-10-08 01:33:19 +04:00
int dump ( ostringstream & oss ,
2012-05-05 05:18:25 +04:00
const string & elem_name ,
2012-10-08 01:33:19 +04:00
const char * table ,
2012-05-05 05:18:25 +04:00
const string & where ) ;
/**
* Dumps the output of the custom sql query into an xml
*
* @ param oss The output stream to dump the xml contents
* @ param root_elem_name Name of the root xml element name
* @ param sql_query The SQL query to execute
*
* @ return 0 on success
*/
int dump ( ostringstream & oss ,
const string & root_elem_name ,
2012-10-08 01:33:19 +04:00
ostringstream & sql_query ) ;
2011-03-09 13:23:58 +03:00
2011-05-21 04:06:29 +04:00
/* ---------------------------------------------------------------------- */
/* Interface to access the lastOID assigned by the pool */
/* ---------------------------------------------------------------------- */
2011-05-13 14:51:23 +04:00
2011-03-17 23:04:24 +03:00
/**
2011-05-21 04:06:29 +04:00
* Gets the value of the last identifier assigned by the pool
* @ return the lastOID of the pool
2011-03-17 23:04:24 +03:00
*/
int get_lastOID ( )
{
return lastOID ;
} ;
2011-05-21 04:06:29 +04:00
/**
* Sets the lastOID of the pool and updates the control database
* @ param _lastOID for the pool
*/
void set_update_lastOID ( int _lastOID )
{
lastOID = _lastOID ;
update_lastOID ( ) ;
} ;
2008-06-17 20:27:32 +04:00
private :
2011-05-21 04:06:29 +04:00
pthread_mutex_t mutex ;
2008-06-17 20:27:32 +04:00
/**
2010-04-03 18:54:54 +04:00
* Max size for the pool , to control the memory footprint of the pool . This
2008-06-17 20:27:32 +04:00
* number MUST be greater than the max . number of objects that are
* accessed simultaneously .
*/
2011-05-21 04:06:29 +04:00
static const unsigned int MAX_POOL_SIZE ;
/**
* Last object ID assigned to an object . It must be initialized by the
* target pool .
*/
int lastOID ;
2008-06-17 20:27:32 +04:00
2011-05-09 18:09:56 +04:00
/**
* Tablename for this pool
*/
2011-05-21 04:06:29 +04:00
string table ;
2011-05-09 18:09:56 +04:00
2008-06-17 20:27:32 +04:00
/**
2010-04-03 18:54:54 +04:00
* The pool is implemented with a Map of SQL object pointers , using the
2008-06-17 20:27:32 +04:00
* OID as key .
*/
2011-05-21 04:06:29 +04:00
map < int , PoolObjectSQL * > pool ;
2008-06-17 20:27:32 +04:00
2012-04-20 12:23:51 +04:00
/**
* Whether or not this pool uses the name_pool index
*/
bool uses_name_pool ;
2011-03-05 00:37:21 +03:00
/**
* This is a name index for the pool map . The key is the name of the object
* , that may be combained with the owner id .
*/
2011-03-05 05:24:11 +03:00
map < string , PoolObjectSQL * > name_pool ;
2008-06-17 20:27:32 +04:00
/**
* Factory method , must return an ObjectSQL pointer to an allocated pool
* specific object .
*/
virtual PoolObjectSQL * create ( ) = 0 ;
/**
2010-04-03 18:54:54 +04:00
* OID queue to implement a FIFO - like replacement policy for the pool
* cache .
2008-06-17 20:27:32 +04:00
*/
2011-05-21 04:06:29 +04:00
queue < int > oid_queue ;
2010-06-03 13:47:03 +04:00
/**
* Function to lock the pool
*/
void lock ( )
{
pthread_mutex_lock ( & mutex ) ;
} ;
/**
* Function to unlock the pool
*/
void unlock ( )
{
pthread_mutex_unlock ( & mutex ) ;
} ;
2008-06-17 20:27:32 +04:00
/**
* FIFO - like replacement policy function . Before removing an object ( pop )
2010-04-03 18:54:54 +04:00
* from the cache its lock is checked . The object is removed only if
* the associated mutex IS NOT blocked . Otherwise the oid is sent to the
* back of the queue .
2008-06-17 20:27:32 +04:00
*/
void replace ( ) ;
2010-04-03 18:54:54 +04:00
2011-03-05 00:37:21 +03:00
/**
* Generate an index key for the object
* @ param name of the object
* @ param uid owner of the object , only used if needed
2012-10-08 01:33:19 +04:00
*
2011-03-05 00:37:21 +03:00
* @ return the key , a string
*/
2012-01-25 15:26:46 +04:00
virtual string key ( const string & name , int uid )
2011-03-05 00:37:21 +03:00
{
ostringstream key ;
key < < name < < ' : ' < < uid ;
return key . str ( ) ;
} ;
2011-05-23 00:30:36 +04:00
/**
* Inserts the last oid into the pool_control table
*/
void update_lastOID ( ) ;
2011-03-05 05:24:11 +03:00
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
2011-03-05 00:37:21 +03:00
2010-04-03 18:54:54 +04:00
/**
* Callback to set the lastOID ( PoolSQL : : PoolSQL )
*/
int init_cb ( void * nil , int num , char * * values , char * * names ) ;
/**
* Callback to store the IDs of pool objects ( PoolSQL : : search )
*/
int search_cb ( void * _oids , int num , char * * values , char * * names ) ;
2011-03-09 13:23:58 +03:00
/**
* Callback function to get output in XML format
* @ param num the number of columns read from the DB
* @ param names the column names
* @ param vaues the column values
* @ return 0 on success
*/
int dump_cb ( void * _oss , int num , char * * values , char * * names ) ;
2008-06-17 20:27:32 +04:00
} ;
2010-04-21 17:06:26 +04:00
# endif /*POOL_SQL_H_*/