poco/Data/include/Poco/Data/AbstractExtraction.h
Aleksandar Fabijanic c7d16b2a7e
4368 oracle odbc tests (#4410)
* feat(format): Add string_view format type spec #4409

* chore(Types): add demangle

* fix(Data): Oracle failing ODBC tests #4368

* fix some CQL and fuzz warnings; add Var::typeName()

* fix(build): -std=c++17 and c11

* fix windows build

* fix(Foundation): test apps vs projects c++17

* chore(build): remove uneeded compiler flag

* fix(VarHolder): number of digits range check for int->float conversion (reported by CIFuzz)

* fix(test): CIFuzz

* fix(CIFuzz): another attempt

* fix(progen): add LanguageStandard (stdcpp17, stdc11); regenerate vs170 projects

* fix(CiFuzz): add int->float precision loss barrier; fix erroneous number of digits logic

* enh(Var): silent loss of precision on int->float conversion #4423

* enh(Var): silent loss of precision on int->float conversion #4423

* chore(build): remove old build files

* chore: fix missing parens warning

* enh(Thread_POSIX): prevent double-joining; add error description to exceptions

* fix(Data): unresolved Column<long> linkage in test

* fix(demangle): determine type name from template parameter; add eror diagnostic for demangling failures

* chore(buildwin): remove old vs versions from build and progen scripts; update documentation

* chore(buildwin): remove leftover closing curly
2024-01-31 22:07:07 +01:00

299 lines
7.5 KiB
C++

//
// AbstractExtraction.h
//
// Library: Data
// Package: DataCore
// Module: AbstractExtraction
//
// Definition of the AbstractExtraction class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_AbstractExtraction_INCLUDED
#define Data_AbstractExtraction_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/Data/AbstractPreparation.h"
#include "Poco/Data/Limit.h"
#include "Poco/RefCountedObject.h"
#include "Poco/UTFString.h"
#include "Poco/AutoPtr.h"
#include <vector>
#include <deque>
#include <list>
#include <cstddef>
namespace Poco {
namespace Data {
class AbstractPreparator;
class Data_API AbstractExtraction
/// AbstractExtraction is the interface class that connects output positions to concrete values
/// retrieved via an AbstractExtractor.
{
public:
using Ptr = SharedPtr<AbstractExtraction>;
using ExtractorPtr = SharedPtr<AbstractExtractor>;
using PreparatorPtr = SharedPtr<AbstractPreparator>;
AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
Poco::UInt32 position = 0, bool bulk = false);
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
/// means that we extract as much data as possible during one execute.
/// Otherwise the limit value is used to partition data extracting to a limited amount of rows.
virtual ~AbstractExtraction();
/// Destroys the AbstractExtraction.
void setExtractor(ExtractorPtr pExtractor);
/// Sets the class used for extracting the data. Does not take ownership of the pointer.
ExtractorPtr getExtractor() const;
/// Retrieves the extractor object
Poco::UInt32 position() const;
/// Returns the extraction position.
virtual std::size_t numOfColumnsHandled() const = 0;
/// Returns the number of columns that the extraction handles.
///
/// The trivial case will be one single column but when
/// complex types are used this value can be larger than one.
virtual std::size_t numOfRowsHandled() const = 0;
/// Returns the number of rows that the extraction handles.
///
/// The trivial case will be one single row but
/// for collection data types (ie vector) it can be larger.
virtual std::size_t numOfRowsAllowed() const = 0;
/// Returns the upper limit on number of rows that the extraction will handle.
virtual std::size_t extract(std::size_t pos) = 0;
/// Extracts a value from the param, starting at the given column position.
/// Returns the number of rows extracted.
virtual void reset();
/// Resets the extractor so that it can be re-used.
/// Does nothing in this implementation.
/// Implementations should override it for different behavior.
virtual bool canExtract() const;
/// Returns true. Implementations should override it for different behavior.
virtual AbstractPreparation::Ptr createPreparation(PreparatorPtr& pPrep, std::size_t pos) = 0;
/// Creates and returns shared pointer to Preparation object for the extracting object.
void setLimit(Poco::UInt32 limit);
/// Sets the limit.
Poco::UInt32 getLimit() const;
/// Gets the limit.
virtual bool isNull(std::size_t row) const;
/// In implementations, this function returns true if value at row is null,
/// false otherwise.
/// Normal behavior is to replace nulls with default values.
/// However, extraction implementations may remember the underlying database
/// null values and be able to later provide information about them.
/// Here, this function throws NotImplementedException.
bool isBulk() const;
/// Returns true if this is bulk extraction.
void setEmptyStringIsNull(bool emptyStringIsNull);
/// Sets the empty string handling flag.
bool getEmptyStringIsNull() const;
/// Returns the empty string handling flag.
void setForceEmptyString(bool forceEmptyString);
/// Sets the force empty string flag.
bool getForceEmptyString() const;
/// Returns the force empty string flag.
template <typename T>
bool isValueNull(const T& /*str*/, bool deflt)
/// Utility function to determine the nullness of the value.
/// This generic version always returns default value
/// (i.e. does nothing). The std::string overload does
/// the actual work.
///
{
return deflt;
}
bool isValueNull(const std::string& str, bool deflt);
/// Overload for const reference to std::string.
///
/// Returns true when folowing conditions are met:
///
/// - string is empty
/// - getEmptyStringIsNull() returns true
bool isValueNull(const Poco::UTF16String& str, bool deflt);
/// Overload for const reference to UTF16String.
///
/// Returns true when folowing conditions are met:
///
/// - string is empty
/// - getEmptyStringIsNull() returns true
std::string getHeldType() const
/// Returns the held type name, if set.
/// If held type name is not set, returns empty string.
/// Held type is optionally set by calling setHeldType<T>()
/// in child classes.
/// Useful for dynamic_cast failure diagnostics.
{
std::string held;
if (_pHeldType) held = *_pHeldType;
return held;
}
protected:
template<typename T>
void setHeldType()
{
_pHeldType.reset(new std::string(Poco::demangle<T>()));
}
private:
template <typename S>
bool isStringNull(const S& str, bool deflt)
{
if (getForceEmptyString()) return false;
if (getEmptyStringIsNull() && str.empty())
return true;
return deflt;
}
ExtractorPtr _pExtractor;
Poco::UInt32 _limit;
Poco::UInt32 _position;
bool _bulk;
bool _emptyStringIsNull;
bool _forceEmptyString;
std::unique_ptr<std::string> _pHeldType;
};
using AbstractExtractionVec = std::vector<AbstractExtraction::Ptr>;
using AbstractExtractionVecVec = std::vector<AbstractExtractionVec>;
using AbstractExtractionDeq = std::deque<AbstractExtraction::Ptr>;
using AbstractExtractionDeqVec = std::vector<AbstractExtractionDeq>;
using AbstractExtractionLst = std::list<AbstractExtraction::Ptr>;
using AbstractExtractionLstVec = std::vector<AbstractExtractionLst>;
//
// inlines
//
inline void AbstractExtraction::setExtractor(ExtractorPtr pExtractor)
{
_pExtractor = pExtractor;
}
inline AbstractExtraction::ExtractorPtr AbstractExtraction::getExtractor() const
{
return _pExtractor;
}
inline void AbstractExtraction::setLimit(Poco::UInt32 limit)
{
_limit = limit;
}
inline Poco::UInt32 AbstractExtraction::getLimit() const
{
return _limit;
}
inline bool AbstractExtraction::isNull(std::size_t /*row*/) const
{
throw NotImplementedException("Check for null values not implemented.");
}
inline Poco::UInt32 AbstractExtraction::position() const
{
return _position;
}
inline bool AbstractExtraction::isBulk() const
{
return _bulk;
}
inline void AbstractExtraction::reset()
{
}
inline bool AbstractExtraction::canExtract() const
{
return true;
}
inline void AbstractExtraction::setEmptyStringIsNull(bool emptyStringIsNull)
{
_emptyStringIsNull = emptyStringIsNull;
}
inline bool AbstractExtraction::getEmptyStringIsNull() const
{
return _emptyStringIsNull;
}
inline void AbstractExtraction::setForceEmptyString(bool forceEmptyString)
{
_forceEmptyString = forceEmptyString;
}
inline bool AbstractExtraction::getForceEmptyString() const
{
return _forceEmptyString;
}
inline bool AbstractExtraction::isValueNull(const std::string& str, bool deflt)
{
return isStringNull(str, deflt);
}
inline bool AbstractExtraction::isValueNull(const Poco::UTF16String& str, bool deflt)
{
return isStringNull(str, deflt);
}
} } // namespace Poco::Data
#endif // Data_AbstractExtraction_INCLUDED