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 "key_state.h"
31 #include "db_error.h"
32
33
34 #include <string.h>
35
36 const db_enum_t key_state_enum_set_type[] = {
37 { "DS", (key_state_type_t)KEY_STATE_TYPE_DS },
38 { "RRSIG", (key_state_type_t)KEY_STATE_TYPE_RRSIG },
39 { "DNSKEY", (key_state_type_t)KEY_STATE_TYPE_DNSKEY },
40 { "RRSIGDNSKEY", (key_state_type_t)KEY_STATE_TYPE_RRSIGDNSKEY },
41 { NULL, 0 }
42 };
43
44 const db_enum_t key_state_enum_set_state[] = {
45 { "hidden", (key_state_state_t)KEY_STATE_STATE_HIDDEN },
46 { "rumoured", (key_state_state_t)KEY_STATE_STATE_RUMOURED },
47 { "omnipresent", (key_state_state_t)KEY_STATE_STATE_OMNIPRESENT },
48 { "unretentive", (key_state_state_t)KEY_STATE_STATE_UNRETENTIVE },
49 { "NA", (key_state_state_t)KEY_STATE_STATE_NA },
50 { NULL, 0 }
51 };
52
53 /**
54 * Create a new key state object.
55 * \param[in] connection a db_connection_t pointer.
56 * \return a key_state_t pointer or NULL on error.
57 */
__key_state_new_object(const db_connection_t * connection)58 static db_object_t* __key_state_new_object(const db_connection_t* connection) {
59 db_object_field_list_t* object_field_list;
60 db_object_field_t* object_field;
61 db_object_t* object;
62
63 if (!(object = db_object_new())
64 || db_object_set_connection(object, connection)
65 || db_object_set_table(object, "keyState")
66 || db_object_set_primary_key_name(object, "id")
67 || !(object_field_list = db_object_field_list_new()))
68 {
69 db_object_free(object);
70 return NULL;
71 }
72
73 if (!(object_field = db_object_field_new())
74 || db_object_field_set_name(object_field, "id")
75 || db_object_field_set_type(object_field, DB_TYPE_PRIMARY_KEY)
76 || db_object_field_list_add(object_field_list, object_field))
77 {
78 db_object_field_free(object_field);
79 db_object_field_list_free(object_field_list);
80 db_object_free(object);
81 return NULL;
82 }
83
84 if (!(object_field = db_object_field_new())
85 || db_object_field_set_name(object_field, "rev")
86 || db_object_field_set_type(object_field, DB_TYPE_REVISION)
87 || db_object_field_list_add(object_field_list, object_field))
88 {
89 db_object_field_free(object_field);
90 db_object_field_list_free(object_field_list);
91 db_object_free(object);
92 return NULL;
93 }
94
95 if (!(object_field = db_object_field_new())
96 || db_object_field_set_name(object_field, "keyDataId")
97 || db_object_field_set_type(object_field, DB_TYPE_ANY)
98 || db_object_field_list_add(object_field_list, object_field))
99 {
100 db_object_field_free(object_field);
101 db_object_field_list_free(object_field_list);
102 db_object_free(object);
103 return NULL;
104 }
105
106 if (!(object_field = db_object_field_new())
107 || db_object_field_set_name(object_field, "type")
108 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
109 || db_object_field_set_enum_set(object_field, key_state_enum_set_type)
110 || db_object_field_list_add(object_field_list, object_field))
111 {
112 db_object_field_free(object_field);
113 db_object_field_list_free(object_field_list);
114 db_object_free(object);
115 return NULL;
116 }
117
118 if (!(object_field = db_object_field_new())
119 || db_object_field_set_name(object_field, "state")
120 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
121 || db_object_field_set_enum_set(object_field, key_state_enum_set_state)
122 || db_object_field_list_add(object_field_list, object_field))
123 {
124 db_object_field_free(object_field);
125 db_object_field_list_free(object_field_list);
126 db_object_free(object);
127 return NULL;
128 }
129
130 if (!(object_field = db_object_field_new())
131 || db_object_field_set_name(object_field, "lastChange")
132 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
133 || db_object_field_list_add(object_field_list, object_field))
134 {
135 db_object_field_free(object_field);
136 db_object_field_list_free(object_field_list);
137 db_object_free(object);
138 return NULL;
139 }
140
141 if (!(object_field = db_object_field_new())
142 || db_object_field_set_name(object_field, "minimize")
143 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
144 || db_object_field_list_add(object_field_list, object_field))
145 {
146 db_object_field_free(object_field);
147 db_object_field_list_free(object_field_list);
148 db_object_free(object);
149 return NULL;
150 }
151
152 if (!(object_field = db_object_field_new())
153 || db_object_field_set_name(object_field, "ttl")
154 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
155 || db_object_field_list_add(object_field_list, object_field))
156 {
157 db_object_field_free(object_field);
158 db_object_field_list_free(object_field_list);
159 db_object_free(object);
160 return NULL;
161 }
162
163 if (db_object_set_object_field_list(object, object_field_list)) {
164 db_object_field_list_free(object_field_list);
165 db_object_free(object);
166 return NULL;
167 }
168
169 return object;
170 }
171
172 /* KEY STATE */
173
174
175
key_state_new(const db_connection_t * connection)176 key_state_t* key_state_new(const db_connection_t* connection) {
177 key_state_t* key_state =
178 (key_state_t*)calloc(1, sizeof(key_state_t));
179
180 if (key_state) {
181 if (!(key_state->dbo = __key_state_new_object(connection))) {
182 free(key_state);
183 return NULL;
184 }
185 db_value_reset(&(key_state->id));
186 db_value_reset(&(key_state->rev));
187 db_value_reset(&(key_state->key_data_id));
188 key_state->type = KEY_STATE_TYPE_INVALID;
189 key_state->state = KEY_STATE_STATE_HIDDEN;
190 }
191
192 return key_state;
193 }
194
key_state_new_copy(const key_state_t * key_state)195 key_state_t* key_state_new_copy(const key_state_t* key_state) {
196 key_state_t* new_key_state;
197
198 if (!key_state) {
199 return NULL;
200 }
201 if (!key_state->dbo) {
202 return NULL;
203 }
204
205 if (!(new_key_state = key_state_new(db_object_connection(key_state->dbo)))
206 || key_state_copy(new_key_state, key_state))
207 {
208 key_state_free(new_key_state);
209 return NULL;
210 }
211 return new_key_state;
212 }
213
key_state_free(key_state_t * key_state)214 void key_state_free(key_state_t* key_state) {
215 if (key_state) {
216 if (key_state->dbo) {
217 db_object_free(key_state->dbo);
218 }
219 db_value_reset(&(key_state->id));
220 db_value_reset(&(key_state->rev));
221 db_value_reset(&(key_state->key_data_id));
222 if (key_state->private_key_data_id) {
223 key_data_free(key_state->private_key_data_id);
224 }
225 free(key_state);
226 }
227 }
228
key_state_copy(key_state_t * key_state,const key_state_t * key_state_copy)229 int key_state_copy(key_state_t* key_state, const key_state_t* key_state_copy) {
230 if (!key_state) {
231 return DB_ERROR_UNKNOWN;
232 }
233 if (!key_state_copy) {
234 return DB_ERROR_UNKNOWN;
235 }
236
237 if (db_value_copy(&(key_state->id), &(key_state_copy->id))) {
238 return DB_ERROR_UNKNOWN;
239 }
240 if (db_value_copy(&(key_state->rev), &(key_state_copy->rev))) {
241 return DB_ERROR_UNKNOWN;
242 }
243 if (db_value_copy(&(key_state->key_data_id), &(key_state_copy->key_data_id))) {
244 return DB_ERROR_UNKNOWN;
245 }
246 if (key_state->private_key_data_id) {
247 key_data_free(key_state->private_key_data_id);
248 key_state->private_key_data_id = NULL;
249 }
250 if (key_state_copy->private_key_data_id
251 && !(key_state->private_key_data_id = key_data_new_copy(key_state_copy->private_key_data_id)))
252 {
253 return DB_ERROR_UNKNOWN;
254 }
255 key_state->associated_key_data_id = NULL;
256 if (!key_state_copy->private_key_data_id
257 && key_state_copy->associated_key_data_id
258 && !(key_state->private_key_data_id = key_data_new_copy(key_state_copy->associated_key_data_id)))
259 {
260 return DB_ERROR_UNKNOWN;
261 }
262 key_state->type = key_state_copy->type;
263 key_state->state = key_state_copy->state;
264 key_state->last_change = key_state_copy->last_change;
265 key_state->minimize = key_state_copy->minimize;
266 key_state->ttl = key_state_copy->ttl;
267 return DB_OK;
268 }
269
key_state_from_result(key_state_t * key_state,const db_result_t * result)270 int key_state_from_result(key_state_t* key_state, const db_result_t* result) {
271 const db_value_set_t* value_set;
272 int type;
273 int state;
274
275 if (!key_state) {
276 return DB_ERROR_UNKNOWN;
277 }
278 if (!result) {
279 return DB_ERROR_UNKNOWN;
280 }
281
282 db_value_reset(&(key_state->id));
283 db_value_reset(&(key_state->rev));
284 db_value_reset(&(key_state->key_data_id));
285 if (!(value_set = db_result_value_set(result))
286 || db_value_set_size(value_set) != 8
287 || db_value_copy(&(key_state->id), db_value_set_at(value_set, 0))
288 || db_value_copy(&(key_state->rev), db_value_set_at(value_set, 1))
289 || db_value_copy(&(key_state->key_data_id), db_value_set_at(value_set, 2))
290 || db_value_to_enum_value(db_value_set_at(value_set, 3), &type, key_state_enum_set_type)
291 || db_value_to_enum_value(db_value_set_at(value_set, 4), &state, key_state_enum_set_state)
292 || db_value_to_uint32(db_value_set_at(value_set, 5), &(key_state->last_change))
293 || db_value_to_uint32(db_value_set_at(value_set, 6), &(key_state->minimize))
294 || db_value_to_uint32(db_value_set_at(value_set, 7), &(key_state->ttl)))
295 {
296 return DB_ERROR_UNKNOWN;
297 }
298
299 if (type == (key_state_type_t)KEY_STATE_TYPE_DS) {
300 key_state->type = KEY_STATE_TYPE_DS;
301 }
302 else if (type == (key_state_type_t)KEY_STATE_TYPE_RRSIG) {
303 key_state->type = KEY_STATE_TYPE_RRSIG;
304 }
305 else if (type == (key_state_type_t)KEY_STATE_TYPE_DNSKEY) {
306 key_state->type = KEY_STATE_TYPE_DNSKEY;
307 }
308 else if (type == (key_state_type_t)KEY_STATE_TYPE_RRSIGDNSKEY) {
309 key_state->type = KEY_STATE_TYPE_RRSIGDNSKEY;
310 }
311 else {
312 return DB_ERROR_UNKNOWN;
313 }
314
315 if (state == (key_state_state_t)KEY_STATE_STATE_HIDDEN) {
316 key_state->state = KEY_STATE_STATE_HIDDEN;
317 }
318 else if (state == (key_state_state_t)KEY_STATE_STATE_RUMOURED) {
319 key_state->state = KEY_STATE_STATE_RUMOURED;
320 }
321 else if (state == (key_state_state_t)KEY_STATE_STATE_OMNIPRESENT) {
322 key_state->state = KEY_STATE_STATE_OMNIPRESENT;
323 }
324 else if (state == (key_state_state_t)KEY_STATE_STATE_UNRETENTIVE) {
325 key_state->state = KEY_STATE_STATE_UNRETENTIVE;
326 }
327 else if (state == (key_state_state_t)KEY_STATE_STATE_NA) {
328 key_state->state = KEY_STATE_STATE_NA;
329 }
330 else {
331 return DB_ERROR_UNKNOWN;
332 }
333
334 return DB_OK;
335 }
336
key_state_key_data_id(const key_state_t * key_state)337 const db_value_t* key_state_key_data_id(const key_state_t* key_state) {
338 if (!key_state) {
339 return NULL;
340 }
341
342 return &(key_state->key_data_id);
343 }
344
key_state_type(const key_state_t * key_state)345 key_state_type_t key_state_type(const key_state_t* key_state) {
346 if (!key_state) {
347 return KEY_STATE_TYPE_INVALID;
348 }
349
350 return key_state->type;
351 }
352
key_state_type_text(const key_state_t * key_state)353 const char* key_state_type_text(const key_state_t* key_state) {
354 const db_enum_t* enum_set = key_state_enum_set_type;
355
356 if (!key_state) {
357 return NULL;
358 }
359
360 while (enum_set->text) {
361 if (enum_set->value == key_state->type) {
362 return enum_set->text;
363 }
364 enum_set++;
365 }
366 return NULL;
367 }
368
key_state_state(const key_state_t * key_state)369 key_state_state_t key_state_state(const key_state_t* key_state) {
370 if (!key_state) {
371 return KEY_STATE_STATE_INVALID;
372 }
373
374 return key_state->state;
375 }
376
key_state_state_text(const key_state_t * key_state)377 const char* key_state_state_text(const key_state_t* key_state) {
378 const db_enum_t* enum_set = key_state_enum_set_state;
379
380 if (!key_state) {
381 return NULL;
382 }
383
384 while (enum_set->text) {
385 if (enum_set->value == key_state->state) {
386 return enum_set->text;
387 }
388 enum_set++;
389 }
390 return NULL;
391 }
392
key_state_last_change(const key_state_t * key_state)393 unsigned int key_state_last_change(const key_state_t* key_state) {
394 if (!key_state) {
395 return 0;
396 }
397
398 return key_state->last_change;
399 }
400
key_state_minimize(const key_state_t * key_state)401 unsigned int key_state_minimize(const key_state_t* key_state) {
402 if (!key_state) {
403 return 0;
404 }
405
406 return key_state->minimize;
407 }
408
key_state_ttl(const key_state_t * key_state)409 unsigned int key_state_ttl(const key_state_t* key_state) {
410 if (!key_state) {
411 return 0;
412 }
413
414 return key_state->ttl;
415 }
416
key_state_set_key_data_id(key_state_t * key_state,const db_value_t * key_data_id)417 int key_state_set_key_data_id(key_state_t* key_state, const db_value_t* key_data_id) {
418 if (!key_state) {
419 return DB_ERROR_UNKNOWN;
420 }
421 if (!key_data_id) {
422 return DB_ERROR_UNKNOWN;
423 }
424 if (db_value_not_empty(key_data_id)) {
425 return DB_ERROR_UNKNOWN;
426 }
427
428 db_value_reset(&(key_state->key_data_id));
429 if (db_value_copy(&(key_state->key_data_id), key_data_id)) {
430 return DB_ERROR_UNKNOWN;
431 }
432
433 return DB_OK;
434 }
435
key_state_set_type(key_state_t * key_state,key_state_type_t type)436 int key_state_set_type(key_state_t* key_state, key_state_type_t type) {
437 if (!key_state) {
438 return DB_ERROR_UNKNOWN;
439 }
440 if (type == KEY_STATE_TYPE_INVALID) {
441 return DB_ERROR_UNKNOWN;
442 }
443
444 key_state->type = type;
445
446 return DB_OK;
447 }
448
key_state_set_state(key_state_t * key_state,key_state_state_t state)449 int key_state_set_state(key_state_t* key_state, key_state_state_t state) {
450 if (!key_state) {
451 return DB_ERROR_UNKNOWN;
452 }
453 if (state == KEY_STATE_STATE_INVALID) {
454 return DB_ERROR_UNKNOWN;
455 }
456
457 key_state->state = state;
458
459 return DB_OK;
460 }
461
key_state_set_last_change(key_state_t * key_state,unsigned int last_change)462 int key_state_set_last_change(key_state_t* key_state, unsigned int last_change) {
463 if (!key_state) {
464 return DB_ERROR_UNKNOWN;
465 }
466
467 key_state->last_change = last_change;
468
469 return DB_OK;
470 }
471
key_state_set_minimize(key_state_t * key_state,unsigned int minimize)472 int key_state_set_minimize(key_state_t* key_state, unsigned int minimize) {
473 if (!key_state) {
474 return DB_ERROR_UNKNOWN;
475 }
476
477 key_state->minimize = minimize;
478
479 return DB_OK;
480 }
481
key_state_set_ttl(key_state_t * key_state,unsigned int ttl)482 int key_state_set_ttl(key_state_t* key_state, unsigned int ttl) {
483 if (!key_state) {
484 return DB_ERROR_UNKNOWN;
485 }
486
487 key_state->ttl = ttl;
488
489 return DB_OK;
490 }
491
key_state_key_data_id_clause(db_clause_list_t * clause_list,const db_value_t * key_data_id)492 db_clause_t* key_state_key_data_id_clause(db_clause_list_t* clause_list, const db_value_t* key_data_id) {
493 db_clause_t* clause;
494
495 if (!clause_list) {
496 return NULL;
497 }
498 if (!key_data_id) {
499 return NULL;
500 }
501 if (db_value_not_empty(key_data_id)) {
502 return NULL;
503 }
504
505 if (!(clause = db_clause_new())
506 || db_clause_set_field(clause, "keyDataId")
507 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
508 || db_clause_set_operator(clause, DB_CLAUSE_OPERATOR_AND)
509 || db_value_copy(db_clause_get_value(clause), key_data_id)
510 || db_clause_list_add(clause_list, clause))
511 {
512 db_clause_free(clause);
513 return NULL;
514 }
515
516 return clause;
517 }
518
key_state_create(key_state_t * key_state)519 int key_state_create(key_state_t* key_state) {
520 db_object_field_list_t* object_field_list;
521 db_object_field_t* object_field;
522 db_value_set_t* value_set;
523 int ret;
524
525 if (!key_state) {
526 return DB_ERROR_UNKNOWN;
527 }
528 if (!key_state->dbo) {
529 return DB_ERROR_UNKNOWN;
530 }
531 if (!db_value_not_empty(&(key_state->id))) {
532 return DB_ERROR_UNKNOWN;
533 }
534 if (!db_value_not_empty(&(key_state->rev))) {
535 return DB_ERROR_UNKNOWN;
536 }
537 if (db_value_not_empty(&(key_state->key_data_id))) {
538 return DB_ERROR_UNKNOWN;
539 }
540 /* TODO: validate content more */
541
542 if (!(object_field_list = db_object_field_list_new())) {
543 return DB_ERROR_UNKNOWN;
544 }
545
546 if (!(object_field = db_object_field_new())
547 || db_object_field_set_name(object_field, "keyDataId")
548 || db_object_field_set_type(object_field, DB_TYPE_ANY)
549 || db_object_field_list_add(object_field_list, object_field))
550 {
551 db_object_field_free(object_field);
552 db_object_field_list_free(object_field_list);
553 return DB_ERROR_UNKNOWN;
554 }
555
556 if (!(object_field = db_object_field_new())
557 || db_object_field_set_name(object_field, "type")
558 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
559 || db_object_field_set_enum_set(object_field, key_state_enum_set_type)
560 || db_object_field_list_add(object_field_list, object_field))
561 {
562 db_object_field_free(object_field);
563 db_object_field_list_free(object_field_list);
564 return DB_ERROR_UNKNOWN;
565 }
566
567 if (!(object_field = db_object_field_new())
568 || db_object_field_set_name(object_field, "state")
569 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
570 || db_object_field_set_enum_set(object_field, key_state_enum_set_state)
571 || db_object_field_list_add(object_field_list, object_field))
572 {
573 db_object_field_free(object_field);
574 db_object_field_list_free(object_field_list);
575 return DB_ERROR_UNKNOWN;
576 }
577
578 if (!(object_field = db_object_field_new())
579 || db_object_field_set_name(object_field, "lastChange")
580 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
581 || db_object_field_list_add(object_field_list, object_field))
582 {
583 db_object_field_free(object_field);
584 db_object_field_list_free(object_field_list);
585 return DB_ERROR_UNKNOWN;
586 }
587
588 if (!(object_field = db_object_field_new())
589 || db_object_field_set_name(object_field, "minimize")
590 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
591 || db_object_field_list_add(object_field_list, object_field))
592 {
593 db_object_field_free(object_field);
594 db_object_field_list_free(object_field_list);
595 return DB_ERROR_UNKNOWN;
596 }
597
598 if (!(object_field = db_object_field_new())
599 || db_object_field_set_name(object_field, "ttl")
600 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
601 || db_object_field_list_add(object_field_list, object_field))
602 {
603 db_object_field_free(object_field);
604 db_object_field_list_free(object_field_list);
605 return DB_ERROR_UNKNOWN;
606 }
607
608 if (!(value_set = db_value_set_new(6))) {
609 db_object_field_list_free(object_field_list);
610 return DB_ERROR_UNKNOWN;
611 }
612
613 if (db_value_copy(db_value_set_get(value_set, 0), &(key_state->key_data_id))
614 || db_value_from_enum_value(db_value_set_get(value_set, 1), key_state->type, key_state_enum_set_type)
615 || db_value_from_enum_value(db_value_set_get(value_set, 2), key_state->state, key_state_enum_set_state)
616 || db_value_from_uint32(db_value_set_get(value_set, 3), key_state->last_change)
617 || db_value_from_uint32(db_value_set_get(value_set, 4), key_state->minimize)
618 || db_value_from_uint32(db_value_set_get(value_set, 5), key_state->ttl))
619 {
620 db_value_set_free(value_set);
621 db_object_field_list_free(object_field_list);
622 return DB_ERROR_UNKNOWN;
623 }
624
625 ret = db_object_create(key_state->dbo, object_field_list, value_set);
626 db_value_set_free(value_set);
627 db_object_field_list_free(object_field_list);
628 return ret;
629 }
630
key_state_get_by_id(key_state_t * key_state,const db_value_t * id)631 int key_state_get_by_id(key_state_t* key_state, const db_value_t* id) {
632 db_clause_list_t* clause_list;
633 db_clause_t* clause;
634 db_result_list_t* result_list;
635 const db_result_t* result;
636
637 if (!key_state) {
638 return DB_ERROR_UNKNOWN;
639 }
640 if (!key_state->dbo) {
641 return DB_ERROR_UNKNOWN;
642 }
643 if (!id) {
644 return DB_ERROR_UNKNOWN;
645 }
646 if (db_value_not_empty(id)) {
647 return DB_ERROR_UNKNOWN;
648 }
649
650 if (!(clause_list = db_clause_list_new())) {
651 return DB_ERROR_UNKNOWN;
652 }
653 if (!(clause = db_clause_new())
654 || db_clause_set_field(clause, "id")
655 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
656 || db_value_copy(db_clause_get_value(clause), id)
657 || db_clause_list_add(clause_list, clause))
658 {
659 db_clause_free(clause);
660 db_clause_list_free(clause_list);
661 return DB_ERROR_UNKNOWN;
662 }
663
664 result_list = db_object_read(key_state->dbo, NULL, clause_list);
665 db_clause_list_free(clause_list);
666
667 if (result_list) {
668 result = db_result_list_next(result_list);
669 if (result) {
670 if (key_state_from_result(key_state, result)) {
671 db_result_list_free(result_list);
672 return DB_ERROR_UNKNOWN;
673 }
674
675 db_result_list_free(result_list);
676 return DB_OK;
677 }
678 }
679
680 db_result_list_free(result_list);
681 return DB_ERROR_UNKNOWN;
682 }
683
key_state_update(key_state_t * key_state)684 int key_state_update(key_state_t* key_state) {
685 db_object_field_list_t* object_field_list;
686 db_object_field_t* object_field;
687 db_value_set_t* value_set;
688 db_clause_list_t* clause_list;
689 db_clause_t* clause;
690 int ret;
691
692 if (!key_state) {
693 return DB_ERROR_UNKNOWN;
694 }
695 if (!key_state->dbo) {
696 return DB_ERROR_UNKNOWN;
697 }
698 if (db_value_not_empty(&(key_state->id))) {
699 return DB_ERROR_UNKNOWN;
700 }
701 if (db_value_not_empty(&(key_state->rev))) {
702 return DB_ERROR_UNKNOWN;
703 }
704 if (db_value_not_empty(&(key_state->key_data_id))) {
705 return DB_ERROR_UNKNOWN;
706 }
707 /* TODO: validate content more */
708
709 if (!(object_field_list = db_object_field_list_new())) {
710 return DB_ERROR_UNKNOWN;
711 }
712
713 if (!(object_field = db_object_field_new())
714 || db_object_field_set_name(object_field, "keyDataId")
715 || db_object_field_set_type(object_field, DB_TYPE_ANY)
716 || db_object_field_list_add(object_field_list, object_field))
717 {
718 db_object_field_free(object_field);
719 db_object_field_list_free(object_field_list);
720 return DB_ERROR_UNKNOWN;
721 }
722
723 if (!(object_field = db_object_field_new())
724 || db_object_field_set_name(object_field, "type")
725 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
726 || db_object_field_set_enum_set(object_field, key_state_enum_set_type)
727 || db_object_field_list_add(object_field_list, object_field))
728 {
729 db_object_field_free(object_field);
730 db_object_field_list_free(object_field_list);
731 return DB_ERROR_UNKNOWN;
732 }
733
734 if (!(object_field = db_object_field_new())
735 || db_object_field_set_name(object_field, "state")
736 || db_object_field_set_type(object_field, DB_TYPE_ENUM)
737 || db_object_field_set_enum_set(object_field, key_state_enum_set_state)
738 || db_object_field_list_add(object_field_list, object_field))
739 {
740 db_object_field_free(object_field);
741 db_object_field_list_free(object_field_list);
742 return DB_ERROR_UNKNOWN;
743 }
744
745 if (!(object_field = db_object_field_new())
746 || db_object_field_set_name(object_field, "lastChange")
747 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
748 || db_object_field_list_add(object_field_list, object_field))
749 {
750 db_object_field_free(object_field);
751 db_object_field_list_free(object_field_list);
752 return DB_ERROR_UNKNOWN;
753 }
754
755 if (!(object_field = db_object_field_new())
756 || db_object_field_set_name(object_field, "minimize")
757 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
758 || db_object_field_list_add(object_field_list, object_field))
759 {
760 db_object_field_free(object_field);
761 db_object_field_list_free(object_field_list);
762 return DB_ERROR_UNKNOWN;
763 }
764
765 if (!(object_field = db_object_field_new())
766 || db_object_field_set_name(object_field, "ttl")
767 || db_object_field_set_type(object_field, DB_TYPE_UINT32)
768 || db_object_field_list_add(object_field_list, object_field))
769 {
770 db_object_field_free(object_field);
771 db_object_field_list_free(object_field_list);
772 return DB_ERROR_UNKNOWN;
773 }
774
775 if (!(value_set = db_value_set_new(6))) {
776 db_object_field_list_free(object_field_list);
777 return DB_ERROR_UNKNOWN;
778 }
779
780 if (db_value_copy(db_value_set_get(value_set, 0), &(key_state->key_data_id))
781 || db_value_from_enum_value(db_value_set_get(value_set, 1), key_state->type, key_state_enum_set_type)
782 || db_value_from_enum_value(db_value_set_get(value_set, 2), key_state->state, key_state_enum_set_state)
783 || db_value_from_uint32(db_value_set_get(value_set, 3), key_state->last_change)
784 || db_value_from_uint32(db_value_set_get(value_set, 4), key_state->minimize)
785 || db_value_from_uint32(db_value_set_get(value_set, 5), key_state->ttl))
786 {
787 db_value_set_free(value_set);
788 db_object_field_list_free(object_field_list);
789 return DB_ERROR_UNKNOWN;
790 }
791
792 if (!(clause_list = db_clause_list_new())) {
793 db_value_set_free(value_set);
794 db_object_field_list_free(object_field_list);
795 return DB_ERROR_UNKNOWN;
796 }
797
798 if (!(clause = db_clause_new())
799 || db_clause_set_field(clause, "id")
800 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
801 || db_value_copy(db_clause_get_value(clause), &(key_state->id))
802 || db_clause_list_add(clause_list, clause))
803 {
804 db_clause_free(clause);
805 db_clause_list_free(clause_list);
806 db_value_set_free(value_set);
807 db_object_field_list_free(object_field_list);
808 return DB_ERROR_UNKNOWN;
809 }
810
811 if (!(clause = db_clause_new())
812 || db_clause_set_field(clause, "rev")
813 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
814 || db_value_copy(db_clause_get_value(clause), &(key_state->rev))
815 || db_clause_list_add(clause_list, clause))
816 {
817 db_clause_free(clause);
818 db_clause_list_free(clause_list);
819 db_value_set_free(value_set);
820 db_object_field_list_free(object_field_list);
821 return DB_ERROR_UNKNOWN;
822 }
823
824 ret = db_object_update(key_state->dbo, object_field_list, value_set, clause_list);
825 db_value_set_free(value_set);
826 db_object_field_list_free(object_field_list);
827 db_clause_list_free(clause_list);
828 return ret;
829 }
830
key_state_delete(const key_state_t * key_state)831 int key_state_delete(const key_state_t* key_state) {
832 db_clause_list_t* clause_list;
833 db_clause_t* clause;
834 int ret;
835
836 if (!key_state) {
837 return DB_ERROR_UNKNOWN;
838 }
839 if (!key_state->dbo) {
840 return DB_ERROR_UNKNOWN;
841 }
842 if (db_value_not_empty(&(key_state->id))) {
843 return DB_ERROR_UNKNOWN;
844 }
845
846 if (!(clause_list = db_clause_list_new())) {
847 return DB_ERROR_UNKNOWN;
848 }
849
850 if (!(clause = db_clause_new())
851 || db_clause_set_field(clause, "id")
852 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
853 || db_value_copy(db_clause_get_value(clause), &(key_state->id))
854 || db_clause_list_add(clause_list, clause))
855 {
856 db_clause_free(clause);
857 db_clause_list_free(clause_list);
858 return DB_ERROR_UNKNOWN;
859 }
860
861 if (!(clause = db_clause_new())
862 || db_clause_set_field(clause, "rev")
863 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
864 || db_value_copy(db_clause_get_value(clause), &(key_state->rev))
865 || db_clause_list_add(clause_list, clause))
866 {
867 db_clause_free(clause);
868 db_clause_list_free(clause_list);
869 return DB_ERROR_UNKNOWN;
870 }
871
872 ret = db_object_delete(key_state->dbo, clause_list);
873 db_clause_list_free(clause_list);
874 return ret;
875 }
876
877 /* KEY STATE LIST */
878
879
880
key_state_list_new(const db_connection_t * connection)881 key_state_list_t* key_state_list_new(const db_connection_t* connection) {
882 key_state_list_t* key_state_list =
883 (key_state_list_t*)calloc(1, sizeof(key_state_list_t));
884
885 if (key_state_list) {
886 if (!(key_state_list->dbo = __key_state_new_object(connection))) {
887 free(key_state_list);
888 return NULL;
889 }
890 }
891
892 return key_state_list;
893 }
894
key_state_list_new_copy(const key_state_list_t * from_key_state_list)895 key_state_list_t* key_state_list_new_copy(const key_state_list_t* from_key_state_list) {
896 key_state_list_t* key_state_list;
897
898 if (!from_key_state_list) {
899 return NULL;
900 }
901 if (!from_key_state_list->dbo) {
902 return NULL;
903 }
904
905 if (!(key_state_list = key_state_list_new(db_object_connection(from_key_state_list->dbo)))
906 || key_state_list_copy(key_state_list, from_key_state_list))
907 {
908 key_state_list_free(key_state_list);
909 return NULL;
910 }
911 return key_state_list;
912 }
913
key_state_list_object_store(key_state_list_t * key_state_list)914 int key_state_list_object_store(key_state_list_t* key_state_list) {
915 if (!key_state_list) {
916 return DB_ERROR_UNKNOWN;
917 }
918
919 key_state_list->object_store = 1;
920
921 return DB_OK;
922 }
923
key_state_list_free(key_state_list_t * key_state_list)924 void key_state_list_free(key_state_list_t* key_state_list) {
925 size_t i;
926
927 if (key_state_list) {
928 if (key_state_list->dbo) {
929 db_object_free(key_state_list->dbo);
930 }
931 if (key_state_list->result_list) {
932 db_result_list_free(key_state_list->result_list);
933 }
934 if (key_state_list->key_state) {
935 key_state_free(key_state_list->key_state);
936 }
937 for (i = 0; i < key_state_list->object_list_size; i++) {
938 if (key_state_list->object_list[i]) {
939 key_state_free(key_state_list->object_list[i]);
940 }
941 }
942 if (key_state_list->object_list) {
943 free(key_state_list->object_list);
944 }
945 if (key_state_list->key_data_id_list) {
946 key_data_list_free(key_state_list->key_data_id_list);
947 }
948 free(key_state_list);
949 }
950 }
951
key_state_list_copy(key_state_list_t * key_state_list,const key_state_list_t * from_key_state_list)952 int key_state_list_copy(key_state_list_t* key_state_list, const key_state_list_t* from_key_state_list) {
953 size_t i;
954
955 if (!key_state_list) {
956 return DB_ERROR_UNKNOWN;
957 }
958 if (!from_key_state_list) {
959 return DB_ERROR_UNKNOWN;
960 }
961 if (from_key_state_list->object_list && !from_key_state_list->object_list_size) {
962 return DB_ERROR_UNKNOWN;
963 }
964
965 if (key_state_list->result_list) {
966 db_result_list_free(key_state_list->result_list);
967 key_state_list->result_list = NULL;
968 }
969 if (from_key_state_list->result_list
970 && !(key_state_list->result_list = db_result_list_new_copy(from_key_state_list->result_list)))
971 {
972 return DB_ERROR_UNKNOWN;
973 }
974
975 key_state_list->object_store = from_key_state_list->object_store;
976 for (i = 0; i < key_state_list->object_list_size; i++) {
977 if (key_state_list->object_list[i]) {
978 key_state_free(key_state_list->object_list[i]);
979 }
980 }
981 key_state_list->object_list_size = 0;
982 if (key_state_list->object_list) {
983 free(key_state_list->object_list);
984 key_state_list->object_list = NULL;
985 }
986 if (from_key_state_list->object_list) {
987 if (!(key_state_list->object_list = (key_state_t**)calloc(from_key_state_list->object_list_size, sizeof(key_state_t*)))) {
988 return DB_ERROR_UNKNOWN;
989 }
990 key_state_list->object_list_size = from_key_state_list->object_list_size;
991 for (i = 0; i < from_key_state_list->object_list_size; i++) {
992 if (!from_key_state_list->object_list[i]) {
993 continue;
994 }
995 if (!(key_state_list->object_list[i] = key_state_new_copy(from_key_state_list->object_list[i]))) {
996 return DB_ERROR_UNKNOWN;
997 }
998 }
999 }
1000 key_state_list->object_list_position = 0;;
1001 key_state_list->object_list_first = 1;
1002 key_state_list->associated_fetch = from_key_state_list->associated_fetch;
1003
1004 if (from_key_state_list->key_data_id_list
1005 && !(key_state_list->key_data_id_list = key_data_list_new_copy(from_key_state_list->key_data_id_list)))
1006 {
1007 return DB_ERROR_UNKNOWN;
1008 }
1009
1010 return DB_OK;
1011 }
1012
key_state_list_get_associated(key_state_list_t * key_state_list)1013 static int key_state_list_get_associated(key_state_list_t* key_state_list) {
1014 const db_clause_t* clause_walk;
1015 const key_data_t* key_data_key_data_id;
1016 int cmp;
1017 size_t i;
1018 db_clause_list_t* clause_list;
1019 db_clause_t* clause;
1020 const key_state_t* key_state;
1021
1022 if (!key_state_list) {
1023 return DB_ERROR_UNKNOWN;
1024 }
1025 if (!key_state_list->dbo) {
1026 return DB_ERROR_UNKNOWN;
1027 }
1028 if (!key_state_list->associated_fetch) {
1029 return DB_ERROR_UNKNOWN;
1030 }
1031 if (!key_state_list->result_list) {
1032 return DB_ERROR_UNKNOWN;
1033 }
1034 if (key_state_list->object_list) {
1035 return DB_ERROR_UNKNOWN;
1036 }
1037
1038 if (key_state_list->key_data_id_list) {
1039 key_data_list_free(key_state_list->key_data_id_list);
1040 key_state_list->key_data_id_list = NULL;
1041 }
1042
1043 if (!(clause_list = db_clause_list_new())) {
1044 return DB_ERROR_UNKNOWN;
1045 }
1046 key_state = key_state_list_begin(key_state_list);
1047 while (key_state) {
1048 cmp = 1;
1049 clause_walk = db_clause_list_begin(clause_list);
1050 while (clause_walk) {
1051 if (db_value_cmp(db_clause_value(clause_walk), key_state_key_data_id(key_state), &cmp)) {
1052 db_clause_list_free(clause_list);
1053 return DB_ERROR_UNKNOWN;
1054 }
1055 if (!cmp) {
1056 break;
1057 }
1058 clause_walk = db_clause_next(clause_walk);
1059 }
1060 if (cmp) {
1061 if (!(clause = db_clause_new())
1062 || db_clause_set_field(clause, "id")
1063 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
1064 || db_clause_set_operator(clause, DB_CLAUSE_OPERATOR_OR)
1065 || db_value_copy(db_clause_get_value(clause), key_state_key_data_id(key_state))
1066 || db_clause_list_add(clause_list, clause))
1067 {
1068 db_clause_free(clause);
1069 db_clause_list_free(clause_list);
1070 return DB_ERROR_UNKNOWN;
1071 }
1072 }
1073
1074 key_state = key_state_list_next(key_state_list);
1075 }
1076
1077 if (!(key_state_list->key_data_id_list = key_data_list_new(db_object_connection(key_state_list->dbo)))
1078 || key_data_list_object_store(key_state_list->key_data_id_list)
1079 || key_data_list_get_by_clauses(key_state_list->key_data_id_list, clause_list))
1080 {
1081 if (key_state_list->key_data_id_list) {
1082 key_data_list_free(key_state_list->key_data_id_list);
1083 key_state_list->key_data_id_list = NULL;
1084 }
1085 db_clause_list_free(clause_list);
1086 return DB_ERROR_UNKNOWN;
1087 }
1088 db_clause_list_free(clause_list);
1089
1090 for (i = 0; i < key_state_list->object_list_size; i++) {
1091 if (!(key_state_list->object_list[i])) {
1092 return DB_ERROR_UNKNOWN;
1093 }
1094
1095 key_data_key_data_id = key_data_list_begin(key_state_list->key_data_id_list);
1096 while (key_data_key_data_id) {
1097 if (db_value_cmp(key_state_key_data_id(key_state_list->object_list[i]), key_data_id(key_data_key_data_id), &cmp)) {
1098 return DB_ERROR_UNKNOWN;
1099 }
1100 if (!cmp) {
1101 key_state_list->object_list[i]->associated_key_data_id = key_data_key_data_id;
1102 }
1103
1104 key_data_key_data_id = key_data_list_next(key_state_list->key_data_id_list);
1105 }
1106 }
1107
1108 key_state_list->object_list_first = 1;
1109 return DB_OK;
1110 }
1111
key_state_list_get_by_clauses(key_state_list_t * key_state_list,const db_clause_list_t * clause_list)1112 int key_state_list_get_by_clauses(key_state_list_t* key_state_list, const db_clause_list_t* clause_list) {
1113 size_t i;
1114
1115 if (!key_state_list) {
1116 return DB_ERROR_UNKNOWN;
1117 }
1118 if (!clause_list) {
1119 return DB_ERROR_UNKNOWN;
1120 }
1121 if (!key_state_list->dbo) {
1122 return DB_ERROR_UNKNOWN;
1123 }
1124
1125 if (key_state_list->result_list) {
1126 db_result_list_free(key_state_list->result_list);
1127 }
1128 if (key_state_list->object_list_size) {
1129 for (i = 0; i < key_state_list->object_list_size; i++) {
1130 if (key_state_list->object_list[i]) {
1131 key_state_free(key_state_list->object_list[i]);
1132 }
1133 }
1134 key_state_list->object_list_size = 0;
1135 key_state_list->object_list_first = 0;
1136 }
1137 if (key_state_list->object_list) {
1138 free(key_state_list->object_list);
1139 key_state_list->object_list = NULL;
1140 }
1141 if (!(key_state_list->result_list = db_object_read(key_state_list->dbo, NULL, clause_list))
1142 || db_result_list_fetch_all(key_state_list->result_list))
1143 {
1144 return DB_ERROR_UNKNOWN;
1145 }
1146 if (key_state_list->associated_fetch
1147 && key_state_list_get_associated(key_state_list))
1148 {
1149 return DB_ERROR_UNKNOWN;
1150 }
1151 return DB_OK;
1152 }
1153
key_state_list_get_by_key_data_id(key_state_list_t * key_state_list,const db_value_t * key_data_id)1154 int key_state_list_get_by_key_data_id(key_state_list_t* key_state_list, const db_value_t* key_data_id) {
1155 db_clause_list_t* clause_list;
1156 db_clause_t* clause;
1157 size_t i;
1158
1159 if (!key_state_list) {
1160 return DB_ERROR_UNKNOWN;
1161 }
1162 if (!key_state_list->dbo) {
1163 return DB_ERROR_UNKNOWN;
1164 }
1165 if (!key_data_id) {
1166 return DB_ERROR_UNKNOWN;
1167 }
1168 if (db_value_not_empty(key_data_id)) {
1169 return DB_ERROR_UNKNOWN;
1170 }
1171
1172 if (!(clause_list = db_clause_list_new())) {
1173 return DB_ERROR_UNKNOWN;
1174 }
1175 if (!(clause = db_clause_new())
1176 || db_clause_set_field(clause, "keyDataId")
1177 || db_clause_set_type(clause, DB_CLAUSE_EQUAL)
1178 || db_value_copy(db_clause_get_value(clause), key_data_id)
1179 || db_clause_list_add(clause_list, clause))
1180 {
1181 db_clause_free(clause);
1182 db_clause_list_free(clause_list);
1183 return DB_ERROR_UNKNOWN;
1184 }
1185
1186 if (key_state_list->result_list) {
1187 db_result_list_free(key_state_list->result_list);
1188 }
1189 if (key_state_list->object_list_size) {
1190 for (i = 0; i < key_state_list->object_list_size; i++) {
1191 if (key_state_list->object_list[i]) {
1192 key_state_free(key_state_list->object_list[i]);
1193 }
1194 }
1195 key_state_list->object_list_size = 0;
1196 key_state_list->object_list_first = 0;
1197 }
1198 if (key_state_list->object_list) {
1199 free(key_state_list->object_list);
1200 key_state_list->object_list = NULL;
1201 }
1202 if (!(key_state_list->result_list = db_object_read(key_state_list->dbo, NULL, clause_list))
1203 || db_result_list_fetch_all(key_state_list->result_list))
1204 {
1205 db_clause_list_free(clause_list);
1206 return DB_ERROR_UNKNOWN;
1207 }
1208 db_clause_list_free(clause_list);
1209 if (key_state_list->associated_fetch
1210 && key_state_list_get_associated(key_state_list))
1211 {
1212 return DB_ERROR_UNKNOWN;
1213 }
1214 return DB_OK;
1215 }
1216
key_state_list_new_get_by_key_data_id(const db_connection_t * connection,const db_value_t * key_data_id)1217 key_state_list_t* key_state_list_new_get_by_key_data_id(const db_connection_t* connection, const db_value_t* key_data_id) {
1218 key_state_list_t* key_state_list;
1219
1220 if (!connection) {
1221 return NULL;
1222 }
1223 if (!key_data_id) {
1224 return NULL;
1225 }
1226 if (db_value_not_empty(key_data_id)) {
1227 return NULL;
1228 }
1229
1230 if (!(key_state_list = key_state_list_new(connection))
1231 || key_state_list_get_by_key_data_id(key_state_list, key_data_id))
1232 {
1233 key_state_list_free(key_state_list);
1234 return NULL;
1235 }
1236
1237 return key_state_list;
1238 }
1239
key_state_list_begin(key_state_list_t * key_state_list)1240 const key_state_t* key_state_list_begin(key_state_list_t* key_state_list) {
1241 const db_result_t* result;
1242
1243 if (!key_state_list) {
1244 return NULL;
1245 }
1246
1247 if (key_state_list->object_store) {
1248 if (!key_state_list->object_list) {
1249 if (!key_state_list->result_list) {
1250 return NULL;
1251 }
1252 if (!db_result_list_size(key_state_list->result_list)) {
1253 return NULL;
1254 }
1255 if (!(key_state_list->object_list = (key_state_t**)calloc(db_result_list_size(key_state_list->result_list), sizeof(key_state_t*)))) {
1256 return NULL;
1257 }
1258 key_state_list->object_list_size = db_result_list_size(key_state_list->result_list);
1259 }
1260 if (!(key_state_list->object_list[0])) {
1261 if (!key_state_list->result_list) {
1262 return NULL;
1263 }
1264 if (!(result = db_result_list_begin(key_state_list->result_list))) {
1265 return NULL;
1266 }
1267 if (!(key_state_list->object_list[0] = key_state_new(db_object_connection(key_state_list->dbo)))) {
1268 return NULL;
1269 }
1270 if (key_state_from_result(key_state_list->object_list[0], result)) {
1271 return NULL;
1272 }
1273 }
1274 key_state_list->object_list_position = 0;
1275 return key_state_list->object_list[0];
1276 }
1277
1278 if (!key_state_list->result_list) {
1279 return NULL;
1280 }
1281
1282 if (!(result = db_result_list_begin(key_state_list->result_list))) {
1283 return NULL;
1284 }
1285 if (!key_state_list->key_state) {
1286 if (!(key_state_list->key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1287 return NULL;
1288 }
1289 }
1290 if (key_state_from_result(key_state_list->key_state, result)) {
1291 return NULL;
1292 }
1293 return key_state_list->key_state;
1294 }
1295
key_state_list_get_begin(key_state_list_t * key_state_list)1296 key_state_t* key_state_list_get_begin(key_state_list_t* key_state_list) {
1297 const db_result_t* result;
1298 key_state_t* key_state;
1299
1300 if (!key_state_list) {
1301 return NULL;
1302 }
1303
1304 if (key_state_list->object_store) {
1305 if (!(key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1306 return NULL;
1307 }
1308 if (key_state_copy(key_state, key_state_list_begin(key_state_list))) {
1309 key_state_free(key_state);
1310 return NULL;
1311 }
1312 return key_state;
1313 }
1314
1315 if (!key_state_list->result_list) {
1316 return NULL;
1317 }
1318
1319 if (!(result = db_result_list_begin(key_state_list->result_list))) {
1320 return NULL;
1321 }
1322 if (!(key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1323 return NULL;
1324 }
1325 if (key_state_from_result(key_state, result)) {
1326 key_state_free(key_state);
1327 return NULL;
1328 }
1329 return key_state;
1330 }
1331
key_state_list_next(key_state_list_t * key_state_list)1332 const key_state_t* key_state_list_next(key_state_list_t* key_state_list) {
1333 const db_result_t* result;
1334
1335 if (!key_state_list) {
1336 return NULL;
1337 }
1338
1339 if (key_state_list->object_store) {
1340 if (!key_state_list->object_list) {
1341 if (!key_state_list->result_list) {
1342 return NULL;
1343 }
1344 if (!db_result_list_size(key_state_list->result_list)) {
1345 return NULL;
1346 }
1347 if (!(key_state_list->object_list = (key_state_t**)calloc(db_result_list_size(key_state_list->result_list), sizeof(key_state_t*)))) {
1348 return NULL;
1349 }
1350 key_state_list->object_list_size = db_result_list_size(key_state_list->result_list);
1351 key_state_list->object_list_position = 0;
1352 }
1353 else if (key_state_list->object_list_first) {
1354 key_state_list->object_list_first = 0;
1355 key_state_list->object_list_position = 0;
1356 }
1357 else {
1358 key_state_list->object_list_position++;
1359 }
1360 if (key_state_list->object_list_position >= key_state_list->object_list_size) {
1361 return NULL;
1362 }
1363 if (!(key_state_list->object_list[key_state_list->object_list_position])) {
1364 if (!key_state_list->result_list) {
1365 return NULL;
1366 }
1367 if (!(result = db_result_list_next(key_state_list->result_list))) {
1368 return NULL;
1369 }
1370 if (!(key_state_list->object_list[key_state_list->object_list_position] = key_state_new(db_object_connection(key_state_list->dbo)))) {
1371 return NULL;
1372 }
1373 if (key_state_from_result(key_state_list->object_list[key_state_list->object_list_position], result)) {
1374 return NULL;
1375 }
1376 }
1377 return key_state_list->object_list[key_state_list->object_list_position];
1378 }
1379
1380 if (!key_state_list->result_list) {
1381 return NULL;
1382 }
1383
1384 if (!(result = db_result_list_next(key_state_list->result_list))) {
1385 return NULL;
1386 }
1387 if (!key_state_list->key_state) {
1388 if (!(key_state_list->key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1389 return NULL;
1390 }
1391 }
1392 if (key_state_from_result(key_state_list->key_state, result)) {
1393 return NULL;
1394 }
1395 return key_state_list->key_state;
1396 }
1397
key_state_list_get_next(key_state_list_t * key_state_list)1398 key_state_t* key_state_list_get_next(key_state_list_t* key_state_list) {
1399 const db_result_t* result;
1400 key_state_t* key_state;
1401
1402 if (!key_state_list) {
1403 return NULL;
1404 }
1405
1406 if (key_state_list->object_store) {
1407 if (!(key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1408 return NULL;
1409 }
1410 if (key_state_copy(key_state, key_state_list_next(key_state_list))) {
1411 key_state_free(key_state);
1412 return NULL;
1413 }
1414 return key_state;
1415 }
1416
1417 if (!key_state_list->result_list) {
1418 return NULL;
1419 }
1420
1421 if (!(result = db_result_list_next(key_state_list->result_list))) {
1422 return NULL;
1423 }
1424 if (!(key_state = key_state_new(db_object_connection(key_state_list->dbo)))) {
1425 return NULL;
1426 }
1427 if (key_state_from_result(key_state, result)) {
1428 key_state_free(key_state);
1429 return NULL;
1430 }
1431 return key_state;
1432 }
1433