Code

parser: Let the TIMESERIES command accept optional data-source names.
[sysdb.git] / src / parser / ast.c
1 /*
2  * SysDB - src/parser/ast.c
3  * Copyright (C) 2013-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 #include "core/store.h"
30 #include "parser/ast.h"
32 #include <ctype.h>
33 #include <stdlib.h>
34 #include <string.h>
36 /*
37  * data types
38  */
40 static void
41 op_destroy(sdb_object_t *obj)
42 {
43         sdb_ast_op_t *op = SDB_AST_OP(obj);
44         sdb_object_deref(SDB_OBJ(op->left));
45         sdb_object_deref(SDB_OBJ(op->right));
46         op->left = op->right = NULL;
47 } /* op_destroy */
49 static void
50 iter_destroy(sdb_object_t *obj)
51 {
52         sdb_ast_iter_t *iter = SDB_AST_ITER(obj);
53         sdb_object_deref(SDB_OBJ(iter->iter));
54         sdb_object_deref(SDB_OBJ(iter->expr));
55         iter->iter = iter->expr = NULL;
56 } /* iter_destroy */
58 static void
59 typed_destroy(sdb_object_t *obj)
60 {
61         sdb_ast_typed_t *typed = SDB_AST_TYPED(obj);
62         sdb_object_deref(SDB_OBJ(typed->expr));
63         typed->expr = NULL;
64 } /* typed_destroy */
66 static void
67 const_destroy(sdb_object_t *obj)
68 {
69         sdb_ast_const_t *c = SDB_AST_CONST(obj);
70         sdb_data_free_datum(&c->value);
71 } /* const_destroy */
73 static void
74 value_destroy(sdb_object_t *obj)
75 {
76         sdb_ast_value_t *value = SDB_AST_VALUE(obj);
77         if (value->name)
78                 free(value->name);
79         value->name = NULL;
80 } /* value_destroy */
82 static void
83 fetch_destroy(sdb_object_t *obj)
84 {
85         sdb_ast_fetch_t *fetch = SDB_AST_FETCH(obj);
86         if (fetch->hostname)
87                 free(fetch->hostname);
88         if (fetch->parent)
89                 free(fetch->parent);
90         if (fetch->name)
91                 free(fetch->name);
92         fetch->hostname = fetch->name = NULL;
94         sdb_object_deref(SDB_OBJ(fetch->filter));
95         fetch->filter = NULL;
96 } /* fetch_destroy */
98 static void
99 list_destroy(sdb_object_t *obj)
101         sdb_ast_list_t *list = SDB_AST_LIST(obj);
102         sdb_object_deref(SDB_OBJ(list->filter));
103         list->filter = NULL;
104 } /* list_destroy */
106 static void
107 lookup_destroy(sdb_object_t *obj)
109         sdb_ast_lookup_t *lookup = SDB_AST_LOOKUP(obj);
110         sdb_object_deref(SDB_OBJ(lookup->matcher));
111         sdb_object_deref(SDB_OBJ(lookup->filter));
112         lookup->matcher = lookup->filter = NULL;
113 } /* lookup_destroy */
115 static void
116 store_destroy(sdb_object_t *obj)
118         sdb_ast_store_t *store = SDB_AST_STORE(obj);
119         if (store->hostname)
120                 free(store->hostname);
121         if (store->parent)
122                 free(store->parent);
123         if (store->name)
124                 free(store->name);
125         store->hostname = store->parent = store->name = NULL;
127         if (store->store_type)
128                 free(store->store_type);
129         if (store->store_id)
130                 free(store->store_id);
131         store->store_type = store->store_id = NULL;
133         sdb_data_free_datum(&store->value);
134 } /* store_destroy */
136 static void
137 timeseries_destroy(sdb_object_t *obj)
139         sdb_ast_timeseries_t *timeseries = SDB_AST_TIMESERIES(obj);
140         if (timeseries->hostname)
141                 free(timeseries->hostname);
142         if (timeseries->metric)
143                 free(timeseries->metric);
144         if (timeseries->data_names) {
145                 size_t i;
146                 for (i = 0; i < timeseries->data_names_len; i++)
147                         free(timeseries->data_names[i]);
148                 free(timeseries->data_names);
149                 timeseries->data_names = NULL;
150         }
151         timeseries->hostname = timeseries->metric = NULL;
152 } /* timeseries_destroy */
154 static sdb_type_t op_type = {
155         /* size */ sizeof(sdb_ast_op_t),
156         /* init */ NULL,
157         /* destroy */ op_destroy,
158 };
160 static sdb_type_t iter_type = {
161         /* size */ sizeof(sdb_ast_iter_t),
162         /* init */ NULL,
163         /* destroy */ iter_destroy,
164 };
166 static sdb_type_t typed_type = {
167         /* size */ sizeof(sdb_ast_typed_t),
168         /* init */ NULL,
169         /* destroy */ typed_destroy,
170 };
172 static sdb_type_t const_type = {
173         /* size */ sizeof(sdb_ast_const_t),
174         /* init */ NULL,
175         /* destroy */ const_destroy,
176 };
178 static sdb_type_t value_type = {
179         /* size */ sizeof(sdb_ast_value_t),
180         /* init */ NULL,
181         /* destroy */ value_destroy,
182 };
184 static sdb_type_t fetch_type = {
185         /* size */ sizeof(sdb_ast_fetch_t),
186         /* init */ NULL,
187         /* destroy */ fetch_destroy,
188 };
190 static sdb_type_t list_type = {
191         /* size */ sizeof(sdb_ast_list_t),
192         /* init */ NULL,
193         /* destroy */ list_destroy,
194 };
196 static sdb_type_t lookup_type = {
197         /* size */ sizeof(sdb_ast_lookup_t),
198         /* init */ NULL,
199         /* destroy */ lookup_destroy,
200 };
202 static sdb_type_t st_type = {
203         /* size */ sizeof(sdb_ast_store_t),
204         /* init */ NULL,
205         /* destroy */ store_destroy,
206 };
208 static sdb_type_t ts_type = {
209         /* size */ sizeof(sdb_ast_timeseries_t),
210         /* init */ NULL,
211         /* destroy */ timeseries_destroy,
212 };
214 /*
215  * public API
216  */
218 sdb_ast_node_t *
219 sdb_ast_op_create(int kind, sdb_ast_node_t *left, sdb_ast_node_t *right)
221         sdb_ast_op_t *op;
222         op = SDB_AST_OP(sdb_object_create(SDB_AST_OP_TO_STRING(kind), op_type));
223         if (! op)
224                 return NULL;
226         op->super.type = SDB_AST_TYPE_OPERATOR;
228         op->kind = kind;
229         op->left = left;
230         op->right = right;
231         return SDB_AST_NODE(op);
232 } /* sdb_ast_op_create */
234 sdb_ast_node_t *
235 sdb_ast_iter_create(int kind, sdb_ast_node_t *iter, sdb_ast_node_t *expr)
237         sdb_ast_iter_t *i;
238         i = SDB_AST_ITER(sdb_object_create(SDB_AST_OP_TO_STRING(kind), iter_type));
239         if (! i)
240                 return NULL;
242         i->super.type = SDB_AST_TYPE_ITERATOR;
244         i->kind = kind;
245         i->iter = iter;
246         i->expr = expr;
247         return SDB_AST_NODE(i);
248 } /* sdb_ast_iter_create */
250 sdb_ast_node_t *
251 sdb_ast_typed_create(int type, sdb_ast_node_t *expr)
253         char name[32];
254         sdb_ast_typed_t *typed;
255         size_t i;
257         strncpy(name, SDB_STORE_TYPE_TO_NAME(type), sizeof(name));
258         for (i = 0; i < strlen(name); ++i)
259                 name[i] = (char)toupper((int)name[i]);
260         typed = SDB_AST_TYPED(sdb_object_create(name, typed_type));
261         if (! typed)
262                 return NULL;
264         typed->super.type = SDB_AST_TYPE_TYPED;
266         typed->type = type;
267         typed->expr = expr;
268         return SDB_AST_NODE(typed);
269 } /* sdb_ast_typed_create */
271 sdb_ast_node_t *
272 sdb_ast_const_create(sdb_data_t value)
274         sdb_ast_const_t *c;
275         c = SDB_AST_CONST(sdb_object_create("CONST", const_type));
276         if (! c)
277                 return NULL;
279         c->super.type = SDB_AST_TYPE_CONST;
281         c->value = value;
282         return SDB_AST_NODE(c);
283 } /* sdb_ast_const_create */
285 sdb_ast_node_t *
286 sdb_ast_value_create(int type, char *name)
288         sdb_ast_value_t *value;
289         value = SDB_AST_VALUE(sdb_object_create("VALUE", value_type));
290         if (! value)
291                 return NULL;
293         value->super.type = SDB_AST_TYPE_VALUE;
295         value->type = type;
296         value->name = name;
297         return SDB_AST_NODE(value);
298 } /* sdb_ast_value_create */
300 sdb_ast_node_t *
301 sdb_ast_fetch_create(int obj_type, char *hostname,
302                 int parent_type, char *parent, char *name,
303                 bool full, sdb_ast_node_t *filter)
305         sdb_ast_fetch_t *fetch;
306         fetch = SDB_AST_FETCH(sdb_object_create("FETCH", fetch_type));
307         if (! fetch)
308                 return NULL;
310         fetch->super.type = SDB_AST_TYPE_FETCH;
312         fetch->obj_type = obj_type;
313         fetch->hostname = hostname;
314         fetch->parent_type = parent_type;
315         fetch->parent = parent;
316         fetch->name = name;
317         fetch->full = full;
318         fetch->filter = filter;
319         return SDB_AST_NODE(fetch);
320 } /* sdb_ast_fetch_create */
322 sdb_ast_node_t *
323 sdb_ast_list_create(int obj_type, sdb_ast_node_t *filter)
325         sdb_ast_list_t *list;
326         list = SDB_AST_LIST(sdb_object_create("LIST", list_type));
327         if (! list)
328                 return NULL;
330         list->super.type = SDB_AST_TYPE_LIST;
332         list->obj_type = obj_type;
333         list->filter = filter;
334         return SDB_AST_NODE(list);
335 } /* sdb_ast_list_create */
337 sdb_ast_node_t *
338 sdb_ast_lookup_create(int obj_type, sdb_ast_node_t *matcher,
339                 sdb_ast_node_t *filter)
341         sdb_ast_lookup_t *lookup;
342         lookup = SDB_AST_LOOKUP(sdb_object_create("LOOKUP", lookup_type));
343         if (! lookup)
344                 return NULL;
346         lookup->super.type = SDB_AST_TYPE_LOOKUP;
348         lookup->obj_type = obj_type;
349         lookup->matcher = matcher;
350         lookup->filter = filter;
351         return SDB_AST_NODE(lookup);
352 } /* sdb_ast_lookup_create */
354 sdb_ast_node_t *
355 sdb_ast_store_create(int obj_type, char *hostname,
356                 int parent_type, char *parent, char *name, sdb_time_t last_update,
357                 char *store_type, char *store_id, sdb_time_t store_last_update,
358                 sdb_data_t value)
360         sdb_ast_store_t *store;
361         store = SDB_AST_STORE(sdb_object_create("STORE", st_type));
362         if (! store)
363                 return NULL;
365         store->super.type = SDB_AST_TYPE_STORE;
367         store->obj_type = obj_type;
368         store->hostname = hostname;
369         store->parent_type = parent_type;
370         store->parent = parent;
371         store->name = name;
372         store->last_update = last_update;
373         store->store_type = store_type;
374         store->store_id = store_id;
375         store->store_last_update = store_last_update;
376         store->value = value;
377         return SDB_AST_NODE(store);
378 } /* sdb_ast_store_create */
380 sdb_ast_node_t *
381 sdb_ast_timeseries_create(char *hostname, char *metric,
382                 char **data_names, size_t data_names_len,
383                 sdb_time_t start, sdb_time_t end)
385         sdb_ast_timeseries_t *timeseries;
386         timeseries = SDB_AST_TIMESERIES(sdb_object_create("TIMESERIES", ts_type));
387         if (! timeseries)
388                 return NULL;
390         timeseries->super.type = SDB_AST_TYPE_TIMESERIES;
392         timeseries->hostname = hostname;
393         timeseries->metric = metric;
394         timeseries->data_names = data_names;
395         timeseries->data_names_len = data_names_len;
396         timeseries->start = start;
397         timeseries->end = end;
398         return SDB_AST_NODE(timeseries);
399 } /* sdb_ast_timeseries_create */
401 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */