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"
24 #include "persistence_client_library_prct_access.h"
26 #include "persistence_client_library_dbus_service.h"
28 #include <dbus/dbus.h>
35 /// definition of a key-value pair stored in the database
36 typedef struct _KeyValuePair_s
38 char m_key[DbKeySize]; /// the key
39 char m_data[DbValueSize]; /// the data
40 unsigned int m_data_size; /// the size of the data
45 // definition of a cursor entry
46 typedef struct _CursorEntry_s
48 itzam_btree_cursor m_cursor;
54 // cursor array handle
55 CursorEntry_s gCursorArray[MaxPersHandle];
58 static int gHandleIdx = 1;
61 int gFreeCursorHandleArray[MaxPersHandle];
63 int gFreeCursorHandleIdxHead = 0;
65 // mutex to controll access to the cursor array
66 pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
70 static itzam_btree gBtree[DbTableSize][PersistencePolicy_LastEntry];
71 static int gBtreeCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
75 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, unsigned int reason);
76 int pers_get_default_data(char* dbPath, char* key, unsigned char* buffer, unsigned int buffer_size);
81 int pers_db_open_default(itzam_btree* btree, const char* dbPath, int configDefault)
83 itzam_state state = ITZAM_FAILED;
84 char path[DbPathMaxLen] = {0};
86 if(1 == configDefault)
88 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gConfigDefault);
90 else if(0 == configDefault)
92 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gDefault);
99 state = itzam_btree_open(btree, path, itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
100 if (state != ITZAM_OKAY)
102 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open_default ==> itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
109 itzam_btree* pers_db_open(PersistenceInfo_s* info, const char* dbPath)
112 itzam_btree* btree = NULL;
114 // create array index: index is a combination of resource config table type and group
115 arrayIdx = info->configKey.storage + info->context.ldbid;
117 //if(arrayIdx <= DbTableSize)
118 if(arrayIdx < DbTableSize)
120 if(gBtreeCreated[arrayIdx][info->configKey.policy] == 0)
122 itzam_state state = ITZAM_FAILED;
123 char path[DbPathMaxLen] = {0};
125 if(PersistencePolicy_wt == info->configKey.policy)
127 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gWt);
129 else if(PersistencePolicy_wc == info->configKey.policy)
131 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gCached);
138 state = itzam_btree_open(&gBtree[arrayIdx][info->configKey.policy], path,
139 itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
140 if (state != ITZAM_OKAY)
142 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
144 gBtreeCreated[arrayIdx][info->configKey.policy] = 1;
147 btree = &gBtree[arrayIdx][info->configKey.policy];
151 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> invalid storage type"), DLT_STRING(dbPath));
158 void pers_db_close(PersistenceInfo_s* info)
160 int arrayIdx = info->configKey.storage + info->context.ldbid;
162 if(info->configKey.storage <= PersistenceStorage_shared )
164 itzam_state state = ITZAM_FAILED;
165 state = itzam_btree_close(&gBtree[arrayIdx][info->configKey.policy]);
166 if (state != ITZAM_OKAY)
168 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
170 gBtreeCreated[arrayIdx][info->configKey.policy] = 0;
174 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> invalid storage type"), DLT_INT(info->context.ldbid ));
180 void pers_db_close_all()
184 for(i=0; i<DbTableSize; i++)
186 // close write cached database
187 if(gBtreeCreated[i][PersistencePolicy_wc] == 1)
189 itzam_state state = ITZAM_FAILED;
190 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wc]);
191 if (state != ITZAM_OKAY)
193 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==> itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]) );
195 gBtreeCreated[i][PersistencePolicy_wc] = 0;
198 // close write through database
199 if(gBtreeCreated[i][PersistencePolicy_wt] == 1)
201 itzam_state state = ITZAM_FAILED;
202 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wt]);
203 if (state != ITZAM_OKAY)
205 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==>itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]));
207 gBtreeCreated[i][PersistencePolicy_wt] = 0;
213 void pers_rct_close_all()
216 itzam_btree* resourceTable = NULL;
217 itzam_state state = ITZAM_FAILED;
219 // close open persistence resource configuration table
220 for(i=0; i< PrctDbTableSize; i++)
222 resourceTable = (itzam_btree*)get_resource_cfg_table_by_idx(i);
223 // dereference opend database
224 if(resourceTable != NULL && get_resource_cfg_table_status(i) == 1)
226 state = itzam_btree_close(resourceTable);
227 invalidate_resource_cfg_table(i);
228 if (state != ITZAM_OKAY)
230 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
236 int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
240 if( PersistenceStorage_shared == info->configKey.storage
241 || PersistenceStorage_local == info->configKey.storage)
243 itzam_btree* btree = NULL;
246 btree = pers_db_open(info, dbPath);
249 KeyValuePair_s search;
251 if(itzam_true == itzam_btree_find(btree, key, &search))
253 read_size = search.m_data_size;
254 if(read_size > buffer_size)
256 read_size = buffer_size; // truncate data size to buffer size
258 memcpy(buffer, search.m_data, read_size);
262 if(keyFound == 0) // check for default values.
264 read_size = pers_get_default_data(dbPath, key, buffer, buffer_size);
267 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
269 int idx = custom_client_name_to_id(dbPath, 1);
270 char workaroundPath[128]; // workaround, because /sys/ can not be accessed on host!!!!
271 snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath );
273 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_data != NULL) )
275 char pathKeyString[128] = {0};
276 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
278 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
282 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
284 read_size = gPersCustomFuncs[idx].custom_plugin_get_data(pathKeyString, (char*)buffer, buffer_size);
286 if(read_size < 0) // check if for custom storage default values are available
288 read_size = pers_get_default_data(dbPath, key, buffer, buffer_size);
293 read_size = EPERS_NOPLUGINFUNCT;
301 int pers_get_default_data(char* dbPath, char* key, unsigned char* buffer, unsigned int buffer_size)
305 KeyValuePair_s search;
307 itzam_state state = ITZAM_FAILED;
308 itzam_btree btreeConfDefault;
309 itzam_btree btreeDefault;
311 // 1. check if _configurable_ default data is available
312 // --------------------------------
313 if(pers_db_open_default(&btreeConfDefault, dbPath, 1) != -1)
315 if(itzam_true == itzam_btree_find(&btreeConfDefault, key, &search)) // read db
317 read_size = search.m_data_size;
318 if(read_size > buffer_size)
320 read_size = buffer_size; // truncate data size to buffer size
322 memcpy(buffer, search.m_data, read_size);
328 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> 2. resource not found in default config => search in default db"), DLT_STRING(key));
331 state = itzam_btree_close(&btreeConfDefault);
332 if (state != ITZAM_OKAY)
334 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> default: itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
338 // 2. check if default data is available
339 // --------------------------------
342 if(pers_db_open_default(&btreeDefault, dbPath, 0) != -1)
344 if(itzam_true == itzam_btree_find(&btreeDefault, key, &search)) // read db
346 read_size = search.m_data_size;
347 if(read_size > buffer_size)
349 read_size = buffer_size; // truncate data size to buffer size
351 memcpy(buffer, search.m_data, read_size);
355 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> 3. reasoure not found in both default db's"), DLT_STRING(key) );
356 read_size = EPERS_NOKEY; // the key is not available neither in regular db nor in the default db's
359 state = itzam_btree_close(&btreeDefault);
360 if (state != ITZAM_OKAY)
362 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> default: itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
367 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==>no resource config table"), DLT_STRING(dbPath), DLT_STRING(key) );
368 read_size = EPERS_NOPRCTABLE;
376 int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
380 if( PersistenceStorage_local == info->configKey.storage
381 || PersistenceStorage_shared == info->configKey.storage )
383 write_size = buffer_size;
384 itzam_btree* btree = NULL;
385 itzam_state state = ITZAM_FAILED;
386 KeyValuePair_s insert;
388 btree = pers_db_open(info, dbPath);
392 keySize = (int)strlen((const char*)key);
393 if(keySize < DbKeySize)
396 dataSize = (int)strlen( (const char*)buffer);
397 if(dataSize < DbValueSize)
399 // -----------------------------------------------------------------------------
401 // itzam_btree_transaction_start(btree);
404 memset(insert.m_key, 0, DbKeySize);
405 memcpy(insert.m_key, key, keySize);
406 if(itzam_true == itzam_btree_find(btree, key, &insert))
408 // key already available, so delete "old" key
409 state = itzam_btree_remove(btree, (const void *)&insert);
413 memset(insert.m_data, 0, DbValueSize);
414 memcpy(insert.m_data, buffer, dataSize);
417 insert.m_data_size = buffer_size;
419 state = itzam_btree_insert(btree,(const void *)&insert);
420 if (state != ITZAM_OKAY)
422 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> itzam_btree_insert => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]) );
423 write_size = EPERS_DB_ERROR_INTERNAL;
426 // itzam_btree_transaction_commit(btree);
428 // -----------------------------------------------------------------------------
430 if(PersistenceStorage_shared == info->configKey.storage)
432 int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
435 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> failed to send notification signal"));
442 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> data to long » size:"), DLT_INT(dataSize), DLT_INT(DbValueSize) );
443 write_size = EPERS_DB_VALUE_SIZE;
448 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> key to long » size"), DLT_INT(keySize), DLT_INT(DbKeySize) );
449 write_size = EPERS_DB_KEY_SIZE;
454 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
455 write_size = EPERS_NOPRCTABLE;
458 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
460 int idx = custom_client_name_to_id(dbPath, 1);
461 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_set_data != NULL) )
463 char pathKeyString[128] = {0};
464 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
466 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
470 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
472 write_size = gPersCustomFuncs[idx].custom_plugin_set_data(pathKeyString, (char*)buffer, buffer_size);
474 if(write_size >= 0) // success ==> send deleted notification
476 int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
479 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> failed to send notification signal"));
486 write_size = EPERS_NOPLUGINFUNCT;
494 int pers_db_get_key_size(char* dbPath, char* key, PersistenceInfo_s* info)
498 if( PersistenceStorage_shared == info->configKey.storage
499 || PersistenceStorage_local == info->configKey.storage)
502 itzam_btree* btree = NULL;
503 KeyValuePair_s search;
505 btree = pers_db_open(info, dbPath);
508 keySize = (int)strlen((const char*)key);
509 if(keySize < DbKeySize)
511 memset(search.m_key,0, DbKeySize);
512 memcpy(search.m_key, key, keySize);
513 if(itzam_true == itzam_btree_find(btree, key, &search))
515 read_size = search.m_data_size;
519 read_size = EPERS_NOKEY;
524 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
525 read_size = EPERS_DB_KEY_SIZE;
530 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> no config table"), DLT_STRING(dbPath), DLT_STRING(key));
531 read_size = EPERS_NOPRCTABLE;
534 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
536 int idx = custom_client_name_to_id(dbPath, 1);
537 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
539 char pathKeyString[128] = {0};
540 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
542 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
546 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
548 read_size = gPersCustomFuncs[idx].custom_plugin_get_size(pathKeyString);
552 read_size = EPERS_NOPLUGINFUNCT;
560 int pers_db_delete_key(char* dbPath, char* key, PersistenceInfo_s* info)
563 if(PersistenceStorage_custom != info->configKey.storage)
565 itzam_btree* btree = NULL;
566 KeyValuePair_s delete;
568 btree = pers_db_open(info, dbPath);
572 keySize = (int)strlen((const char*)key);
573 if(keySize < DbKeySize)
575 // -----------------------------------------------------------------------------
577 itzam_btree_transaction_start(btree);
581 memset(delete.m_key,0, DbKeySize);
582 memcpy(delete.m_key, key, keySize);
583 state = itzam_btree_remove(btree, (const void *)&delete);
584 if (state != ITZAM_OKAY)
586 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> itzam_btree_remove => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
587 ret = EPERS_DB_ERROR_INTERNAL;
589 itzam_btree_transaction_commit(btree);
591 // -----------------------------------------------------------------------------
593 if(PersistenceStorage_shared == info->configKey.storage)
595 ret = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
600 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
601 ret = EPERS_DB_KEY_SIZE;
606 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
607 ret = EPERS_NOPRCTABLE;
610 else // custom storage implementation via custom library
612 int idx = custom_client_name_to_id(dbPath, 1);
613 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_delete_data != NULL) )
615 char pathKeyString[128] = {0};
616 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
618 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
622 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
624 ret = gPersCustomFuncs[idx].custom_plugin_delete_data(pathKeyString);
625 if(ret >= 0) // success ==> send deleted notification
627 ret = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
632 ret = EPERS_NOPLUGINFUNCT;
639 int persistence_notify_on_change(char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no,
640 pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
644 if(regPolicy < Notify_lastEntry)
646 snprintf(gNotifykey, DbKeyMaxLen, "%s", key);
647 gNotifyLdbid = ldbid; // to do: pass correct ==> JUST TESTING!!!!
648 gNotifyUserNo = user_no;
649 gNotifySeatNo = seat_no;
650 gNotifyReason = regPolicy;
652 if(regPolicy == Notify_register)
655 gChangeNotifyCallback = callback;
657 else if(regPolicy == Notify_unregister)
660 gChangeNotifyCallback = NULL;
663 if(-1 == deliverToMainloop(CMD_REG_NOTIFY_SIGNAL, 0, 0))
665 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_notify_on_change => failed to write to pipe"), DLT_INT(errno));
682 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, pclNotifyStatus_e reason)
685 if(reason < pclNotifyStatus_lastEntry)
687 snprintf(gNotifykey, DbKeyMaxLen, "%s", key);
689 gNotifyLdbid = context->ldbid; // to do: pass correct ==> JUST TESTING!!!!
690 gNotifyUserNo = context->user_no;
691 gNotifySeatNo = context->seat_no;
692 gNotifyReason = reason;
694 if(-1 == deliverToMainloop(CMD_SEND_NOTIFY_SIGNAL, 0,0) )
696 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal => failed to write to pipe"), DLT_INT(errno));
697 rval = EPERS_NOTIFY_SIG;
702 rval = EPERS_NOTIFY_SIG;
709 //---------------------------------------------------------------------------------------------------------
710 // C U R S O R F U N C T I O N S
711 //---------------------------------------------------------------------------------------------------------
713 int get_cursor_handle()
717 if(pthread_mutex_lock(&gMtx) == 0)
719 if(gFreeCursorHandleIdxHead > 0) // check if we have a free spot in the array before the current max
721 handle = gFreeCursorHandleArray[--gFreeCursorHandleIdxHead];
725 if(gHandleIdx < MaxPersHandle-1)
727 handle = gHandleIdx++; // no free spot before current max, increment handle index
731 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_cursor_handle ==> Reached maximum of open handles:"), DLT_INT(MaxPersHandle));
735 pthread_mutex_unlock(&gMtx);
741 void close_cursor_handle(int handlerDB)
743 if(pthread_mutex_lock(&gMtx) == 0)
745 if(gFreeCursorHandleIdxHead < MaxPersHandle)
747 gFreeCursorHandleArray[gFreeCursorHandleIdxHead++] = handlerDB;
749 pthread_mutex_unlock(&gMtx);
755 int pers_db_cursor_create(char* dbPath)
758 itzam_state state = ITZAM_FAILED;
760 handle = get_cursor_handle();
762 if(handle < MaxPersHandle && handle >= 0)
765 state = itzam_btree_open(&gCursorArray[handle].m_btree, dbPath, itzam_comparator_string, error_handler, 1/*recover*/, 0/*read_only*/);
766 if (state != ITZAM_OKAY)
768 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_create ==> itzam_btree_open"), DLT_STRING(STATE_MESSAGES[state]));
774 state = itzam_btree_cursor_create(&gCursorArray[handle].m_cursor, &gCursorArray[handle].m_btree);
775 if(state == ITZAM_OKAY)
777 gCursorArray[handle].m_empty = 0;
781 gCursorArray[handle].m_empty = 1;
790 int pers_db_cursor_next(unsigned int handlerDB)
794 //if(handlerDB < MaxPersHandle && handlerDB >= 0)
795 if(handlerDB < MaxPersHandle )
797 if(gCursorArray[handlerDB].m_empty != 1)
800 success = itzam_btree_cursor_next(&gCursorArray[handlerDB].m_cursor);
802 if(success == itzam_true)
808 rval = EPERS_LAST_ENTRY_IN_DB;
813 printf("Invalid handle\n");
814 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> invalid handle: "), DLT_INT(handlerDB));
819 printf("Handle bigger than max\n");
820 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
827 int pers_db_cursor_get_key(unsigned int handlerDB, char * bufKeyName_out, int bufSize)
830 KeyValuePair_s search;
832 if(handlerDB < MaxPersHandle)
834 if(gCursorArray[handlerDB].m_empty != 1)
837 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
838 length = strlen(search.m_key);
841 memcpy(bufKeyName_out, search.m_key, length);
846 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_key ==> buffer to small » keySize: "), DLT_INT(bufSize));
851 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> invalid handle:"), DLT_INT(handlerDB));
856 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
863 int pers_db_cursor_get_data(unsigned int handlerDB, char * bufData_out, int bufSize)
866 KeyValuePair_s search;
868 if(handlerDB < MaxPersHandle)
870 if(gCursorArray[handlerDB].m_empty != 1)
873 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
875 length = strlen(search.m_data);
878 memcpy(bufData_out, search.m_data, length);
883 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data ==> buffer to small » keySize: "), DLT_INT(bufSize));
888 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> invalid handle:"), DLT_INT(handlerDB));
893 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
900 int pers_db_cursor_get_data_size(unsigned int handlerDB)
903 KeyValuePair_s search;
905 if(handlerDB < MaxPersHandle)
907 if(gCursorArray[handlerDB].m_empty != 1)
909 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
910 size = strlen(search.m_data);
914 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data_size ==> invalid handle:"), DLT_INT(handlerDB));
919 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
926 int pers_db_cursor_destroy(unsigned int handlerDB)
929 if(handlerDB < MaxPersHandle)
931 itzam_btree_cursor_free(&gCursorArray[handlerDB].m_cursor);
932 gCursorArray[handlerDB].m_empty = 1;
934 itzam_state state = ITZAM_FAILED;
935 state = itzam_btree_close(&gCursorArray[handlerDB].m_btree);
936 if (state != ITZAM_OKAY)
938 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_destroy ==> itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
941 close_cursor_handle(handlerDB);
951 //-----------------------------------------------------------------------------
952 // code to print database content (for debugging)
953 //-----------------------------------------------------------------------------
957 itzam_btree_cursor cursor;
958 state = itzam_btree_cursor_create(&cursor, &btree);
959 if(state == ITZAM_OKAY)
961 printf("==> Database content ==> db size: %d\n", (int)itzam_btree_count(&btree));
964 // get the key pointed to by the cursor
965 state = itzam_btree_cursor_read(&cursor,(void *)&rec);
966 if (state == ITZAM_OKAY)
968 printf(" Key: %s \n ==> data: %s\n", rec.m_key, rec.m_data);
971 fprintf(stderr, "\nItzam problem: %s\n", STATE_MESSAGES[state]);
973 while (itzam_btree_cursor_next(&cursor));
975 state = itzam_btree_cursor_free(&cursor);
978 //-----------------------------------------------------------------------------