Commit 827f7835 authored by Andrea Valassi's avatar Andrea Valassi
Browse files

Add private 28PATCHES2013 (again) and also USERCONTEXT. Will delete this tag.


git-svn-id: file:///git/lcgcool.svndb/cool/tags/COOL_2_8-patches@19447 4525493e-7705-40b1-a816-d608a930855b
parent 8bef75f4
#ifndef COOLKERNEL_IFIELD_H
#define COOLKERNEL_IFIELD_H 1
// First of all, enable or disable the COOL290 API extensions (see bug #92204)
#include "CoolKernel/VersionInfo.h"
// Include files
#include "CoolKernel/IFieldSpecification.h"
#include "CoolKernel/RecordException.h"
// Forward declarations
namespace coral
{
class Attribute;
}
namespace cool
{
//--------------------------------------------------------------------------
/** @class IField IField.h
*
* Abstract interface to a data field of user-defined name and storage type.
*
* A field is a transient data value that can be made persistent.
* Its StorageType specification defines constraints on its allowed
* data values (e.g. strings of less than 256 characters), to ensure
* portability across different platforms and persistent backends.
* While each StorageType is associated to a platform-dependent transient
* C++ type and to a backend-dependent persistent (e.g. SQL) data type,
* the StorageType class allows users to write their code to define and
* handles records and fields in a platform- and backend-independent way.
*
* All methods of the IField interface are const except for the two
* methods (setValue and setNull) that allow changes to the data values.
* Implementations of IField are responsible for enforcing the
* StorageType constraints on the data values in these two and all other
* non-const methods, as well as at construction and assignment time.
* The use of const_cast on any const method is highly discouraged
* as it may lead to data corruption inside the IField instance.
*
* The data values at construction time are defined in the concrete
* implementations of the IField interface: default C++ values are
* recommended over nulls for all storage types (0 for numbers and
* chars, false for bool, "" for strings, empty blob for blobs).
* The value of a field is either null or a well-defined true type.
* Once the field has been set to null, its previous true type value
* is lost and the field can only be set again to non-null by setting
* it equal to a true type value using the setValue method: there is no
* such thing as a setNull(false) method to recover the previous value.
*
* Note the special semantics of null values for string variables only.
* For strings, setNull() is now considered equivalent to setValue(""):
* after such calls, isNull() returns false, and data() returns "".
* This has been introduced to avoid inconsistencies for Oracle databases
* (where empty strings are treated as SQL NULL values - see bug #22381).
* **WARNING**: CORAL Attribute's are different from COOL Field's in the
* management of null values. IField::data<T>() throws if IField::isNull()
* returns true, while coral::Attribute::data<T>() does not throw and
* returns an undefined value if coral::Attribute::isNull() returns true.
* Note also that IField::isNull() is always false for strings.
*
* It is not possible to change the name or storage types of a field
* via the IField interface: if necessary, this is the responsibility
* of the concrete classes implementing IField or IFieldSpecification.
*
* Implementations of the IField interface may or may not be based on
* the coral::Attribute class. To simplify the port of user code to the
* new API, an attribute() method is provided to retrieve the contents
* of the IField as a (read-only) constant Attribute reference.
* This is DEPRECATED and may be removed in a future COOL release.
* **WARNING**: in line with was explained above about CORAL Attribute's
* being different from COOL Field's in the management of null values, the
* Attribute reference returned by the attribute() method will behave as
* follows: for all types except strings, isNull() and attribute().isNull(),
* as well as data() and attribute().data(), always return the same value;
* for strings, isNull() always returns false, while data() returns ""
* if either of attribute().isNull() or attribute.data<std::string>()==""
* are true, but it is not guaranteed that both these conditions are true.
*
* @author Andrea Valassi and Marco Clemencic
* @date 2006-09-28
*/
class IField
{
public:
virtual ~IField() {}
/// Return the specification of this field.
virtual const IFieldSpecification& specification() const = 0;
/// Return the name of this field (from the spec).
const std::string& name() const;
/// Return the storage type of this field (from the spec).
const StorageType& storageType() const;
/// Is the value of this field null?
/// For strings, this is always false.
virtual bool isNull() const = 0;
/// Return the data value of this field (as true type).
/// Throw FieldWrongCppType if the field C++ type is not T.
/// Throw FieldIsNull the field is null, i.e. if isNull() is true.
/// For strings, return "" if setNull() was called.
template<typename T> const T& data() const;
/// Return the address of the true-type data value of this field.
/// Throw FieldIsNull the field is null, i.e. if isNull() is true.
/// For strings, return a pointer to "" if setNull() was called.
virtual const void* addressOfData() const = 0;
/// Set the value of this field to null: any previous value is lost.
/// For strings, setNull() is equivalent to setValue(""): data() and
/// addressOfData() will return "" and a pointer to "" after setNull().
virtual void setNull() = 0;
/// Set the value of this field to a well defined (non null) true-type.
/// Throw FieldWrongCppType if the field C++ type is not T.
/// For strings, setNull() is equivalent to setValue("").
template<typename T> void setValue( const T& value );
/// Set the value of this field equal to the value of another field
/// (with the same StorageType, but not necessarily the same name).
/// Throw FieldSpecificationWrongStorageType if field has the wrong type.
void setValue( const IField& field );
/// Compare the names, types and values of this and another field.
virtual bool operator== ( const IField& rhs ) const;
/// Compare the names, types and values of this and another field.
virtual bool operator!= ( const IField& rhs ) const;
/// Print the name, storage type and data value of this field.
virtual std::ostream& print( std::ostream& os ) const;
/// Print the data value of this field.
/// Print "NULL" if the field is null (print "" for null strings).
virtual std::ostream& printValue( std::ostream& os ) const = 0;
/// DEPRECATED - added for easier compatibility with COOL 1.3
/// (this is likely to be removed in a future COOL release).
/// Explicit conversion to a constant coral Attribute reference.
virtual const coral::Attribute& attribute() const = 0;
#ifdef COOL290
protected:
/// Standard constructor is protected (see bug #95823)
IField() {}
#endif
private:
#ifdef COOL290
/// Copy constructor is private (see bug #95823)
IField( const IField& rhs );
/// Assignment operator is private (see bug #95823)
IField& operator=( const IField& rhs );
#endif
/// Compare the values of this and another field.
/// The values of two fields are equal either if they are both non null
/// and their true type values are equal, or if they are both null.
/// Private method - this does not check that fields have the same type.
virtual bool compareValue( const IField& rhs ) const = 0;
/// Set the value of this field to a well defined (non null) true-type.
/// For strings, setNull() is equivalent to setValue("").
/// Throw FieldWrongCppType if the field C++ type is not cppType.
/// Private method - this will crash if the address is not of cppType type.
virtual void setValue( const std::type_info& cppType,
const void* externalAddress ) = 0;
};
/// Print the name, storage type and data value of a field.
std::ostream& operator<<( std::ostream& s, const IField& field );
//--------------------------------------------------------------------------
inline const std::string& IField::name() const
{
return specification().name();
}
//--------------------------------------------------------------------------
inline const StorageType& IField::storageType() const
{
return specification().storageType();
}
//--------------------------------------------------------------------------
template<typename T>
inline const T& IField::data() const
{
if ( this->storageType().cppType() != typeid(T) )
throw FieldWrongCppType
( this->name(), this->storageType(), typeid(T), "IField" );
if ( this->isNull() )
throw FieldIsNull
( this->name(), this->storageType(), "IField" );
return *( static_cast< const T* >( this->addressOfData() ) );
}
//--------------------------------------------------------------------------
template<typename T>
inline void IField::setValue( const T& value )
{
this->setValue( typeid(T), &value );
}
//--------------------------------------------------------------------------
/// Set value to null if the other field is null, else set value from C++
/// address of the other field's value (as in coral::Attribute::fastCopy).
inline void IField::setValue( const IField& field )
{
if ( this->storageType() != field.storageType() )
throw FieldSpecificationWrongStorageType
( this->name(), this->storageType(), field.storageType(), "IField" );
if ( field.isNull() )
this->setNull();
else
this->setValue( this->storageType().cppType(), field.addressOfData() );
}
//--------------------------------------------------------------------------
inline bool IField::operator==( const IField& rhs ) const
{
// Compare names, storage types and values
// (NB coral::Attribute::operator== does NOT compare names)
return ( this->specification() == rhs.specification() )
&& this->compareValue( rhs );
}
//--------------------------------------------------------------------------
inline bool IField::operator!=( const IField& rhs ) const
{
return ( ! ( *this == rhs ) );
}
//--------------------------------------------------------------------------
inline std::ostream& IField::print( std::ostream& s ) const
{
s << name() << " (" << storageType().name() << ") : ";
return this->printValue( s );
}
//--------------------------------------------------------------------------
inline std::ostream& operator<<( std::ostream& s, const IField& field )
{
return field.print( s );
}
//--------------------------------------------------------------------------
}
#endif // COOLKERNEL_IFIELD_H
#ifndef COOLKERNEL_IFIELDSPECIFICATION_H
#define COOLKERNEL_IFIELDSPECIFICATION_H 1
// First of all, enable or disable the COOL290 API extensions (see bug #92204)
#include "CoolKernel/VersionInfo.h"
// Include files
#include "CoolKernel/StorageType.h"
// Forward declarations
namespace coral
{
class Attribute;
}
namespace cool
{
// Forward declarations
class IField;
/** @class IFieldSpecification IFieldSpecification.h
*
* Abstract interface to the specification of a data field
* of user-defined name and storage type.
*
* A field is a transient data value that can be made persistent.
* Its StorageType specification defines constraints on its allowed
* data values (e.g. strings of less than 256 characters), to ensure
* portability across different platforms and persistent backends.
* While each StorageType is associated to a platform-dependent transient
* C++ type and to a backend-dependent persistent (e.g. SQL) data type,
* the StorageType class allows users to write their code to define and
* handles records and fields in a platform- and backend-independent way.
*
* The IFieldSpecification interface only allows read-only access to
* the specification of a record: appropriate methods to change the name
* or storage type of a field are meant to be defined and implemented in
* the concrete classes derived from it, if at all necessary.
*
* Implementations of IField and IRecord are responsible for enforcing
* the StorageType constraints on the data values in all of their
* non-const methods, as well as at construction and assignment time.
* The IFieldSpecification interface provides a validate() method to
* check if the data offered by a IField complies to the specification.
*
* Implementations of the IField interface may or may not be based
* on the coral::Attribute class. For internal COOL usage, another
* signature of the validate() method is provided to check if the
* data in an Attribue complies to the field specification.
* This is DEPRECATED and may be removed in a future COOL release.
* @author Andrea Valassi and Marco Clemencic
* @date 2006-09-22
*/
class IFieldSpecification
{
public:
virtual ~IFieldSpecification() {}
/// Return the name of this field.
virtual const std::string& name() const = 0;
/// Return the storage type of this field.
virtual const StorageType& storageType() const = 0;
/// Compare the names and storage types of this and another field.
virtual bool operator==( const IFieldSpecification& rhs ) const = 0;
/// Compare the names and storage types of this and another field.
virtual bool operator!=( const IFieldSpecification& rhs ) const = 0;
/// Check that a given field is compatible with this specification.
/// The field must have the same transient C++ type and a value
/// compatible with the persistent storage type of the 'reference' field.
/// If checkName is true, the field (as well as the attribute accessible
/// via the field) must also have the same name as the reference field (*).
/// Throw FieldSpecificationWrongName if field/attribute name is wrong (*).
/// Throw FieldSpecificationWrongStorageType if field has the wrong type.
/// Throw StorageTypeInvalidValue for values outside the allowed range.
virtual void validate( const IField& field,
bool checkName = true ) const = 0;
/// DEPRECATED - added for easier compatibility with COOL 1.3
/// (this is likely to be removed in a future COOL release).
/// Check that a given attribute is compatible with this specification.
/// The attribute must have the same transient C++ type and a value
/// compatible with the persistent storage type of the 'reference' field.
/// If checkName is true, the attribute must also have the same name (*).
/// Throw FieldSpecificationWrongName if attribute name is wrong (*).
/// Throw StorageTypeWrongCppType if the attribute has the wrong C++ type.
/// Throw StorageTypeInvalidValue for values outside the allowed range.
virtual void validate( const coral::Attribute& attribute,
bool checkName = true ) const = 0;
#ifdef COOL290
protected:
/// Standard constructor is protected (see bug #95823)
IFieldSpecification() {}
/// Copy constructor is protected (see bug #95823)
IFieldSpecification( const IFieldSpecification& ) {}
private:
/// Assignment operator is private (see bug #95823)
IFieldSpecification& operator=( const IFieldSpecification& rhs );
#endif
};
}
#endif // COOLKERNEL_IFIELDSPECIFICATION_H
#ifndef COOLKERNEL_IFOLDERSPECIFICATION_H
#define COOLKERNEL_IFOLDERSPECIFICATION_H 1
// First of all, enable or disable the COOL290 API extensions (see bug #92204)
#include "CoolKernel/VersionInfo.h"
// Include files
#include "CoolKernel/IRecordSpecification.h"
#include "CoolKernel/FolderVersioning.h"
#ifdef COOL290
#include "CoolKernel/PayloadMode.h"
#endif
namespace cool
{
//--------------------------------------------------------------------------
/** @class IFolderSpecification IFolderSpecification.h
*
* Abstract interface to the specification of a COOL "folder".
*
* This includes the payload specification and the versioning mode.
* The description is not included as it is a generic "HVS node"
* property (it applies to folder sets as well as to folders).
*
* This class only provides const access to the specification.
* Creating or modifying it is the task of concrete derived classes.
*
* @author Andrea Valassi and Marco Clemencic
* @date 2006-09-22
*/
class IFolderSpecification
{
public:
virtual ~IFolderSpecification() {}
/// Get the versioning mode (const).
virtual const FolderVersioning::Mode& versioningMode() const = 0;
/// Get the payload specification (const).
virtual const IRecordSpecification& payloadSpecification() const = 0;
/*
/// Get the channel specification (const).
virtual const IRecordSpecification& channelSpecification() const = 0;
*/
/// Get the payload table flag (const).
/// DEPRECATED!! This data member will be removed in COOL290!!
virtual const bool& hasPayloadTable() const = 0;
#ifdef COOL290
/// Get the payload mode (const).
virtual const PayloadMode::Mode& payloadMode() const = 0;
#endif
/// Comparison operator.
bool operator==( const IFolderSpecification& rhs ) const;
/// Comparison operator.
bool operator!=( const IFolderSpecification& rhs ) const;
#ifdef COOL290
protected:
/// Standard constructor is protected (see bug #95823)
IFolderSpecification() {}
private:
/// Copy constructor is private (see bug #95823)
IFolderSpecification( const IFolderSpecification& rhs );
/// Assignment operator is private (see bug #95823)
IFolderSpecification& operator=( const IFolderSpecification& rhs );
#endif
};
//--------------------------------------------------------------------------
inline bool
IFolderSpecification::operator==( const IFolderSpecification& rhs ) const
{
if ( versioningMode() != rhs.versioningMode() ) return false;
if ( payloadSpecification() != rhs.payloadSpecification() ) return false;
//if ( channelSpecification() != rhs.channelSpecification() ) return false;
if ( hasPayloadTable() != rhs.hasPayloadTable() ) return false;
return true;
}
//--------------------------------------------------------------------------
inline bool
IFolderSpecification::operator!=( const IFolderSpecification& rhs ) const
{
return ( ! ( *this == rhs ) );
}
//--------------------------------------------------------------------------
}
#endif // COOLKERNEL_IFOLDERSPECIFICATION_H
#ifndef COOLKERNEL_IRECORD_H
#define COOLKERNEL_IRECORD_H 1
// First of all, enable or disable the COOL290 API extensions (see bug #92204)
#include "CoolKernel/VersionInfo.h"
// Include files
#include <sstream>
#include "CoolKernel/IField.h"
#include "CoolKernel/IRecordSpecification.h"
// Forward declarations
namespace coral
{
class AttributeList;
}
namespace cool
{
//--------------------------------------------------------------------------
class IRecord
{
/** @class IRecord IRecord.h
*
* Abstract interface to a data record: an ordered collection
* of data fields of user-defined names and storage types.
*
* A field is a transient data value that can be made persistent.
* Its StorageType specification defines constraints on its allowed
* data values (e.g. strings of less than 256 characters), to ensure
* portability across different platforms and persistent backends.
* While each StorageType is associated to a platform-dependent transient
* C++ type and to a backend-dependent persistent (e.g. SQL) data type,
* the StorageType class allows users to write their code to define and
* handles records and fields in a platform- and backend-independent way.
*
* All public methods of the IRecord interface are const: this is in
* practice a read-only interface. The only non-const methods are those
* that allow non-const access to the IField interfaces of its fields:
* these are protected, to be used or implemented in derived classes.
* Implementations of IField and IRecord are responsible for enforcing
* the StorageType constraints on the data values in all of their
* non-const methods, as well as at construction and assignment time.
* The use of const_cast on any const method is highly discouraged
* as it may lead to data corruption inside the IRecord instance.
*
* It is not possible to add, remove, rename or change the types of fields
* via the IRecord interface: if necessary, this is the responsibility
* of the concrete classes implementing IRecord or IRecordSpecification.
*
* Field names are a property of fields and their specifications: record
* specifications only define which fields exist and in which order.
* The IRecord base class manages field names and indexes according
* to its record specification. The implementation of size, index and
* operator[] is inlined and delegated to IRecordSpecification, while
* the concrete derived classes must only implement the field() method.
*
* Implementations of the IRecord interface may or may not be based on
* the coral::AttributeList class. To simplify the port of user code,
* an attributeList() method is provided to retrieve the contents of
* the IRecord as a (read-only) constant AttributeList reference.
* This is DEPRECATED and may be removed in a future COOL release.
*
* @author Andrea Valassi and Marco Clemencic
* @date 2006-09-28
*/
public:
virtual ~IRecord() {}
/// Return the specification of this record.
virtual const IRecordSpecification& specification() const = 0;
/// Return the number of fields in this record (from the spec).
UInt32 size() const;
/// Return the index of a field in this record by its name (from the spec).
UInt32 index( const std::string& name ) const;
/// Return a field in this record by its name (const).
const IField& operator[] ( const std::string& name ) const;
/// Return a field in this record by its index in [0, N-1] (const).
const IField& operator[] ( UInt32 index ) const;
/// Comparison operator. Two records are equal if they have the same
/// fields (each with the same name, type and value), in the same order.
virtual bool operator== ( const IRecord& rhs ) const;
/// Comparison operator. Two records are equal if they have the same
/// fields (each with the same name, type and value), in the same order.
virtual bool operator!= ( const IRecord& rhs ) const;
/// Print the names, types and data values of all fields in this record.
virtual std::ostream& print( std::ostream& os ) const;
/// DEPRECATED - added for easier compatibility with COOL 1.3
/// (this is likely to be removed in a future COOL release).
/// Explicit conversion to a constant coral AttributeList reference.
virtual const coral::AttributeList& attributeList() const = 0;
protected:
<