1//
2// Statement.h
3//
4// Library: Data
5// Package: DataCore
6// Module: Statement
7//
8// Definition of the Statement 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_Statement_INCLUDED
18#define Data_Statement_INCLUDED
19
20
21#include "Poco/Data/Data.h"
22#include "Poco/Data/StatementImpl.h"
23#include "Poco/Data/Binding.h"
24#include "Poco/Data/Range.h"
25#include "Poco/Data/Bulk.h"
26#include "Poco/Data/Row.h"
27#include "Poco/Data/SimpleRowFormatter.h"
28#include "Poco/SharedPtr.h"
29#include "Poco/Mutex.h"
30#include "Poco/ActiveMethod.h"
31#include "Poco/ActiveResult.h"
32#include "Poco/Format.h"
33#include <algorithm>
34
35
36namespace Poco {
37namespace Data {
38
39
40class AbstractBinding;
41class AbstractExtraction;
42class Session;
43class Limit;
44
45
46class Data_API Statement
47 /// A Statement is used to execute SQL statements.
48 /// It does not contain code of its own.
49 /// Its main purpose is to forward calls to the concrete StatementImpl stored inside.
50 /// Statement execution can be synchronous or asynchronous.
51 /// Synchronous execution is achieved through execute() call, while asynchronous is
52 /// achieved through executeAsync() method call.
53 /// An asynchronously executing statement should not be copied during the execution.
54 ///
55 /// Note:
56 ///
57 /// Once set as asynchronous through 'async' manipulator, statement remains
58 /// asynchronous for all subsequent execution calls, both execute() and executeAsync().
59 /// However, calling executAsync() on a synchronous statement shall execute
60 /// asynchronously but without altering the underlying statement's synchronous nature.
61 ///
62 /// Once asynchronous, a statement can be reverted back to synchronous state in two ways:
63 ///
64 /// 1) By calling setAsync(false)
65 /// 2) By means of 'sync' or 'reset' manipulators
66 ///
67 /// See individual functions documentation for more details.
68 ///
69 /// Statement owns the RowFormatter, which can be provided externally through setFormatter()
70 /// member function.
71 /// If no formatter is externally supplied to the statement, the SimpleRowFormatter is lazy
72 /// created and used.
73{
74public:
75 typedef void (*Manipulator)(Statement&);
76
77 typedef ActiveResult<std::size_t> Result;
78 typedef SharedPtr<Result> ResultPtr;
79 typedef ActiveMethod<std::size_t, bool, StatementImpl> AsyncExecMethod;
80 typedef SharedPtr<AsyncExecMethod> AsyncExecMethodPtr;
81
82 static const int WAIT_FOREVER = -1;
83
84 enum Storage
85 {
86 STORAGE_DEQUE = StatementImpl::STORAGE_DEQUE_IMPL,
87 STORAGE_VECTOR = StatementImpl::STORAGE_VECTOR_IMPL,
88 STORAGE_LIST = StatementImpl::STORAGE_LIST_IMPL,
89 STORAGE_UNKNOWN = StatementImpl::STORAGE_UNKNOWN_IMPL
90 };
91
92 Statement(StatementImpl::Ptr pImpl);
93 /// Creates the Statement.
94
95 explicit Statement(Session& session);
96 /// Creates the Statement for the given Session.
97 ///
98 /// The following:
99 ///
100 /// Statement stmt(sess);
101 /// stmt << "SELECT * FROM Table", ...
102 ///
103 /// is equivalent to:
104 ///
105 /// Statement stmt(sess << "SELECT * FROM Table", ...);
106 ///
107 /// but in some cases better readable.
108
109 ~Statement();
110 /// Destroys the Statement.
111
112 Statement(const Statement& stmt);
113 /// Copy constructor.
114 /// If the statement has been executed asynchronously and has not been
115 /// synchronized prior to copy operation (i.e. is copied while executing),
116 /// this constructor shall synchronize it.
117
118 Statement& operator = (const Statement& stmt);
119 /// Assignment operator.
120
121 void swap(Statement& other);
122 /// Swaps the statement with another one.
123
124 template <typename T>
125 Statement& operator << (const T& t)
126 /// Concatenates data with the SQL statement string.
127 {
128 _pImpl->add(t);
129 return *this;
130 }
131
132 Statement& operator , (Manipulator manip);
133 /// Handles manipulators, such as now, async, etc.
134
135 Statement& operator , (AbstractBinding::Ptr pBind);
136 /// Registers the Binding with the Statement by calling addBind().
137
138 Statement& addBind(AbstractBinding::Ptr pBind);
139 /// Registers a single binding with the statement.
140
141 void removeBind(const std::string& name);
142 /// Removes the all the bindings with specified name from the statement.
143
144 Statement& operator , (AbstractBindingVec& bindVec);
145 /// Registers the Binding vector with the Statement.
146
147 template <typename C>
148 Statement& addBinding(C& bindingCont, bool doReset)
149 /// Registers binding container with the Statement.
150 {
151 if (doReset) _pImpl->resetBinding();
152 typename C::iterator itAB = bindingCont.begin();
153 typename C::iterator itABEnd = bindingCont.end();
154 for (; itAB != itABEnd; ++itAB) addBind(*itAB);
155 return *this;
156 }
157
158 Statement& operator , (AbstractExtraction::Ptr extract);
159 /// Registers objects used for extracting data with the Statement by
160 /// calling addExtract().
161
162 Statement& operator , (AbstractExtractionVec& extVec);
163 /// Registers the extraction vector with the Statement.
164 /// The vector is registered at position 0 (i.e. for the first returned data set).
165
166 Statement& operator , (AbstractExtractionVecVec& extVecVec);
167 /// Registers the vector of extraction vectors with the Statement.
168
169 template <typename C>
170 Statement& addExtraction(C& val, bool doReset)
171 /// Registers extraction container with the Statement.
172 {
173 if (doReset) _pImpl->resetExtraction();
174 typename C::iterator itAE = val.begin();
175 typename C::iterator itAEEnd = val.end();
176 for (; itAE != itAEEnd; ++itAE) addExtract(*itAE);
177 return *this;
178 }
179
180 template <typename C>
181 Statement& addExtractions(C& val)
182 /// Registers container of extraction containers with the Statement.
183 {
184 _pImpl->resetExtraction();
185 typename C::iterator itAEV = val.begin();
186 typename C::iterator itAEVEnd = val.end();
187 for (; itAEV != itAEVEnd; ++itAEV) addExtraction(*itAEV, false);
188 return *this;
189 }
190
191 Statement& addExtract(AbstractExtraction::Ptr pExtract);
192 /// Registers a single extraction with the statement.
193
194 Statement& operator , (const Bulk& bulk);
195 /// Sets the bulk execution mode (both binding and extraction) for this
196 /// statement.Statement must not have any extractors or binders set at the
197 /// time when this operator is applied.
198 /// Failure to adhere to the above constraint shall result in
199 /// InvalidAccessException.
200
201 Statement& operator , (BulkFnType);
202 /// Sets the bulk execution mode (both binding and extraction) for this
203 /// statement.Statement must not have any extractors or binders set at the
204 /// time when this operator is applied.
205 /// Additionally, this function requires limit to be set in order to
206 /// determine the bulk size.
207 /// Failure to adhere to the above constraints shall result in
208 /// InvalidAccessException.
209
210 Statement& operator , (const Limit& extrLimit);
211 /// Sets a limit on the maximum number of rows a select is allowed to return.
212 ///
213 /// Set per default to zero to Limit::LIMIT_UNLIMITED, which disables the limit.
214
215 Statement& operator , (RowFormatter::Ptr pRowFformatter);
216 /// Sets the row formatter for the statement.
217
218 Statement& operator , (const Range& extrRange);
219 /// Sets a an extraction range for the maximum number of rows a select is allowed to return.
220 ///
221 /// Set per default to Limit::LIMIT_UNLIMITED which disables the range.
222
223 Statement& operator , (char value);
224 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
225
226 Statement& operator , (Poco::UInt8 value);
227 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
228
229 Statement& operator , (Poco::Int8 value);
230 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
231
232 Statement& operator , (Poco::UInt16 value);
233 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
234
235 Statement& operator , (Poco::Int16 value);
236 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
237
238 Statement& operator , (Poco::UInt32 value);
239 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
240
241 Statement& operator , (Poco::Int32 value);
242 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
243
244#ifndef POCO_LONG_IS_64_BIT
245 Statement& operator , (long value);
246 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
247
248 Statement& operator , (unsigned long value);
249 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
250#endif
251 Statement& operator , (Poco::UInt64 value);
252 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
253
254 Statement& operator , (Poco::Int64 value);
255 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
256
257 Statement& operator , (double value);
258 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
259
260 Statement& operator , (float value);
261 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
262
263 Statement& operator , (bool value);
264 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
265
266 Statement& operator , (const std::string& value);
267 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
268
269 Statement& operator , (const char* value);
270 /// Adds the value to the list of values to be supplied to the SQL string formatting function.
271
272 const std::string& toString() const;
273 /// Creates a string from the accumulated SQL statement.
274
275 std::size_t execute(bool reset = true);
276 /// Executes the statement synchronously or asynchronously.
277 /// Stops when either a limit is hit or the whole statement was executed.
278 /// Returns the number of rows extracted from the database (for statements
279 /// returning data) or number of rows affected (for all other statements).
280 /// If reset is true (default), associated storage is reset and reused.
281 /// Otherwise, the results from this execution step are appended.
282 /// Reset argument has no meaning for unlimited statements that return all rows.
283 /// If isAsync() returns true, the statement is executed asynchronously
284 /// and the return value from this function is zero.
285 /// The result of execution (i.e. number of returned or affected rows) can be
286 /// obtained by calling wait() on the statement at a later point in time.
287
288 const Result& executeAsync(bool reset = true);
289 /// Executes the statement asynchronously.
290 /// Stops when either a limit is hit or the whole statement was executed.
291 /// Returns immediately. Calling wait() (on either the result returned from this
292 /// call or the statement itself) returns the number of rows extracted or number
293 /// of rows affected by the statement execution.
294 /// When executed on a synchronous statement, this method does not alter the
295 /// statement's synchronous nature.
296
297 void setAsync(bool async = true);
298 /// Sets the asynchronous flag. If this flag is true, executeAsync() is called
299 /// from the now() manipulator. This setting does not affect the statement's
300 /// capability to be executed synchronously by directly calling execute().
301
302 bool isAsync() const;
303 /// Returns true if statement was marked for asynchronous execution.
304
305 std::size_t wait(long milliseconds = WAIT_FOREVER);
306 /// Waits for the execution completion for asynchronous statements or
307 /// returns immediately for synchronous ones. The return value for
308 /// asynchronous statement is the execution result (i.e. number of
309 /// rows retrieved). For synchronous statements, the return value is zero.
310
311 bool initialized();
312 /// Returns true if the statement was initialized (i.e. not executed yet).
313
314 bool paused();
315 /// Returns true if the statement was paused (a range limit stopped it
316 /// and there is more work to do).
317
318 bool done();
319 /// Returns true if the statement was completely executed or false if a range limit stopped it
320 /// and there is more work to do. When no limit is set, it will always return true after calling execute().
321
322 Statement& reset(Session& session);
323 /// Resets the Statement so that it can be filled with a new SQL command.
324
325 bool canModifyStorage();
326 /// Returns true if statement is in a state that allows the internal storage to be modified.
327
328 Storage storage() const;
329 /// Returns the internal storage type for the statement.
330
331 void setStorage(const std::string& storage);
332 /// Sets the internal storage type for the statement.
333
334 const std::string& getStorage() const;
335 /// Returns the internal storage type for the statement.
336
337 std::size_t columnsExtracted(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
338 /// Returns the number of columns returned for current data set.
339 /// Default value indicates current data set (if any).
340
341 std::size_t rowsExtracted(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
342 /// Returns the number of rows returned for current data set during last statement
343 /// execution. Default value indicates current data set (if any).
344
345 std::size_t subTotalRowCount(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
346 /// Returns the number of rows extracted so far for the data set.
347 /// Default value indicates current data set (if any).
348
349 std::size_t totalRowCount() const;
350 //@ deprecated
351 /// Replaced with subTotalRowCount() and getTotalRowCount().
352
353 std::size_t getTotalRowCount() const;
354 /// Returns the total number of rows in the RecordSet.
355 /// The number of rows reported is independent of filtering.
356 /// If the total row count has not been set externally
357 /// (either explicitly or implicitly through SQL), the value
358 /// returned shall only be accurate if the statement limit
359 /// is less or equal to the total row count.
360
361 void setTotalRowCount(std::size_t totalRowCount);
362 /// Explicitly sets the total row count.
363
364 void setTotalRowCount(const std::string& sql);
365 /// Implicitly sets the total row count.
366 /// The supplied sql must return exactly one column
367 /// and one row. The returned value must be an unsigned
368 /// integer. The value is set as the total number of rows.
369
370 std::size_t extractionCount() const;
371 /// Returns the number of extraction storage buffers associated
372 /// with the current data set.
373
374 std::size_t dataSetCount() const;
375 /// Returns the number of data sets associated with the statement.
376
377 std::size_t nextDataSet();
378 /// Returns the index of the next data set.
379
380 std::size_t previousDataSet();
381 /// Returns the index of the previous data set.
382
383 bool hasMoreDataSets() const;
384 /// Returns false if the current data set index points to the last
385 /// data set. Otherwise, it returns true.
386
387 std::size_t firstDataSet();
388 /// Activates the first data set
389
390 std::size_t currentDataSet() const;
391 /// Returns the current data set.
392
393 void setRowFormatter(RowFormatter::Ptr pRowFormatter);
394 /// Sets the row formatter for this statement.
395 /// Statement takes the ownership of the formatter.
396
397 void insertHint();
398 /// Tells the statement that it is an sinsert one
399protected:
400 typedef StatementImpl::Ptr ImplPtr;
401
402 const AbstractExtractionVec& extractions() const;
403 /// Returns the extractions vector.
404
405 const MetaColumn& metaColumn(std::size_t pos) const;
406 /// Returns the type for the column at specified position.
407
408 const MetaColumn& metaColumn(const std::string& name) const;
409 /// Returns the type for the column with specified name.
410
411 bool isNull(std::size_t col, std::size_t row) const;
412 /// Returns true if the current row value at column pos is null.
413
414 bool isBulkExtraction() const;
415 /// Returns true if this statement extracts data in bulk.
416
417 ImplPtr impl() const;
418 /// Returns pointer to statement implementation.
419
420 const RowFormatter::Ptr& getRowFormatter();
421 /// Returns the row formatter for this statement.
422
423 Session session();
424 /// Returns the underlying session.
425
426private:
427
428 const Result& doAsyncExec(bool reset = true);
429 /// Asynchronously executes the statement.
430
431 template <typename T>
432 Statement& commaPODImpl(const T& val)
433 {
434 _arguments.push_back(val);
435 return *this;
436 }
437
438 StatementImpl::Ptr _pImpl;
439
440 // asynchronous execution related members
441 bool _async;
442 mutable ResultPtr _pResult;
443 Mutex _mutex;
444 AsyncExecMethodPtr _pAsyncExec;
445 std::vector<Any> _arguments;
446 RowFormatter::Ptr _pRowFormatter;
447 mutable std::string _stmtString;
448};
449
450//
451// inlines
452
453inline std::size_t Statement::subTotalRowCount(int dataSet) const
454{
455 return _pImpl->subTotalRowCount(dataSet);
456}
457
458
459inline std::size_t Statement::getTotalRowCount() const
460{
461 return _pImpl->getTotalRowCount();
462}
463
464
465inline std::size_t Statement::totalRowCount() const
466{
467 return getTotalRowCount();
468}
469
470
471inline void Statement::setTotalRowCount(std::size_t count)
472{
473 _pImpl->setTotalRowCount(count);
474}
475
476
477namespace Keywords {
478
479
480//
481// Manipulators
482//
483
484inline void Data_API now(Statement& statement)
485 /// Enforces immediate execution of the statement.
486 /// If _isAsync flag has been set, execution is invoked asynchronously.
487{
488 statement.execute();
489}
490
491
492inline void Data_API sync(Statement& statement)
493 /// Sets the _isAsync flag to false, signalling synchronous execution.
494 /// Synchronous execution is default, so specifying this manipulator
495 /// only makes sense if async() was called for the statement before.
496{
497 statement.setAsync(false);
498}
499
500
501inline void Data_API async(Statement& statement)
502 /// Sets the _async flag to true, signalling asynchronous execution.
503{
504 statement.setAsync(true);
505}
506
507
508inline void Data_API deque(Statement& statement)
509 /// Sets the internal storage to std::deque.
510 /// std::deque is default storage, so specifying this manipulator
511 /// only makes sense if list() or deque() were called for the statement before.
512{
513 if (!statement.canModifyStorage())
514 throw InvalidAccessException("Storage not modifiable.");
515
516 statement.setStorage("deque");
517}
518
519
520inline void Data_API vector(Statement& statement)
521 /// Sets the internal storage to std::vector.
522{
523 if (!statement.canModifyStorage())
524 throw InvalidAccessException("Storage not modifiable.");
525
526 statement.setStorage("vector");
527}
528
529
530inline void Data_API list(Statement& statement)
531 /// Sets the internal storage to std::list.
532{
533 if (!statement.canModifyStorage())
534 throw InvalidAccessException("Storage not modifiable.");
535
536 statement.setStorage("list");
537}
538
539
540inline void Data_API reset(Statement& statement)
541 /// Sets all internal settings to their respective default values.
542{
543 if (!statement.canModifyStorage())
544 throw InvalidAccessException("Storage not modifiable.");
545
546 statement.setStorage("deque");
547 statement.setAsync(false);
548}
549
550
551} // namespace Keywords
552
553
554//
555// inlines
556//
557
558inline Statement& Statement::operator , (RowFormatter::Ptr pRowFformatter)
559{
560 _pRowFormatter = pRowFformatter;
561 return *this;
562}
563
564
565inline Statement& Statement::operator , (char value)
566{
567 return commaPODImpl(value);
568}
569
570
571inline Statement& Statement::operator , (Poco::UInt8 value)
572{
573 return commaPODImpl(value);
574}
575
576
577inline Statement& Statement::operator , (Poco::Int8 value)
578{
579 return commaPODImpl(value);
580}
581
582
583inline Statement& Statement::operator , (Poco::UInt16 value)
584{
585 return commaPODImpl(value);
586}
587
588
589inline Statement& Statement::operator , (Poco::Int16 value)
590{
591 return commaPODImpl(value);
592}
593
594
595inline Statement& Statement::operator , (Poco::UInt32 value)
596{
597 return commaPODImpl(value);
598}
599
600
601inline Statement& Statement::operator , (Poco::Int32 value)
602{
603 return commaPODImpl(value);
604}
605
606
607#ifndef POCO_LONG_IS_64_BIT
608inline Statement& Statement::operator , (long value)
609{
610 return commaPODImpl(value);
611}
612
613
614inline Statement& Statement::operator , (unsigned long value)
615{
616 return commaPODImpl(value);
617}
618#endif
619
620
621inline Statement& Statement::operator , (Poco::UInt64 value)
622{
623 return commaPODImpl(value);
624}
625
626
627inline Statement& Statement::operator , (Poco::Int64 value)
628{
629 return commaPODImpl(value);
630}
631
632
633inline Statement& Statement::operator , (double value)
634{
635 return commaPODImpl(value);
636}
637
638
639inline Statement& Statement::operator , (float value)
640{
641 return commaPODImpl(value);
642}
643
644
645inline Statement& Statement::operator , (bool value)
646{
647 return commaPODImpl(value);
648}
649
650
651inline Statement& Statement::operator , (const std::string& value)
652{
653 return commaPODImpl(value);
654}
655
656
657inline Statement& Statement::operator , (const char* value)
658{
659 return commaPODImpl(std::string(value));
660}
661
662
663inline void Statement::removeBind(const std::string& name)
664{
665 _pImpl->removeBind(name);
666}
667
668
669inline Statement& Statement::operator , (AbstractBinding::Ptr pBind)
670{
671 return addBind(pBind);
672}
673
674
675inline Statement& Statement::operator , (AbstractBindingVec& bindVec)
676{
677 return addBinding(bindVec, false);
678}
679
680
681inline Statement& Statement::operator , (AbstractExtraction::Ptr pExtract)
682{
683 return addExtract(pExtract);
684}
685
686
687inline Statement& Statement::operator , (AbstractExtractionVec& extVec)
688{
689 return addExtraction(extVec, false);
690}
691
692
693inline Statement& Statement::operator , (AbstractExtractionVecVec& extVecVec)
694{
695 return addExtractions(extVecVec);
696}
697
698
699inline Statement::ImplPtr Statement::impl() const
700{
701 return _pImpl;
702}
703
704
705inline const std::string& Statement::toString() const
706{
707 return _stmtString = _pImpl->toString();
708}
709
710inline const AbstractExtractionVec& Statement::extractions() const
711{
712 return _pImpl->extractions();
713}
714
715
716inline const MetaColumn& Statement::metaColumn(std::size_t pos) const
717{
718 return _pImpl->metaColumn(pos, _pImpl->currentDataSet());
719}
720
721
722inline const MetaColumn& Statement::metaColumn(const std::string& name) const
723{
724 return _pImpl->metaColumn(name);
725}
726
727
728inline void Statement::setStorage(const std::string& rStorage)
729{
730 _pImpl->setStorage(rStorage);
731}
732
733
734inline std::size_t Statement::extractionCount() const
735{
736 return _pImpl->extractionCount();
737}
738
739
740inline std::size_t Statement::columnsExtracted(int dataSet) const
741{
742 return _pImpl->columnsExtracted(dataSet);
743}
744
745
746inline std::size_t Statement::rowsExtracted(int dataSet) const
747{
748 return _pImpl->rowsExtracted(dataSet);
749}
750
751
752inline std::size_t Statement::dataSetCount() const
753{
754 return _pImpl->dataSetCount();
755}
756
757
758inline std::size_t Statement::nextDataSet()
759{
760 return _pImpl->activateNextDataSet();
761}
762
763
764inline std::size_t Statement::previousDataSet()
765{
766 return _pImpl->activatePreviousDataSet();
767}
768
769
770inline bool Statement::hasMoreDataSets() const
771{
772 return _pImpl->hasMoreDataSets();
773}
774
775
776inline Statement::Storage Statement::storage() const
777{
778 return static_cast<Storage>(_pImpl->getStorage());
779}
780
781
782inline bool Statement::canModifyStorage()
783{
784 return (0 == extractionCount()) && (initialized() || done());
785}
786
787
788inline bool Statement::initialized()
789{
790 return _pImpl->getState() == StatementImpl::ST_INITIALIZED;
791}
792
793
794inline bool Statement::paused()
795{
796 return _pImpl->getState() == StatementImpl::ST_PAUSED;
797}
798
799
800inline bool Statement::done()
801{
802 return _pImpl->getState() == StatementImpl::ST_DONE;
803}
804
805
806inline bool Statement::isNull(std::size_t col, std::size_t row) const
807{
808 return _pImpl->isNull(col, row);
809}
810
811
812inline bool Statement::isBulkExtraction() const
813{
814 return _pImpl->isBulkExtraction();
815}
816
817
818inline std::size_t Statement::firstDataSet()
819{
820 _pImpl->firstDataSet();
821 return 0;
822}
823
824
825inline std::size_t Statement::currentDataSet() const
826{
827 return _pImpl->currentDataSet();
828}
829
830
831inline bool Statement::isAsync() const
832{
833 return _async;
834}
835
836
837inline void Statement::setRowFormatter(RowFormatter::Ptr pRowFormatter)
838{
839 _pRowFormatter = pRowFormatter;
840}
841
842
843inline const RowFormatter::Ptr& Statement::getRowFormatter()
844{
845 if (!_pRowFormatter) _pRowFormatter = new SimpleRowFormatter;
846 return _pRowFormatter;
847}
848
849
850inline void Statement::insertHint()
851{
852 _pImpl->insertHint();
853}
854
855inline void swap(Statement& s1, Statement& s2)
856{
857 s1.swap(s2);
858}
859
860
861} } // namespace Poco::Data
862
863
864namespace std
865{
866 template<>
867 inline void swap<Poco::Data::Statement>(Poco::Data::Statement& s1,
868 Poco::Data::Statement& s2)
869 /// Full template specialization of std:::swap for Statement
870 {
871 s1.swap(s2);
872 }
873}
874
875
876#endif // Data_Statement_INCLUDED
877