2008-06-17 20:27:32 +04:00
/* -------------------------------------------------------------------------- */
2023-01-09 14:23:19 +03:00
/* Copyright 2002-2023, OpenNebula Project, OpenNebula Systems */
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 <string>
2020-09-10 10:08:29 +03:00
# include <memory>
2008-06-17 20:27:32 +04:00
2010-04-03 18:54:54 +04:00
# include "SqlDB.h"
2008-06-17 20:27:32 +04:00
# include "PoolObjectSQL.h"
2018-03-18 01:31:52 +03:00
# include "PoolSQLCache.h"
2008-06-17 20:27:32 +04:00
/**
* 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 .
*/
2019-09-09 15:43:51 +03:00
class PoolSQL
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 .
*/
2017-06-21 04:22:56 +03:00
PoolSQL ( SqlDB * _db , const char * _table ) ;
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 ,
2020-07-02 23:42:10 +03:00
std : : 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
2020-09-10 10:08:29 +03:00
* database ) . The object is locked , other threads can ' t access the same
* object . The lock is released by destructor .
2008-06-17 20:27:32 +04:00
* @ param oid the object unique identifier
2020-09-10 10:08:29 +03:00
* @ return a pointer to the object , nullptr in case of failure
2008-06-17 20:27:32 +04:00
*/
2020-09-10 10:08:29 +03:00
template < typename T >
std : : unique_ptr < T > get ( int oid )
{
if ( oid < 0 )
{
return nullptr ;
}
2020-09-10 14:32:52 +03:00
std : : mutex * object_lock = cache . lock_line ( oid ) ;
2020-09-10 10:08:29 +03:00
std : : unique_ptr < T > objectsql ( static_cast < T * > ( create ( ) ) ) ;
objectsql - > oid = oid ;
objectsql - > ro = false ;
2020-09-10 14:32:52 +03:00
objectsql - > _mutex = object_lock ;
2020-09-10 10:08:29 +03:00
int rc = objectsql - > select ( db ) ;
if ( rc ! = 0 )
{
return nullptr ;
}
return objectsql ;
}
2008-06-17 20:27:32 +04:00
2018-10-09 12:05:08 +03:00
/**
* Gets a read only object from the pool ( if needed the object is loaded from the
2020-09-10 10:08:29 +03:00
* database ) . No object lock , other threads may work with the same object .
2018-10-09 12:05:08 +03:00
* @ param oid the object unique identifier
2020-09-10 10:08:29 +03:00
* @ return a pointer to the object , nullptr in case of failure
2018-10-09 12:05:08 +03:00
*/
2020-09-10 10:08:29 +03:00
template < typename T >
std : : unique_ptr < T > get_ro ( int oid )
{
if ( oid < 0 )
{
return nullptr ;
}
std : : unique_ptr < T > objectsql ( static_cast < T * > ( create ( ) ) ) ;
objectsql - > oid = oid ;
objectsql - > ro = true ;
int rc = objectsql - > select ( db ) ;
if ( rc ! = 0 )
{
return nullptr ;
}
return objectsql ;
}
2018-10-09 12:05:08 +03:00
2012-01-25 18:54:57 +04:00
/**
2018-03-18 01:31:52 +03:00
* Check if there is an object with the same for a given user
* @ param name of object
* @ param ouid of user
2012-01-25 18:54:57 +04:00
*
2018-03-18 01:31:52 +03:00
* @ return oid of the object if it exists , - 1 otherwise
2012-01-25 18:54:57 +04:00
*/
2020-07-02 23:42:10 +03:00
int exist ( const std : : string & name , int ouid )
2018-03-18 01:31:52 +03:00
{
return PoolObjectSQL : : select_oid ( db , table . c_str ( ) , name , ouid ) ;
}
2020-07-02 23:42:10 +03:00
int exist ( const std : : string & name )
2018-03-18 01:31:52 +03:00
{
return PoolObjectSQL : : select_oid ( db , table . c_str ( ) , name , - 1 ) ;
}
int exist ( int oid )
{
return PoolObjectSQL : : exist ( db , table . c_str ( ) , oid ) ;
}
2012-01-25 18:54:57 +04:00
2020-07-02 23:42:10 +03:00
void exist ( const std : : string & id_str , std : : set < int > & id_list ) ;
2018-11-20 19:24:59 +03:00
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 (
2020-07-02 23:42:10 +03:00
std : : vector < int > & oids ,
const char * table ,
const std : : string & where ) ;
2010-04-03 18:54:54 +04:00
2013-06-27 03:11:41 +04:00
/**
* List the objects in the pool
* @ param oids a vector with the oids of the objects .
2013-07-12 18:51:36 +04:00
* @ param table the name of the DB table .
2013-06-27 03:11:41 +04:00
*
* @ return 0 on success
*/
int list (
2020-07-02 23:42:10 +03:00
std : : vector < int > & oids ,
const char * table )
2013-06-27 03:11:41 +04:00
{
return search ( oids , table , " " ) ;
}
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 )
{
2021-02-08 18:10:34 +03:00
return objsql - > update ( db ) ;
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
*/
2020-07-02 23:42:10 +03:00
virtual int drop ( PoolObjectSQL * objsql , std : : string & error_msg )
2010-04-06 01:34:09 +04:00
{
2018-03-18 01:31:52 +03:00
int rc = objsql - > drop ( db ) ;
2011-06-08 21:18:12 +04:00
if ( rc ! = 0 )
{
error_msg = " SQL DB error " ;
return - 1 ;
}
return 0 ;
2010-04-06 01:34:09 +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
2018-07-24 12:41:41 +03:00
* @ param desc descending order of pool elements
2010-04-21 17:06:26 +04:00
*
* @ return 0 on success
*/
2020-07-02 23:42:10 +03:00
int dump ( std : : string & oss , const std : : string & where , bool desc )
2014-01-13 19:30:43 +04:00
{
2020-04-13 18:32:21 +03:00
return dump ( oss , where , 0 , - 1 , desc ) ;
2014-01-13 19:30:43 +04:00
}
/**
* Dumps the pool in XML format . A filter and limit 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
2020-04-13 18:32:21 +03:00
* @ param sid first element used for pagination
* @ param eid last element used for pagination , - 1 to disable
2018-07-24 12:41:41 +03:00
* @ param desc descending order of pool elements
2014-01-13 19:30:43 +04:00
*
* @ return 0 on success
*/
2020-07-02 23:42:10 +03:00
virtual int dump ( std : : string & oss , const std : : string & where ,
int sid , int eid ,
bool desc ) = 0 ;
2010-04-21 17:06:26 +04:00
2019-03-29 14:43:59 +03:00
/**
* Dumps the pool in extended XML format
* A filter and limit 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
2020-04-13 18:32:21 +03:00
* @ param sid first element used for pagination
* @ param eid last element used for pagination , - 1 to disable
2019-03-29 14:43:59 +03:00
* @ param desc descending order of pool elements
*
* @ return 0 on success
*/
2020-07-02 23:42:10 +03:00
virtual int dump_extended ( std : : string & oss ,
const std : : string & where ,
2020-04-13 18:32:21 +03:00
int sid ,
int eid ,
2019-03-29 14:43:59 +03:00
bool desc )
{
2020-04-13 18:32:21 +03:00
return dump ( oss , where , sid , eid , desc ) ;
2019-03-29 14:43:59 +03:00
}
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
2013-08-23 17:36:43 +04:00
* @ param user_groups Set of group IDs that the user is part of
2012-05-05 05:18:25 +04:00
* @ param auth_object object type
* @ param all returns if the user can access all objects
2014-09-23 22:18:18 +04:00
* @ param disable_all_acl e . g . NET \ *
* @ param disable_cluster_acl e . g . NET / % 100
* @ param disable_group_acl e . g . NET / @ 102
2012-05-05 05:18:25 +04:00
* @ param filter the resulting filter string
2014-09-23 22:18:18 +04:00
*
2012-05-04 19:27:57 +04:00
*/
2012-10-08 01:33:19 +04:00
static void acl_filter ( int uid ,
2020-07-02 23:42:10 +03:00
const std : : set < int > & user_groups ,
2012-05-05 05:18:25 +04:00
PoolObjectSQL : : ObjectType auth_object ,
bool & all ,
2014-09-23 22:18:18 +04:00
bool disable_all_acl ,
bool disable_cluster_acl ,
bool disable_group_acl ,
2020-07-02 23:42:10 +03:00
std : : string & filter ) ;
2012-05-05 05:18:25 +04:00
/**
* Creates a filter for the objects owned by a given user / group
* @ param uid the user id
2016-09-30 18:31:49 +03:00
* @ param gid the primary group of the user
2013-08-23 17:36:43 +04:00
* @ param user_groups Set of group IDs that the user is part of
2012-05-05 05:18:25 +04:00
* @ param filter_flag query type ( ALL , MINE , GROUP )
* @ param all user can access all objects
* @ param filter the resulting filter string
*/
2020-07-02 23:42:10 +03:00
static void usr_filter ( int uid ,
int gid ,
const std : : set < int > & user_groups ,
int filter_flag ,
bool all ,
const std : : string & acl_str ,
std : : string & filter ) ;
2012-05-05 05:18:25 +04:00
/**
* 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
*/
2020-07-02 23:42:10 +03:00
static void oid_filter ( int start_id ,
int end_id ,
std : : string & filter ) ;
2019-01-30 02:10:18 +03:00
/**
* This function returns a legal SQL string that can be used in an SQL
* statement . The string is encoded to an escaped SQL string , taking into
* account the current character set of the connection .
* @ param str the string to be escaped
* @ return a valid SQL string or NULL in case of failure
*/
2020-07-02 23:42:10 +03:00
char * escape_str ( const std : : string & str )
2019-01-30 02:10:18 +03:00
{
return db - > escape_str ( str ) ;
}
/**
* Frees a previously scaped string
* @ param str pointer to the str
*/
void free_str ( char * str )
{
db - > free_str ( str ) ;
}
2019-01-31 19:09:47 +03:00
/**
2020-04-13 18:32:21 +03:00
* Return true if feature is supported
2019-01-31 19:09:47 +03:00
*/
2020-04-13 18:32:21 +03:00
bool supports ( SqlDB : : SqlFeature ft )
2019-01-31 19:09:47 +03:00
{
2020-04-13 18:32:21 +03:00
return db - > supports ( ft ) ;
2019-01-31 19:09:47 +03:00
}
2020-04-13 18:32:21 +03:00
2008-06-17 20:27:32 +04:00
protected :
2012-04-20 12:23:51 +04:00
/**
* Gets an object from the pool ( if needed the object is loaded from the
2020-09-10 10:08:29 +03:00
* database ) . The object is locked , other threads can ' t access the same
* object . The lock is released by destructor .
2012-04-20 12:23:51 +04:00
* @ param name of the object
* @ param uid id of owner
*
* @ return a pointer to the object , 0 in case of failure
*/
2020-09-10 10:08:29 +03:00
template < typename T >
std : : unique_ptr < T > get ( const std : : string & name , int uid )
{
int oid = PoolObjectSQL : : select_oid ( db , table . c_str ( ) , name , uid ) ;
if ( oid = = - 1 )
{
return nullptr ;
}
return get < T > ( oid ) ;
}
2012-04-20 12:23:51 +04:00
2018-10-09 12:05:08 +03:00
/**
* Gets a read only object from the pool ( if needed the object is loaded from the
* database ) .
* @ param name of the object
* @ param uid id of owner
*
* @ return a pointer to the object , 0 in case of failure
*/
2020-09-10 10:08:29 +03:00
template < typename T >
std : : unique_ptr < T > get_ro ( const std : : string & name , int uid )
{
int oid = PoolObjectSQL : : select_oid ( db , table . c_str ( ) , name , uid ) ;
if ( oid = = - 1 )
{
return nullptr ;
}
return get_ro < T > ( oid ) ;
}
2018-10-09 12:05:08 +03:00
2008-06-17 20:27:32 +04:00
/**
* Pointer to the database .
*/
2010-04-03 18:54:54 +04:00
SqlDB * db ;
2014-01-13 19:30:43 +04:00
/**
* Dumps the pool in XML format . A filter and limit 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
2020-04-13 18:32:21 +03:00
* @ param start_id first element used for pagination
* @ param end_id last element used for pagination , - 1 to disable
2018-07-24 12:41:41 +03:00
* @ param desc descending order of pool elements
2014-01-13 19:30:43 +04:00
*
* @ return 0 on success
*/
2020-07-02 23:42:10 +03:00
int dump ( std : : string & oss ,
const std : : string & elem_name ,
const std : : string & column ,
const char * table ,
const std : : string & where ,
int start_id ,
int end_id ,
bool desc ) ;
2014-01-13 19:30:43 +04:00
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
2018-07-24 12:41:41 +03:00
* @ param desc descending order of pool elements
2011-03-09 13:23:58 +03:00
*
* @ return 0 on success
*/
2020-07-02 23:42:10 +03:00
int dump ( std : : string & oss ,
const std : : string & elem_name ,
const char * table ,
const std : : string & where ,
bool desc )
2014-01-13 19:30:43 +04:00
{
2020-04-13 18:32:21 +03:00
return dump ( oss , elem_name , " body " , table , where , 0 , - 1 , desc ) ;
2014-01-13 19:30:43 +04:00
}
2012-05-05 05:18:25 +04:00
/**
* 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
*/
2020-07-02 23:42:10 +03:00
int dump ( std : : string & oss ,
const std : : string & root_elem_name ,
std : : 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-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
*/
2017-05-06 01:20:29 +03:00
int get_lastOID ( ) ;
2011-03-17 23:04:24 +03:00
2011-05-21 04:06:29 +04:00
/**
* Sets the lastOID of the pool and updates the control database
* @ param _lastOID for the pool
*/
2017-05-06 01:20:29 +03:00
void set_lastOID ( int _lastOID ) ;
2011-05-21 04:06:29 +04:00
2008-06-17 20:27:32 +04:00
private :
2020-09-10 14:32:52 +03:00
std : : mutex _mutex ;
2008-06-17 20:27:32 +04:00
2011-05-09 18:09:56 +04:00
/**
* Tablename for this pool
*/
2020-07-02 23:42:10 +03:00
std : : string table ;
2011-05-09 18:09:56 +04:00
2008-06-17 20:27:32 +04:00
/**
2018-03-18 01:31:52 +03:00
* The pool cache is implemented with a Map of SQL object pointers ,
* using the OID as key .
2008-06-17 20:27:32 +04:00
*/
2018-03-18 01:31:52 +03:00
PoolSQLCache cache ;
2011-03-05 05:24:11 +03:00
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-21 17:06:26 +04:00
# endif /*POOL_SQL_H_*/