1 /******************************************************************************
4 * Company XS Embedded GmbH
5 *****************************************************************************/
6 /******************************************************************************
7 * This Source Code Form is subject to the terms of the
8 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
9 * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 ******************************************************************************/
12 * @file persistence_client_library_data_access.c
13 * @ingroup Persistence client library
14 * @author Ingo Huerner
15 * @brief Implementation of persistence database access
16 * Library provides an API to access persistent data
20 #include "../include_protected/persistence_client_library_db_access.h"
21 #include "../include_protected/persistence_client_library_rc_table.h"
22 #include "persistence_client_library_custom_loader.h"
23 #include "persistence_client_library_itzam_errors.h"
25 #include "persistence_client_library_dbus_service.h"
27 #include <dbus/dbus.h>
33 /// definition of a key-value pair stored in the database
34 typedef struct _KeyValuePair_s
36 char m_key[DbKeySize]; /// the key
37 char m_data[DbValueSize]; /// the data
38 unsigned int m_data_size; /// the size of the data
43 // definition of a cursor entry
44 typedef struct _CursorEntry_s
46 itzam_btree_cursor m_cursor;
52 // cursor array handle
53 CursorEntry_s gCursorArray[MaxPersHandle];
56 static int gHandleIdx = 1;
59 int gFreeCursorHandleArray[MaxPersHandle];
61 int gFreeCursorHandleIdxHead = 0;
63 // mutex to controll access to the cursor array
64 pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
68 static itzam_btree gBtree[DbTableSize][PersistencePolicy_LastEntry];
69 static int gBtreeCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
73 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, unsigned int reason);
76 itzam_btree* pers_db_open(PersistenceInfo_s* info, const char* dbPath)
79 itzam_btree* btree = NULL;
81 // create array index: index is a combination of resource config table type and group
82 arrayIdx = info->configKey.storage + info->context.ldbid ;
84 //if(arrayIdx <= DbTableSize)
85 if(arrayIdx < DbTableSize)
87 if(gBtreeCreated[arrayIdx][info->configKey.policy] == 0)
89 itzam_state state = ITZAM_FAILED;
90 state = itzam_btree_open(&gBtree[arrayIdx][info->configKey.policy], dbPath,
91 itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
92 if (state != ITZAM_OKAY)
94 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
96 gBtreeCreated[arrayIdx][info->configKey.policy] = 1;
99 btree = &gBtree[arrayIdx][info->configKey.policy];
103 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> invalid storage type"), DLT_STRING(dbPath));
110 void pers_db_close(PersistenceInfo_s* info)
112 int arrayIdx = info->configKey.storage + info->context.ldbid;
114 if(info->configKey.storage <= PersistenceStorage_shared )
116 itzam_state state = ITZAM_FAILED;
117 state = itzam_btree_close(&gBtree[arrayIdx][info->configKey.policy]);
118 if (state != ITZAM_OKAY)
120 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
122 gBtreeCreated[arrayIdx][info->configKey.policy] = 0;
126 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> invalid storage type"), DLT_INT(info->context.ldbid ));
132 void pers_db_close_all()
136 for(i=0; i<DbTableSize; i++)
138 // close write cached database
139 if(gBtreeCreated[i][PersistencePolicy_wc] == 1)
141 itzam_state state = ITZAM_FAILED;
142 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wc]);
143 if (state != ITZAM_OKAY)
145 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==> itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]) );
147 gBtreeCreated[i][PersistencePolicy_wc] = 0;
150 // close write through database
151 if(gBtreeCreated[i][PersistencePolicy_wt] == 1)
153 itzam_state state = ITZAM_FAILED;
154 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wt]);
155 if (state != ITZAM_OKAY)
157 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==>itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]));
159 gBtreeCreated[i][PersistencePolicy_wt] = 0;
166 int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
170 if( PersistenceStorage_shared == info->configKey.storage
171 || PersistenceStorage_local == info->configKey.storage)
173 itzam_btree* btree = NULL;
174 itzam_state state = ITZAM_FAILED;
175 KeyValuePair_s search;
177 btree = pers_db_open(info, dbPath);
180 if(itzam_true == itzam_btree_find(btree, key, &search))
182 read_size = search.m_data_size;
183 if(read_size > buffer_size)
185 read_size = buffer_size; // truncate data size to buffer size
187 memcpy(buffer, search.m_data, read_size);
191 read_size = EPERS_NOKEY;
196 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==>no resource config table"), DLT_STRING(dbPath), DLT_STRING(key) );
197 read_size = EPERS_NOPRCTABLE;
200 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
202 int idx = custom_client_name_to_id(dbPath, 1);
203 char workaroundPath[128]; // workaround, because /sys/ can not be accessed on host!!!!
204 snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath );
206 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
208 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
210 char pathKeyString[128];
211 snprintf(pathKeyString, 128, "%s/%s", dbPath, key);
212 read_size = gPersCustomFuncs[idx].custom_plugin_get_data(pathKeyString, (char*)buffer, buffer_size);
216 read_size = gPersCustomFuncs[idx].custom_plugin_get_data(info->configKey.customID, (char*)buffer, buffer_size);
221 read_size = EPERS_NOPLUGINFUNCT;
229 int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
233 if( PersistenceStorage_local == info->configKey.storage
234 || PersistenceStorage_shared == info->configKey.storage )
236 write_size = buffer_size;
237 itzam_btree* btree = NULL;
238 itzam_state state = ITZAM_FAILED;
239 KeyValuePair_s insert;
241 btree = pers_db_open(info, dbPath);
245 keySize = (int)strlen((const char*)key);
246 if(keySize < DbKeySize)
249 dataSize = (int)strlen( (const char*)buffer);
250 if(dataSize < DbValueSize)
252 // -----------------------------------------------------------------------------
254 itzam_btree_transaction_start(btree);
257 memset(insert.m_key, 0, DbKeySize);
258 memcpy(insert.m_key, key, keySize);
259 if(itzam_true == itzam_btree_find(btree, key, &insert))
261 // key already available, so delete "old" key
262 state = itzam_btree_remove(btree, (const void *)&insert);
266 memset(insert.m_data, 0, DbValueSize);
267 memcpy(insert.m_data, buffer, dataSize);
270 insert.m_data_size = buffer_size;
272 state = itzam_btree_insert(btree,(const void *)&insert);
273 if (state != ITZAM_OKAY)
275 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> itzam_btree_insert => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]) );
276 write_size = EPERS_DB_ERROR_INTERNAL;
280 itzam_btree_transaction_commit(btree);
282 // -----------------------------------------------------------------------------
284 if(PersistenceStorage_shared == info->configKey.storage)
286 pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
291 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> data to long » size:"), DLT_INT(dataSize), DLT_INT(DbValueSize) );
292 write_size = EPERS_DB_VALUE_SIZE;
297 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> key to long » size"), DLT_INT(keySize), DLT_INT(DbKeySize) );
298 write_size = EPERS_DB_KEY_SIZE;
303 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
304 write_size = EPERS_NOPRCTABLE;
307 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
309 int idx = custom_client_name_to_id(dbPath, 1);
310 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
312 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
314 char pathKeyString[128];
315 snprintf(pathKeyString, 128, "%s/%s", dbPath, key);
316 write_size = gPersCustomFuncs[idx].custom_plugin_set_data(pathKeyString, (char*)buffer, buffer_size);
319 write_size = gPersCustomFuncs[idx].custom_plugin_set_data(info->configKey.customID, (char*)buffer, buffer_size);
323 write_size = EPERS_NOPLUGINFUNCT;
331 int pers_db_get_key_size(char* dbPath, char* key, PersistenceInfo_s* info)
335 if( PersistenceStorage_shared == info->configKey.storage
336 || PersistenceStorage_local == info->configKey.storage)
339 itzam_btree* btree = NULL;
340 itzam_state state = ITZAM_FAILED;
341 KeyValuePair_s search;
343 btree = pers_db_open(info, dbPath);
346 keySize = (int)strlen((const char*)key);
347 if(keySize < DbKeySize)
349 memset(search.m_key,0, DbKeySize);
350 memcpy(search.m_key, key, keySize);
351 if(itzam_true == itzam_btree_find(btree, key, &search))
353 read_size = search.m_data_size;
357 read_size = EPERS_NOKEY;
362 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
363 read_size = EPERS_DB_KEY_SIZE;
368 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> no config table"), DLT_STRING(dbPath), DLT_STRING(key));
369 read_size = EPERS_NOPRCTABLE;
372 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
374 int idx = custom_client_name_to_id(dbPath, 1);
375 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
377 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
379 char pathKeyString[128];
380 snprintf(pathKeyString, 128, "%s/%s", dbPath, key);
381 read_size = gPersCustomFuncs[idx].custom_plugin_get_size(pathKeyString);
384 read_size = gPersCustomFuncs[idx].custom_plugin_get_size(info->configKey.customID);
388 read_size = EPERS_NOPLUGINFUNCT;
396 int pers_db_delete_key(char* dbPath, char* key, PersistenceInfo_s* info)
399 if(PersistenceStorage_custom != info->configKey.storage)
401 itzam_btree* btree = NULL;
402 KeyValuePair_s delete;
404 //printf("delete_key_from_table_itzam => Path: \"%s\" | key: \"%s\" \n", dbPath, key);
405 btree = pers_db_open(info, dbPath);
409 keySize = (int)strlen((const char*)key);
410 if(keySize < DbKeySize)
412 // -----------------------------------------------------------------------------
414 itzam_btree_transaction_start(btree);
418 memset(delete.m_key,0, DbKeySize);
419 memcpy(delete.m_key, key, keySize);
420 state = itzam_btree_remove(btree, (const void *)&delete);
421 if (state != ITZAM_OKAY)
423 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> itzam_btree_remove => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
424 ret = EPERS_DB_ERROR_INTERNAL;
426 itzam_btree_transaction_commit(btree);
428 // -----------------------------------------------------------------------------
430 if(PersistenceStorage_shared == info->configKey.storage)
432 pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
437 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
438 ret = EPERS_DB_KEY_SIZE;
443 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
444 ret = EPERS_NOPRCTABLE;
447 else // custom storage implementation via custom library
449 int idx = custom_client_name_to_id(dbPath, 1);
450 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data != NULL) )
452 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
454 char pathKeyString[128];
455 snprintf(pathKeyString, 128, "%s/%s", dbPath, key);
456 ret = gPersCustomFuncs[idx].custom_plugin_delete_data(pathKeyString);
459 ret = gPersCustomFuncs[idx].custom_plugin_delete_data(info->configKey.customID);
463 ret = EPERS_NOPLUGINFUNCT;
470 int persistence_reg_notify_on_change(char* dbPath, char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no,
471 pclChangeNotifyCallback_t callback)
475 dbus_error_init (&error);
476 char ruleChanged[DbusMatchRuleSize];
477 char ruleDeleted[DbusMatchRuleSize];
480 gChangeNotifyCallback = callback;
482 // add match for c h a n g e
483 snprintf(ruleChanged, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResChange',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
484 key, ldbid, user_no, seat_no);
485 dbus_bus_add_match(get_dbus_connection(), ruleChanged, &error);
488 // add match for d e l e t e
489 snprintf(ruleDeleted, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResDelete',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
490 key, ldbid, user_no, seat_no);
491 dbus_bus_add_match(get_dbus_connection(), ruleDeleted, &error);
494 // add match for c r e a t e
495 snprintf(ruleDeleted, DbusMatchRuleSize, "type='signal',interface='org.genivi.persistence.adminconsumer',member='PersistenceResCreate',path='/org/genivi/persistence/adminconsumer',arg0='%s',arg1='%u',arg2='%u',arg3='%u'",
496 key, ldbid, user_no, seat_no);
497 dbus_bus_add_match(get_dbus_connection(), ruleDeleted, &error);
503 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, pclNotifyStatus_e reason)
505 DBusMessage* message;
508 char ldbid_array[DbusSubMatchSize];
509 char user_array[DbusSubMatchSize];
510 char seat_array[DbusSubMatchSize];
511 const char* ldbid_ptr = ldbid_array;
512 const char* user_ptr = user_array;
513 const char* seat_ptr = seat_array;
515 char* changeSignal = "PersistenceResChange";
516 char* deleteSignal = "PersistenceResDelete";
517 char* createSignal = "PersistenceResCreate";
518 char* theReason = NULL;
520 DBusConnection* conn = get_dbus_connection();
522 memset(ldbid_array, 0, DbusSubMatchSize);
523 memset(user_array, 0, DbusSubMatchSize);
524 memset(seat_array, 0, DbusSubMatchSize);
527 // dbus_bus_add_match is used for the notification mechanism,
528 // and this works only for type DBUS_TYPE_STRING as message arguments
529 // this is the reason to use string instead of integer types directly
530 snprintf(ldbid_array, DbusSubMatchSize, "%d", context->ldbid);
531 snprintf(user_array, DbusSubMatchSize, "%d", context->user_no);
532 snprintf(seat_array, DbusSubMatchSize, "%d", context->seat_no);
536 case pclNotifyStatus_deleted:
537 theReason = deleteSignal;
539 case pclNotifyStatus_created:
540 theReason = createSignal;
542 case pclNotifyStatus_changed:
543 theReason = changeSignal;
546 theReason = changeSignal;
550 if(theReason != NULL)
552 message = dbus_message_new_signal("/org/genivi/persistence/adminconsumer", // const char *path,
553 "org.genivi.persistence.adminconsumer", // const char *interface,
554 theReason); // const char *name
556 ret = dbus_message_append_args(message,
557 DBUS_TYPE_STRING, &key,
558 DBUS_TYPE_STRING, &ldbid_ptr,
559 DBUS_TYPE_STRING, &user_ptr,
560 DBUS_TYPE_STRING, &seat_ptr,
567 if(dbus_connection_send(conn, message, 0) == TRUE)
569 // Free the signal now we have finished with it
570 dbus_message_unref(message);
574 rval = EPERS_NOTIFY_SIG;
579 printf("pers_send_Notification_Signal ==> E R R O R C O N E C T I O N NULL!!\n");
580 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal ==> E R R O R C O N E C T I O N NULL!!"));
585 printf("pers_send_Notification_Signal: ERROR \n");
586 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal ==> ERROR dbus_message_append_args"));
587 rval = EPERS_NOTIFY_SIG;
592 rval = EPERS_NOTIFY_SIG;
599 //---------------------------------------------------------------------------------------------------------
600 // C U R S O R F U N C T I O N S
601 //---------------------------------------------------------------------------------------------------------
603 int get_cursor_handle()
607 if(pthread_mutex_lock(&gMtx) == 0)
609 if(gFreeCursorHandleIdxHead > 0) // check if we have a free spot in the array before the current max
611 handle = gFreeCursorHandleArray[--gFreeCursorHandleIdxHead];
615 if(gHandleIdx < MaxPersHandle-1)
617 handle = gHandleIdx++; // no free spot before current max, increment handle index
621 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_cursor_handle ==> Reached maximum of open handles:"), DLT_INT(MaxPersHandle));
625 pthread_mutex_unlock(&gMtx);
631 void close_cursor_handle(int handlerDB)
633 if(pthread_mutex_lock(&gMtx) == 0)
635 if(gFreeCursorHandleIdxHead < MaxPersHandle)
637 gFreeCursorHandleArray[gFreeCursorHandleIdxHead++] = handlerDB;
639 pthread_mutex_unlock(&gMtx);
645 int pers_db_cursor_create(char* dbPath)
648 itzam_state state = ITZAM_FAILED;
650 handle = get_cursor_handle();
652 if(handle < MaxPersHandle && handle >= 0)
655 state = itzam_btree_open(&gCursorArray[handle].m_btree, dbPath, itzam_comparator_string, error_handler, 1/*recover*/, 0/*read_only*/);
656 if (state != ITZAM_OKAY)
658 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_create ==> itzam_btree_open"), DLT_STRING(STATE_MESSAGES[state]));
664 state = itzam_btree_cursor_create(&gCursorArray[handle].m_cursor, &gCursorArray[handle].m_btree);
665 if(state == ITZAM_OKAY)
667 gCursorArray[handle].m_empty = 0;
671 gCursorArray[handle].m_empty = 1;
680 int pers_db_cursor_next(unsigned int handlerDB)
683 //if(handlerDB < MaxPersHandle && handlerDB >= 0)
684 if(handlerDB < MaxPersHandle )
686 if(gCursorArray[handlerDB].m_empty != 1)
689 success = itzam_btree_cursor_next(&gCursorArray[handlerDB].m_cursor);
691 if(success == itzam_true)
697 rval = EPERS_LAST_ENTRY_IN_DB;
702 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> invalid handle: "), DLT_INT(handlerDB));
707 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
714 int pers_db_cursor_get_key(unsigned int handlerDB, char * bufKeyName_out, int bufSize)
717 KeyValuePair_s search;
719 if(handlerDB < MaxPersHandle)
721 if(gCursorArray[handlerDB].m_empty != 1)
724 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
725 length = strlen(search.m_key);
728 memcpy(bufKeyName_out, search.m_key, length);
733 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_key ==> buffer to small » keySize: "), DLT_INT(bufSize));
738 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> invalid handle:"), DLT_INT(handlerDB));
743 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
750 int pers_db_cursor_get_data(unsigned int handlerDB, char * bufData_out, int bufSize)
753 KeyValuePair_s search;
755 if(handlerDB < MaxPersHandle)
757 if(gCursorArray[handlerDB].m_empty != 1)
760 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
762 length = strlen(search.m_data);
765 memcpy(bufData_out, search.m_data, length);
770 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data ==> buffer to small » keySize: "), DLT_INT(bufSize));
775 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> invalid handle:"), DLT_INT(handlerDB));
780 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
787 int pers_db_cursor_get_data_size(unsigned int handlerDB)
790 KeyValuePair_s search;
792 if(handlerDB < MaxPersHandle)
794 if(gCursorArray[handlerDB].m_empty != 1)
796 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
797 size = strlen(search.m_data);
801 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data_size ==> invalid handle:"), DLT_INT(handlerDB));
806 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
813 int pers_db_cursor_destroy(unsigned int handlerDB)
816 if(handlerDB < MaxPersHandle)
818 itzam_btree_cursor_free(&gCursorArray[handlerDB].m_cursor);
819 gCursorArray[handlerDB].m_empty = 1;
821 itzam_state state = ITZAM_FAILED;
822 state = itzam_btree_close(&gCursorArray[handlerDB].m_btree);
823 if (state != ITZAM_OKAY)
825 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_destroy ==> itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
828 close_cursor_handle(handlerDB);
838 //-----------------------------------------------------------------------------
839 // code to print database content (for debugging)
840 //-----------------------------------------------------------------------------
844 itzam_btree_cursor cursor;
845 state = itzam_btree_cursor_create(&cursor, &btree);
846 if(state == ITZAM_OKAY)
848 printf("==> Database content ==> db size: %d\n", (int)itzam_btree_count(&btree));
851 // get the key pointed to by the cursor
852 state = itzam_btree_cursor_read(&cursor,(void *)&rec);
853 if (state == ITZAM_OKAY)
855 printf(" Key: %s \n ==> data: %s\n", rec.m_key, rec.m_data);
858 fprintf(stderr, "\nItzam problem: %s\n", STATE_MESSAGES[state]);
860 while (itzam_btree_cursor_next(&cursor));
862 state = itzam_btree_cursor_free(&cursor);
865 //-----------------------------------------------------------------------------