/usr/include/dballe/db/v7/data.h is in libdballe-dev 7.21-1build1.
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 | #ifndef DBALLE_DB_V7_DATAV7_H
#define DBALLE_DB_V7_DATAV7_H
#include <dballe/core/defs.h>
#include <dballe/sql/fwd.h>
#include <dballe/db/defs.h>
#include <dballe/db/v7/state.h>
#include <wreport/var.h>
#include <memory>
#include <vector>
#include <list>
#include <cstdio>
namespace dballe {
struct Record;
struct Values;
namespace db {
namespace v7 {
struct Transaction;
struct IdQueryBuilder;
namespace bulk {
struct InsertStationVars;
struct InsertVars;
enum UpdateMode {
UPDATE,
IGNORE,
ERROR,
};
}
template<typename Traits>
class DataCommon
{
protected:
/**
* Load attributes from the database into a Values
*/
void read_attrs_into_values(int id_data, Values& values);
/**
* Replace the attributes of a variable with those in Values
*/
virtual void write_attrs(int id_data, const Values& values) = 0;
/**
* Remove all attributes from a variable
*/
virtual void remove_all_attrs(int id_data) = 0;
public:
virtual ~DataCommon() {}
/**
* Load from the database all the attributes for var
*
* @param id_data
* ID of the data row for the value of which we will read attributes
* @param dest
* Function that will be called to consume the attrbutes as they are
* loaded.
*/
virtual void read_attrs(int id_data, std::function<void(std::unique_ptr<wreport::Var>)> dest) = 0;
/**
* Merge the given attributes with the existing attributes of the given
* variable:
*
* * Existing attributes not in attrs are preserved.
* * Existing attributes in attrs are overwritten.
* * New attributes in attrs are inesrted.
*/
void merge_attrs(int id_data, const Values& attrs);
/**
* Remove the given attributes from the given variable, if they exist.
*/
void remove_attrs(int data_id, const db::AttrList& attrs);
/// Bulk variable insert
virtual void insert(dballe::db::v7::Transaction& t, typename Traits::BulkVars& vars, bulk::UpdateMode update_mode=bulk::UPDATE, bool with_attrs=false) = 0;
/// Run the query to delete all records selected by the given QueryBuilder
virtual void remove(const v7::IdQueryBuilder& qb) = 0;
/// Dump the entire contents of the table to an output stream
virtual void dump(FILE* out) = 0;
};
struct StationDataDumper
{
unsigned count = 0;
FILE* out;
StationDataDumper(FILE* out);
void print_head();
void print_row(int id, int id_station, wreport::Varcode code, const char* val, const std::vector<uint8_t>& attrs);
void print_tail();
};
struct DataDumper
{
unsigned count = 0;
FILE* out;
DataDumper(FILE* out);
void print_head();
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);
void print_tail();
};
namespace bulk {
struct Item
{
static const unsigned FLAG_NEEDS_UPDATE = 1 << 0;
static const unsigned FLAG_UPDATED = 1 << 1;
static const unsigned FLAG_NEEDS_INSERT = 1 << 2;
static const unsigned FLAG_INSERTED = 1 << 3;
unsigned flags = 0;
bool needs_update() const { return flags & FLAG_NEEDS_UPDATE; }
bool updated() const { return flags & FLAG_UPDATED; }
bool needs_insert() const { return flags & FLAG_NEEDS_INSERT; }
bool inserted() const { return flags & FLAG_INSERTED; }
void set_needs_update() { flags |= FLAG_NEEDS_UPDATE; }
void set_updated() { flags = (flags & ~FLAG_NEEDS_UPDATE) | FLAG_UPDATED; }
void set_needs_insert() { flags |= FLAG_NEEDS_INSERT; }
void set_inserted() { flags = (flags & ~FLAG_NEEDS_INSERT) | FLAG_INSERTED; }
/**
* Format flags in the first 4 characters of dest.
*
* It adds a trailing 0, so dest should be at least 5 bytes long.
*/
void format_flags(char* dest) const;
};
template<typename state_t>
struct VarItem : public Item
{
typename state_t::iterator cur;
const wreport::Var* var;
VarItem(typename state_t::iterator cur, const wreport::Var* var)
: cur(cur), var(var) {}
};
/**
* Workflow information about a variable listed for bulk insert/update
*/
struct StationVar : public VarItem<stationvalues_t>
{
using VarItem::VarItem;
bool is_new() const { return false; }
bool has_cur(State& state) const { return cur != state.stationvalues.end(); }
void fill_cur(State& state, const StationValueDesc& desc) { cur = state.stationvalues.find(desc); }
void dump(FILE* out) const;
};
/**
* Workflow information about a variable listed for bulk insert/update
*/
struct Var : public VarItem<values_t>
{
LevTrState levtr;
Var(values_t::iterator cur, const wreport::Var* var, const LevTrState& levtr)
: VarItem(cur, var), levtr(levtr) {}
bool is_new() const { return levtr.is_new; }
bool has_cur(State& state) const { return cur != state.values.end(); }
void fill_cur(State& state, const ValueDesc& desc) { cur = state.values.find(desc); }
void dump(FILE* out) const;
};
struct SharedContext
{
stations_t::iterator station;
SharedContext() {}
SharedContext(stations_t::iterator station) : station(station) {}
bool is_new() const { return station->second.is_new; }
};
struct SharedStationContext : public SharedContext
{
using SharedContext::SharedContext;
StationValueDesc make_desc(StationVar& v) const
{
return StationValueDesc(station, v.var->code());
}
};
struct SharedDataContext : public SharedContext
{
Datetime datetime;
SharedDataContext() {}
SharedDataContext(stations_t::iterator station) : SharedContext(station) {}
SharedDataContext(stations_t::iterator station, const Datetime& datetime) : SharedContext(station), datetime(datetime) {}
ValueDesc make_desc(Var& v) const
{
return ValueDesc(station, v.levtr.id, datetime, v.var->code());
}
};
template<typename var_t, typename shared_context_t>
struct InsertPlan : public std::vector<var_t>
{
typedef typename std::vector<var_t>::iterator iterator;
State& state;
shared_context_t shared_context;
bool do_insert = false;
bool do_update = false;
std::list<var_t*> to_query;
template<typename... Args>
InsertPlan(State& state, Args&&... args) : state(state), shared_context(std::forward<Args>(args)...) {}
/**
* Fill the cur state pointer in all variables to insert.
*
* When state info is not available, add the variable to to_query.
*/
void map_known_values()
{
to_query.clear();
for (auto i = this->begin(); i != this->end(); ++i)
{
i->fill_cur(state, shared_context.make_desc(*i));
if (i->has_cur(state)) continue;
if (shared_context.is_new() || i->is_new()) continue;
to_query.push_back(&*i);
}
}
void compute_plan()
{
do_insert = false;
do_update = false;
for (auto& var: *this)
{
if (!var.has_cur(state))
{
var.set_needs_insert();
do_insert = true;
}
else
{
var.set_needs_update();
do_update = true;
}
}
}
};
/**
* Input for a bulk insert of a lot of variables sharing the same context
* information.
*/
struct InsertStationVars : public InsertPlan<StationVar, SharedStationContext>
{
using InsertPlan::InsertPlan;
StationValueDesc make_desc(iterator& i) const
{
return StationValueDesc(shared_context.station, i->var->code());
}
void add(const wreport::Var* var)
{
emplace_back(state.stationvalues.end(), var);
}
void dump(FILE* out) const;
};
/**
* Input for a bulk insert of a lot of variables sharing the same context
* information.
*/
struct InsertVars : public InsertPlan<Var, SharedDataContext>
{
using InsertPlan::InsertPlan;
bool has_datetime() const
{
return not shared_context.datetime.is_missing();
}
void set_datetime(const Datetime& dt)
{
shared_context.datetime = dt;
}
void add(const wreport::Var* var, const LevTrState& levtr)
{
emplace_back(state.values.end(), var, levtr);
}
void dump(FILE* out) const;
};
}
struct StationDataTraits
{
typedef bulk::InsertStationVars BulkVars;
static const char* table_name;
};
struct DataTraits
{
typedef bulk::InsertVars BulkVars;
static const char* table_name;
};
extern template class DataCommon<StationDataTraits>;
extern template class DataCommon<DataTraits>;
typedef DataCommon<StationDataTraits> StationData;
typedef DataCommon<DataTraits> Data;
}
}
}
#endif
|