libdballe  7.29
data.h
1 #ifndef DBALLE_DB_V7_DATAV7_H
2 #define DBALLE_DB_V7_DATAV7_H
3 
4 #include <dballe/core/defs.h>
5 #include <dballe/sql/fwd.h>
6 #include <dballe/db/defs.h>
7 #include <dballe/db/v7/state.h>
8 #include <wreport/var.h>
9 #include <memory>
10 #include <vector>
11 #include <list>
12 #include <cstdio>
13 #include <functional>
14 
15 namespace dballe {
16 struct Record;
17 struct Values;
18 
19 namespace db {
20 namespace v7 {
21 struct Transaction;
22 struct IdQueryBuilder;
23 
24 namespace bulk {
25 struct InsertStationVars;
26 struct InsertVars;
27 
28 enum UpdateMode {
29  UPDATE,
30  IGNORE,
31  ERROR,
32 };
33 
34 }
35 
36 template<typename Traits>
38 {
39 protected:
43  void read_attrs_into_values(int id_data, Values& values);
44 
48  virtual void write_attrs(int id_data, const Values& values) = 0;
49 
53  virtual void remove_all_attrs(int id_data) = 0;
54 
55 public:
56  virtual ~DataCommon() {}
57 
67  virtual void read_attrs(int id_data, std::function<void(std::unique_ptr<wreport::Var>)> dest) = 0;
68 
77  void merge_attrs(int id_data, const Values& attrs);
78 
82  void remove_attrs(int data_id, const db::AttrList& attrs);
83 
85  virtual void insert(dballe::db::v7::Transaction& t, typename Traits::BulkVars& vars, bulk::UpdateMode update_mode=bulk::UPDATE, bool with_attrs=false) = 0;
86 
88  virtual void remove(const v7::IdQueryBuilder& qb) = 0;
89 
91  virtual void dump(FILE* out) = 0;
92 };
93 
94 
96 {
97  unsigned count = 0;
98  FILE* out;
99 
100  StationDataDumper(FILE* out);
101 
102  void print_head();
103  void print_row(int id, int id_station, wreport::Varcode code, const char* val, const std::vector<uint8_t>& attrs);
104  void print_tail();
105 };
106 
108 {
109  unsigned count = 0;
110  FILE* out;
111 
112  DataDumper(FILE* out);
113 
114  void print_head();
115  void print_row(int id, int id_station, int id_levtr, const Datetime& dt, wreport::Varcode code, const char* val, const std::vector<uint8_t>& attrs);
116  void print_tail();
117 };
118 
119 namespace bulk {
120 
121 struct Item
122 {
123  static const unsigned FLAG_NEEDS_UPDATE = 1 << 0;
124  static const unsigned FLAG_UPDATED = 1 << 1;
125  static const unsigned FLAG_NEEDS_INSERT = 1 << 2;
126  static const unsigned FLAG_INSERTED = 1 << 3;
127  unsigned flags = 0;
128 
129  bool needs_update() const { return flags & FLAG_NEEDS_UPDATE; }
130  bool updated() const { return flags & FLAG_UPDATED; }
131  bool needs_insert() const { return flags & FLAG_NEEDS_INSERT; }
132  bool inserted() const { return flags & FLAG_INSERTED; }
133  void set_needs_update() { flags |= FLAG_NEEDS_UPDATE; }
134  void set_updated() { flags = (flags & ~FLAG_NEEDS_UPDATE) | FLAG_UPDATED; }
135  void set_needs_insert() { flags |= FLAG_NEEDS_INSERT; }
136  void set_inserted() { flags = (flags & ~FLAG_NEEDS_INSERT) | FLAG_INSERTED; }
137 
143  void format_flags(char* dest) const;
144 };
145 
146 template<typename state_t>
147 struct VarItem : public Item
148 {
149  typename state_t::iterator cur;
150  const wreport::Var* var;
151 
152  VarItem(typename state_t::iterator cur, const wreport::Var* var)
153  : cur(cur), var(var) {}
154 };
155 
159 struct StationVar : public VarItem<stationvalues_t>
160 {
161  using VarItem::VarItem;
162 
163  bool is_new() const { return false; }
164  bool has_cur(State& state) const { return cur != state.stationvalues.end(); }
165  void fill_cur(State& state, const StationValueDesc& desc) { cur = state.stationvalues.find(desc); }
166  void dump(FILE* out) const;
167 };
168 
169 
173 struct Var : public VarItem<values_t>
174 {
175  LevTrState levtr;
176 
177  Var(values_t::iterator cur, const wreport::Var* var, const LevTrState& levtr)
178  : VarItem(cur, var), levtr(levtr) {}
179 
180  bool is_new() const { return levtr.is_new; }
181  bool has_cur(State& state) const { return cur != state.values.end(); }
182  void fill_cur(State& state, const ValueDesc& desc) { cur = state.values.find(desc); }
183  void dump(FILE* out) const;
184 };
185 
187 {
188  stations_t::iterator station;
189 
190  SharedContext() {}
191  SharedContext(stations_t::iterator station) : station(station) {}
192 
193  bool is_new() const { return station->second.is_new; }
194 };
195 
197 {
198  using SharedContext::SharedContext;
199 
200  StationValueDesc make_desc(StationVar& v) const
201  {
202  return StationValueDesc(station, v.var->code());
203  }
204 };
205 
207 {
208  Datetime datetime;
209 
210  SharedDataContext() {}
211  SharedDataContext(stations_t::iterator station) : SharedContext(station) {}
212  SharedDataContext(stations_t::iterator station, const Datetime& datetime) : SharedContext(station), datetime(datetime) {}
213 
214  ValueDesc make_desc(Var& v) const
215  {
216  return ValueDesc(station, v.levtr.id, datetime, v.var->code());
217  }
218 };
219 
220 template<typename var_t, typename shared_context_t>
221 struct InsertPlan : public std::vector<var_t>
222 {
223  typedef typename std::vector<var_t>::iterator iterator;
224 
225  State& state;
226  shared_context_t shared_context;
227 
228  bool do_insert = false;
229  bool do_update = false;
230  std::list<var_t*> to_query;
231 
232  template<typename... Args>
233  InsertPlan(State& state, Args&&... args) : state(state), shared_context(std::forward<Args>(args)...) {}
234 
241  {
242  to_query.clear();
243  for (auto i = this->begin(); i != this->end(); ++i)
244  {
245  i->fill_cur(state, shared_context.make_desc(*i));
246  if (i->has_cur(state)) continue;
247  if (shared_context.is_new() || i->is_new()) continue;
248  to_query.push_back(&*i);
249  }
250  }
251 
252  void compute_plan()
253  {
254  do_insert = false;
255  do_update = false;
256  for (auto& var: *this)
257  {
258  if (!var.has_cur(state))
259  {
260  var.set_needs_insert();
261  do_insert = true;
262  }
263  else
264  {
265  var.set_needs_update();
266  do_update = true;
267  }
268  }
269  }
270 };
271 
276 struct InsertStationVars : public InsertPlan<StationVar, SharedStationContext>
277 {
278  using InsertPlan::InsertPlan;
279 
280  StationValueDesc make_desc(iterator& i) const
281  {
282  return StationValueDesc(shared_context.station, i->var->code());
283  }
284 
285  void add(const wreport::Var* var)
286  {
287  emplace_back(state.stationvalues.end(), var);
288  }
289 
290  void dump(FILE* out) const;
291 };
292 
293 
298 struct InsertVars : public InsertPlan<Var, SharedDataContext>
299 {
300  using InsertPlan::InsertPlan;
301 
302  bool has_datetime() const
303  {
304  return not shared_context.datetime.is_missing();
305  }
306 
307  void set_datetime(const Datetime& dt)
308  {
309  shared_context.datetime = dt;
310  }
311 
312  void add(const wreport::Var* var, const LevTrState& levtr)
313  {
314  emplace_back(state.values.end(), var, levtr);
315  }
316 
317  void dump(FILE* out) const;
318 };
319 
320 }
321 
323 {
325  static const char* table_name;
326 };
327 
329 {
330  typedef bulk::InsertVars BulkVars;
331  static const char* table_name;
332 };
333 
334 extern template class DataCommon<StationDataTraits>;
335 extern template class DataCommon<DataTraits>;
336 
339 
340 }
341 }
342 }
343 #endif
void format_flags(char *dest) const
Format flags in the first 4 characters of dest.
virtual void dump(FILE *out)=0
Dump the entire contents of the table to an output stream.
Definition: data.h:107
Definition: v7/qbuilder.h:115
bool is_missing() const
Check if this datetime is the missing value.
Cache intermediate results during a database transaction, to avoid hitting the database multiple time...
Definition: state.h:140
Definition: data.h:37
void read_attrs_into_values(int id_data, Values &values)
Load attributes from the database into a Values.
Definition: data.h:147
virtual void write_attrs(int id_data, const Values &values)=0
Replace the attributes of a variable with those in Values.
Forward declarations for public dballe/sql names.
Definition: state.h:86
Definition: data.h:121
Input for a bulk insert of a lot of variables sharing the same context information.
Definition: data.h:276
uint16_t Varcode
Definition: data.h:221
Definition: db/v7/transaction.h:12
void map_known_values()
Fill the cur state pointer in all variables to insert.
Definition: data.h:240
Definition: state.h:77
virtual void insert(dballe::db::v7::Transaction &t, typename Traits::BulkVars &vars, bulk::UpdateMode update_mode=bulk::UPDATE, bool with_attrs=false)=0
Bulk variable insert.
Definition: data.h:322
Workflow information about a variable listed for bulk insert/update.
Definition: data.h:173
Varcode code() const
Date and time.
Definition: types.h:158
void merge_attrs(int id_data, const Values &attrs)
Merge the given attributes with the existing attributes of the given variable:
Definition: data.h:328
virtual void read_attrs(int id_data, std::function< void(std::unique_ptr< wreport::Var >)> dest)=0
Load from the database all the attributes for var.
Input for a bulk insert of a lot of variables sharing the same context information.
Definition: data.h:298
void remove_attrs(int data_id, const db::AttrList &attrs)
Remove the given attributes from the given variable, if they exist.
Definition: state.h:109
Common definitions.
Collection of Value objects, indexed by wreport::Varcode.
Definition: values.h:203
virtual void remove_all_attrs(int id_data)=0
Remove all attributes from a variable.
Workflow information about a variable listed for bulk insert/update.
Definition: data.h:159