libdballe 9.6
commonapi.h
1#ifndef DBALLE_FORTRAN_COMMONAPI_H
2#define DBALLE_FORTRAN_COMMONAPI_H
3
4#include "api.h"
5#include "enq.h"
6#include <dballe/core/cursor.h>
7#include <dballe/core/enq.h>
8#include <dballe/values.h>
9#include <dballe/core/query.h>
10#include <dballe/core/data.h>
11#include <functional>
12#include <cstring>
13
14namespace dballe {
15namespace fortran {
16
21{
22 Values values;
23 Values::const_iterator current;
24 bool valid = false;
25
28
30 void invalidate();
31
39};
40
45{
46public:
47 virtual ~Operation();
48 virtual void set_varcode(wreport::Varcode varcode);
49 virtual void query_attributes(Attributes& dest) = 0;
50 virtual void insert_attributes(Values& qcinput) = 0;
51 virtual void remove_attributes() = 0;
52 virtual bool next_station();
53 virtual wreport::Varcode next_data();
54
55 virtual int enqi(const char* param) const = 0;
56 virtual signed char enqb(const char* param) const;
57 virtual float enqr(const char* param) const;
58 virtual double enqd(const char* param) const = 0;
59 virtual bool enqc(const char* param, char* res, unsigned res_len) const = 0;
60 virtual void enqlevel(int& ltype1, int& l1, int& ltype2, int& l2) const = 0;
61 virtual void enqtimerange(int& ptype, int& p1, int& p2) const = 0;
62 virtual void enqdate(int& year, int& month, int& day, int& hour, int& min, int& sec) const = 0;
63};
64
65namespace {
66
67inline Level cursor_get_level(const CursorStation& c) { return Level(); }
68inline Level cursor_get_level(const CursorStationData& c) { return Level(); }
69inline Level cursor_get_level(const CursorData& c) { return c.get_level(); }
70inline Level cursor_get_level(const CursorSummary& c) { return c.get_level(); }
71inline Trange cursor_get_trange(const CursorStation& c) { return Trange(); }
72inline Trange cursor_get_trange(const CursorStationData& c) { return Trange(); }
73inline Trange cursor_get_trange(const CursorData& c) { return c.get_trange(); }
74inline Trange cursor_get_trange(const CursorSummary& c) { return c.get_trange(); }
75inline Datetime cursor_get_datetime(const CursorStation& c) { return Datetime(); }
76inline Datetime cursor_get_datetime(const CursorSummary& c) { return Datetime(); }
77inline Datetime cursor_get_datetime(const CursorStationData& c) { return Datetime(); }
78inline Datetime cursor_get_datetime(const CursorData& c) { return c.get_datetime(); }
79
80}
81
82template<typename Cursor>
84{
85 std::shared_ptr<Cursor> cursor;
86
88 {
89 if (cursor) cursor->discard();
90 }
91
92 int enqi(const char* param) const override
93 {
94 if (!cursor)
95 throw wreport::error_consistency("enqi called before running a query");
96
97 impl::Enqi enq(param, strlen(param));
98 cursor->enq(enq);
99 if (enq.missing)
100 return API::missing_int;
101 return enq.res;
102 }
103 double enqd(const char* param) const override
104 {
105 if (!cursor)
106 throw wreport::error_consistency("enqd called before running a query");
107 impl::Enqd enq(param, strlen(param));
108 cursor->enq(enq);
109 if (enq.missing)
110 return API::missing_double;
111 return enq.res;
112 }
113 bool enqc(const char* param, char* res, unsigned res_len) const override
114 {
115 if (!cursor)
116 throw wreport::error_consistency("enqc called before running a query");
117 Enqc enq(param, strlen(param), res, res_len);
118 cursor->enq(enq);
119 return !enq.missing;
120 }
121 void enqlevel(int& ltype1, int& l1, int& ltype2, int& l2) const override
122 {
123 Level lev = cursor_get_level(*cursor);
124 ltype1 = lev.ltype1 != MISSING_INT ? lev.ltype1 : API::missing_int;
125 l1 = lev.l1 != MISSING_INT ? lev.l1 : API::missing_int;
126 ltype2 = lev.ltype2 != MISSING_INT ? lev.ltype2 : API::missing_int;
127 l2 = lev.l2 != MISSING_INT ? lev.l2 : API::missing_int;
128 }
129 void enqtimerange(int& ptype, int& p1, int& p2) const override
130 {
131 Trange tr = cursor_get_trange(*cursor);
132 ptype = tr.pind != MISSING_INT ? tr.pind : API::missing_int;
133 p1 = tr.p1 != MISSING_INT ? tr.p1 : API::missing_int;
134 p2 = tr.p2 != MISSING_INT ? tr.p2 : API::missing_int;
135 }
136 void enqdate(int& year, int& month, int& day, int& hour, int& min, int& sec) const override
137 {
138 Datetime dt = cursor_get_datetime(*cursor);
139 year = dt.year != 0xffff ? dt.year : API::missing_int;
140 month = dt.month != 0xff ? dt.month : API::missing_int;
141 day = dt.day != 0xff ? dt.day : API::missing_int;
142 hour = dt.hour != 0xff ? dt.hour : API::missing_int;
143 min = dt.minute != 0xff ? dt.minute : API::missing_int;
144 sec = dt.second != 0xff ? dt.second : API::missing_int;
145 }
146};
147
153{
154public:
155 enum Permissions {
156 PERM_ANA_RO = (1 << 0),
157 PERM_ANA_WRITE = (1 << 1),
158 PERM_DATA_RO = (1 << 2),
159 PERM_DATA_ADD = (1 << 3),
160 PERM_DATA_WRITE = (1 << 4),
161 PERM_ATTR_RO = (1 << 5),
162 PERM_ATTR_WRITE = (1 << 6)
163 };
164
168 static unsigned compute_permissions(const char* anaflag, const char* dataflag, const char* attrflag);
169
170 unsigned perms = 0;
171
172 core::Query input_query;
173 /*
174 * Fortran code wants to do something like set("var", …); unset("varlist").
175 *
176 * If both var and varlist edit input_query.varcodes, the unset of varlist
177 * will also unset the previous set of var, with unexpected results.
178 *
179 * To work around this, var and varlist are stored in the following
180 * members, and merged into input_query when validate_input_query() is
181 * called.
182 */
183 wreport::Varcode input_query_var = 0;
184 std::set<wreport::Varcode> input_query_varlist;
185
186 core::Data input_data;
188 std::vector<wreport::Varcode> selected_attr_codes;
189 bool station_context = false;
190 Values qcinput;
191 Attributes qcoutput;
192
193protected:
194 Operation* operation = nullptr;
195
196 // Last string returned by one of the spiega* functions, held here so
197 // that we can deallocate it when needed.
198 std::string cached_spiega;
199
200 bool _seti(const char* key, unsigned len, int val);
201 bool _setd(const char* key, unsigned len, double val);
202 bool _setc(const char* key, unsigned len, const char* val);
203 bool _unset(const char* key, unsigned len);
204 void validate_input_query();
205
206public:
210 virtual ~CommonAPIImplementation();
211 CommonAPIImplementation& operator=(const CommonAPIImplementation&) = delete;
213
214 template<typename Operation>
215 auto reset_operation(Operation* op) -> decltype(op->run())
216 {
217 delete operation;
218 operation = op;
219 qcoutput.invalidate();
220 return op->run();
221 }
222
223 void reset_operation()
224 {
225 delete operation;
226 operation = nullptr;
227 qcoutput.invalidate();
228 }
229
230 int enqi(const char* param) override;
231 signed char enqb(const char* param) override;
232 float enqr(const char* param) override;
233 double enqd(const char* param) override;
234 bool enqc(const char* param, char* res, unsigned res_len) override;
235 void seti(const char* param, int value) override;
236 void setb(const char* param, signed char value) override;
237 void setr(const char* param, float value) override;
238 void setd(const char* param, double value) override;
239 void setc(const char* param, const char* value) override;
240 void set_station_context() override;
241 void enqlevel(int& ltype1, int& l1, int& ltype2, int& l2) override;
242 void setlevel(int ltype1, int l1, int ltype2, int l2) override;
243 void enqtimerange(int& ptype, int& p1, int& p2) override;
244 void settimerange(int ptype, int p1, int p2) override;
245 void enqdate(int& year, int& month, int& day, int& hour, int& min, int& sec) override;
246 void setdate(int year, int month, int day, int hour, int min, int sec) override;
247 void setdatemin(int year, int month, int day, int hour, int min, int sec) override;
248 void setdatemax(int year, int month, int day, int hour, int min, int sec) override;
249 void unset(const char* param) override;
250 void unsetall() override;
251 void unsetb() override;
252 const char* describe_level(int ltype1, int l1, int ltype2, int l2) override;
253 const char* describe_timerange(int ptype, int p1, int p2) override;
254 const char* describe_var(const char* varcode, const char* value) override;
255 void next_station() override;
256 wreport::Varcode next_data() override;
257 int query_attributes() override;
258 const char* next_attribute() override;
259 void insert_attributes() override;
260 void remove_attributes() override;
261 void commit() override;
262
263 const Operation* test_get_operation() const { return operation; }
264
265 const core::Query& test_get_input_query() const { return input_query; }
266 const core::Data& test_get_input_data() const { return input_data; }
267 const Values& test_get_qcinput() const { return qcinput; }
268
269 friend class Operation;
270};
271
272}
273}
274#endif
Cursor iterating over station data values.
Definition: cursor.h:67
Cursor iterating over stations.
Definition: cursor.h:57
Holds data for database I/O.
Definition: core/data.h:18
Common implementation of the set* and enq* machinery using input and output records.
Definition: commonapi.h:153
static unsigned compute_permissions(const char *anaflag, const char *dataflag, const char *attrflag)
Set the permission bits, parsing the flags and doing consistency checks.
std::vector< wreport::Varcode > selected_attr_codes
Selected attribute varcodes (*varlist)
Definition: commonapi.h:188
Operation-specific behaviour for the API.
Definition: commonapi.h:45
uint16_t Varcode
Date and time.
Definition: types.h:165
Vertical level or layer.
Definition: types.h:625
int l1
L1 value of the level or the first layer.
Definition: types.h:629
int l2
L2 value of the second layer.
Definition: types.h:633
int ltype1
Type of the level or the first layer.
Definition: types.h:627
int ltype2
Type of the the second layer.
Definition: types.h:631
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:687
int p1
Time range P1 indicator.
Definition: types.h:691
int pind
Time range type indicator.
Definition: types.h:689
int p2
Time range P2 indicator.
Definition: types.h:693
Collection of Value objects, indexed by wreport::Varcode.
Definition: values.h:177
Standard dballe::Query implementation.
Definition: core/query.h:35
C++ implementation for the Fortran API.
Definition: api.h:16
Storage for currently queried attributes.
Definition: commonapi.h:21
void has_new_values()
Mark that there is a new set of values in values.
wreport::Varcode next()
Return the next attribute in the result set.
void invalidate()
Mark the result set as invalid.
Definition: commonapi.h:84
Definition: fortran/enq.h:11
Definition: core/enq.h:207
Definition: core/enq.h:157
Structures used as input to database insert functions.