IODA Bundle
SQLSelectOutput.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 /// @author Simon Smart
12 /// @date Aug 2018
13 
14 /// @note This output is designed to generalise and standardise the output mechanism for the
15 /// odc::Select class. Prior to this, the class had two problems:
16 ///
17 /// i) It invasively used the internals of the SQLSelect and TableIterators, accessing their
18 /// internal data buffers, and the results objects directly. This is nasty and results in
19 /// significant duplicate code.
20 ///
21 /// ii) As a result of the original IFS origins of this code, integers are returned as DOUBLES.
22 /// this is reasonable, but a bit odd, and it is worth having in code the support to output
23 /// integers as integers for future/other use - without having to reimplement and duplicate
24 /// everything.
25 ///
26 /// This output mechanism allows output to be made to a specified buffer (which may be changed
27 /// on a per-step basis) with a semantically correct behaviour depending on the column type.
28 ///
29 /// This has been put in odc, not in eckit, on the understanding that the handling of
30 /// integers as doubles is esoteric and should probably not be replicated anywhere else.
31 
32 
33 #ifndef odc_SQLSelectOutput_H
34 #define odc_SQLSelectOutput_H
35 
36 #include <vector>
37 #include "eckit/sql/SQLOutput.h"
38 
39 #include "odc/core/MetaData.h"
40 
41 
42 namespace odc {
43 namespace sql {
44 
45 //----------------------------------------------------------------------------------------------------------------------
46 
47 class SQLSelectOutput : public eckit::sql::SQLOutput {
48 
49 public: // methods
50 
51  /// out/count specify an output buffer and its size in doubles.
52  SQLSelectOutput(bool manageOwnBuffer=true);
53  virtual ~SQLSelectOutput();
54 
55  void resetBuffer(double* out, size_t count);
56 
57  // Enable access to the aggregated data from the SelectIterator
58 
59  const double* data() const { return out_; }
60  double& data(size_t i) { return out_[offsets_[i]]; }
61  size_t rowDataSizeDoubles() const { return requiredBufferSize_; }
62  const core::MetaData& metadata() const { return metaData_; }
63  size_t dataOffset(size_t i) const { return offsets_[i]; }
64 
65 private: // utility
66 
67  void outputNumber(double);
68 
69 private: // methods (overrides)
70 
71  virtual void print(std::ostream&) const;
72 
73  virtual void reset();
74  virtual void flush();
75  virtual bool output(const eckit::sql::expression::Expressions&);
76  virtual void prepare(eckit::sql::SQLSelect&);
77  virtual void updateTypes(eckit::sql::SQLSelect&);
78  virtual void cleanup(eckit::sql::SQLSelect&);
79  virtual unsigned long long count();
80 
81  virtual void outputReal(double, bool);
82  virtual void outputDouble(double, bool);
83  virtual void outputInt(double, bool);
84  virtual void outputUnsignedInt(double, bool);
85  virtual void outputString(const char*, size_t, bool);
86  virtual void outputBitfield(double, bool);
87 
88 private: // members
89 
90  /// Only used if managing own buffer.
91  std::vector<double> data_;
92 
93  /// Where are we writing data to (and how many elements can we write)
94  double* out_;
95  double* pos_;
96  double* end_;
99 
100  /// How are writes carried out
101  std::vector<size_t> columnSizesDoubles_;
102  std::vector<size_t> offsets_;
103 
105 
106  /// How much output have we done
107  unsigned long long count_;
109 
111 };
112 
113 //----------------------------------------------------------------------------------------------------------------------
114 
115 } // namespace sql
116 } // namespace odc
117 
118 #endif
virtual void outputDouble(double, bool)
SQLSelectOutput(bool manageOwnBuffer=true)
out/count specify an output buffer and its size in doubles.
const core::MetaData & metadata() const
virtual void outputString(const char *, size_t, bool)
const double * data() const
std::vector< size_t > columnSizesDoubles_
How are writes carried out.
virtual void cleanup(eckit::sql::SQLSelect &)
virtual void outputUnsignedInt(double, bool)
virtual void updateTypes(eckit::sql::SQLSelect &)
virtual unsigned long long count()
virtual void outputInt(double, bool)
virtual void outputReal(double, bool)
virtual void print(std::ostream &) const
double * out_
Where are we writing data to (and how many elements can we write)
void resetBuffer(double *out, size_t count)
std::vector< size_t > offsets_
virtual void outputBitfield(double, bool)
unsigned long long count_
How much output have we done.
std::vector< double > data_
Only used if managing own buffer.
virtual bool output(const eckit::sql::expression::Expressions &)
double & data(size_t i)
size_t rowDataSizeDoubles() const
virtual void prepare(eckit::sql::SQLSelect &)
size_t dataOffset(size_t i) const
Definition: ColumnInfo.h:23