libdballe 9.13
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 <cstring>
7#include <dballe/core/cursor.h>
8#include <dballe/core/data.h>
9#include <dballe/core/enq.h>
10#include <dballe/core/query.h>
11#include <dballe/values.h>
12#include <functional>
13
14namespace dballe {
15namespace fortran {
16
21{
22 Values values;
23 Values::const_iterator current;
24 bool valid = false;
25
27 wreport::Varcode next();
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,
63 int& sec) const = 0;
64};
65
66namespace {
67
68inline Level cursor_get_level(const CursorStation& c) { return Level(); }
69inline Level cursor_get_level(const CursorStationData& c) { return Level(); }
70inline Level cursor_get_level(const CursorData& c) { return c.get_level(); }
71inline Level cursor_get_level(const CursorSummary& c) { return c.get_level(); }
72inline Trange cursor_get_trange(const CursorStation& c) { return Trange(); }
73inline Trange cursor_get_trange(const CursorStationData& c) { return Trange(); }
74inline Trange cursor_get_trange(const CursorData& c) { return c.get_trange(); }
75inline Trange cursor_get_trange(const CursorSummary& c)
76{
77 return c.get_trange();
78}
79inline Datetime cursor_get_datetime(const CursorStation& c)
80{
81 return Datetime();
82}
83inline Datetime cursor_get_datetime(const CursorSummary& c)
84{
85 return Datetime();
86}
87inline Datetime cursor_get_datetime(const CursorStationData& c)
88{
89 return Datetime();
90}
91inline Datetime cursor_get_datetime(const CursorData& c)
92{
93 return c.get_datetime();
94}
95
96} // namespace
97
98template <typename Cursor> struct CursorOperation : public Operation
99{
100 std::shared_ptr<Cursor> cursor;
101
103 {
104 if (cursor)
105 cursor->discard();
106 }
107
108 int enqi(const char* param) const override
109 {
110 if (!cursor)
112 "enqi called before running a query");
113
114 impl::Enqi enq(param, strlen(param));
115 cursor->enq(enq);
116 if (enq.missing)
117 return API::missing_int;
118 return enq.res;
119 }
120 double enqd(const char* param) const override
121 {
122 if (!cursor)
124 "enqd called before running a query");
125 impl::Enqd enq(param, strlen(param));
126 cursor->enq(enq);
127 if (enq.missing)
128 return API::missing_double;
129 return enq.res;
130 }
131 bool enqc(const char* param, char* res, unsigned res_len) const override
132 {
133 if (!cursor)
135 "enqc called before running a query");
136 Enqc enq(param, strlen(param), res, res_len);
137 cursor->enq(enq);
138 return !enq.missing;
139 }
140 void enqlevel(int& ltype1, int& l1, int& ltype2, int& l2) const override
141 {
142 Level lev = cursor_get_level(*cursor);
143 ltype1 = lev.ltype1 != MISSING_INT ? lev.ltype1 : API::missing_int;
144 l1 = lev.l1 != MISSING_INT ? lev.l1 : API::missing_int;
145 ltype2 = lev.ltype2 != MISSING_INT ? lev.ltype2 : API::missing_int;
146 l2 = lev.l2 != MISSING_INT ? lev.l2 : API::missing_int;
147 }
148 void enqtimerange(int& ptype, int& p1, int& p2) const override
149 {
150 Trange tr = cursor_get_trange(*cursor);
151 ptype = tr.pind != MISSING_INT ? tr.pind : API::missing_int;
152 p1 = tr.p1 != MISSING_INT ? tr.p1 : API::missing_int;
153 p2 = tr.p2 != MISSING_INT ? tr.p2 : API::missing_int;
154 }
155 void enqdate(int& year, int& month, int& day, int& hour, int& min,
156 int& sec) const override
157 {
158 Datetime dt = cursor_get_datetime(*cursor);
159 year = dt.year != 0xffff ? dt.year : API::missing_int;
160 month = dt.month != 0xff ? dt.month : API::missing_int;
161 day = dt.day != 0xff ? dt.day : API::missing_int;
162 hour = dt.hour != 0xff ? dt.hour : API::missing_int;
163 min = dt.minute != 0xff ? dt.minute : API::missing_int;
164 sec = dt.second != 0xff ? dt.second : API::missing_int;
165 }
166};
167
172class CommonAPIImplementation : public API
173{
174public:
175 enum Permissions {
176 PERM_ANA_RO = (1 << 0),
177 PERM_ANA_WRITE = (1 << 1),
178 PERM_DATA_RO = (1 << 2),
179 PERM_DATA_ADD = (1 << 3),
180 PERM_DATA_WRITE = (1 << 4),
181 PERM_ATTR_RO = (1 << 5),
182 PERM_ATTR_WRITE = (1 << 6)
183 };
184
188 static unsigned compute_permissions(const char* anaflag,
189 const char* dataflag,
190 const char* attrflag);
191
192 unsigned perms = 0;
193
194 core::Query input_query;
195 /*
196 * Fortran code wants to do something like set("var", …); unset("varlist").
197 *
198 * If both var and varlist edit input_query.varcodes, the unset of varlist
199 * will also unset the previous set of var, with unexpected results.
200 *
201 * To work around this, var and varlist are stored in the following
202 * members, and merged into input_query when validate_input_query() is
203 * called.
204 */
205 wreport::Varcode input_query_var = 0;
206 std::set<wreport::Varcode> input_query_varlist;
207
208 core::Data input_data;
210 std::vector<wreport::Varcode> selected_attr_codes;
211 bool station_context = false;
212 Values qcinput;
213 Attributes qcoutput;
214
215protected:
216 Operation* operation = nullptr;
217
218 // Last string returned by one of the spiega* functions, held here so
219 // that we can deallocate it when needed.
220 std::string cached_spiega;
221
222 bool _seti(const char* key, unsigned len, int val);
223 bool _setd(const char* key, unsigned len, double val);
224 bool _setc(const char* key, unsigned len, const char* val);
225 bool _unset(const char* key, unsigned len);
226 void validate_input_query();
227
228public:
229 CommonAPIImplementation();
230 CommonAPIImplementation(const CommonAPIImplementation&) = delete;
231 CommonAPIImplementation(CommonAPIImplementation&&) = delete;
232 virtual ~CommonAPIImplementation();
233 CommonAPIImplementation& operator=(const CommonAPIImplementation&) = delete;
234 CommonAPIImplementation& operator=(CommonAPIImplementation&&) = delete;
235
236 template <typename Operation>
237 auto reset_operation(Operation* op) -> decltype(op->run())
238 {
239 delete operation;
240 operation = op;
241 qcoutput.invalidate();
242 return op->run();
243 }
244
245 void reset_operation()
246 {
247 delete operation;
248 operation = nullptr;
249 qcoutput.invalidate();
250 }
251
252 int enqi(const char* param) override;
253 signed char enqb(const char* param) override;
254 float enqr(const char* param) override;
255 double enqd(const char* param) override;
256 bool enqc(const char* param, char* res, unsigned res_len) override;
257 void seti(const char* param, int value) override;
258 void setb(const char* param, signed char value) override;
259 void setr(const char* param, float value) override;
260 void setd(const char* param, double value) override;
261 void setc(const char* param, const char* value) override;
262 void set_station_context() override;
263 void enqlevel(int& ltype1, int& l1, int& ltype2, int& l2) override;
264 void setlevel(int ltype1, int l1, int ltype2, int l2) override;
265 void enqtimerange(int& ptype, int& p1, int& p2) override;
266 void settimerange(int ptype, int p1, int p2) override;
267 void enqdate(int& year, int& month, int& day, int& hour, int& min,
268 int& sec) override;
269 void setdate(int year, int month, int day, int hour, int min,
270 int sec) override;
271 void setdatemin(int year, int month, int day, int hour, int min,
272 int sec) override;
273 void setdatemax(int year, int month, int day, int hour, int min,
274 int sec) override;
275 void unset(const char* param) override;
276 void unsetall() override;
277 void unsetb() override;
278 const char* describe_level(int ltype1, int l1, int ltype2, int l2) override;
279 const char* describe_timerange(int ptype, int p1, int p2) override;
280 const char* describe_var(const char* varcode, const char* value) override;
281 void next_station() override;
282 wreport::Varcode next_data() override;
283 int query_attributes() override;
284 const char* next_attribute() override;
285 void insert_attributes() override;
286 void remove_attributes() override;
287 void commit() override;
288
289 const Operation* test_get_operation() const { return operation; }
290
291 const core::Query& test_get_input_query() const { return input_query; }
292 const core::Data& test_get_input_data() const { return input_data; }
293 const Values& test_get_qcinput() const { return qcinput; }
294
295 friend class Operation;
296};
297
298} // namespace fortran
299} // namespace dballe
300#endif
Cursor iterating over station data values.
Definition cursor.h:68
Cursor iterating over stations.
Definition cursor.h:58
Holds data for database I/O.
Definition core/data.h:18
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:210
Operation-specific behaviour for the API.
Definition commonapi.h:45
Date and time.
Definition types.h:164
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:689
int p1
Time range P1 indicator.
Definition types.h:693
int pind
Time range type indicator.
Definition types.h:691
int p2
Time range P2 indicator.
Definition types.h:695
Collection of Value objects, indexed by wreport::Varcode.
Definition values.h:216
Standard dballe::Query implementation.
Definition core/query.h:36
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:99
Definition fortran/enq.h:11
Definition core/enq.h:227
Definition core/enq.h:177
Structures used as input to database insert functions.