1 /*
2  * Copyright (c) 2014 Jerry Lundström <lundstrom.jerry@gmail.com>
3  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
4  * Copyright (c) 2014 OpenDNSSEC AB (svb)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "db_clause.h"
31 #include "db_error.h"
32 
33 
34 #include <stdlib.h>
35 #include <string.h>
36 
37 /* DB CLAUSE */
38 
39 
40 
41 /* TODO: add more check for type and what value/list is set, maybe add type to new */
42 
db_clause_new(void)43 db_clause_t* db_clause_new(void) {
44     db_clause_t* clause =
45         (db_clause_t*)calloc(1, sizeof(db_clause_t));
46 
47     if (clause) {
48         clause->type = DB_CLAUSE_UNKNOWN;
49         clause->clause_operator = DB_CLAUSE_OPERATOR_AND;
50         db_value_reset(&(clause->value));
51     }
52 
53     return clause;
54 }
55 
db_clause_free(db_clause_t * clause)56 void db_clause_free(db_clause_t* clause) {
57     if (clause) {
58         if (clause->field) {
59             free(clause->field);
60         }
61         db_value_reset(&(clause->value));
62         if (clause->clause_list) {
63             db_clause_list_free(clause->clause_list);
64         }
65         free(clause);
66     }
67 }
68 
db_clause_field(const db_clause_t * clause)69 const char* db_clause_field(const db_clause_t* clause) {
70     if (!clause) {
71         return NULL;
72     }
73 
74     return clause->field;
75 }
76 
db_clause_type(const db_clause_t * clause)77 db_clause_type_t db_clause_type(const db_clause_t* clause) {
78     if (!clause) {
79         return DB_CLAUSE_UNKNOWN;
80     }
81 
82     return clause->type;
83 }
84 
db_clause_value(const db_clause_t * clause)85 const db_value_t* db_clause_value(const db_clause_t* clause) {
86     if (!clause) {
87         return NULL;
88     }
89 
90     return &(clause->value);
91 }
92 
db_clause_operator(const db_clause_t * clause)93 db_clause_operator_t db_clause_operator(const db_clause_t* clause) {
94     if (!clause) {
95         return DB_CLAUSE_OPERATOR_UNKNOWN;
96     }
97 
98     return clause->clause_operator;
99 }
100 
db_clause_list(const db_clause_t * clause)101 const db_clause_list_t* db_clause_list(const db_clause_t* clause) {
102     if (!clause) {
103         return NULL;
104     }
105 
106     return clause->clause_list;
107 }
108 
db_clause_set_field(db_clause_t * clause,const char * field)109 int db_clause_set_field(db_clause_t* clause, const char* field) {
110     char* new_field;
111 
112     if (!clause) {
113         return DB_ERROR_UNKNOWN;
114     }
115     if (clause->clause_list) {
116         return DB_ERROR_UNKNOWN;
117     }
118 
119     if (!(new_field = strdup(field))) {
120         return DB_ERROR_UNKNOWN;
121     }
122 
123     if (clause->field) {
124         free(clause->field);
125     }
126     clause->field = new_field;
127     return DB_OK;
128 }
129 
db_clause_set_type(db_clause_t * clause,db_clause_type_t type)130 int db_clause_set_type(db_clause_t* clause, db_clause_type_t type) {
131     if (!clause) {
132         return DB_ERROR_UNKNOWN;
133     }
134     if (type == DB_CLAUSE_UNKNOWN) {
135         return DB_ERROR_UNKNOWN;
136     }
137 
138     clause->type = type;
139     return DB_OK;
140 }
141 
db_clause_set_operator(db_clause_t * clause,db_clause_operator_t clause_operator)142 int db_clause_set_operator(db_clause_t* clause, db_clause_operator_t clause_operator) {
143     if (!clause) {
144         return DB_ERROR_UNKNOWN;
145     }
146     if (clause_operator == DB_CLAUSE_OPERATOR_UNKNOWN) {
147         return DB_ERROR_UNKNOWN;
148     }
149 
150     clause->clause_operator = clause_operator;
151     return DB_OK;
152 }
153 
db_clause_not_empty(const db_clause_t * clause)154 int db_clause_not_empty(const db_clause_t* clause) {
155     if (!clause) {
156         return DB_ERROR_UNKNOWN;
157     }
158     if (clause->type == DB_CLAUSE_UNKNOWN) {
159         return DB_ERROR_UNKNOWN;
160     }
161 
162     if (clause->type == DB_CLAUSE_NESTED) {
163         if (!clause->clause_list) {
164             return DB_ERROR_UNKNOWN;
165         }
166     }
167     else {
168         if (!clause->field) {
169             return DB_ERROR_UNKNOWN;
170         }
171         if (db_value_type(&(clause->value)) == DB_TYPE_EMPTY) {
172             return DB_ERROR_UNKNOWN;
173         }
174     }
175 
176     return DB_OK;
177 }
178 
db_clause_next(const db_clause_t * clause)179 const db_clause_t* db_clause_next(const db_clause_t* clause) {
180     if (!clause) {
181         return NULL;
182     }
183 
184     return clause->next;
185 }
186 
db_clause_get_value(db_clause_t * clause)187 db_value_t* db_clause_get_value(db_clause_t* clause) {
188     if (!clause) {
189         return NULL;
190     }
191     if (clause->clause_list) {
192         return NULL;
193     }
194 
195     return &(clause->value);
196 }
197 
198 /* DB CLAUSE LIST */
199 
200 
201 
db_clause_list_new(void)202 db_clause_list_t* db_clause_list_new(void) {
203     db_clause_list_t* clause_list =
204         (db_clause_list_t*)calloc(1, sizeof(db_clause_list_t));
205 
206     return clause_list;
207 }
208 
db_clause_list_free(db_clause_list_t * clause_list)209 void db_clause_list_free(db_clause_list_t* clause_list) {
210     if (clause_list) {
211         if (clause_list->begin) {
212             db_clause_t* this = clause_list->begin;
213             db_clause_t* next = NULL;
214 
215             while (this) {
216                 next = this->next;
217                 this->clause_list = NULL;
218                 db_clause_free(this);
219                 this = next;
220             }
221         }
222         free(clause_list);
223     }
224 }
225 
db_clause_list_add(db_clause_list_t * clause_list,db_clause_t * clause)226 int db_clause_list_add(db_clause_list_t* clause_list, db_clause_t* clause) {
227     if (!clause_list) {
228         return DB_ERROR_UNKNOWN;
229     }
230     if (!clause) {
231         return DB_ERROR_UNKNOWN;
232     }
233     if (db_clause_not_empty(clause)) {
234         return DB_ERROR_UNKNOWN;
235     }
236     if (clause->next) {
237         return DB_ERROR_UNKNOWN;
238     }
239 
240     if (clause_list->begin) {
241         if (!clause_list->end) {
242             return DB_ERROR_UNKNOWN;
243         }
244         clause_list->end->next = clause;
245         clause_list->end = clause;
246     }
247     else {
248         clause_list->begin = clause;
249         clause_list->end = clause;
250     }
251 
252     return DB_OK;
253 }
254 
db_clause_list_begin(const db_clause_list_t * clause_list)255 const db_clause_t* db_clause_list_begin(const db_clause_list_t* clause_list) {
256     if (!clause_list) {
257         return NULL;
258     }
259 
260     return clause_list->begin;
261 }
262