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