96c05ffa612ab22fb4e28658912b98b48c65bc1a
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)
100 {
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)
108 {
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)
117 {
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)
138 {
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 timeseries->hostname = timeseries->metric = NULL;
145 } /* timeseries_destroy */
147 static sdb_type_t op_type = {
148 /* size */ sizeof(sdb_ast_op_t),
149 /* init */ NULL,
150 /* destroy */ op_destroy,
151 };
153 static sdb_type_t iter_type = {
154 /* size */ sizeof(sdb_ast_iter_t),
155 /* init */ NULL,
156 /* destroy */ iter_destroy,
157 };
159 static sdb_type_t typed_type = {
160 /* size */ sizeof(sdb_ast_typed_t),
161 /* init */ NULL,
162 /* destroy */ typed_destroy,
163 };
165 static sdb_type_t const_type = {
166 /* size */ sizeof(sdb_ast_const_t),
167 /* init */ NULL,
168 /* destroy */ const_destroy,
169 };
171 static sdb_type_t value_type = {
172 /* size */ sizeof(sdb_ast_value_t),
173 /* init */ NULL,
174 /* destroy */ value_destroy,
175 };
177 static sdb_type_t fetch_type = {
178 /* size */ sizeof(sdb_ast_fetch_t),
179 /* init */ NULL,
180 /* destroy */ fetch_destroy,
181 };
183 static sdb_type_t list_type = {
184 /* size */ sizeof(sdb_ast_list_t),
185 /* init */ NULL,
186 /* destroy */ list_destroy,
187 };
189 static sdb_type_t lookup_type = {
190 /* size */ sizeof(sdb_ast_lookup_t),
191 /* init */ NULL,
192 /* destroy */ lookup_destroy,
193 };
195 static sdb_type_t st_type = {
196 /* size */ sizeof(sdb_ast_store_t),
197 /* init */ NULL,
198 /* destroy */ store_destroy,
199 };
201 static sdb_type_t ts_type = {
202 /* size */ sizeof(sdb_ast_timeseries_t),
203 /* init */ NULL,
204 /* destroy */ timeseries_destroy,
205 };
207 /*
208 * public API
209 */
211 sdb_ast_node_t *
212 sdb_ast_op_create(int kind, sdb_ast_node_t *left, sdb_ast_node_t *right)
213 {
214 sdb_ast_op_t *op;
215 op = SDB_AST_OP(sdb_object_create(SDB_AST_OP_TO_STRING(kind), op_type));
216 if (! op)
217 return NULL;
219 op->super.type = SDB_AST_TYPE_OPERATOR;
221 op->kind = kind;
222 op->left = left;
223 op->right = right;
224 return SDB_AST_NODE(op);
225 } /* sdb_ast_op_create */
227 sdb_ast_node_t *
228 sdb_ast_iter_create(int kind, sdb_ast_node_t *iter, sdb_ast_node_t *expr)
229 {
230 sdb_ast_iter_t *i;
231 i = SDB_AST_ITER(sdb_object_create(SDB_AST_OP_TO_STRING(kind), iter_type));
232 if (! i)
233 return NULL;
235 i->super.type = SDB_AST_TYPE_ITERATOR;
237 i->kind = kind;
238 i->iter = iter;
239 i->expr = expr;
240 return SDB_AST_NODE(i);
241 } /* sdb_ast_iter_create */
243 sdb_ast_node_t *
244 sdb_ast_typed_create(int type, sdb_ast_node_t *expr)
245 {
246 char name[32];
247 sdb_ast_typed_t *typed;
248 size_t i;
250 strncpy(name, SDB_STORE_TYPE_TO_NAME(type), sizeof(name));
251 for (i = 0; i < strlen(name); ++i)
252 name[i] = (char)toupper((int)name[i]);
253 typed = SDB_AST_TYPED(sdb_object_create(name, typed_type));
254 if (! typed)
255 return NULL;
257 typed->super.type = SDB_AST_TYPE_TYPED;
259 typed->type = type;
260 typed->expr = expr;
261 return SDB_AST_NODE(typed);
262 } /* sdb_ast_typed_create */
264 sdb_ast_node_t *
265 sdb_ast_const_create(sdb_data_t value)
266 {
267 sdb_ast_const_t *c;
268 c = SDB_AST_CONST(sdb_object_create("CONST", const_type));
269 if (! c)
270 return NULL;
272 c->super.type = SDB_AST_TYPE_CONST;
274 c->value = value;
275 return SDB_AST_NODE(c);
276 } /* sdb_ast_const_create */
278 sdb_ast_node_t *
279 sdb_ast_value_create(int type, char *name)
280 {
281 sdb_ast_value_t *value;
282 value = SDB_AST_VALUE(sdb_object_create("VALUE", value_type));
283 if (! value)
284 return NULL;
286 value->super.type = SDB_AST_TYPE_VALUE;
288 value->type = type;
289 value->name = name;
290 return SDB_AST_NODE(value);
291 } /* sdb_ast_value_create */
293 sdb_ast_node_t *
294 sdb_ast_fetch_create(int obj_type, char *hostname,
295 int parent_type, char *parent, char *name,
296 bool full, sdb_ast_node_t *filter)
297 {
298 sdb_ast_fetch_t *fetch;
299 fetch = SDB_AST_FETCH(sdb_object_create("FETCH", fetch_type));
300 if (! fetch)
301 return NULL;
303 fetch->super.type = SDB_AST_TYPE_FETCH;
305 fetch->obj_type = obj_type;
306 fetch->hostname = hostname;
307 fetch->parent_type = parent_type;
308 fetch->parent = parent;
309 fetch->name = name;
310 fetch->full = full;
311 fetch->filter = filter;
312 return SDB_AST_NODE(fetch);
313 } /* sdb_ast_fetch_create */
315 sdb_ast_node_t *
316 sdb_ast_list_create(int obj_type, sdb_ast_node_t *filter)
317 {
318 sdb_ast_list_t *list;
319 list = SDB_AST_LIST(sdb_object_create("LIST", list_type));
320 if (! list)
321 return NULL;
323 list->super.type = SDB_AST_TYPE_LIST;
325 list->obj_type = obj_type;
326 list->filter = filter;
327 return SDB_AST_NODE(list);
328 } /* sdb_ast_list_create */
330 sdb_ast_node_t *
331 sdb_ast_lookup_create(int obj_type, sdb_ast_node_t *matcher,
332 sdb_ast_node_t *filter)
333 {
334 sdb_ast_lookup_t *lookup;
335 lookup = SDB_AST_LOOKUP(sdb_object_create("LOOKUP", lookup_type));
336 if (! lookup)
337 return NULL;
339 lookup->super.type = SDB_AST_TYPE_LOOKUP;
341 lookup->obj_type = obj_type;
342 lookup->matcher = matcher;
343 lookup->filter = filter;
344 return SDB_AST_NODE(lookup);
345 } /* sdb_ast_lookup_create */
347 sdb_ast_node_t *
348 sdb_ast_store_create(int obj_type, char *hostname,
349 int parent_type, char *parent, char *name, sdb_time_t last_update,
350 char *store_type, char *store_id, sdb_time_t store_last_update,
351 sdb_data_t value)
352 {
353 sdb_ast_store_t *store;
354 store = SDB_AST_STORE(sdb_object_create("STORE", st_type));
355 if (! store)
356 return NULL;
358 store->super.type = SDB_AST_TYPE_STORE;
360 store->obj_type = obj_type;
361 store->hostname = hostname;
362 store->parent_type = parent_type;
363 store->parent = parent;
364 store->name = name;
365 store->last_update = last_update;
366 store->store_type = store_type;
367 store->store_id = store_id;
368 store->store_last_update = store_last_update;
369 store->value = value;
370 return SDB_AST_NODE(store);
371 } /* sdb_ast_store_create */
373 sdb_ast_node_t *
374 sdb_ast_timeseries_create(char *hostname, char *metric,
375 sdb_time_t start, sdb_time_t end)
376 {
377 sdb_ast_timeseries_t *timeseries;
378 timeseries = SDB_AST_TIMESERIES(sdb_object_create("TIMESERIES", ts_type));
379 if (! timeseries)
380 return NULL;
382 timeseries->super.type = SDB_AST_TYPE_TIMESERIES;
384 timeseries->hostname = hostname;
385 timeseries->metric = metric;
386 timeseries->start = start;
387 timeseries->end = end;
388 return SDB_AST_NODE(timeseries);
389 } /* sdb_ast_timeseries_create */
391 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */