domain-control: added domain-control plugin (modified decision-proto).
[profile/ivi/murphy.git] / src / plugins / decision-proto / table-common.c
1 #include <errno.h>
2
3 #include <murphy/common/debug.h>
4 #include <murphy/common/mm.h>
5 #include <murphy/common/hashtbl.h>
6 #include <murphy/common/utils.h>
7
8 #include <murphy-db/mqi.h>
9
10 #include "table.h"
11
12
13 /*
14  * client-side tables, common table routines
15  */
16
17 static void purge_pep_table(mrp_pep_table_t *t)
18 {
19     int i;
20
21     if (t != NULL) {
22         mrp_free((char *)t->name);
23
24         for (i = 0; i < t->ncolumn; i++)
25             mrp_free((char *)t->columns[i].name);
26
27         mrp_free(t->columns);
28     }
29 }
30
31
32 static void free_column_definitions(mqi_column_def_t *columns, int ncolumn)
33 {
34     int i;
35
36     if (columns != NULL) {
37         for (i = 0; i < ncolumn; i++)
38             mrp_free((char *)columns[i].name);
39
40         mrp_free(columns);
41     }
42 }
43
44
45 static int copy_column_definitions(mqi_column_def_t *src, int nsrc,
46                                    mqi_column_def_t **dstcol, int *ndst)
47 {
48     mqi_column_def_t *dst;
49     int               n, i;
50
51     if (nsrc > 0) {
52         if (src[nsrc - 1].name == NULL)
53             n = nsrc - 1;
54         else
55             n = nsrc;
56
57         dst = mrp_allocz_array(mqi_column_def_t, n + 1);
58
59         if (dst == NULL)
60             return FALSE;
61
62         for (i = 0; i < n; i++) {
63             dst[i].type   = src[i].type;
64             dst[i].length = src[i].length;
65             dst[i].name   = mrp_strdup(src[i].name);
66
67             if (dst[i].name == NULL)
68                 goto fail;
69         }
70
71         *dstcol = dst;
72         *ndst   = n;
73
74         return TRUE;
75     }
76     else {
77         *dstcol = NULL;
78         *ndst   = 0;
79
80         return FALSE;
81     }
82
83  fail:
84     free_column_definitions(dst, n);
85     return FALSE;
86 }
87
88
89 static void free_column_descriptors(mqi_column_desc_t *coldesc)
90 {
91     mrp_free(coldesc);
92 }
93
94
95 static int setup_column_descriptors(mqi_column_def_t *columns, int ncolumn,
96                                     mqi_column_desc_t **coldesc)
97 {
98 #define SETUP_TYPE(type, member)                                        \
99                 case mqi_##type:                                        \
100                     desc->cindex = i;                                   \
101                     desc->offset = (void *)&col->member - (void *)NULL; \
102                     break;
103
104     mqi_column_def_t  *def;
105     mqi_column_desc_t *desc;
106     mrp_pep_value_t   *col;
107     int                i;
108
109     *coldesc = mrp_allocz_array(mqi_column_desc_t, ncolumn + 1);
110
111     if (coldesc != NULL) {
112         def  = columns;
113         desc = *coldesc;
114         col  = NULL;
115
116         for (i = 0; i < ncolumn; i++) {
117             switch (def->type) {
118                 SETUP_TYPE(integer , s32);
119                 SETUP_TYPE(unsignd , u32);
120                 SETUP_TYPE(floating, dbl);
121                 SETUP_TYPE(string  , str);
122
123             default:
124             case mqi_blob:
125                 goto fail;
126             }
127
128             def++;
129             desc++;
130             col++;
131         }
132
133         desc->cindex = -1;
134         desc->offset = 1;
135
136         return TRUE;
137     }
138
139  fail:
140     free_column_descriptors(*coldesc);
141     *coldesc = NULL;
142
143     return FALSE;
144
145 #undef SETUP_TYPE
146 }
147
148
149 static int check_columns(mqi_column_def_t *p, int np,
150                          mqi_column_def_t *q, int nq)
151 {
152     int i;
153
154     if  (np == nq) {
155         for (i = 0; i < np; i++, p++, q++) {
156             if (p->type != q->type || p->length != q->length)
157                 return FALSE;
158             if (strcmp(p->name, q->name))
159                 return FALSE;
160         }
161
162         return TRUE;
163     }
164     else
165         return FALSE;
166 }
167
168
169 int copy_pep_table(mrp_pep_table_t *src, mrp_pep_table_t *dst)
170 {
171     int i, ncolumn;
172
173     dst->name = mrp_strdup(src->name);
174     if (dst->name == NULL)
175         return FALSE;
176
177     if (src->columns[src->ncolumn - 1].name != NULL)
178         ncolumn = src->ncolumn;
179     else
180         ncolumn = src->ncolumn - 1;
181
182     dst->columns = mrp_allocz_array(typeof(*dst->columns), ncolumn + 1);
183     if (dst->columns == NULL) {
184         mrp_free((char *)dst->name);
185
186         return FALSE;
187     }
188
189     dst->ncolumn = ncolumn;
190     dst->idx_col = -1;
191
192     for (i = 0; i < ncolumn; i++) {
193         dst->columns[i].type   = src->columns[i].type;
194         dst->columns[i].length = src->columns[i].length;
195         dst->columns[i].name   = mrp_strdup(src->columns[i].name);
196
197         if (dst->columns[i].name == NULL)
198             goto fail;
199
200         if (src->columns[i].flags != 0) {
201             if (dst->idx_col == -1)
202                 dst->idx_col = i;
203             else
204                 goto fail;
205         }
206
207         dst->columns[i].flags = 0;
208     }
209
210     return TRUE;
211
212  fail:
213     purge_pep_table(dst);
214
215     return FALSE;
216 }
217
218
219 int copy_pep_tables(mrp_pep_table_t *src, mrp_pep_table_t *dst, int n)
220 {
221     int i;
222
223     for (i = 0; i < n; i++) {
224         if (!copy_pep_table(src + i, dst + i)) {
225             for (i--; i >= 0; i--)
226                 purge_pep_table(dst + i);
227
228             return FALSE;
229         }
230     }
231
232     return TRUE;
233 }
234
235
236 void free_pep_table(mrp_pep_table_t *t)
237 {
238     purge_pep_table(t);
239     mrp_free(t);
240 }
241
242
243 void free_pep_tables(mrp_pep_table_t *tables, int n)
244 {
245     int i;
246
247     for (i = 0; i < n; i++)
248         purge_pep_table(tables + i);
249
250     mrp_free(tables);
251 }