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