Code

store: Added sdb_store_get_child().
[sysdb.git] / src / include / core / store.h
1 /*
2  * SysDB - src/include/core/store.h
3  * Copyright (C) 2012 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_STORE_H
29 #define SDB_CORE_STORE_H 1
31 #include "sysdb.h"
32 #include "core/object.h"
33 #include "core/data.h"
34 #include "core/time.h"
35 #include "core/timeseries.h"
36 #include "utils/strbuf.h"
38 #include <stdio.h>
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
44 /*
45  * Store object types.
46  */
47 enum {
48         SDB_HOST = 1,
49         SDB_SERVICE,
50         SDB_METRIC,
51         SDB_ATTRIBUTE,
52 };
53 #define SDB_STORE_TYPE_TO_NAME(t) \
54         (((t) == SDB_HOST) ? "host" \
55                 : ((t) == SDB_SERVICE) ? "service" \
56                 : ((t) == SDB_METRIC) ? "metric" \
57                 : ((t) == SDB_ATTRIBUTE) ? "attribute" : "unknown")
59 /*
60  * sdb_store_obj_t represents the super-class of any object stored in the
61  * database. It inherits from sdb_object_t and may safely be cast to a generic
62  * object to access its name.
63  */
64 struct sdb_store_obj;
65 typedef struct sdb_store_obj sdb_store_obj_t;
67 /*
68  * Expressions represent arithmetic expressions based on stored objects and
69  * their various attributes.
70  *
71  * An expression object inherits from sdb_object_t and, thus, may safely be
72  * cast to a generic object.
73  */
74 struct sdb_store_expr;
75 typedef struct sdb_store_expr sdb_store_expr_t;
76 #define SDB_STORE_EXPR(obj) ((sdb_store_expr_t *)(obj))
78 /*
79  * Store matchers may be used to lookup hosts from the store based on their
80  * various attributes. Service and attribute matchers are applied to a host's
81  * services and attributes and evaluate to true if *any* service or attribute
82  * matches.
83  *
84  * A store matcher object inherits from sdb_object_t and, thus, may safely be
85  * cast to a generic object.
86  */
87 struct sdb_store_matcher;
88 typedef struct sdb_store_matcher sdb_store_matcher_t;
89 #define SDB_STORE_MATCHER(obj) ((sdb_store_matcher_t *)(obj))
91 /*
92  * A JSON formatter converts stored objects into the JSON format.
93  * See http://www.ietf.org/rfc/rfc4627.txt
94  */
95 struct sdb_store_json_formatter;
96 typedef struct sdb_store_json_formatter sdb_store_json_formatter_t;
98 /*
99  * Queryable fields of a stored object.
100  */
101 enum {
102         SDB_FIELD_NAME = 1,    /* string */
103         SDB_FIELD_LAST_UPDATE, /* datetime */
104         SDB_FIELD_AGE,         /* datetime */
105         SDB_FIELD_INTERVAL,    /* datetime */
106         SDB_FIELD_BACKEND,     /* string */
107 };
109 #define SDB_FIELD_TO_NAME(f) \
110         (((f) == SDB_FIELD_NAME) ? "name" \
111                 : ((f) == SDB_FIELD_LAST_UPDATE) ? "last-update" \
112                 : ((f) == SDB_FIELD_AGE) ? "age" \
113                 : ((f) == SDB_FIELD_INTERVAL) ? "interval" \
114                 : ((f) == SDB_FIELD_BACKEND) ? "backend" : "unknown")
116 #define SDB_FIELD_TYPE(f) \
117         (((f) == SDB_FIELD_NAME) ? SDB_TYPE_STRING \
118                 : ((f) == SDB_FIELD_LAST_UPDATE) ? SDB_TYPE_DATETIME \
119                 : ((f) == SDB_FIELD_AGE) ? SDB_TYPE_DATETIME \
120                 : ((f) == SDB_FIELD_INTERVAL) ? SDB_TYPE_DATETIME \
121                 : ((f) == SDB_FIELD_BACKEND) ? (SDB_TYPE_ARRAY | SDB_TYPE_STRING) \
122                 : -1)
124 /*
125  * sdb_store_clear:
126  * Clear the entire store and remove all stored objects.
127  */
128 void
129 sdb_store_clear(void);
131 /*
132  * sdb_store_host:
133  * Add/update a host in the store. If the host, identified by its
134  * canonicalized name, already exists, it will be updated according to the
135  * specified name and timestamp. Else, a new entry will be created in the
136  * store. Any memory required for storing the entry will be allocated an
137  * managed by the store itself.
138  *
139  * Returns:
140  *  - 0 on success
141  *  - a positive value if the new entry is older than the currently stored
142  *    entry (in this case, no update will happen)
143  *  - a negative value on error
144  */
145 int
146 sdb_store_host(const char *name, sdb_time_t last_update);
148 /*
149  * sdb_store_has_host:
150  * sdb_store_get_host:
151  * Query the store for a host by its (canonicalized) name.
152  *
153  * sdb_store_get_host increments the ref count of the host object. The caller
154  * needs to deref it when no longer using it.
155  */
156 _Bool
157 sdb_store_has_host(const char *name);
159 sdb_store_obj_t *
160 sdb_store_get_host(const char *name);
162 /*
163  * sdb_store_attribute:
164  * Add/update a host's attribute in the store. If the attribute, identified by
165  * its key, already exists for the specified host, it will be updated to the
166  * specified values. If the referenced host does not exist, an error will be
167  * reported. Else, a new entry will be created in the store. Any memory
168  * required for storing the entry will be allocated and managed by the store
169  * itself.
170  *
171  * Returns:
172  *  - 0 on success
173  *  - a positive value if the new entry is older than the currently stored
174  *    entry (in this case, no update will happen)
175  *  - a negative value on error
176  */
177 int
178 sdb_store_attribute(const char *hostname,
179                 const char *key, const sdb_data_t *value,
180                 sdb_time_t last_update);
182 /*
183  * sdb_store_service:
184  * Add/update a service in the store. If the service, identified by its name,
185  * already exists for the specified host, it will be updated according to the
186  * specified 'service' object. If the referenced host does not exist, an error
187  * will be reported. Else, a new entry will be created in the store. Any
188  * memory required for storing the entry will be allocated an managed by the
189  * store itself.
190  *
191  * Returns:
192  *  - 0 on success
193  *  - a positive value if the new entry is older than the currently stored
194  *    entry (in this case, no update will happen)
195  *  - a negative value on error
196  */
197 int
198 sdb_store_service(const char *hostname, const char *name,
199                 sdb_time_t last_update);
201 /*
202  * sdb_store_service_attr:
203  * Add/update a service's attribute in the store. If the attribute, identified
204  * by its key, already exists for the specified service, it will be updated to
205  * the specified value. If the references service (for the specified host)
206  * does not exist, an error will be reported. Any memory required for storing
207  * the entry will be allocated and managed by the store itself.
208  *
209  * Returns:
210  *  - 0 on success
211  *  - a positive value if the new entry is older than the currently stored
212  *    entry (in this case, no update will happen)
213  *  - a negative value on error
214  */
215 int
216 sdb_store_service_attr(const char *hostname, const char *service,
217                 const char *key, const sdb_data_t *value, sdb_time_t last_update);
219 /*
220  * sdb_store_get_child:
221  * Retrieve a host's child object of the specified type and name. The
222  * reference count of the child object will be incremented before returning
223  * it. The caller is responsible for releasing the object once it's no longer
224  * used.
225  *
226  * Returns:
227  *  - the child object on success
228  *  - NULL else
229  */
230 sdb_store_obj_t *
231 sdb_store_get_child(sdb_store_obj_t *host, int type, const char *name);
233 /*
234  * A metric store describes how to access a metric's data.
235  */
236 typedef struct {
237         const char *type;
238         const char *id;
239 } sdb_metric_store_t;
241 /*
242  * sdb_store_metric:
243  * Add/update a metric in the store. If the metric, identified by its name,
244  * already exists for the specified host, it will be updated according to the
245  * specified 'metric' object. If the referenced host does not exist, an error
246  * will be reported. Else, a new entry will be created in the store. Any
247  * memory required for storing the entry will be allocated an managed by the
248  * store itself.
249  *
250  * If specified, the metric store describes where to access the metric's data.
251  *
252  * Returns:
253  *  - 0 on success
254  *  - a positive value if the new entry is older than the currently stored
255  *    entry (in this case, no update will happen)
256  *  - a negative value on error
257  */
258 int
259 sdb_store_metric(const char *hostname, const char *name,
260                 sdb_metric_store_t *store, sdb_time_t last_update);
262 /*
263  * sdb_store_metric_attr:
264  * Add/update a metric's attribute in the store. If the attribute, identified
265  * by its key, already exists for the specified metric, it will be updated to
266  * the specified value. If the references metric (for the specified host)
267  * does not exist, an error will be reported. Any memory required for storing
268  * the entry will be allocated and managed by the store itself.
269  *
270  * Returns:
271  *  - 0 on success
272  *  - a positive value if the new entry is older than the currently stored
273  *    entry (in this case, no update will happen)
274  *  - a negative value on error
275  */
276 int
277 sdb_store_metric_attr(const char *hostname, const char *metric,
278                 const char *key, const sdb_data_t *value, sdb_time_t last_update);
280 /*
281  * sdb_store_fetch_timeseries:
282  * Fetch the time-series described by the specified host's metric and
283  * serialize it as JSON into the provided string buffer.
284  *
285  * Returns:
286  *  - 0 on success
287  *  - a negative value else
288  */
289 int
290 sdb_store_fetch_timeseries(const char *hostname, const char *metric,
291                 sdb_timeseries_opts_t *opts, sdb_strbuf_t *buf);
293 /*
294  * sdb_store_get_field:
295  * Get the value of a stored object's queryable field. The caller is
296  * responsible for freeing any dynamically allocated memory possibly stored in
297  * the returned value. If 'res' is NULL, the function will return whether the
298  * field exists.
299  *
300  * Note: Retrieving the backend this way is not currently supported.
301  *
302  * Returns:
303  *  - 0 on success
304  *  - a negative value else
305  */
306 int
307 sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res);
309 /*
310  * sdb_store_get_attr:
311  * Get the value of a stored object's attribute. The caller is responsible for
312  * freeing any dynamically allocated memory possibly stored in the returned
313  * value. If 'res' is NULL, the function will return whether the attribute
314  * exists. If specified, only attributes matching the filter will be
315  * considered.
316  *
317  * Returns:
318  *  - 0 if the attribute exists
319  *  - a negative value else
320  */
321 int
322 sdb_store_get_attr(sdb_store_obj_t *obj, const char *name, sdb_data_t *res,
323                 sdb_store_matcher_t *filter);
325 /*
326  * sdb_store_expr_create:
327  * Creates an arithmetic expression implementing the specified operator on the
328  * specified left and right operand.
329  *
330  * Returns:
331  *  - an expression object on success
332  *  - NULL else
333  */
334 sdb_store_expr_t *
335 sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right);
337 /*
338  * sdb_store_expr_fieldvalue:
339  * Creates an expression which evaluates to the value of the specified
340  * queryable field of a stored object.
341  *
342  * Returns:
343  *  - an expression object on success
344  *  - NULL else
345  */
346 sdb_store_expr_t *
347 sdb_store_expr_fieldvalue(int field);
349 /*
350  * sdb_store_expr_attrvalue:
351  * Creates an expression which evaluates to the value of the specified
352  * attribute of a stored object. Evaluates to a NULL value if the attribute
353  * does not exist.
354  *
355  * Returns:
356  *  - an expression object on success
357  *  - NULL else
358  */
359 sdb_store_expr_t *
360 sdb_store_expr_attrvalue(const char *name);
362 /*
363  * sdb_store_expr_constvalue:
364  * Creates an expression which evaluates to the specified constant value.
365  *
366  * Returns:
367  *  - an expression object on success
368  *  - NULL else
369  */
370 sdb_store_expr_t *
371 sdb_store_expr_constvalue(const sdb_data_t *value);
373 /*
374  * sdb_store_expr_eval:
375  * Evaluate an expression for the specified stored object and stores the
376  * result in 'res'. The result's value will be allocated dynamically if
377  * necessary and, thus, should be free'd by the caller (e.g. using
378  * sdb_data_free_datum). The object may be NULL, in which case the expression
379  * needs to evaluate to a constant value. If specified, only objects matching
380  * the filter will be used during the evaluation.
381  *
382  * Returns:
383  *  - 0 on success
384  *  - a negative value else
385  */
386 int
387 sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
388                 sdb_data_t *res, sdb_store_matcher_t *filter);
390 /*
391  * sdb_store_isnull_matcher:
392  * Creates a matcher matching NULL values.
393  */
394 sdb_store_matcher_t *
395 sdb_store_isnull_matcher(sdb_store_expr_t *expr);
397 /*
398  * sdb_store_isnnull_matcher:
399  * Creates a matcher matching non-NULL values.
400  */
401 sdb_store_matcher_t *
402 sdb_store_isnnull_matcher(sdb_store_expr_t *expr);
404 /*
405  * sdb_store_any_matcher:
406  * Creates a matcher iterating over objects of the specified type. It matches
407  * if *any* of those objects match 'm'.
408  */
409 sdb_store_matcher_t *
410 sdb_store_any_matcher(int type, sdb_store_matcher_t *m);
412 /*
413  * sdb_store_all_matcher:
414  * Creates a matcher iterating over objects of the specified type. It matches
415  * if *all* of those objects match 'm'.
416  */
417 sdb_store_matcher_t *
418 sdb_store_all_matcher(int type, sdb_store_matcher_t *m);
420 /*
421  * sdb_store_lt_matcher, sdb_store_le_matcher, sdb_store_eq_matcher,
422  * sdb_store_ge_matcher, sdb_store_gt_matcher:
423  * Create conditional matchers comparing the values of two expressions. The
424  * matcher matches if the left expression compres less than, less or equal
425  * than, equal to, not equal to, greater or equal than, or greater than the
426  * right expression.
427  */
428 sdb_store_matcher_t *
429 sdb_store_lt_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
430 sdb_store_matcher_t *
431 sdb_store_le_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
432 sdb_store_matcher_t *
433 sdb_store_eq_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
434 sdb_store_matcher_t *
435 sdb_store_ne_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
436 sdb_store_matcher_t *
437 sdb_store_ge_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
438 sdb_store_matcher_t *
439 sdb_store_gt_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
441 /*
442  * sdb_store_in_matcher:
443  * Creates a matcher which matches if the right value evaluates to an array
444  * value and the left value is included in that array. See sdb_data_inarray
445  * for more details.
446  */
447 sdb_store_matcher_t *
448 sdb_store_in_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
450 /*
451  * sdb_store_regex_matcher:
452  * Creates a matcher which matches the string value the left expression
453  * evaluates to against the regular expression the right expression evaluates
454  * to. The right expression may either be a constant value regular expression
455  * or string or a dynamic value evaluating to a string. In the latter case,
456  * the string is compiled to a regex every time the matcher is executed.
457  */
458 sdb_store_matcher_t *
459 sdb_store_regex_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
461 /*
462  * sdb_store_nregex_matcher:
463  * Creates a regex matcher just like sdb_store_regex_matcher except that it
464  * matches in case the regular expression does not match.
465  */
466 sdb_store_matcher_t *
467 sdb_store_nregex_matcher(sdb_store_expr_t *left, sdb_store_expr_t *right);
469 /*
470  * sdb_store_matcher_op_cb:
471  * Callback constructing a matcher operator.
472  */
473 typedef sdb_store_matcher_t *(*sdb_store_matcher_op_cb)
474         (sdb_store_expr_t *, sdb_store_expr_t *);
476 /*
477  * sdb_store_parse_matcher_op:
478  * Parse a matcher operator and return a constructor for the respective
479  * matcher.
480  *
481  * Returns:
482  *  - matcher operator constructor on success
483  *  - NULL else
484  */
485 sdb_store_matcher_op_cb
486 sdb_store_parse_matcher_op(const char *op);
488 /*
489  * sdb_store_parse_object_type:
490  * Parse the type name of a stored object.
491  *
492  * Returns:
493  *  - the object type on success
494  *  - a negative value else
495  */
496 int
497 sdb_store_parse_object_type(const char *name);
499 /*
500  * sdb_store_parse_object_type_plural:
501  * Parse the type name (plural) of a stored object.
502  *
503  * Returns:
504  *  - the object type on success
505  *  - a negative value else
506  */
507 int
508 sdb_store_parse_object_type_plural(const char *name);
510 /*
511  * sdb_store_parse_field_name:
512  * Parse the name of a stored object's queryable field.
513  *
514  * Returns:
515  *  - the field id on success
516  *  - a negative value else
517  */
518 int
519 sdb_store_parse_field_name(const char *name);
521 /*
522  * sdb_store_dis_matcher:
523  * Creates a matcher matching the disjunction (logical OR) of two matchers.
524  */
525 sdb_store_matcher_t *
526 sdb_store_dis_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right);
528 /*
529  * sdb_store_con_matcher:
530  * Creates a matcher matching the conjunction (logical AND) of two matchers.
531  */
532 sdb_store_matcher_t *
533 sdb_store_con_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right);
535 /*
536  * sdb_store_con_matcher::
537  * Creates a matcher matching the inverse (logical NOT) of a matcher.
538  */
539 sdb_store_matcher_t *
540 sdb_store_inv_matcher(sdb_store_matcher_t *m);
542 /*
543  * sdb_store_matcher_matches:
544  * Check whether the specified matcher matches the specified store object. If
545  * specified, the filter will be used to preselect objects for further
546  * evaluation. It is applied to any object that's used during the evaluation
547  * of the matcher. Only those objects matching the filter will be considered.
548  *
549  * Note that the filter is applied to all object types (hosts, service,
550  * metric, attribute). Thus, any object-specific matchers are mostly unsuited
551  * for this purpose and, if used, may result in unexpected behavior.
552  *
553  * Returns:
554  *  - 1 if the object matches
555  *  - 0 else
556  */
557 int
558 sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
559                 sdb_store_matcher_t *filter);
561 /*
562  * sdb_store_lookup_cb:
563  * Lookup callback. It is called for each matching object when looking up data
564  * in the store passing on the lookup filter and the specified user-data. The
565  * lookup aborts early if the callback returns non-zero.
566  */
567 typedef int (*sdb_store_lookup_cb)(sdb_store_obj_t *obj,
568                 sdb_store_matcher_t *filter, void *user_data);
570 /*
571  * sdb_store_scan:
572  * Look up objects of the specified type in the store. The specified callback
573  * function is called for each object in the store matching 'm'. The function
574  * performs a full scan of all objects stored in the database. If specified,
575  * the filter will be used to preselect objects for further evaluation. See
576  * the description of 'sdb_store_matcher_matches' for details.
577  *
578  * Returns:
579  *  - 0 on success
580  *  - a negative value else
581  */
582 int
583 sdb_store_scan(int type, sdb_store_matcher_t *m, sdb_store_matcher_t *filter,
584                 sdb_store_lookup_cb cb, void *user_data);
586 /*
587  * Flags for JSON formatting.
588  */
589 enum {
590         SDB_WANT_ARRAY = 1 << 0,
591 };
593 /*
594  * sdb_store_json_formatter:
595  * Create a JSON formatter for the specified object types writing to the
596  * specified buffer.
597  */
598 sdb_store_json_formatter_t *
599 sdb_store_json_formatter(sdb_strbuf_t *buf, int type, int flags);
601 /*
602  * sdb_store_json_emit:
603  * Serialize a single object to JSON adding it to the string buffer associated
604  * with the formatter object. The serialized object will not include
605  * attributes or any child objects. Instead, call the function again for each
606  * of those objects. All attributes have to be emitted before any other
607  * children types. Use sdb_store_json_emit_full() to emit a full (filtered)
608  * object.
609  *
610  * Note that the output might not be valid JSON before calling
611  * sdb_store_json_finish().
612  *
613  * Returns:
614  *  - 0 on success
615  *  - a negative value else
616  */
617 int
618 sdb_store_json_emit(sdb_store_json_formatter_t *f, sdb_store_obj_t *obj);
620 /*
621  * sdb_store_json_emit_full:
622  * Serialize a single object including it's attributes and all children to
623  * JSON, adding it to the string buffer associated with the formatter object.
624  * The filter, if specified, is applied to each attribute and child object.
625  * Only matching objects will be included in the output.
626  *
627  * Note that the output might not be valid JSON before calling
628  * sdb_store_json_finish().
629  *
630  * Returns:
631  *  - 0 on success
632  *  - a negative value else
633  */
634 int
635 sdb_store_json_emit_full(sdb_store_json_formatter_t *f, sdb_store_obj_t *obj,
636                 sdb_store_matcher_t *filter);
638 /*
639  * sdb_store_json_finish:
640  * Finish the JSON output. This function has to be called once after emiting
641  * all objects.
642  */
643 int
644 sdb_store_json_finish(sdb_store_json_formatter_t *f);
646 #ifdef __cplusplus
647 } /* extern "C" */
648 #endif
650 #endif /* ! SDB_CORE_STORE_H */
652 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */