This file is indexed.

/usr/include/Poco/Data/StatementImpl.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
//
// StatementImpl.h
//
// Library: Data
// Package: DataCore
// Module:  StatementImpl
//
// Definition of the StatementImpl class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef Data_StatementImpl_INCLUDED
#define Data_StatementImpl_INCLUDED


#include "Poco/Data/Data.h"
#include "Poco/Data/AbstractBinding.h"
#include "Poco/Data/AbstractExtraction.h"
#include "Poco/Data/Range.h"
#include "Poco/Data/Bulk.h"
#include "Poco/Data/Column.h"
#include "Poco/Data/Extraction.h"
#include "Poco/Data/BulkExtraction.h"
#include "Poco/Data/SessionImpl.h"
#include "Poco/RefCountedObject.h"
#include "Poco/String.h"
#include "Poco/Format.h"
#include "Poco/Exception.h"
#include <vector>
#include <list>
#include <deque>
#include <string>
#include <sstream>


namespace Poco {
namespace Data {


class Data_API StatementImpl
	/// StatementImpl interface that subclasses must implement to define database dependent query execution.
	///
	/// StatementImpl's are noncopyable.
{
public:
	typedef Poco::SharedPtr<StatementImpl> Ptr;

	enum State
	{
		ST_INITIALIZED,
		ST_COMPILED,
		ST_BOUND,
		ST_PAUSED,
		ST_DONE,
		ST_RESET
	};

	enum Storage
	{
		STORAGE_DEQUE_IMPL,
		STORAGE_VECTOR_IMPL,
		STORAGE_LIST_IMPL,
		STORAGE_UNKNOWN_IMPL
	};

	enum BulkType
	{
		BULK_UNDEFINED,     
			/// Bulk mode not defined yet.
		BULK_BINDING,       
			/// Binding in bulk mode.
			/// If extraction is present in the same statement, 
			/// it must also be bulk.
		BULK_EXTRACTION,    
			/// Extraction in bulk mode.
			/// If binding is present in the same statement, 
			/// it must also be bulk.
		BULK_FORBIDDEN     
			/// Bulk forbidden. 
			/// Happens when the statement has already been 
			/// configured as non-bulk.
	};

	static const std::string DEQUE;
	static const std::string VECTOR;
	static const std::string LIST;
	static const std::string UNKNOWN;

	static const int USE_CURRENT_DATA_SET = -1;

	StatementImpl(SessionImpl& rSession);
		/// Creates the StatementImpl.

	virtual ~StatementImpl();
		/// Destroys the StatementImpl.

	template <typename T> 
	void add(const T& t)
		/// Appends SQL statement (fragments).
	{
		_ostr << t;
	}

	void addBind(AbstractBinding::Ptr pBinding);
		/// Registers the Binding with the StatementImpl.

	void removeBind(const std::string& name);
		/// Unregisters all the bindings having specified name with the StatementImpl.
		/// Bindings are released and, if this class was the sole owner, deleted.

	void addExtract(AbstractExtraction::Ptr pExtraction);
		/// Registers objects used for extracting data with the StatementImpl.

	void setExtractionLimit(const Limit& extrLimit);
		/// Changes the extractionLimit to extrLimit. 
		/// Per default no limit (EXTRACT_UNLIMITED) is set.

	std::string toString() const;
		/// Create a string version of the SQL statement.

	std::size_t execute(const bool& reset = true);
		/// Executes a statement. Returns the number of rows 
		/// extracted for statements returning data or number of rows 
		/// affected for all other statements (insert, update, delete).
		/// If reset is true (default), the underlying bound storage is
		/// reset and reused. In case of containers, this means they are
		/// cleared and resized to accomodate the number of rows returned by
		/// this execution step. When reset is false, data is appended to the
		/// bound containers during multiple execute calls.

	void reset();
		/// Resets the statement, so that we can reuse all bindings and re-execute again.

	State getState() const;
		/// Returns the state of the Statement.

	void setStorage(Storage storage);
		/// Sets the storage type for this statement;

	void setStorage(const std::string& storage);
		/// Sets the storage type for this statement;

	Storage getStorage() const;
		/// Returns the storage type for this statement.

	std::size_t extractionCount() const;
		/// Returns the number of extraction storage buffers associated
		/// with the statement.

	std::size_t dataSetCount() const;
		/// Returns the number of data sets associated with the statement.
		
protected:
	virtual std::size_t columnsReturned() const = 0;
		/// Returns number of columns returned by query. 

	virtual int affectedRowCount() const = 0;
		/// Returns the number of affected rows.
		/// Used to find out the number of rows affected by insert, delete or update.
		/// 
		/// Some back-ends may return a negative number in certain circumstances (e.g.
		/// some ODBC drivers when this function is called after a select statement
		/// execution).

	virtual const MetaColumn& metaColumn(std::size_t pos) const = 0;
		/// Returns column meta data.

	const MetaColumn& metaColumn(const std::string& name) const;
		/// Returns column meta data.

	virtual bool hasNext() = 0;
		/// Returns true if a call to next() will return data. 
		///
		/// Note that the implementation must support
		/// several consecutive calls to hasNext without data getting lost, 
		/// ie. hasNext(); hasNext(); next() must be equal to hasNext(); next();

	virtual std::size_t next() = 0;
		/// Retrieves the next row or set of rows from the resultset and
		/// returns the number of rows retreved.
		///
		/// Will throw, if the resultset is empty.
		/// Expects the statement to be compiled and bound.

	virtual bool canBind() const = 0;
		/// Returns true if another bind is possible.

	virtual bool canCompile() const = 0;
		/// Returns true if another compile is possible.

	virtual void compileImpl() = 0;
		/// Compiles the statement, doesn't bind yet.

	virtual void bindImpl() = 0;
		/// Binds parameters.

	virtual AbstractExtraction::ExtractorPtr extractor() = 0;
		/// Returns the concrete extractor used by the statement.

	const AbstractExtractionVec& extractions() const;
		/// Returns the const reference to extractions vector.

	AbstractExtractionVec& extractions();
		/// Returns the reference to extractions vector.

	void fixupExtraction();
		/// Sets the AbstractExtractor at the extractors.

	Limit::SizeT getExtractionLimit();
		/// Returns the extraction limit value.

	const Limit& extractionLimit() const;
		/// Returns the extraction limit.

	std::size_t columnsExtracted(int dataSet = USE_CURRENT_DATA_SET) const;
		/// Returns the number of columns that the extractors handle.

	std::size_t rowsExtracted(int dataSet = USE_CURRENT_DATA_SET) const;
		/// Returns the number of rows extracted for current data set.
		/// Default value (USE_CURRENT_DATA_SET) indicates current data set (if any).

	std::size_t subTotalRowCount(int dataSet = 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).

	void makeExtractors(std::size_t count);
		/// Determines the type of the internal extraction container and
		/// calls the extraction creation function (addInternalExtract)
		/// with appropriate data type and container type arguments.
		/// 
		/// This function is only called in cases when there is data 
		/// returned by query, but no data storage supplied by user.
		///
		/// The type of the internal container is determined in the
		/// following order:
		/// 1. If statement has the container type set, the type is used.
		/// 2. If statement does not have the container type set,
		///    session is queried for container type setting. If the
		///    session container type setting is found, it is used.
		/// 3. If neither session nor statement have the internal
		///    container type set, std::deque is used.
		///
		/// Supported internal extraction container types are:
		/// - std::deque (default)
		/// - std::vector
		/// - std::list

	SessionImpl& session();
		/// Rteurns session associated with this statement.

	virtual AbstractBinding::BinderPtr binder() = 0;
		/// Returns the concrete binder used by the statement.

	const AbstractBindingVec& bindings() const;
		/// Returns the const reference to bindings vector.

	AbstractBindingVec& bindings();
		/// Returns the reference to bindings.

	void fixupBinding();
		/// Sets the AbstractBinder at the bindings.

	void resetBinding();
		/// Resets binding so it can be reused again.

	virtual bool isStoredProcedure() const;
		/// Returns true if the statement is stored procedure.
		/// Used as a help to determine whether to automatically create the
		/// internal extractions when no outside extraction is supplied.
		/// The reason for this function is to prevent unnecessary internal
		/// extraction creation in cases (behavior exhibited by some ODBC drivers) 
		/// when there is data available from the stored procedure call 
		/// statement execution but no external extraction is supplied (as is 
		/// usually the case when stored procedures are called). In such cases
		/// no storage is needed because output parameters serve as storage.
		/// At the Data framework level, this function always returns false.
		/// When connector-specific behavior is desired, it should be overriden 
		/// by the statement implementation.

	std::size_t currentDataSet() const;
		/// Returns the current data set.

	std::size_t activateNextDataSet();
		/// Returns the next data set index, or throws NoDataException if the last 
		/// data set was reached.

	std::size_t activatePreviousDataSet();
		/// Returns the previous data set index, or throws NoDataException if the last 
		/// data set was reached.

	bool hasMoreDataSets() const;
		/// Returns true if there are data sets not activated yet.

private:
	void compile();
		/// Compiles the statement.

	void bind();
		/// Binds the statement, if not yet bound.

	std::size_t executeWithLimit();
		/// Executes with an upper limit set. Returns the number of rows 
		/// extracted for statements returning data or number of rows 
		/// affected for all other statements (insert, update, delete).

	std::size_t executeWithoutLimit();
		/// Executes without an upper limit set. Returns the number of rows 
		/// extracted for statements returning data or number of rows 
		/// affected for all other statements (insert, update, delete).

	void resetExtraction();
		/// Resets extraction so it can be reused again.

	template <class C>
	SharedPtr<InternalExtraction<C> > createExtract(const MetaColumn& mc)
	{
		C* pData = new C;
		Column<C>* pCol = new Column<C>(mc, pData);
		return new InternalExtraction<C>(*pData, pCol, Poco::UInt32(currentDataSet()));
	}

	template <class C>
	SharedPtr<InternalBulkExtraction<C> > createBulkExtract(const MetaColumn& mc)
	{
		C* pData = new C;
		Column<C>* pCol = new Column<C>(mc, pData);
		return new InternalBulkExtraction<C>(*pData,
			pCol,
			static_cast<Poco::UInt32>(getExtractionLimit()),
			Position(static_cast<Poco::UInt32>(currentDataSet())));
	}

	template <class T>
	void addInternalExtract(const MetaColumn& mc)
		/// Creates and adds the internal extraction.
		///
		/// The decision about internal extraction container is done 
		/// in a following way:
		///
		/// If this statement has _storage member set, that setting
		/// overrides the session setting for storage, otherwise the
		/// session setting is used.
		/// If neither this statement nor the session have the storage
		/// type set, std::deque is the default container type used.
	{
		std::string storage;
	
		switch (_storage)
		{
		case STORAGE_DEQUE_IMPL:  
			storage = DEQUE; break;
		case STORAGE_VECTOR_IMPL: 
			storage = VECTOR; break;
		case STORAGE_LIST_IMPL:   
			storage = LIST; break;
		case STORAGE_UNKNOWN_IMPL:
			storage = AnyCast<std::string>(session().getProperty("storage")); 
			break;
		}

		if (storage.empty()) storage = DEQUE;

		if (0 == icompare(DEQUE, storage))
		{
			if (!isBulkExtraction())
				addExtract(createExtract<std::deque<T> >(mc));
			else
				addExtract(createBulkExtract<std::deque<T> >(mc));
		}
		else if (0 == icompare(VECTOR, storage))
		{
			if (!isBulkExtraction())
				addExtract(createExtract<std::vector<T> >(mc));
			else
				addExtract(createBulkExtract<std::vector<T> >(mc));
		}
		else if (0 == icompare(LIST, storage))
		{
			if (!isBulkExtraction())
				addExtract(createExtract<std::list<T> >(mc));
			else
				addExtract(createBulkExtract<std::list<T> >(mc));
		}
	}

	bool isNull(std::size_t col, std::size_t row) const;
		/// Returns true if the value in [col, row] is null.
		
	void forbidBulk();
		/// Forbids bulk operations.

	void setBulkBinding();
		/// Sets the bulk binding flag.

	void setBulkExtraction(const Bulk& l);
		/// Sets the bulk extraction flag and extraction limit.
	
	void resetBulk();
		/// Resets the bulk extraction and binding flag.

	bool bulkBindingAllowed() const;
		/// Returns true if statement can be set to bind data in bulk.
		/// Once bulk binding is set for a statement, it can be
		/// neither altered nor mixed with non-bulk mode binding.

	bool bulkExtractionAllowed() const;
		/// Returns true if statement can be set to extract data in bulk.
		/// Once bulk extraction is set for a statement, it can be
		/// neither altered nor mixed with non-bulk mode extraction.

	bool isBulkBinding() const;
		/// Returns true if statement is set to bind data in bulk.

	bool isBulkExtraction() const;
		/// Returns true if statement is set to extract data in bulk.

	bool isBulkSupported() const;
		/// Returns true if connector and session support bulk operation.

	void formatSQL(std::vector<Any>& arguments);
		/// Formats the SQL string by filling in placeholders with values from supplied vector.

	void assignSubTotal(bool reset);

	StatementImpl(const StatementImpl& stmt);
	StatementImpl& operator = (const StatementImpl& stmt);

	typedef std::vector<std::size_t> CountVec;

	State                    _state;
	Limit                    _extrLimit;
	std::size_t              _lowerLimit;
	std::vector<int>         _columnsExtracted;
	SessionImpl&             _rSession;
	Storage                  _storage;
	std::ostringstream       _ostr;
	AbstractBindingVec       _bindings;
	AbstractExtractionVecVec _extractors;
	std::size_t              _curDataSet;
	BulkType                 _bulkBinding;
	BulkType                 _bulkExtraction;
	CountVec                 _subTotalRowCount;

	friend class Statement; 
};


//
// inlines
//


inline void StatementImpl::addBind(AbstractBinding::Ptr pBinding)
{
	poco_check_ptr (pBinding);
	_bindings.push_back(pBinding);
}


inline std::string StatementImpl::toString() const
{
	return _ostr.str();
}


inline const AbstractBindingVec& StatementImpl::bindings() const
{
	return _bindings;
}


inline AbstractBindingVec& StatementImpl::bindings()
{
	return _bindings;
}


inline const AbstractExtractionVec& StatementImpl::extractions() const
{
	poco_assert (_curDataSet < _extractors.size());
	return _extractors[_curDataSet];
}


inline AbstractExtractionVec& StatementImpl::extractions()
{
	poco_assert (_curDataSet < _extractors.size());
	return _extractors[_curDataSet];
}


inline StatementImpl::State StatementImpl::getState() const
{
	return _state;
}


inline SessionImpl& StatementImpl::session()
{
	return _rSession;
}


inline void StatementImpl::setStorage(Storage storage)
{
	_storage = storage;
}


inline StatementImpl::Storage StatementImpl::getStorage() const
{
	return _storage;
}


inline std::size_t StatementImpl::extractionCount() const
{
	return static_cast<std::size_t>(extractions().size());
}


inline std::size_t StatementImpl::dataSetCount() const
{
	return static_cast<std::size_t>(_extractors.size());
}


inline bool StatementImpl::isStoredProcedure() const
{
	return false;
}


inline bool StatementImpl::isNull(std::size_t col, std::size_t row) const
{
	try 
	{
		return extractions().at(col)->isNull(row);
	}
	catch (std::out_of_range& ex)
	{ 
		throw RangeException(ex.what()); 
	}
}


inline std::size_t StatementImpl::currentDataSet() const
{
	return _curDataSet;
}


inline Limit::SizeT StatementImpl::getExtractionLimit()
{
	return _extrLimit.value();
}


inline const Limit& StatementImpl::extractionLimit() const
{
	return _extrLimit;
}


inline void StatementImpl::forbidBulk()
{
	_bulkBinding = BULK_FORBIDDEN;
	_bulkExtraction = BULK_FORBIDDEN;
}


inline void StatementImpl::setBulkBinding()
{
	_bulkBinding = BULK_BINDING;
}


inline bool StatementImpl::bulkBindingAllowed() const
{
	return BULK_UNDEFINED == _bulkBinding ||
		BULK_BINDING == _bulkBinding;
}


inline bool StatementImpl::bulkExtractionAllowed() const
{
	return BULK_UNDEFINED == _bulkExtraction ||
		BULK_EXTRACTION == _bulkExtraction;
}


inline bool StatementImpl::isBulkBinding() const
{
	return BULK_BINDING == _bulkBinding;
}


inline bool StatementImpl::isBulkExtraction() const
{
	return BULK_EXTRACTION == _bulkExtraction;
}

	
inline void StatementImpl::resetBulk()
{
	_bulkExtraction = BULK_UNDEFINED;
	_bulkBinding = BULK_UNDEFINED;\
	setExtractionLimit(Limit(Limit::LIMIT_UNLIMITED, false, false));
}


inline bool StatementImpl::isBulkSupported() const
{
	return _rSession.getFeature("bulk");
}


inline bool StatementImpl::hasMoreDataSets() const
{
	return currentDataSet() + 1 < dataSetCount();
}


} } // namespace Poco::Data


#endif // Data_StatementImpl_INCLUDED