Code

Handle last_update/interval in the core rather than in memstore.
[sysdb.git] / src / include / core / memstore.h
1 /*
2  * SysDB - src/include/core/memstore.h
3  * Copyright (C) 2012-2015 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #ifndef SDB_CORE_MEMSTORE_H
29 #define SDB_CORE_MEMSTORE_H 1
31 #include "sysdb.h"
32 #include "core/object.h"
33 #include "core/data.h"
34 #include "core/store.h"
35 #include "core/time.h"
36 #include "parser/ast.h"
37 #include "utils/strbuf.h"
39 #include <stdbool.h>
40 #include <stdio.h>
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
46 /*
47  * sdb_memstore_t represents an in-memory store. It inherits from sdb_object_t
48  * and may safely be case to a generic object.
49  */
50 struct sdb_memstore;
51 typedef struct sdb_memstore sdb_memstore_t;
52 #define SDB_MEMSTORE(obj) ((sdb_memstore_t *)(obj))
54 /*
55  * sdb_memstore_obj_t represents the super-class of any stored object. It
56  * inherits from sdb_object_t and may safely be cast to a generic object to
57  * access its name.
58  */
59 struct sdb_memstore_obj;
60 typedef struct sdb_memstore_obj sdb_memstore_obj_t;
62 /*
63  * Expressions represent arithmetic expressions based on stored objects and
64  * their various attributes.
65  *
66  * An expression object inherits from sdb_object_t and, thus, may safely be
67  * cast to a generic object.
68  */
69 struct sdb_memstore_expr;
70 typedef struct sdb_memstore_expr sdb_memstore_expr_t;
71 #define SDB_MEMSTORE_EXPR(obj) ((sdb_memstore_expr_t *)(obj))
73 /*
74  * An expression iterator iterates over the values of an iterable expression.
75  */
76 struct sdb_memstore_expr_iter;
77 typedef struct sdb_memstore_expr_iter sdb_memstore_expr_iter_t;
79 /*
80  * Store matchers may be used to lookup hosts from the store based on their
81  * various attributes. Service and attribute matchers are applied to a host's
82  * services and attributes and evaluate to true if *any* service or attribute
83  * matches.
84  *
85  * A store matcher object inherits from sdb_object_t and, thus, may safely be
86  * cast to a generic object.
87  */
88 struct sdb_memstore_matcher;
89 typedef struct sdb_memstore_matcher sdb_memstore_matcher_t;
90 #define SDB_MEMSTORE_MATCHER(obj) ((sdb_memstore_matcher_t *)(obj))
92 /*
93  * sdb_memstore_writer:
94  * A store writer implementation that provides an in-memory object store. It
95  * expects a store object as its user-data argument.
96  */
97 extern sdb_store_writer_t sdb_memstore_writer;
99 /*
100  * sdb_memstore_reader:
101  * A store reader implementation that uses an in-memory object store. It
102  * expects a store object as its user-data argument.
103  */
104 extern sdb_store_reader_t sdb_memstore_reader;
106 /*
107  * sdb_memstore_create:
108  * Allocate a new in-memory store.
109  */
110 sdb_memstore_t *
111 sdb_memstore_create(void);
113 /*
114  * sdb_memstore_host, sdb_memstore_service, sdb_memstore_metric,
115  * sdb_memstore_attribute, sdb_memstore_metric_attr:
116  * Store an object in the specified store. The hostname is expected to be
117  * canonical.
118  */
119 int
120 sdb_memstore_host(sdb_memstore_t *store, const char *name,
121                 sdb_time_t last_update, sdb_time_t interval);
122 int
123 sdb_memstore_service(sdb_memstore_t *store, const char *hostname, const char *name,
124                 sdb_time_t last_update, sdb_time_t interval);
125 int
126 sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *name,
127                 sdb_metric_store_t *metric_store,
128                 sdb_time_t last_update, sdb_time_t interval);
129 int
130 sdb_memstore_attribute(sdb_memstore_t *store, const char *hostname,
131                 const char *key, const sdb_data_t *value,
132                 sdb_time_t last_update, sdb_time_t interval);
133 int
134 sdb_memstore_service_attr(sdb_memstore_t *store, const char *hostname,
135                 const char *service, const char *key, const sdb_data_t *value,
136                 sdb_time_t last_update, sdb_time_t interval);
137 int
138 sdb_memstore_metric_attr(sdb_memstore_t *store, const char *hostname,
139                 const char *metric, const char *key, const sdb_data_t *value,
140                 sdb_time_t last_update, sdb_time_t interval);
142 /*
143  * sdb_memstore_get_host:
144  * Query the specified store for a host by its (canonicalized) name.
145  *
146  * The function increments the ref count of the host object. The caller needs
147  * to deref it when no longer using it.
148  */
149 sdb_memstore_obj_t *
150 sdb_memstore_get_host(sdb_memstore_t *store, const char *name);
152 /*
153  * sdb_memstore_get_child:
154  * Retrieve an object's child object of the specified type and name. The
155  * reference count of the child object will be incremented before returning
156  * it. The caller is responsible for releasing the object once it's no longer
157  * used.
158  *
159  * Returns:
160  *  - the child object on success
161  *  - NULL else
162  */
163 sdb_memstore_obj_t *
164 sdb_memstore_get_child(sdb_memstore_obj_t *obj, int type, const char *name);
166 /*
167  * sdb_memstore_get_field:
168  * Get the value of a stored object's queryable field. The caller is
169  * responsible for freeing any dynamically allocated memory possibly stored in
170  * the returned value. If 'res' is NULL, the function will return whether the
171  * field exists.
172  *
173  * Returns:
174  *  - 0 on success
175  *  - a negative value else
176  */
177 int
178 sdb_memstore_get_field(sdb_memstore_obj_t *obj, int field, sdb_data_t *res);
180 /*
181  * sdb_memstore_get_attr:
182  * Get the value of a stored object's attribute. The caller is responsible for
183  * freeing any dynamically allocated memory possibly stored in the returned
184  * value. If 'res' is NULL, the function will return whether the attribute
185  * exists. If specified, only attributes matching the filter will be
186  * considered.
187  *
188  * Returns:
189  *  - 0 if the attribute exists
190  *  - a negative value else
191  */
192 int
193 sdb_memstore_get_attr(sdb_memstore_obj_t *obj, const char *name, sdb_data_t *res,
194                 sdb_memstore_matcher_t *filter);
196 /*
197  * Querying a store:
198  *
199  *  - Query interface: A query is a formal description of an interaction with
200  *    the store. It can be used, both, for read and write access. The query is
201  *    described by its abstract syntax tree (AST). The parser package provides
202  *    means to parse a string (SysQL) representation of the query into an AST.
203  *
204  *  - Matcher / expression interface: This low-level interface provides direct
205  *    control over how to access the store. It is used by the query
206  *    implementation internally and can only be used for read access.
207  */
209 /*
210  * sdb_memstore_query_t:
211  * A parsed query readily prepared for execution.
212  */
213 struct sdb_memstore_query;
214 typedef struct sdb_memstore_query sdb_memstore_query_t;
216 /*
217  * sdb_memstore_query_prepare:
218  * Prepare the query described by 'ast' for execution in a store.
219  *
220  * Returns:
221  *  - a store query on success
222  *  - NULL else
223  */
224 sdb_memstore_query_t *
225 sdb_memstore_query_prepare(sdb_ast_node_t *ast);
227 /*
228  * sdb_memstore_query_prepare_matcher:
229  * Prepare the logical expression described by 'ast' for execution as a store
230  * matcher.
231  *
232  * Returns:
233  *  - a matcher on success
234  *  - NULL else
235  */
236 sdb_memstore_matcher_t *
237 sdb_memstore_query_prepare_matcher(sdb_ast_node_t *ast);
239 /*
240  * sdb_memstore_query_execute:
241  * Execute a previously prepared query in the specified store. The query
242  * result will be written to 'buf' and any errors to 'errbuf'.
243  *
244  * Returns:
245  *  - the result type (to be used by the server reply)
246  *  - a negative value on error
247  */
248 int
249 sdb_memstore_query_execute(sdb_memstore_t *store, sdb_memstore_query_t *m,
250                 sdb_store_writer_t *w, sdb_object_t *wd, sdb_strbuf_t *errbuf);
252 /*
253  * sdb_memstore_expr_create:
254  * Creates an arithmetic expression implementing the specified operator on the
255  * specified left and right operand.
256  *
257  * Returns:
258  *  - an expression object on success
259  *  - NULL else
260  */
261 sdb_memstore_expr_t *
262 sdb_memstore_expr_create(int op,
263                 sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
265 /*
266  * sdb_memstore_expr_typed:
267  * Creates an expression which evaluates in the context of an object's sibling
268  * as specified by the given type.
269  *
270  * Returns:
271  *  - an expression object on success
272  *  - NULL else
273  */
274 sdb_memstore_expr_t *
275 sdb_memstore_expr_typed(int typ, sdb_memstore_expr_t *expr);
277 /*
278  * sdb_memstore_expr_fieldvalue:
279  * Creates an expression which evaluates to the value of the specified
280  * queryable field of a stored object.
281  *
282  * Returns:
283  *  - an expression object on success
284  *  - NULL else
285  */
286 sdb_memstore_expr_t *
287 sdb_memstore_expr_fieldvalue(int field);
289 /*
290  * sdb_memstore_expr_attrvalue:
291  * Creates an expression which evaluates to the value of the specified
292  * attribute of a stored object. Evaluates to a NULL value if the attribute
293  * does not exist.
294  *
295  * Returns:
296  *  - an expression object on success
297  *  - NULL else
298  */
299 sdb_memstore_expr_t *
300 sdb_memstore_expr_attrvalue(const char *name);
302 /*
303  * sdb_memstore_expr_constvalue:
304  * Creates an expression which evaluates to the specified constant value.
305  *
306  * Returns:
307  *  - an expression object on success
308  *  - NULL else
309  */
310 sdb_memstore_expr_t *
311 sdb_memstore_expr_constvalue(const sdb_data_t *value);
313 /*
314  * sdb_memstore_expr_eval:
315  * Evaluate an expression for the specified stored object and stores the
316  * result in 'res'. The result's value will be allocated dynamically if
317  * necessary and, thus, should be free'd by the caller (e.g. using
318  * sdb_data_free_datum). The object may be NULL, in which case the expression
319  * needs to evaluate to a constant value. If specified, only objects matching
320  * the filter will be used during the evaluation.
321  *
322  * Returns:
323  *  - 0 on success
324  *  - a negative value else
325  */
326 int
327 sdb_memstore_expr_eval(sdb_memstore_expr_t *expr, sdb_memstore_obj_t *obj,
328                 sdb_data_t *res, sdb_memstore_matcher_t *filter);
330 /*
331  * sdb_memstore_expr_iter:
332  * Iterate over the elements of an iterable expression. sdb_memstore_expr_iter
333  * returns NULL if the expression is not iterable (for the specified object).
334  *
335  * sdb_memstore_expr_iter_get_next returns NULL if there is no next element.
336  */
337 sdb_memstore_expr_iter_t *
338 sdb_memstore_expr_iter(sdb_memstore_expr_t *expr, sdb_memstore_obj_t *obj,
339                 sdb_memstore_matcher_t *filter);
340 void
341 sdb_memstore_expr_iter_destroy(sdb_memstore_expr_iter_t *iter);
343 bool
344 sdb_memstore_expr_iter_has_next(sdb_memstore_expr_iter_t *iter);
345 sdb_data_t
346 sdb_memstore_expr_iter_get_next(sdb_memstore_expr_iter_t *iter);
348 /*
349  * sdb_memstore_dis_matcher:
350  * Creates a matcher matching the disjunction (logical OR) of two matchers.
351  */
352 sdb_memstore_matcher_t *
353 sdb_memstore_dis_matcher(sdb_memstore_matcher_t *left, sdb_memstore_matcher_t *right);
355 /*
356  * sdb_memstore_con_matcher:
357  * Creates a matcher matching the conjunction (logical AND) of two matchers.
358  */
359 sdb_memstore_matcher_t *
360 sdb_memstore_con_matcher(sdb_memstore_matcher_t *left, sdb_memstore_matcher_t *right);
362 /*
363  * sdb_memstore_inv_matcher:
364  * Creates a matcher matching the inverse (logical NOT) of a matcher.
365  */
366 sdb_memstore_matcher_t *
367 sdb_memstore_inv_matcher(sdb_memstore_matcher_t *m);
369 /*
370  * sdb_memstore_any_matcher:
371  * Creates a matcher iterating over values of the first expression (which has
372  * to be iterable). It matches if *any* of those elements match 'm'. 'm' has
373  * to be an ary operation with the left operand unset.
374  */
375 sdb_memstore_matcher_t *
376 sdb_memstore_any_matcher(sdb_memstore_expr_t *iter, sdb_memstore_matcher_t *m);
378 /*
379  * sdb_memstore_all_matcher:
380  * Creates a matcher iterating over values of the first expression (which has
381  * to be iterable). It matches if *all* of those elements match 'm'. 'm' has
382  * to be an ary operation with the left operand unset.
383  */
384 sdb_memstore_matcher_t *
385 sdb_memstore_all_matcher(sdb_memstore_expr_t *iter, sdb_memstore_matcher_t *m);
387 /*
388  * sdb_memstore_in_matcher:
389  * Creates a matcher which matches if the right value evaluates to an array
390  * value and the left value is included in that array. See sdb_data_inarray
391  * for more details.
392  */
393 sdb_memstore_matcher_t *
394 sdb_memstore_in_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
396 /*
397  * sdb_memstore_lt_matcher, sdb_memstore_le_matcher, sdb_memstore_eq_matcher,
398  * sdb_memstore_ge_matcher, sdb_memstore_gt_matcher:
399  * Create conditional matchers comparing the values of two expressions. The
400  * matcher matches if the left expression compres less than, less or equal
401  * than, equal to, not equal to, greater or equal than, or greater than the
402  * right expression.
403  */
404 sdb_memstore_matcher_t *
405 sdb_memstore_lt_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
406 sdb_memstore_matcher_t *
407 sdb_memstore_le_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
408 sdb_memstore_matcher_t *
409 sdb_memstore_eq_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
410 sdb_memstore_matcher_t *
411 sdb_memstore_ne_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
412 sdb_memstore_matcher_t *
413 sdb_memstore_ge_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
414 sdb_memstore_matcher_t *
415 sdb_memstore_gt_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
417 /*
418  * sdb_memstore_regex_matcher:
419  * Creates a matcher which matches the string value the left expression
420  * evaluates to against the regular expression the right expression evaluates
421  * to. The right expression may either be a constant value regular expression
422  * or string or a dynamic value evaluating to a string. In the latter case,
423  * the string is compiled to a regex every time the matcher is executed.
424  */
425 sdb_memstore_matcher_t *
426 sdb_memstore_regex_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
428 /*
429  * sdb_memstore_nregex_matcher:
430  * Creates a regex matcher just like sdb_memstore_regex_matcher except that it
431  * matches in case the regular expression does not match.
432  */
433 sdb_memstore_matcher_t *
434 sdb_memstore_nregex_matcher(sdb_memstore_expr_t *left, sdb_memstore_expr_t *right);
436 /*
437  * sdb_memstore_isnull_matcher:
438  * Creates a matcher matching NULL values.
439  */
440 sdb_memstore_matcher_t *
441 sdb_memstore_isnull_matcher(sdb_memstore_expr_t *expr);
443 /*
444  * sdb_memstore_istrue_matcher, sdb_memstore_isfalse_matcher:
445  * Creates a matcher matching boolean values.
446  */
447 sdb_memstore_matcher_t *
448 sdb_memstore_istrue_matcher(sdb_memstore_expr_t *expr);
449 sdb_memstore_matcher_t *
450 sdb_memstore_isfalse_matcher(sdb_memstore_expr_t *expr);
452 /*
453  * sdb_memstore_matcher_matches:
454  * Check whether the specified matcher matches the specified store object. If
455  * specified, the filter will be used to preselect objects for further
456  * evaluation. It is applied to any object that's used during the evaluation
457  * of the matcher. Only those objects matching the filter will be considered.
458  *
459  * Note that the filter is applied to all object types (hosts, service,
460  * metric, attribute). Thus, any object-specific matchers are mostly unsuited
461  * for this purpose and, if used, may result in unexpected behavior.
462  *
463  * Returns:
464  *  - 1 if the object matches
465  *  - 0 else
466  */
467 int
468 sdb_memstore_matcher_matches(sdb_memstore_matcher_t *m, sdb_memstore_obj_t *obj,
469                 sdb_memstore_matcher_t *filter);
471 /*
472  * sdb_memstore_matcher_op_cb:
473  * Callback constructing a matcher operator.
474  */
475 typedef sdb_memstore_matcher_t *(*sdb_memstore_matcher_op_cb)
476         (sdb_memstore_expr_t *, sdb_memstore_expr_t *);
478 /*
479  * sdb_memstore_lookup_cb:
480  * Lookup callback. It is called for each matching object when looking up data
481  * in the store passing on the lookup filter and the specified user-data. The
482  * lookup aborts early if the callback returns non-zero.
483  */
484 typedef int (*sdb_memstore_lookup_cb)(sdb_memstore_obj_t *obj,
485                 sdb_memstore_matcher_t *filter, void *user_data);
487 /*
488  * sdb_memstore_scan:
489  * Look up objects of the specified type in the specified store. The specified
490  * callback function is called for each object in the store matching 'm'. The
491  * function performs a full scan of all stored objects. If specified, the
492  * filter will be used to preselect objects for further evaluation. See the
493  * description of 'sdb_memstore_matcher_matches' for details.
494  *
495  * Returns:
496  *  - 0 on success
497  *  - a negative value else
498  */
499 int
500 sdb_memstore_scan(sdb_memstore_t *store, int type,
501                 sdb_memstore_matcher_t *m, sdb_memstore_matcher_t *filter,
502                 sdb_memstore_lookup_cb cb, void *user_data);
504 /*
505  * sdb_memstore_emit:
506  * Send a single object to the specified store writer. Attributes or any child
507  * objects are not included. Use sdb_memstore_emit_full() to emit a full
508  * (filtered) object.
509  *
510  * Returns:
511  *  - 0 on success
512  *  - a negative value else
513  */
514 int
515 sdb_memstore_emit(sdb_memstore_obj_t *obj, sdb_store_writer_t *w, sdb_object_t *wd);
517 /*
518  * sdb_memstore_emit_full:
519  * Send a single object and its attributes and all children to the specified
520  * store writer. The filter, if specified, is applied to each attribute and
521  * child object. Only matching objects will be emitted.
522  *
523  * Returns:
524  *  - 0 on success
525  *  - a negative value else
526  */
527 int
528 sdb_memstore_emit_full(sdb_memstore_obj_t *obj, sdb_memstore_matcher_t *filter,
529                 sdb_store_writer_t *w, sdb_object_t *wd);
531 #ifdef __cplusplus
532 } /* extern "C" */
533 #endif
535 #endif /* ! SDB_CORE_MEMSTORE_H */
537 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */