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_object.h"
31 #include "db_error.h"
32
33
34 #include <stdlib.h>
35
36 /* DB OBJECT FIELD */
37
38
39
db_object_field_new(void)40 db_object_field_t* db_object_field_new(void) {
41 db_object_field_t* object_field =
42 (db_object_field_t*)calloc(1, sizeof(db_object_field_t));
43
44 if (object_field) {
45 object_field->type = DB_TYPE_EMPTY;
46 }
47
48 return object_field;
49 }
50
51 /* TODO: unit test */
db_object_field_new_copy(const db_object_field_t * from_object_field)52 db_object_field_t* db_object_field_new_copy(const db_object_field_t* from_object_field) {
53 db_object_field_t* object_field;
54
55 if (!from_object_field) {
56 return NULL;
57 }
58
59 if (!(object_field = db_object_field_new())
60 || db_object_field_copy(object_field, from_object_field))
61 {
62 db_object_field_free(object_field);
63 return NULL;
64 }
65
66 return object_field;
67 }
68
db_object_field_free(db_object_field_t * object_field)69 void db_object_field_free(db_object_field_t* object_field) {
70 if (object_field) {
71 free(object_field);
72 }
73 }
74
75 /* TODO: unit test */
db_object_field_copy(db_object_field_t * object_field,const db_object_field_t * from_object_field)76 int db_object_field_copy(db_object_field_t* object_field, const db_object_field_t* from_object_field) {
77 if (!object_field) {
78 return DB_ERROR_UNKNOWN;
79 }
80 if (!from_object_field) {
81 return DB_ERROR_UNKNOWN;
82 }
83 if (object_field->next) {
84 return DB_ERROR_UNKNOWN;
85 }
86
87 object_field->name = from_object_field->name;
88 object_field->type = from_object_field->type;
89 object_field->enum_set = from_object_field->enum_set;
90
91 return DB_OK;
92 }
93
db_object_field_name(const db_object_field_t * object_field)94 const char* db_object_field_name(const db_object_field_t* object_field) {
95 if (!object_field) {
96 return NULL;
97 }
98
99 return object_field->name;
100 }
101
db_object_field_type(const db_object_field_t * object_field)102 db_type_t db_object_field_type(const db_object_field_t* object_field) {
103 if (!object_field) {
104 return DB_TYPE_EMPTY;
105 }
106
107 return object_field->type;
108 }
109
db_object_field_set_name(db_object_field_t * object_field,const char * name)110 int db_object_field_set_name(db_object_field_t* object_field, const char* name) {
111 if (!object_field) {
112 return DB_ERROR_UNKNOWN;
113 }
114 if (!name) {
115 return DB_ERROR_UNKNOWN;
116 }
117
118 object_field->name = name;
119 return DB_OK;
120 }
121
db_object_field_set_type(db_object_field_t * object_field,db_type_t type)122 int db_object_field_set_type(db_object_field_t* object_field, db_type_t type) {
123 if (!object_field) {
124 return DB_ERROR_UNKNOWN;
125 }
126 if (type == DB_TYPE_EMPTY) {
127 return DB_ERROR_UNKNOWN;
128 }
129
130 object_field->type = type;
131 return DB_OK;
132 }
133
db_object_field_set_enum_set(db_object_field_t * object_field,const db_enum_t * enum_set)134 int db_object_field_set_enum_set(db_object_field_t* object_field, const db_enum_t* enum_set) {
135 if (!object_field) {
136 return DB_ERROR_UNKNOWN;
137 }
138 if (object_field->type != DB_TYPE_ENUM) {
139 return DB_ERROR_UNKNOWN;
140 }
141
142 object_field->enum_set = enum_set;
143 return DB_OK;
144 }
145
db_object_field_not_empty(const db_object_field_t * object_field)146 int db_object_field_not_empty(const db_object_field_t* object_field) {
147 if (!object_field) {
148 return DB_ERROR_UNKNOWN;
149 }
150 if (!object_field->name) {
151 return DB_ERROR_UNKNOWN;
152 }
153 if (object_field->type == DB_TYPE_EMPTY) {
154 return DB_ERROR_UNKNOWN;
155 }
156 if (object_field->type == DB_TYPE_ENUM && !object_field->enum_set) {
157 return DB_ERROR_UNKNOWN;
158 }
159 return DB_OK;
160 }
161
db_object_field_next(const db_object_field_t * object_field)162 const db_object_field_t* db_object_field_next(const db_object_field_t* object_field) {
163 if (!object_field) {
164 return NULL;
165 }
166
167 return object_field->next;
168 }
169
170 /* DB OBJECT FIELD LIST */
171
172
173
db_object_field_list_new(void)174 db_object_field_list_t* db_object_field_list_new(void) {
175 db_object_field_list_t* object_field_list =
176 (db_object_field_list_t*)calloc(1, sizeof(db_object_field_list_t));
177
178 return object_field_list;
179 }
180
181 /* TODO: unit test */
db_object_field_list_new_copy(const db_object_field_list_t * from_object_field_list)182 db_object_field_list_t* db_object_field_list_new_copy(const db_object_field_list_t* from_object_field_list) {
183 db_object_field_list_t* object_field_list;
184
185 if (!from_object_field_list) {
186 return NULL;
187 }
188
189 if (!(object_field_list = db_object_field_list_new())
190 || db_object_field_list_copy(object_field_list, from_object_field_list))
191 {
192 db_object_field_list_free(object_field_list);
193 return NULL;
194 }
195
196 return object_field_list;
197 }
198
db_object_field_list_free(db_object_field_list_t * object_field_list)199 void db_object_field_list_free(db_object_field_list_t* object_field_list) {
200 if (object_field_list) {
201 if (object_field_list->begin) {
202 db_object_field_t* this = object_field_list->begin;
203 db_object_field_t* next = NULL;
204
205 while (this) {
206 next = this->next;
207 db_object_field_free(this);
208 this = next;
209 }
210 }
211 free(object_field_list);
212 }
213 }
214
215 /* TODO: unit test */
db_object_field_list_copy(db_object_field_list_t * object_field_list,const db_object_field_list_t * from_object_field_list)216 int db_object_field_list_copy(db_object_field_list_t* object_field_list, const db_object_field_list_t* from_object_field_list) {
217 db_object_field_t* object_field;
218 db_object_field_t* object_field_copy;
219
220 if (!object_field_list) {
221 return DB_ERROR_UNKNOWN;
222 }
223 /*
224 * TODO: Should we be able to copy into a object field list that already
225 * contains data?
226 */
227 if (object_field_list->begin) {
228 return DB_ERROR_UNKNOWN;
229 }
230 if (object_field_list->end) {
231 return DB_ERROR_UNKNOWN;
232 }
233 if (object_field_list->size) {
234 return DB_ERROR_UNKNOWN;
235 }
236 if (!from_object_field_list) {
237 return DB_ERROR_UNKNOWN;
238 }
239
240 object_field = from_object_field_list->begin;
241 while (object_field) {
242 if (!(object_field_copy = db_object_field_new_copy(object_field))
243 || db_object_field_list_add(object_field_list, object_field_copy))
244 {
245 return DB_ERROR_UNKNOWN;
246 }
247
248 object_field = object_field->next;
249 }
250
251 return DB_OK;
252 }
253
db_object_field_list_add(db_object_field_list_t * object_field_list,db_object_field_t * object_field)254 int db_object_field_list_add(db_object_field_list_t* object_field_list, db_object_field_t* object_field) {
255 if (!object_field_list) {
256 return DB_ERROR_UNKNOWN;
257 }
258 if (!object_field) {
259 return DB_ERROR_UNKNOWN;
260 }
261 if (db_object_field_not_empty(object_field)) {
262 return DB_ERROR_UNKNOWN;
263 }
264 if (object_field->next) {
265 return DB_ERROR_UNKNOWN;
266 }
267
268 if (object_field_list->begin) {
269 if (!object_field_list->end) {
270 return DB_ERROR_UNKNOWN;
271 }
272 object_field_list->end->next = object_field;
273 object_field_list->end = object_field;
274 }
275 else {
276 object_field_list->begin = object_field;
277 object_field_list->end = object_field;
278 }
279 object_field_list->size++;
280
281 return DB_OK;
282 }
283
db_object_field_list_begin(const db_object_field_list_t * object_field_list)284 const db_object_field_t* db_object_field_list_begin(const db_object_field_list_t* object_field_list) {
285 if (!object_field_list) {
286 return NULL;
287 }
288
289 return object_field_list->begin;
290 }
291
db_object_field_list_size(const db_object_field_list_t * object_field_list)292 size_t db_object_field_list_size(const db_object_field_list_t* object_field_list) {
293 if (!object_field_list) {
294 return 0;
295 }
296
297 return object_field_list->size;
298 }
299
300 /* DB OBJECT */
301
302
303
db_object_new(void)304 db_object_t* db_object_new(void) {
305 db_object_t* object =
306 (db_object_t*)calloc(1, sizeof(db_object_t));
307
308 return object;
309 }
310
db_object_free(db_object_t * object)311 void db_object_free(db_object_t* object) {
312 if (object) {
313 if (object->object_field_list) {
314 db_object_field_list_free(object->object_field_list);
315 }
316 free(object);
317 }
318 }
319
db_object_connection(const db_object_t * object)320 const db_connection_t* db_object_connection(const db_object_t* object) {
321 if (!object) {
322 return NULL;
323 }
324 return object->connection;
325 }
326
db_object_table(const db_object_t * object)327 const char* db_object_table(const db_object_t* object) {
328 if (!object) {
329 return NULL;
330 }
331 return object->table;
332 }
333
db_object_object_field_list(const db_object_t * object)334 const db_object_field_list_t* db_object_object_field_list(const db_object_t* object) {
335 if (!object) {
336 return NULL;
337 }
338 return object->object_field_list;
339 }
340
db_object_set_connection(db_object_t * object,const db_connection_t * connection)341 int db_object_set_connection(db_object_t* object, const db_connection_t* connection) {
342 if (!object) {
343 return DB_ERROR_UNKNOWN;
344 }
345 if (!connection) {
346 return DB_ERROR_UNKNOWN;
347 }
348 if (object->connection) {
349 return DB_ERROR_UNKNOWN;
350 }
351
352 object->connection = connection;
353 return DB_OK;
354 }
355
db_object_set_table(db_object_t * object,const char * table)356 int db_object_set_table(db_object_t* object, const char* table) {
357 if (!object) {
358 return DB_ERROR_UNKNOWN;
359 }
360 if (!table) {
361 return DB_ERROR_UNKNOWN;
362 }
363 if (object->table) {
364 return DB_ERROR_UNKNOWN;
365 }
366
367 object->table = table;
368 return DB_OK;
369 }
370
db_object_set_primary_key_name(db_object_t * object,const char * primary_key_name)371 int db_object_set_primary_key_name(db_object_t* object, const char* primary_key_name) {
372 if (!object) {
373 return DB_ERROR_UNKNOWN;
374 }
375 if (!primary_key_name) {
376 return DB_ERROR_UNKNOWN;
377 }
378 if (object->primary_key_name) {
379 return DB_ERROR_UNKNOWN;
380 }
381
382 object->primary_key_name = primary_key_name;
383 return DB_OK;
384 }
385
db_object_set_object_field_list(db_object_t * object,db_object_field_list_t * object_field_list)386 int db_object_set_object_field_list(db_object_t* object, db_object_field_list_t* object_field_list) {
387 if (!object) {
388 return DB_ERROR_UNKNOWN;
389 }
390 if (!object_field_list) {
391 return DB_ERROR_UNKNOWN;
392 }
393 if (object->object_field_list) {
394 return DB_ERROR_UNKNOWN;
395 }
396
397 object->object_field_list = object_field_list;
398 return DB_OK;
399 }
400
db_object_create(const db_object_t * object,const db_object_field_list_t * object_field_list,const db_value_set_t * value_set)401 int db_object_create(const db_object_t* object, const db_object_field_list_t* object_field_list, const db_value_set_t* value_set) {
402 if (!object) {
403 return DB_ERROR_UNKNOWN;
404 }
405 if (!value_set) {
406 return DB_ERROR_UNKNOWN;
407 }
408 if (!object->connection) {
409 return DB_ERROR_UNKNOWN;
410 }
411 if (!object->table) {
412 return DB_ERROR_UNKNOWN;
413 }
414 if (!object->primary_key_name) {
415 return DB_ERROR_UNKNOWN;
416 }
417
418 if (object_field_list) {
419 return db_connection_create(object->connection, object, object_field_list, value_set);
420 }
421 return db_connection_create(object->connection, object, object->object_field_list, value_set);
422 }
423
db_object_read(const db_object_t * object,const db_join_list_t * join_list,const db_clause_list_t * clause_list)424 db_result_list_t* db_object_read(const db_object_t* object, const db_join_list_t* join_list, const db_clause_list_t* clause_list) {
425 if (!object) {
426 return NULL;
427 }
428 if (!object->connection) {
429 return NULL;
430 }
431 if (!object->table) {
432 return NULL;
433 }
434 if (!object->primary_key_name) {
435 return NULL;
436 }
437
438 return db_connection_read(object->connection, object, join_list, clause_list);
439 }
440
db_object_update(const db_object_t * object,const db_object_field_list_t * object_field_list,const db_value_set_t * value_set,const db_clause_list_t * clause_list)441 int db_object_update(const db_object_t* object, const db_object_field_list_t* object_field_list, const db_value_set_t* value_set, const db_clause_list_t* clause_list) {
442 if (!object) {
443 return DB_ERROR_UNKNOWN;
444 }
445 if (!value_set) {
446 return DB_ERROR_UNKNOWN;
447 }
448 if (!object->connection) {
449 return DB_ERROR_UNKNOWN;
450 }
451 if (!object->table) {
452 return DB_ERROR_UNKNOWN;
453 }
454 if (!object->primary_key_name) {
455 return DB_ERROR_UNKNOWN;
456 }
457
458 if (object_field_list) {
459 return db_connection_update(object->connection, object, object_field_list, value_set, clause_list);
460 }
461 return db_connection_update(object->connection, object, object->object_field_list, value_set, clause_list);
462 }
463
db_object_delete(const db_object_t * object,const db_clause_list_t * clause_list)464 int db_object_delete(const db_object_t* object, const db_clause_list_t* clause_list) {
465 if (!object) {
466 return DB_ERROR_UNKNOWN;
467 }
468 if (!object->connection) {
469 return DB_ERROR_UNKNOWN;
470 }
471 if (!object->table) {
472 return DB_ERROR_UNKNOWN;
473 }
474 if (!object->primary_key_name) {
475 return DB_ERROR_UNKNOWN;
476 }
477
478 return db_connection_delete(object->connection, object, clause_list);
479 }
480
db_object_count(const db_object_t * object,const db_join_list_t * join_list,const db_clause_list_t * clause_list,size_t * count)481 int db_object_count(const db_object_t* object, const db_join_list_t* join_list, const db_clause_list_t* clause_list, size_t* count) {
482 if (!object) {
483 return DB_ERROR_UNKNOWN;
484 }
485 if (!count) {
486 return DB_ERROR_UNKNOWN;
487 }
488 if (!object->connection) {
489 return DB_ERROR_UNKNOWN;
490 }
491 if (!object->table) {
492 return DB_ERROR_UNKNOWN;
493 }
494 if (!object->primary_key_name) {
495 return DB_ERROR_UNKNOWN;
496 }
497
498 return db_connection_count(object->connection, object, join_list, clause_list, count);
499 }
500