1 //
2 // AbstractExtraction.h
3 //
4 // Library: Data
5 // Package: DataCore
6 // Module:  AbstractExtraction
7 //
8 // Definition of the AbstractExtraction class.
9 //
10 // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier:	BSL-1.0
14 //
15 
16 
17 #ifndef Data_AbstractExtraction_INCLUDED
18 #define Data_AbstractExtraction_INCLUDED
19 
20 
21 #include "Poco/Data/Data.h"
22 #include "Poco/Data/AbstractExtractor.h"
23 #include "Poco/Data/AbstractPreparation.h"
24 #include "Poco/Data/Limit.h"
25 #include "Poco/RefCountedObject.h"
26 #include "Poco/UTFString.h"
27 #include "Poco/AutoPtr.h"
28 #include <vector>
29 #include <deque>
30 #include <list>
31 #include <cstddef>
32 
33 
34 namespace Poco {
35 namespace Data {
36 
37 
38 class AbstractPreparator;
39 
40 
41 class Data_API AbstractExtraction
42 	/// AbstractExtraction is the interface class that connects output positions to concrete values
43 	/// retrieved via an AbstractExtractor.
44 {
45 public:
46 	using Ptr = SharedPtr<AbstractExtraction>;
47 	using ExtractorPtr = SharedPtr<AbstractExtractor>;
48 	using PreparatorPtr = SharedPtr<AbstractPreparator>;
49 
50 	AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
51 		Poco::UInt32 position = 0, bool bulk = false);
52 		/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
53 		/// means that we extract as much data as possible during one execute.
54 		/// Otherwise the limit value is used to partition data extracting to a limited amount of rows.
55 
56 	virtual ~AbstractExtraction();
57 		/// Destroys the AbstractExtraction.
58 
59 	void setExtractor(ExtractorPtr pExtractor);
60 		/// Sets the class used for extracting the data. Does not take ownership of the pointer.
61 
62 	ExtractorPtr getExtractor() const;
63 		/// Retrieves the extractor object
64 
65 	Poco::UInt32 position() const;
66 		/// Returns the extraction position.
67 
68 	virtual std::size_t numOfColumnsHandled() const = 0;
69 		/// Returns the number of columns that the extraction handles.
70 		///
71 		/// The trivial case will be one single column but when
72 		/// complex types are used this value can be larger than one.
73 
74 	virtual std::size_t numOfRowsHandled() const = 0;
75 		/// Returns the number of rows that the extraction handles.
76 		///
77 		/// The trivial case will be one single row but
78 		/// for collection data types (ie vector) it can be larger.
79 
80 	virtual std::size_t numOfRowsAllowed() const = 0;
81 		/// Returns the upper limit on number of rows that the extraction will handle.
82 
83 	virtual std::size_t extract(std::size_t pos) = 0;
84 		/// Extracts a value from the param, starting at the given column position.
85 		/// Returns the number of rows extracted.
86 
87 	virtual void reset();
88 		/// Resets the extractor so that it can be re-used.
89 		/// Does nothing in this implementation.
90 		/// Implementations should override it for different behavior.
91 
92 	virtual bool canExtract() const;
93 		/// Returns true. Implementations should override it for different behavior.
94 
95 	virtual AbstractPreparation::Ptr createPreparation(PreparatorPtr& pPrep, std::size_t pos) = 0;
96 		/// Creates and returns shared pointer to Preparation object for the extracting object.
97 
98 	void setLimit(Poco::UInt32 limit);
99 		/// Sets the limit.
100 
101 	Poco::UInt32 getLimit() const;
102 		/// Gets the limit.
103 
104 	virtual bool isNull(std::size_t row) const;
105 		/// In implementations, this function returns true if value at row is null,
106 		/// false otherwise.
107 		/// Normal behavior is to replace nulls with default values.
108 		/// However, extraction implementations may remember the underlying database
109 		/// null values and be able to later provide information about them.
110 		/// Here, this function throws NotImplementedException.
111 
112 	bool isBulk() const;
113 		/// Returns true if this is bulk extraction.
114 
115 	void setEmptyStringIsNull(bool emptyStringIsNull);
116 		/// Sets the empty string handling flag.
117 
118 	bool getEmptyStringIsNull() const;
119 		/// Returns the empty string handling flag.
120 
121 	void setForceEmptyString(bool forceEmptyString);
122 		/// Sets the force empty string flag.
123 
124 	bool getForceEmptyString() const;
125 		/// Returns the force empty string flag.
126 
127 	template <typename T>
isValueNull(const T &,bool deflt)128 	bool isValueNull(const T& /*str*/, bool deflt)
129 		/// Utility function to determine the nullness of the value.
130 		/// This generic version always returns default value
131 		/// (i.e. does nothing). The std::string overload does
132 		/// the actual work.
133 		///
134 	{
135 		return deflt;
136 	}
137 
138 	bool isValueNull(const std::string& str, bool deflt);
139 		/// Overload for const reference to std::string.
140 		///
141 		/// Returns true when folowing conditions are met:
142 		///
143 		/// - string is empty
144 		/// - getEmptyStringIsNull() returns true
145 
146 	bool isValueNull(const Poco::UTF16String& str, bool deflt);
147 		/// Overload for const reference to UTF16String.
148 		///
149 		/// Returns true when folowing conditions are met:
150 		///
151 		/// - string is empty
152 		/// - getEmptyStringIsNull() returns true
153 
154 private:
155 	template <typename S>
isStringNull(const S & str,bool deflt)156 	bool isStringNull(const S& str, bool deflt)
157 	{
158 		if (getForceEmptyString()) return false;
159 
160 		if (getEmptyStringIsNull() && str.empty())
161 			return true;
162 
163 		return deflt;
164 	}
165 
166 	ExtractorPtr _pExtractor;
167 	Poco::UInt32 _limit;
168 	Poco::UInt32 _position;
169 	bool         _bulk;
170 	bool         _emptyStringIsNull;
171 	bool         _forceEmptyString;
172 };
173 
174 
175 using AbstractExtractionVec = std::vector<AbstractExtraction::Ptr>;
176 using AbstractExtractionVecVec = std::vector<AbstractExtractionVec>;
177 using AbstractExtractionDeq = std::deque<AbstractExtraction::Ptr>;
178 using AbstractExtractionDeqVec = std::vector<AbstractExtractionDeq>;
179 using AbstractExtractionLst = std::list<AbstractExtraction::Ptr>;
180 using AbstractExtractionLstVec = std::vector<AbstractExtractionLst>;
181 
182 
183 //
184 // inlines
185 //
setExtractor(ExtractorPtr pExtractor)186 inline void AbstractExtraction::setExtractor(ExtractorPtr pExtractor)
187 {
188 	_pExtractor = pExtractor;
189 }
190 
191 
getExtractor()192 inline AbstractExtraction::ExtractorPtr AbstractExtraction::getExtractor() const
193 {
194 	return _pExtractor;
195 }
196 
197 
setLimit(Poco::UInt32 limit)198 inline void AbstractExtraction::setLimit(Poco::UInt32 limit)
199 {
200 	_limit = limit;
201 }
202 
203 
getLimit()204 inline Poco::UInt32 AbstractExtraction::getLimit() const
205 {
206 	return _limit;
207 }
208 
209 
isNull(std::size_t)210 inline bool AbstractExtraction::isNull(std::size_t /*row*/) const
211 {
212 	throw NotImplementedException("Check for null values not implemented.");
213 }
214 
215 
position()216 inline Poco::UInt32 AbstractExtraction::position() const
217 {
218 	return _position;
219 }
220 
221 
isBulk()222 inline bool AbstractExtraction::isBulk() const
223 {
224 	return _bulk;
225 }
226 
227 
reset()228 inline void AbstractExtraction::reset()
229 {
230 }
231 
232 
canExtract()233 inline bool AbstractExtraction::canExtract() const
234 {
235 	return true;
236 }
237 
238 
setEmptyStringIsNull(bool emptyStringIsNull)239 inline void AbstractExtraction::setEmptyStringIsNull(bool emptyStringIsNull)
240 {
241 	_emptyStringIsNull = emptyStringIsNull;
242 }
243 
244 
getEmptyStringIsNull()245 inline bool AbstractExtraction::getEmptyStringIsNull() const
246 {
247 	return _emptyStringIsNull;
248 }
249 
250 
setForceEmptyString(bool forceEmptyString)251 inline void AbstractExtraction::setForceEmptyString(bool forceEmptyString)
252 {
253 	_forceEmptyString = forceEmptyString;
254 }
255 
256 
getForceEmptyString()257 inline bool AbstractExtraction::getForceEmptyString() const
258 {
259 	return _forceEmptyString;
260 }
261 
262 
isValueNull(const std::string & str,bool deflt)263 inline bool AbstractExtraction::isValueNull(const std::string& str, bool deflt)
264 {
265 	return isStringNull(str, deflt);
266 }
267 
268 
isValueNull(const Poco::UTF16String & str,bool deflt)269 inline bool AbstractExtraction::isValueNull(const Poco::UTF16String& str, bool deflt)
270 {
271 	return isStringNull(str, deflt);
272 }
273 
274 
275 } } // namespace Poco::Data
276 
277 
278 #endif // Data_AbstractExtraction_INCLUDED
279