Extraction.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. //
  2. // Extraction.h
  3. //
  4. // $Id: //poco/Main/Data/include/Poco/Data/Extraction.h#7 $
  5. //
  6. // Library: Data
  7. // Package: DataCore
  8. // Module: Extraction
  9. //
  10. // Definition of the Extraction class.
  11. //
  12. // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Data_Extraction_INCLUDED
  38. #define Data_Extraction_INCLUDED
  39. #include "Poco/Data/Data.h"
  40. #include "Poco/Data/AbstractExtraction.h"
  41. #include "Poco/Data/Prepare.h"
  42. #include "Poco/Data/TypeHandler.h"
  43. #include "Poco/Data/Column.h"
  44. #include "Poco/Data/DataException.h"
  45. #include <set>
  46. #include <vector>
  47. #include <list>
  48. #include <deque>
  49. #include <map>
  50. #include <cstddef>
  51. namespace Poco {
  52. namespace Data {
  53. template <class T>
  54. class Extraction: public AbstractExtraction
  55. /// Concrete Data Type specific extraction of values from a query result set.
  56. {
  57. public:
  58. Extraction(T& result): _rResult(result), _default(), _extracted(false)
  59. /// Creates an Extraction object, uses an empty object T as default value
  60. {
  61. }
  62. Extraction(T& result, const T& def): _rResult(result), _default(def), _extracted(false)
  63. /// Creates an Extraction object, uses the provided def object as default value
  64. {
  65. }
  66. ~Extraction()
  67. /// Destroys the Extraction object.
  68. {
  69. }
  70. std::size_t numOfColumnsHandled() const
  71. {
  72. return TypeHandler<T>::size();
  73. }
  74. std::size_t numOfRowsHandled() const
  75. {
  76. return 1u;
  77. }
  78. std::size_t numOfRowsAllowed() const
  79. {
  80. return 1u;
  81. }
  82. void extract(std::size_t pos)
  83. {
  84. if (_extracted) throw ExtractException("value already extracted");
  85. _extracted = true;
  86. TypeHandler<T>::extract(pos, _rResult, _default, getExtractor());
  87. }
  88. void reset()
  89. {
  90. _extracted = false;
  91. }
  92. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  93. {
  94. return new Prepare<T>(pPrep, pos, _default);
  95. }
  96. private:
  97. T& _rResult;
  98. T _default; // copy the default
  99. bool _extracted;
  100. };
  101. template <class T>
  102. class Extraction<std::vector<T> >: public AbstractExtraction
  103. /// Vector Data Type specialization for extraction of values from a query result set.
  104. {
  105. public:
  106. Extraction(std::vector<T>& result): _rResult(result), _default()
  107. {
  108. }
  109. Extraction(std::vector<T>& result, const T& def): _rResult(result), _default(def)
  110. {
  111. }
  112. virtual ~Extraction()
  113. {
  114. }
  115. std::size_t numOfColumnsHandled() const
  116. {
  117. return TypeHandler<T>::size();
  118. }
  119. std::size_t numOfRowsHandled() const
  120. {
  121. return _rResult.size();
  122. }
  123. std::size_t numOfRowsAllowed() const
  124. {
  125. return getLimit();
  126. }
  127. void extract(std::size_t pos)
  128. {
  129. _rResult.push_back(_default);
  130. TypeHandler<T>::extract(pos, _rResult.back(), _default, getExtractor());
  131. }
  132. virtual void reset()
  133. {
  134. }
  135. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  136. {
  137. return new Prepare<T>(pPrep, pos, _default);
  138. }
  139. protected:
  140. const std::vector<T>& result() const
  141. {
  142. return _rResult;
  143. }
  144. private:
  145. std::vector<T>& _rResult;
  146. T _default; // copy the default
  147. };
  148. template <class T>
  149. class Extraction<std::list<T> >: public AbstractExtraction
  150. /// List Data Type specialization for extraction of values from a query result set.
  151. {
  152. public:
  153. Extraction(std::list<T>& result): _rResult(result), _default()
  154. {
  155. }
  156. Extraction(std::list<T>& result, const T& def): _rResult(result), _default(def)
  157. {
  158. }
  159. virtual ~Extraction()
  160. {
  161. }
  162. std::size_t numOfColumnsHandled() const
  163. {
  164. return TypeHandler<T>::size();
  165. }
  166. std::size_t numOfRowsHandled() const
  167. {
  168. return _rResult.size();
  169. }
  170. std::size_t numOfRowsAllowed() const
  171. {
  172. return getLimit();
  173. }
  174. void extract(std::size_t pos)
  175. {
  176. _rResult.push_back(_default);
  177. TypeHandler<T>::extract(pos, _rResult.back(), _default, getExtractor());
  178. }
  179. virtual void reset()
  180. {
  181. }
  182. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  183. {
  184. return new Prepare<T>(pPrep, pos, _default);
  185. }
  186. protected:
  187. const std::list<T>& result() const
  188. {
  189. return _rResult;
  190. }
  191. private:
  192. std::list<T>& _rResult;
  193. T _default; // copy the default
  194. };
  195. template <class T>
  196. class Extraction<std::deque<T> >: public AbstractExtraction
  197. /// Deque Data Type specialization for extraction of values from a query result set.
  198. {
  199. public:
  200. Extraction(std::deque<T>& result): _rResult(result), _default()
  201. {
  202. }
  203. Extraction(std::deque<T>& result, const T& def): _rResult(result), _default(def)
  204. {
  205. }
  206. virtual ~Extraction()
  207. {
  208. }
  209. std::size_t numOfColumnsHandled() const
  210. {
  211. return TypeHandler<T>::size();
  212. }
  213. std::size_t numOfRowsHandled() const
  214. {
  215. return _rResult.size();
  216. }
  217. std::size_t numOfRowsAllowed() const
  218. {
  219. return getLimit();
  220. }
  221. void extract(std::size_t pos)
  222. {
  223. _rResult.push_back(_default);
  224. TypeHandler<T>::extract(pos, _rResult.back(), _default, getExtractor());
  225. }
  226. virtual void reset()
  227. {
  228. }
  229. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  230. {
  231. return new Prepare<T>(pPrep, pos, _default);
  232. }
  233. protected:
  234. const std::deque<T>& result() const
  235. {
  236. return _rResult;
  237. }
  238. private:
  239. std::deque<T>& _rResult;
  240. T _default; // copy the default
  241. };
  242. template <class T, class C = std::vector<T> >
  243. class InternalExtraction: public Extraction<C>
  244. /// Container Data Type specialization extension for extraction of values from a query result set.
  245. ///
  246. /// This class is intended for PocoData internal use - it is used by StatementImpl
  247. /// to automaticaly create internal Extraction in cases when statement returns data and no external storage
  248. /// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
  249. /// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
  250. /// owns the data vector pointer.
  251. ///
  252. /// InternalExtraction objects can not be copied or assigned.
  253. {
  254. public:
  255. explicit InternalExtraction(C& result, Column<T,C>* pColumn):
  256. Extraction<C>(result),
  257. _pColumn(pColumn)
  258. /// Creates InternalExtraction.
  259. {
  260. }
  261. ~InternalExtraction()
  262. /// Destroys InternalExtraction.
  263. {
  264. delete _pColumn;
  265. }
  266. void reset()
  267. {
  268. _pColumn->reset();
  269. }
  270. const T& value(int index) const
  271. {
  272. try
  273. {
  274. return Extraction<C>::result().at(index);
  275. }
  276. catch (std::out_of_range& ex)
  277. {
  278. throw RangeException(ex.what());
  279. }
  280. }
  281. const Column<T,C>& column() const
  282. {
  283. return *_pColumn;
  284. }
  285. private:
  286. InternalExtraction();
  287. InternalExtraction(const InternalExtraction&);
  288. InternalExtraction& operator = (const InternalExtraction&);
  289. Column<T,C>* _pColumn;
  290. };
  291. template <class T>
  292. class Extraction<std::set<T> >: public AbstractExtraction
  293. /// Set Data Type specialization for extraction of values from a query result set.
  294. {
  295. public:
  296. Extraction(std::set<T>& result): _rResult(result), _default()
  297. {
  298. }
  299. Extraction(std::set<T>& result, const T& def): _rResult(result), _default(def)
  300. {
  301. }
  302. ~Extraction()
  303. {
  304. }
  305. std::size_t numOfColumnsHandled() const
  306. {
  307. return TypeHandler<T>::size();
  308. }
  309. std::size_t numOfRowsHandled() const
  310. {
  311. return _rResult.size();
  312. }
  313. std::size_t numOfRowsAllowed() const
  314. {
  315. return getLimit();
  316. }
  317. void extract(std::size_t pos)
  318. {
  319. T tmp;
  320. TypeHandler<T>::extract(pos, tmp, _default, getExtractor());
  321. _rResult.insert(tmp);
  322. }
  323. void reset()
  324. {
  325. }
  326. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  327. {
  328. return new Prepare<T>(pPrep, pos, _default);
  329. }
  330. private:
  331. std::set<T>& _rResult;
  332. T _default; // copy the default
  333. };
  334. template <class T>
  335. class Extraction<std::multiset<T> >: public AbstractExtraction
  336. /// Multiset Data Type specialization for extraction of values from a query result set.
  337. {
  338. public:
  339. Extraction(std::multiset<T>& result): _rResult(result), _default()
  340. {
  341. }
  342. Extraction(std::multiset<T>& result, const T& def): _rResult(result), _default(def)
  343. {
  344. }
  345. ~Extraction()
  346. {
  347. }
  348. std::size_t numOfColumnsHandled() const
  349. {
  350. return TypeHandler<T>::size();
  351. }
  352. std::size_t numOfRowsHandled() const
  353. {
  354. return _rResult.size();
  355. }
  356. std::size_t numOfRowsAllowed() const
  357. {
  358. return getLimit();
  359. }
  360. void extract(std::size_t pos)
  361. {
  362. T tmp;
  363. TypeHandler<T>::extract(pos, tmp, _default, getExtractor());
  364. _rResult.insert(tmp);
  365. }
  366. void reset()
  367. {
  368. }
  369. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  370. {
  371. return new Prepare<T>(pPrep, pos, _default);
  372. }
  373. private:
  374. std::multiset<T>& _rResult;
  375. T _default; // copy the default
  376. };
  377. template <class K, class V>
  378. class Extraction<std::map<K, V> >: public AbstractExtraction
  379. /// Map Data Type specialization for extraction of values from a query result set.
  380. {
  381. public:
  382. Extraction(std::map<K, V>& result): _rResult(result), _default()
  383. {
  384. }
  385. Extraction(std::map<K, V>& result, const V& def): _rResult(result), _default(def)
  386. {
  387. }
  388. ~Extraction()
  389. {
  390. }
  391. std::size_t numOfColumnsHandled() const
  392. {
  393. return TypeHandler<V>::size();
  394. }
  395. std::size_t numOfRowsHandled() const
  396. {
  397. return _rResult.size();
  398. }
  399. std::size_t numOfRowsAllowed() const
  400. {
  401. return getLimit();
  402. }
  403. void extract(std::size_t pos)
  404. {
  405. V tmp;
  406. TypeHandler<V>::extract(pos, tmp, _default, getExtractor());
  407. _rResult.insert(std::make_pair(tmp(), tmp));
  408. }
  409. void reset()
  410. {
  411. }
  412. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  413. {
  414. return new Prepare<V>(pPrep, pos, _default);
  415. }
  416. private:
  417. std::map<K, V>& _rResult;
  418. V _default; // copy the default
  419. };
  420. template <class K, class V>
  421. class Extraction<std::multimap<K, V> >: public AbstractExtraction
  422. /// Multimap Data Type specialization for extraction of values from a query result set.
  423. {
  424. public:
  425. Extraction(std::multimap<K, V>& result): _rResult(result), _default()
  426. {
  427. }
  428. Extraction(std::multimap<K, V>& result, const V& def): _rResult(result), _default(def)
  429. {
  430. }
  431. ~Extraction()
  432. {
  433. }
  434. std::size_t numOfColumnsHandled() const
  435. {
  436. return TypeHandler<V>::size();
  437. }
  438. std::size_t numOfRowsHandled() const
  439. {
  440. return _rResult.size();
  441. }
  442. std::size_t numOfRowsAllowed() const
  443. {
  444. return getLimit();
  445. }
  446. void extract(std::size_t pos)
  447. {
  448. V tmp;
  449. TypeHandler<V>::extract(pos, tmp, _default, getExtractor());
  450. _rResult.insert(std::make_pair(tmp(), tmp));
  451. }
  452. void reset()
  453. {
  454. }
  455. AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
  456. {
  457. return new Prepare<V>(pPrep, pos, _default);
  458. }
  459. private:
  460. std::multimap<K, V>& _rResult;
  461. V _default; // copy the default
  462. };
  463. template <typename T> Extraction<T>* into(T& t)
  464. /// Convenience function to allow for a more compact creation of a default extraction object
  465. {
  466. return new Extraction<T>(t);
  467. }
  468. template <typename T> Extraction<T>* into(T& t, const T& def)
  469. /// Convenience function to allow for a more compact creation of an extraction object with the given default
  470. {
  471. return new Extraction<T>(t, def);
  472. }
  473. } } // namespace Poco::Data
  474. #endif // Data_Extraction_INCLUDED