libdballe  8.6
db/v7/cursor.h
1 #ifndef DBA_DB_V7_CURSOR_H
2 #define DBA_DB_V7_CURSOR_H
3 
4 #include <dballe/types.h>
5 #include <dballe/db/db.h>
6 #include <dballe/db/v7/transaction.h>
7 #include <dballe/db/v7/repinfo.h>
8 #include <dballe/db/v7/levtr.h>
9 #include <dballe/values.h>
10 #include <memory>
11 
12 namespace dballe {
13 namespace db {
14 namespace v7 {
15 namespace cursor {
16 
17 struct Stations;
18 struct StationData;
19 struct Data;
20 struct Summary;
21 
25 struct StationRow
26 {
27  dballe::DBStation station;
28  mutable std::unique_ptr<DBValues> values;
29 
30  StationRow(const dballe::DBStation& station) : station(station) {}
31 
32  void dump(FILE* out) const;
33 };
34 
36 {
37  dballe::DBStation station;
38  DBValue value;
39 
40  StationDataRow(const dballe::DBStation& station, int id_data, std::unique_ptr<wreport::Var> var) : station(station), value(id_data, std::move(var)) {}
41  StationDataRow(const StationDataRow&) = delete;
42  StationDataRow(StationDataRow&& o) = default;
43  StationDataRow& operator=(const StationDataRow&) = delete;
44  StationDataRow& operator=(StationDataRow&& o) = default;
45  ~StationDataRow() {}
46 
47  void dump(FILE* out) const;
48 };
49 
50 struct DataRow : public StationDataRow
51 {
52  int id_levtr;
53  Datetime datetime;
54 
55  using StationDataRow::StationDataRow;
56 
57  DataRow(const dballe::DBStation& station, int id_levtr, const Datetime& datetime, int id_data, std::unique_ptr<wreport::Var> var)
58  : StationDataRow(station, id_data, std::move(var)), id_levtr(id_levtr), datetime(datetime) {}
59 
60  void dump(FILE* out) const;
61 };
62 
63 struct SummaryRow
64 {
65  dballe::DBStation station;
66  int id_levtr;
67  wreport::Varcode code;
68  DatetimeRange dtrange;
69  size_t count = 0;
70 
71  SummaryRow(const dballe::DBStation& station, int id_levtr, wreport::Varcode code, const DatetimeRange& dtrange, size_t count)
72  : station(station), id_levtr(id_levtr), code(code), dtrange(dtrange), count(count) {}
73 
74  void dump(FILE* out) const;
75 };
76 
77 
78 template<typename Row>
79 struct Rows
80 {
82  std::shared_ptr<v7::Transaction> tr;
83 
85  std::vector<Row> results;
86 
88  typename std::vector<Row>::const_iterator cur;
89 
91  bool at_start = true;
92 
93  Rows(std::shared_ptr<v7::Transaction> tr) : tr(tr) {}
94 
95  const Row* operator->() const { return &*cur; }
96 
97  int get_priority() const { return tr->repinfo().get_priority(cur->station.report); }
98 
99  bool next()
100  {
101  if (at_start)
102  at_start = false;
103  else if (cur != results.end())
104  ++cur;
105  return cur != results.end();
106  }
107 
108  void discard()
109  {
110  at_start = false;
111  cur = results.end();
112  }
113 };
114 
115 struct StationRows : public Rows<StationRow>
116 {
117  using Rows::Rows;
118  const DBValues& values() const;
119  void load(Tracer<>& trc, const StationQueryBuilder& qb);
120  void enq(impl::Enq& enq) const;
121 };
122 
123 struct StationDataRows : public Rows<StationDataRow>
124 {
125  using Rows::Rows;
126  void load(Tracer<>& trc, const DataQueryBuilder& qb);
127  void enq(impl::Enq& enq) const;
128 };
129 
130 template<typename Row>
131 struct LevTrRows : public Rows<Row>
132 {
133  using Rows<Row>::Rows;
134 
135  // Cached levtr for the current row
136  mutable const LevTrEntry* levtr = nullptr;
137 
138  bool next()
139  {
140  levtr = nullptr;
141  return Rows<Row>::next();
142  }
143 
144  void discard()
145  {
146  levtr = nullptr;
148  }
149 
150  const LevTrEntry& get_levtr() const
151  {
152  if (levtr == nullptr)
153  // We prefetch levtr info for all IDs, so we do not need to hit the database here
154  levtr = &(this->tr->levtr().lookup_cache(this->cur->id_levtr));
155  return *levtr;
156  }
157 };
158 
159 struct BaseDataRows : public LevTrRows<DataRow>
160 {
161  using LevTrRows::LevTrRows;
162  void enq(impl::Enq& enq) const;
163 };
164 
165 struct DataRows : public BaseDataRows
166 {
167  using BaseDataRows::BaseDataRows;
168 
169  int insert_cur_prio;
170 
172  bool add_to_best_results(const dballe::DBStation& station, int id_levtr, const Datetime& datetime, int id_data, std::unique_ptr<wreport::Var> var);
173 
174  void load(Tracer<>& trc, const DataQueryBuilder& qb);
175  void load_best(Tracer<>& trc, const DataQueryBuilder& qb);
176 };
177 
178 struct SummaryRows : public LevTrRows<SummaryRow>
179 {
180  using LevTrRows::LevTrRows;
181  void load(Tracer<>& trc, const SummaryQueryBuilder& qb);
182  void enq(impl::Enq& enq) const;
183 };
184 
185 
186 template<typename Cursor>
188 {
189 };
190 
191 template<>
193 {
195  typedef db::CursorStation Parent;
196  typedef StationRow Row;
197  typedef StationRows Rows;
198 };
199 
200 template<>
202 {
205  typedef StationDataRow Row;
206  typedef StationDataRows Rows;
207 };
208 
209 template<>
211 {
213  typedef db::CursorData Parent;
214  typedef DataRow Row;
215  typedef DataRows Rows;
216 };
217 
218 template<>
220 {
222  typedef db::CursorSummary Parent;
223  typedef SummaryRow Row;
224  typedef SummaryRows Rows;
225 };
226 
227 
232 template<typename Impl>
233 struct Base : public ImplTraits<Impl>::Parent
234 {
235  typedef typename ImplTraits<Impl>::Row Row;
236  typedef typename ImplTraits<Impl>::Rows Rows;
237  typedef typename ImplTraits<Impl>::Interface Interface;
238 
239  Rows rows;
240 
241  Base(std::shared_ptr<v7::Transaction> tr)
242  : rows(tr)
243  {
244  }
245 
246  virtual ~Base() {}
247 
248  int remaining() const override;
249  bool has_value() const { return !rows.at_start && rows.cur != rows.results.end(); }
250  bool next() override { return rows.next(); }
251  void discard() override;
252 
253  dballe::DBStation get_station() const override { return rows->station; }
254 
255  void enq(impl::Enq& enq) const override { return rows.enq(enq); }
256 
262  unsigned test_iterate(FILE* dump=0) override;
263 
265  inline static std::unique_ptr<Impl> downcast(std::unique_ptr<Interface> c)
266  {
267  Impl* res = dynamic_cast<Impl*>(c.get());
268  if (!res) throw std::runtime_error("Attempted to downcast the wrong kind of cursor");
269  c.release();
270  return std::unique_ptr<Impl>(res);
271  }
272 };
273 
274 extern template class Base<Stations>;
275 extern template class Base<StationData>;
276 extern template class Base<Data>;
277 extern template class Base<Summary>;
278 
279 
281 struct Stations : public Base<Stations>
282 {
283  using Base::Base;
284  DBValues get_values() const override;
285 
286  void remove() override;
287 };
288 
291 {
292  bool with_attributes;
293 
294  StationData(DataQueryBuilder& qb, bool with_attributes);
295  std::shared_ptr<dballe::db::Transaction> get_transaction() const override { return rows.tr; }
296  wreport::Varcode get_varcode() const override { return rows->value.code(); }
297  wreport::Var get_var() const override { return *rows->value; }
298  int attr_reference_id() const override { return rows->value.data_id; }
299  void query_attrs(std::function<void(std::unique_ptr<wreport::Var>)> dest, bool force_read) override;
300  void remove() override;
301 };
302 
304 struct Data : public Base<Data>
305 {
306  bool with_attributes;
307 
308  Data(DataQueryBuilder& qb, bool with_attributes);
309 
310  std::shared_ptr<dballe::db::Transaction> get_transaction() const override { return rows.tr; }
311 
312  Datetime get_datetime() const override { return rows->datetime; }
313  wreport::Varcode get_varcode() const override { return rows->value.code(); }
314  wreport::Var get_var() const override { return *rows->value; }
315  int attr_reference_id() const override { return rows->value.data_id; }
316  Level get_level() const override { return rows.get_levtr().level; }
317  Trange get_trange() const override { return rows.get_levtr().trange; }
318 
319  void query_attrs(std::function<void(std::unique_ptr<wreport::Var>)> dest, bool force_read) override;
320  void remove() override;
321 };
322 
324 struct Summary : public Base<Summary>
325 {
326  using Base<Summary>::Base;
327 
328  DatetimeRange get_datetimerange() const override
329  {
330  return this->rows->dtrange;
331  }
332  Level get_level() const override { return rows.get_levtr().level; }
333  Trange get_trange() const override { return rows.get_levtr().trange; }
334  wreport::Varcode get_varcode() const override { return rows->code; }
335  size_t get_count() const override { return rows->count; }
336  void remove() override;
337 };
338 
339 
340 std::unique_ptr<dballe::CursorStation> run_station_query(Tracer<>& trc, std::shared_ptr<v7::Transaction> tr, const core::Query& query, bool explain);
341 std::unique_ptr<dballe::CursorStationData> run_station_data_query(Tracer<>& trc, std::shared_ptr<v7::Transaction> tr, const core::Query& query, bool explain);
342 std::unique_ptr<dballe::CursorData> run_data_query(Tracer<>& trc, std::shared_ptr<v7::Transaction> tr, const core::Query& query, bool explain);
343 std::unique_ptr<dballe::CursorSummary> run_summary_query(Tracer<>& trc, std::shared_ptr<v7::Transaction> tr, const core::Query& query, bool explain);
344 void run_delete_query(Tracer<>& trc, std::shared_ptr<v7::Transaction> tr, const core::Query& query, bool station_vars, bool explain);
345 
346 }
347 }
348 }
349 }
350 #endif
dballe::CursorStation
Cursor iterating over stations.
Definition: cursor.h:56
dballe::db::v7::SummaryQueryBuilder
Definition: qbuilder.h:124
repinfo.h
dballe::DBValue
Container for a wreport::Var pointer, and its database ID.
Definition: value.h:71
values.h
dballe::db::v7::cursor::Base::test_iterate
unsigned test_iterate(FILE *dump=0) override
Iterate the cursor until the end, returning the number of items.
types.h
dballe::db::CursorStationData
Definition: db/db.h:71
dballe::impl::Enq
Class passed to key-value accessors to set values in an invoker-defined way.
Definition: core/enq.h:17
dballe::CursorSummary
Cursor iterating over summary entries.
Definition: cursor.h:97
dballe::db::v7::cursor::StationRows
Definition: db/v7/cursor.h:115
dballe::db::v7::cursor::Summary
CursorSummary implementation.
Definition: db/v7/cursor.h:324
dballe::db::CursorSummary
Definition: db/db.h:137
dballe::db::v7::cursor::Rows::tr
std::shared_ptr< v7::Transaction > tr
Database to operate on.
Definition: db/v7/cursor.h:82
dballe::db::v7::Tracer
Smart pointer for trace::Step objects, which calls done() when going out of scope.
Definition: db/v7/fwd.h:45
dballe::db::v7::cursor::Data
CursorData implementation.
Definition: db/v7/cursor.h:304
dballe::db::v7::cursor::BaseDataRows
Definition: db/v7/cursor.h:159
dballe::db::v7::LevTrEntry
Definition: cache.h:14
dballe::db::v7::cursor::Base
Structure used to build and execute a query, and to iterate through the results.
Definition: db/v7/cursor.h:233
dballe::db::v7::cursor::Rows::results
std::vector< Row > results
Storage for the raw database results.
Definition: db/v7/cursor.h:85
dballe::DBStation
Definition: types.h:850
wreport::Varcode
uint16_t Varcode
dballe::db::v7::cursor::Base::downcast
static std::unique_ptr< Impl > downcast(std::unique_ptr< Interface > c)
Downcast a unique_ptr pointer.
Definition: db/v7/cursor.h:265
dballe::DBValues
Collection of DBValue objects, indexed by wreport::Varcode.
Definition: values.h:191
dballe::db::v7::cursor::DataRows::add_to_best_results
bool add_to_best_results(const dballe::DBStation &station, int id_levtr, const Datetime &datetime, int id_data, std::unique_ptr< wreport::Var > var)
Append or replace the last result according to priority. Returns false if the value has been ignored.
dballe::db::v7::StationQueryBuilder
Definition: qbuilder.h:81
dballe::db::v7::cursor::SummaryRow
Definition: db/v7/cursor.h:63
dballe::DatetimeRange
Range of datetimes.
Definition: types.h:294
db.h
dballe::db::v7::cursor::Rows::cur
std::vector< Row >::const_iterator cur
Iterator to the current position in results.
Definition: db/v7/cursor.h:88
dballe::db::v7::cursor::StationRow
Row resulting from a station query.
Definition: db/v7/cursor.h:25
dballe::Trange
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:686
dballe::db::CursorData
Definition: db/db.h:104
dballe::Level
Vertical level or layer.
Definition: types.h:624
dballe::db::v7::cursor::StationDataRows
Definition: db/v7/cursor.h:123
wreport::Var
dballe::CursorStationData
Cursor iterating over station data values.
Definition: cursor.h:66
dballe::db::v7::cursor::DataRow
Definition: db/v7/cursor.h:50
dballe::db::v7::cursor::StationDataRow
Definition: db/v7/cursor.h:35
dballe::db::v7::cursor::SummaryRows
Definition: db/v7/cursor.h:178
dballe::db::v7::cursor::Rows::at_start
bool at_start
True if we are at the start of the iteration.
Definition: db/v7/cursor.h:91
dballe::CursorData
Cursor iterating over data values.
Definition: cursor.h:77
dballe::db::v7::cursor::Rows
Definition: db/v7/cursor.h:79
dballe::Datetime
Date and time.
Definition: types.h:164
dballe::db::v7::cursor::ImplTraits
Definition: db/v7/cursor.h:187
dballe::db::CursorStation
Definition: db/db.h:58
dballe::db::v7::cursor::StationData
CursorStationData implementation.
Definition: db/v7/cursor.h:290
dballe::db::v7::cursor::DataRows
Definition: db/v7/cursor.h:165
dballe::core::Query
Standard dballe::Query implementation.
Definition: core/query.h:31
dballe::db::v7::cursor::Stations
CursorStation implementation.
Definition: db/v7/cursor.h:281
dballe::db::v7::cursor::LevTrRows
Definition: db/v7/cursor.h:131
dballe::db::v7::DataQueryBuilder
Definition: qbuilder.h:91