1 /*
2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36 /*
37 * Abstract:
38 * Implementation of the osm_db interface using simple text files
39 */
40
41 #if HAVE_CONFIG_H
42 # include <config.h>
43 #endif /* HAVE_CONFIG_H */
44
45 #include <sys/stat.h>
46 #include <sys/types.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <opensm/st.h>
50 #include <opensm/osm_db.h>
51
52 /****d* Database/OSM_DB_MAX_LINE_LEN
53 * NAME
54 * OSM_DB_MAX_LINE_LEN
55 *
56 * DESCRIPTION
57 * The Maximal line length allowed for the file
58 *
59 * SYNOPSIS
60 */
61 #define OSM_DB_MAX_LINE_LEN 1024
62 /**********/
63
64 /****d* Database/OSM_DB_MAX_GUID_LEN
65 * NAME
66 * OSM_DB_MAX_GUID_LEN
67 *
68 * DESCRIPTION
69 * The Maximal word length allowed for the file (guid or lid)
70 *
71 * SYNOPSIS
72 */
73 #define OSM_DB_MAX_GUID_LEN 32
74 /**********/
75
76 /****s* OpenSM: Database/osm_db_domain_imp
77 * NAME
78 * osm_db_domain_imp
79 *
80 * DESCRIPTION
81 * An implementation for domain of the database based on text files and
82 * hash tables.
83 *
84 * SYNOPSIS
85 */
86 typedef struct osm_db_domain_imp {
87 char *file_name;
88 st_table *p_hash;
89 cl_spinlock_t lock;
90 } osm_db_domain_imp_t;
91 /*
92 * FIELDS
93 *
94 * SEE ALSO
95 * osm_db_domain_t
96 *********/
97
98 /****s* OpenSM: Database/osm_db_imp_t
99 * NAME
100 * osm_db_imp_t
101 *
102 * DESCRIPTION
103 * An implementation for file based database
104 *
105 * SYNOPSIS
106 */
107 typedef struct osm_db_imp {
108 char *db_dir_name;
109 } osm_db_imp_t;
110 /*
111 * FIELDS
112 *
113 * db_dir_name
114 * The directory holding the database
115 *
116 * SEE ALSO
117 * osm_db_t
118 *********/
119
120 /***************************************************************************
121 ***************************************************************************/
osm_db_construct(IN osm_db_t * const p_db)122 void osm_db_construct(IN osm_db_t * const p_db)
123 {
124 memset(p_db, 0, sizeof(osm_db_t));
125 cl_list_construct(&p_db->domains);
126 }
127
128 /***************************************************************************
129 ***************************************************************************/
osm_db_domain_destroy(IN osm_db_domain_t * const p_db_domain)130 void osm_db_domain_destroy(IN osm_db_domain_t * const p_db_domain)
131 {
132 osm_db_domain_imp_t *p_domain_imp;
133 p_domain_imp = (osm_db_domain_imp_t *) p_db_domain->p_domain_imp;
134
135 osm_db_clear(p_db_domain);
136
137 cl_spinlock_destroy(&p_domain_imp->lock);
138
139 st_free_table(p_domain_imp->p_hash);
140 free(p_domain_imp->file_name);
141 free(p_domain_imp);
142 }
143
144 /***************************************************************************
145 ***************************************************************************/
osm_db_destroy(IN osm_db_t * const p_db)146 void osm_db_destroy(IN osm_db_t * const p_db)
147 {
148 osm_db_domain_t *p_domain;
149
150 while ((p_domain = cl_list_remove_head(&p_db->domains)) != NULL) {
151 osm_db_domain_destroy(p_domain);
152 free(p_domain);
153 }
154 cl_list_destroy(&p_db->domains);
155 free(p_db->p_db_imp);
156 }
157
158 /***************************************************************************
159 ***************************************************************************/
osm_db_init(IN osm_db_t * const p_db,IN osm_log_t * p_log)160 int osm_db_init(IN osm_db_t * const p_db, IN osm_log_t * p_log)
161 {
162 osm_db_imp_t *p_db_imp;
163 struct stat dstat;
164
165 OSM_LOG_ENTER(p_log);
166
167 p_db_imp = (osm_db_imp_t *) malloc(sizeof(osm_db_imp_t));
168 CL_ASSERT(p_db_imp != NULL);
169
170 p_db_imp->db_dir_name = getenv("OSM_CACHE_DIR");
171 if (!p_db_imp->db_dir_name || !(*p_db_imp->db_dir_name))
172 p_db_imp->db_dir_name = OSM_DEFAULT_CACHE_DIR;
173
174 /* Create the directory if it doesn't exist */
175 /* There is a difference in creating directory between windows and linux */
176 #ifdef __WIN__
177 /* Check if the directory exists. If not - create it. */
178 CreateDirectory(p_db_imp->db_dir_name, NULL);
179 #else /* __WIN__ */
180 /* make sure the directory exists */
181 if (lstat(p_db_imp->db_dir_name, &dstat)) {
182 if (mkdir(p_db_imp->db_dir_name, 0755)) {
183 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6101: "
184 "Failed to create the db directory:%s\n",
185 p_db_imp->db_dir_name);
186 OSM_LOG_EXIT(p_log);
187 return 1;
188 }
189 }
190 #endif
191
192 p_db->p_log = p_log;
193 p_db->p_db_imp = (void *)p_db_imp;
194
195 cl_list_init(&p_db->domains, 5);
196
197 OSM_LOG_EXIT(p_log);
198
199 return 0;
200 }
201
202 /***************************************************************************
203 ***************************************************************************/
osm_db_domain_init(IN osm_db_t * const p_db,IN char * domain_name)204 osm_db_domain_t *osm_db_domain_init(IN osm_db_t * const p_db,
205 IN char *domain_name)
206 {
207 osm_db_domain_t *p_domain;
208 osm_db_domain_imp_t *p_domain_imp;
209 int dir_name_len;
210 osm_log_t *p_log = p_db->p_log;
211 FILE *p_file;
212
213 OSM_LOG_ENTER(p_log);
214
215 /* allocate a new domain object */
216 p_domain = (osm_db_domain_t *) malloc(sizeof(osm_db_domain_t));
217 CL_ASSERT(p_domain != NULL);
218
219 p_domain_imp =
220 (osm_db_domain_imp_t *) malloc(sizeof(osm_db_domain_imp_t));
221 CL_ASSERT(p_domain_imp != NULL);
222
223 dir_name_len = strlen(((osm_db_imp_t *) p_db->p_db_imp)->db_dir_name);
224
225 /* set the domain file name */
226 p_domain_imp->file_name =
227 (char *)malloc(sizeof(char) * (dir_name_len) + strlen(domain_name) +
228 2);
229 CL_ASSERT(p_domain_imp->file_name != NULL);
230 strcpy(p_domain_imp->file_name,
231 ((osm_db_imp_t *) p_db->p_db_imp)->db_dir_name);
232 strcat(p_domain_imp->file_name, domain_name);
233
234 /* make sure the file exists - or exit if not writable */
235 p_file = fopen(p_domain_imp->file_name, "a+");
236 if (!p_file) {
237 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6102: "
238 "Failed to open the db file:%s\n",
239 p_domain_imp->file_name);
240 free(p_domain_imp);
241 free(p_domain);
242 p_domain = NULL;
243 goto Exit;
244 }
245 fclose(p_file);
246
247 /* initialize the hash table object */
248 p_domain_imp->p_hash = st_init_strtable();
249 CL_ASSERT(p_domain_imp->p_hash != NULL);
250
251 p_domain->p_db = p_db;
252 cl_list_insert_tail(&p_db->domains, p_domain);
253 p_domain->p_domain_imp = p_domain_imp;
254 cl_spinlock_construct(&p_domain_imp->lock);
255 cl_spinlock_init(&p_domain_imp->lock);
256
257 Exit:
258 OSM_LOG_EXIT(p_log);
259 return p_domain;
260 }
261
262 /***************************************************************************
263 ***************************************************************************/
osm_db_restore(IN osm_db_domain_t * p_domain)264 int osm_db_restore(IN osm_db_domain_t * p_domain)
265 {
266
267 osm_log_t *p_log = p_domain->p_db->p_log;
268 osm_db_domain_imp_t *p_domain_imp =
269 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
270 FILE *p_file;
271 int status;
272 char sLine[OSM_DB_MAX_LINE_LEN];
273 boolean_t before_key;
274 char *p_first_word, *p_rest_of_line, *p_last;
275 char *p_key = NULL;
276 char *p_prev_val, *p_accum_val = NULL;
277 char *endptr = NULL;
278 unsigned int line_num;
279
280 OSM_LOG_ENTER(p_log);
281
282 /* take the lock on the domain */
283 cl_spinlock_acquire(&p_domain_imp->lock);
284
285 /* open the file - read mode */
286 p_file = fopen(p_domain_imp->file_name, "r");
287
288 if (!p_file) {
289 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6103: "
290 "Failed to open the db file:%s\n",
291 p_domain_imp->file_name);
292 status = 1;
293 goto Exit;
294 }
295
296 /* parse the file allocating new hash tables as required */
297 /*
298 states:
299 before_key (0) -> in_key (1)
300
301 before_key: if a word on the first byte - it is the key. state=in_key
302 the rest of the line is start of the value.
303 in_key: unless the line is empty - add it (with newlines) to the value.
304 if empty: state=before_key
305 */
306 status = 0;
307 before_key = TRUE;
308 line_num = 0;
309 /* if we got to EOF in the middle of a key we add a last newline */
310 while ((fgets(sLine, OSM_DB_MAX_LINE_LEN, p_file) != NULL) ||
311 ((before_key == FALSE) && strcpy(sLine, "\n"))
312 ) {
313 line_num++;
314 if (before_key) {
315 if ((sLine[0] != ' ') && (sLine[0] != '\t')
316 && (sLine[0] != '\n')) {
317 /* we got a new key */
318 before_key = FALSE;
319
320 /* handle the key */
321 p_first_word =
322 strtok_r(sLine, " \t\n", &p_last);
323 if (!p_first_word) {
324 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6104: "
325 "Failed to get key from line:%u : %s (file:%s)\n",
326 line_num, sLine,
327 p_domain_imp->file_name);
328 status = 1;
329 goto EndParsing;
330 }
331 if (strlen(p_first_word) > OSM_DB_MAX_GUID_LEN) {
332 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610A: "
333 "Illegal key from line:%u : %s (file:%s)\n",
334 line_num, sLine,
335 p_domain_imp->file_name);
336 status = 1;
337 goto EndParsing;
338 }
339
340 p_key =
341 (char *)malloc(sizeof(char) *
342 (strlen(p_first_word) + 1));
343 strcpy(p_key, p_first_word);
344
345 p_rest_of_line = strtok_r(NULL, "\n", &p_last);
346 if (p_rest_of_line != NULL) {
347 p_accum_val =
348 (char *)malloc(sizeof(char) *
349 (strlen
350 (p_rest_of_line) +
351 1));
352 strcpy(p_accum_val, p_rest_of_line);
353 } else {
354 p_accum_val = (char *)malloc(2);
355 strcpy(p_accum_val, "\0");
356 }
357 } else if (sLine[0] != '\n') {
358 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6105: "
359 "How did we get here? line:%u : %s (file:%s)\n",
360 line_num, sLine,
361 p_domain_imp->file_name);
362 status = 1;
363 goto EndParsing;
364 }
365 } /* before key */
366 else {
367 /* we already have a key */
368
369 if (sLine[0] == '\n') {
370 /* got an end of key */
371 before_key = TRUE;
372
373 /* make sure the key was not previously used */
374 if (st_lookup(p_domain_imp->p_hash,
375 (st_data_t) p_key,
376 (void *) & p_prev_val)) {
377 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6106: "
378 "Key:%s already exists in:%s with value:%s."
379 " Removing it\n",
380 p_key,
381 p_domain_imp->file_name,
382 p_prev_val);
383 } else {
384 p_prev_val = NULL;
385 }
386
387 OSM_LOG(p_log, OSM_LOG_DEBUG,
388 "Got key:%s value:%s\n", p_key,
389 p_accum_val);
390
391 /* check that the key is a number */
392 if (!strtouq(p_key, &endptr, 0)
393 && *endptr != '\0') {
394 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610B: "
395 "Key:%s is invalid\n", p_key);
396 } else {
397 /* store our key and value */
398 st_insert(p_domain_imp->p_hash,
399 (st_data_t) p_key,
400 (st_data_t) p_accum_val);
401 }
402 } else {
403 /* accumulate into the value */
404 p_prev_val = p_accum_val;
405 p_accum_val =
406 (char *)malloc(strlen(p_prev_val) +
407 strlen(sLine) + 1);
408 strcpy(p_accum_val, p_prev_val);
409 free(p_prev_val);
410 strcat(p_accum_val, sLine);
411 }
412 } /* in key */
413 } /* while lines or last line */
414
415 EndParsing:
416 fclose(p_file);
417
418 Exit:
419 cl_spinlock_release(&p_domain_imp->lock);
420 OSM_LOG_EXIT(p_log);
421 return status;
422 }
423
424 /***************************************************************************
425 ***************************************************************************/
__osm_dump_tbl_entry(st_data_t key,st_data_t val,st_data_t arg)426 static int __osm_dump_tbl_entry(st_data_t key, st_data_t val, st_data_t arg)
427 {
428 FILE *p_file = (FILE *) arg;
429 char *p_key = (char *)key;
430 char *p_val = (char *)val;
431
432 fprintf(p_file, "%s %s\n\n", p_key, p_val);
433 return ST_CONTINUE;
434 }
435
osm_db_store(IN osm_db_domain_t * p_domain)436 int osm_db_store(IN osm_db_domain_t * p_domain)
437 {
438 osm_log_t *p_log = p_domain->p_db->p_log;
439 osm_db_domain_imp_t *p_domain_imp;
440 FILE *p_file;
441 int status = 0;
442 char *p_tmp_file_name;
443
444 OSM_LOG_ENTER(p_log);
445
446 p_domain_imp = (osm_db_domain_imp_t *) p_domain->p_domain_imp;
447 p_tmp_file_name =
448 (char *)malloc(sizeof(char) *
449 (strlen(p_domain_imp->file_name) + 8));
450 strcpy(p_tmp_file_name, p_domain_imp->file_name);
451 strcat(p_tmp_file_name, ".tmp");
452
453 cl_spinlock_acquire(&p_domain_imp->lock);
454
455 /* open up the output file */
456 p_file = fopen(p_tmp_file_name, "w");
457 if (!p_file) {
458 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6107: "
459 "Failed to open the db file:%s for writing\n",
460 p_domain_imp->file_name);
461 status = 1;
462 goto Exit;
463 }
464
465 st_foreach(p_domain_imp->p_hash, __osm_dump_tbl_entry,
466 (st_data_t) p_file);
467 fclose(p_file);
468
469 /* move the domain file */
470 status = remove(p_domain_imp->file_name);
471 if (status) {
472 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6109: "
473 "Failed to remove file:%s (err:%u)\n",
474 p_domain_imp->file_name, status);
475 }
476
477 status = rename(p_tmp_file_name, p_domain_imp->file_name);
478 if (status) {
479 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6108: "
480 "Failed to rename the db file to:%s (err:%u)\n",
481 p_domain_imp->file_name, status);
482 }
483 Exit:
484 cl_spinlock_release(&p_domain_imp->lock);
485 free(p_tmp_file_name);
486 OSM_LOG_EXIT(p_log);
487 return status;
488 }
489
490 /***************************************************************************
491 ***************************************************************************/
492 /* simply de-allocate the key and the value and return the code
493 that makes the st_foreach delete the entry */
__osm_clear_tbl_entry(st_data_t key,st_data_t val,st_data_t arg)494 static int __osm_clear_tbl_entry(st_data_t key, st_data_t val, st_data_t arg)
495 {
496 free((char *)key);
497 free((char *)val);
498 return ST_DELETE;
499 }
500
osm_db_clear(IN osm_db_domain_t * p_domain)501 int osm_db_clear(IN osm_db_domain_t * p_domain)
502 {
503 osm_db_domain_imp_t *p_domain_imp =
504 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
505
506 cl_spinlock_acquire(&p_domain_imp->lock);
507 st_foreach(p_domain_imp->p_hash, __osm_clear_tbl_entry,
508 (st_data_t) NULL);
509 cl_spinlock_release(&p_domain_imp->lock);
510
511 return 0;
512 }
513
514 /***************************************************************************
515 ***************************************************************************/
__osm_get_key_of_tbl_entry(st_data_t key,st_data_t val,st_data_t arg)516 static int __osm_get_key_of_tbl_entry(st_data_t key, st_data_t val,
517 st_data_t arg)
518 {
519 cl_list_t *p_list = (cl_list_t *) arg;
520 cl_list_insert_tail(p_list, (void *)key);
521 return ST_CONTINUE;
522 }
523
osm_db_keys(IN osm_db_domain_t * p_domain,OUT cl_list_t * p_key_list)524 int osm_db_keys(IN osm_db_domain_t * p_domain, OUT cl_list_t * p_key_list)
525 {
526 osm_db_domain_imp_t *p_domain_imp =
527 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
528
529 cl_spinlock_acquire(&p_domain_imp->lock);
530
531 st_foreach(p_domain_imp->p_hash,
532 __osm_get_key_of_tbl_entry, (st_data_t) p_key_list);
533
534 cl_spinlock_release(&p_domain_imp->lock);
535
536 return 0;
537 }
538
539 /***************************************************************************
540 ***************************************************************************/
osm_db_lookup(IN osm_db_domain_t * p_domain,IN char * const p_key)541 char *osm_db_lookup(IN osm_db_domain_t * p_domain, IN char *const p_key)
542 {
543 osm_db_domain_imp_t *p_domain_imp =
544 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
545 char *p_val = NULL;
546
547 cl_spinlock_acquire(&p_domain_imp->lock);
548
549 if (!st_lookup
550 (p_domain_imp->p_hash, (st_data_t) p_key, (void *) & p_val))
551 p_val = NULL;
552
553 cl_spinlock_release(&p_domain_imp->lock);
554
555 return p_val;
556 }
557
558 /***************************************************************************
559 ***************************************************************************/
560 int
osm_db_update(IN osm_db_domain_t * p_domain,IN char * const p_key,IN char * const p_val)561 osm_db_update(IN osm_db_domain_t * p_domain,
562 IN char *const p_key, IN char *const p_val)
563 {
564 osm_log_t *p_log = p_domain->p_db->p_log;
565 osm_db_domain_imp_t *p_domain_imp =
566 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
567 char *p_prev_val = NULL;
568 char *p_new_key;
569 char *p_new_val;
570
571 cl_spinlock_acquire(&p_domain_imp->lock);
572
573 if (st_lookup(p_domain_imp->p_hash,
574 (st_data_t) p_key, (void *) & p_prev_val)) {
575 OSM_LOG(p_log, OSM_LOG_DEBUG,
576 "Key:%s previously exists in:%s with value:%s\n",
577 p_key, p_domain_imp->file_name, p_prev_val);
578 p_new_key = p_key;
579 } else {
580 /* need to allocate the key */
581 p_new_key = malloc(sizeof(char) * (strlen(p_key) + 1));
582 strcpy(p_new_key, p_key);
583 }
584
585 /* need to arange a new copy of the value */
586 p_new_val = malloc(sizeof(char) * (strlen(p_val) + 1));
587 strcpy(p_new_val, p_val);
588
589 st_insert(p_domain_imp->p_hash, (st_data_t) p_new_key,
590 (st_data_t) p_new_val);
591
592 if (p_prev_val)
593 free(p_prev_val);
594
595 cl_spinlock_release(&p_domain_imp->lock);
596
597 return 0;
598 }
599
600 /***************************************************************************
601 ***************************************************************************/
osm_db_delete(IN osm_db_domain_t * p_domain,IN char * const p_key)602 int osm_db_delete(IN osm_db_domain_t * p_domain, IN char *const p_key)
603 {
604 osm_log_t *p_log = p_domain->p_db->p_log;
605 osm_db_domain_imp_t *p_domain_imp =
606 (osm_db_domain_imp_t *) p_domain->p_domain_imp;
607 char *p_prev_val = NULL;
608 int res;
609
610 OSM_LOG_ENTER(p_log);
611
612 cl_spinlock_acquire(&p_domain_imp->lock);
613 if (st_delete(p_domain_imp->p_hash,
614 (void *) & p_key, (void *) & p_prev_val)) {
615 if (st_lookup(p_domain_imp->p_hash,
616 (st_data_t) p_key, (void *) & p_prev_val)) {
617 OSM_LOG(p_log, OSM_LOG_ERROR,
618 "key:%s still exists in:%s with value:%s\n",
619 p_key, p_domain_imp->file_name, p_prev_val);
620 res = 1;
621 } else {
622 free(p_key);
623 free(p_prev_val);
624 res = 0;
625 }
626 } else {
627 OSM_LOG(p_log, OSM_LOG_DEBUG,
628 "fail to find key:%s. delete failed\n", p_key);
629 res = 1;
630 }
631 cl_spinlock_release(&p_domain_imp->lock);
632
633 OSM_LOG_EXIT(p_log);
634 return res;
635 }
636
637 #ifdef TEST_OSMDB
638 #include <stdlib.h>
639 #include <math.h>
640
main(int argc,char ** argv)641 int main(int argc, char **argv)
642 {
643 osm_db_t db;
644 osm_log_t log;
645 osm_db_domain_t *p_dbd;
646 cl_list_t keys;
647 cl_list_iterator_t kI;
648 char *p_key;
649 char *p_val;
650 int i;
651
652 cl_list_construct(&keys);
653 cl_list_init(&keys, 10);
654
655 osm_log_init_v2(&log, TRUE, 0xff, "/var/log/osm_db_test.log", 0, FALSE);
656
657 osm_db_construct(&db);
658 if (osm_db_init(&db, &log)) {
659 printf("db init failed\n");
660 exit(1);
661 }
662
663 p_dbd = osm_db_domain_init(&db, "lid_by_guid");
664
665 if (osm_db_restore(p_dbd)) {
666 printf("failed to restore\n");
667 }
668
669 if (osm_db_keys(p_dbd, &keys)) {
670 printf("failed to get keys\n");
671 } else {
672 kI = cl_list_head(&keys);
673 while (kI != cl_list_end(&keys)) {
674 p_key = cl_list_obj(kI);
675 kI = cl_list_next(kI);
676
677 p_val = osm_db_lookup(p_dbd, p_key);
678 printf("key = %s val = %s\n", p_key, p_val);
679 }
680 }
681
682 cl_list_remove_all(&keys);
683
684 /* randomly add and remove numbers */
685 for (i = 0; i < 10; i++) {
686 int k;
687 float v;
688 int is_add;
689 char val_buf[16];
690 char key_buf[16];
691
692 k = floor(1.0 * rand() / RAND_MAX * 100);
693 v = rand();
694 sprintf(key_buf, "%u", k);
695 sprintf(val_buf, "%u", v);
696
697 is_add = (rand() < RAND_MAX / 2);
698
699 if (is_add) {
700 osm_db_update(p_dbd, key_buf, val_buf);
701 } else {
702 osm_db_delete(p_dbd, key_buf);
703 }
704 }
705 if (osm_db_keys(p_dbd, &keys)) {
706 printf("failed to get keys\n");
707 } else {
708 kI = cl_list_head(&keys);
709 while (kI != cl_list_end(&keys)) {
710 p_key = cl_list_obj(kI);
711 kI = cl_list_next(kI);
712
713 p_val = osm_db_lookup(p_dbd, p_key);
714 printf("key = %s val = %s\n", p_key, p_val);
715 }
716 }
717 if (osm_db_store(p_dbd))
718 printf("failed to store\n");
719
720 osm_db_destroy(&db);
721 cl_list_destroy(&keys);
722 }
723 #endif
724