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>
34 /// definition of a key-value pair stored in the database
35 typedef struct _KeyValuePair_s
37 char m_key[DbKeySize]; /// the key
38 char m_data[DbValueSize]; /// the data
39 unsigned int m_data_size; /// the size of the data
44 // definition of a cursor entry
45 typedef struct _CursorEntry_s
47 itzam_btree_cursor m_cursor;
53 // cursor array handle
54 CursorEntry_s gCursorArray[MaxPersHandle];
57 static int gHandleIdx = 1;
60 int gFreeCursorHandleArray[MaxPersHandle];
62 int gFreeCursorHandleIdxHead = 0;
64 // mutex to controll access to the cursor array
65 pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
69 static itzam_btree gBtree[DbTableSize][PersistencePolicy_LastEntry];
70 static int gBtreeCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
74 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, unsigned int reason);
75 int pers_get_default_data(char* dbPath, char* key, char* buffer, unsigned int buffer_size);
80 int pers_db_open_default(itzam_btree* btree, const char* dbPath, int configDefault)
82 itzam_state state = ITZAM_FAILED;
83 char path[DbPathMaxLen] = {0};
85 if(1 == configDefault)
87 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gConfigDefault);
89 else if(0 == configDefault)
91 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gDefault);
98 state = itzam_btree_open(btree, path, itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
99 if (state != ITZAM_OKAY)
101 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open_default ==> itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
108 itzam_btree* pers_db_open(PersistenceInfo_s* info, const char* dbPath)
111 itzam_btree* btree = NULL;
113 // create array index: index is a combination of resource config table type and group
114 arrayIdx = info->configKey.storage + info->context.ldbid;
116 //if(arrayIdx <= DbTableSize)
117 if(arrayIdx < DbTableSize)
119 if(gBtreeCreated[arrayIdx][info->configKey.policy] == 0)
121 itzam_state state = ITZAM_FAILED;
122 char path[DbPathMaxLen] = {0};
124 if(PersistencePolicy_wt == info->configKey.policy)
126 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gWt);
128 else if(PersistencePolicy_wc == info->configKey.policy)
130 snprintf(path, DbPathMaxLen, "%s%s", dbPath, gCached);
137 state = itzam_btree_open(&gBtree[arrayIdx][info->configKey.policy], path,
138 itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
139 if (state != ITZAM_OKAY)
141 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
143 gBtreeCreated[arrayIdx][info->configKey.policy] = 1;
146 btree = &gBtree[arrayIdx][info->configKey.policy];
150 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open ==> invalid storage type"), DLT_STRING(dbPath));
157 void pers_db_close(PersistenceInfo_s* info)
159 int arrayIdx = info->configKey.storage + info->context.ldbid;
161 if(info->configKey.storage <= PersistenceStorage_shared )
163 itzam_state state = ITZAM_FAILED;
164 state = itzam_btree_close(&gBtree[arrayIdx][info->configKey.policy]);
165 if (state != ITZAM_OKAY)
167 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
169 gBtreeCreated[arrayIdx][info->configKey.policy] = 0;
173 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close ==> invalid storage type"), DLT_INT(info->context.ldbid ));
179 void pers_db_close_all()
183 for(i=0; i<DbTableSize; i++)
185 // close write cached database
186 if(gBtreeCreated[i][PersistencePolicy_wc] == 1)
188 itzam_state state = ITZAM_FAILED;
189 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wc]);
190 if (state != ITZAM_OKAY)
192 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==> itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]) );
194 gBtreeCreated[i][PersistencePolicy_wc] = 0;
197 // close write through database
198 if(gBtreeCreated[i][PersistencePolicy_wt] == 1)
200 itzam_state state = ITZAM_FAILED;
201 state = itzam_btree_close(&gBtree[i][PersistencePolicy_wt]);
202 if (state != ITZAM_OKAY)
204 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_close_all ==>itzam_btree_close => Itzam problem:"), DLT_STRING(STATE_MESSAGES[state]));
206 gBtreeCreated[i][PersistencePolicy_wt] = 0;
212 int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
216 if( PersistenceStorage_shared == info->configKey.storage
217 || PersistenceStorage_local == info->configKey.storage)
219 itzam_btree* btree = NULL;
221 itzam_state state = ITZAM_FAILED;
223 btree = pers_db_open(info, dbPath);
226 KeyValuePair_s search;
228 if(itzam_true == itzam_btree_find(btree, key, &search))
230 read_size = search.m_data_size;
231 if(read_size > buffer_size)
233 read_size = buffer_size; // truncate data size to buffer size
235 memcpy(buffer, search.m_data, read_size);
239 if(keyFound == 0) // check for default values.
241 read_size = pers_get_default_data(dbPath, key, buffer, buffer_size);
244 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
246 int idx = custom_client_name_to_id(dbPath, 1);
247 char workaroundPath[128]; // workaround, because /sys/ can not be accessed on host!!!!
248 snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath );
250 if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_data != NULL) )
252 char pathKeyString[128] = {0};
253 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
255 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
259 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
261 read_size = gPersCustomFuncs[idx].custom_plugin_get_data(pathKeyString, (char*)buffer, buffer_size);
263 if(read_size < 0) // check if for custom storage default values are available
265 read_size = pers_get_default_data(dbPath, key, buffer, buffer_size);
270 read_size = EPERS_NOPLUGINFUNCT;
278 int pers_get_default_data(char* dbPath, char* key, char* buffer, unsigned int buffer_size)
282 KeyValuePair_s search;
284 itzam_state state = ITZAM_FAILED;
285 itzam_btree btreeConfDefault;
286 itzam_btree btreeDefault;
288 // 1. check if _configurable_ default data is available
289 // --------------------------------
290 if(pers_db_open_default(&btreeConfDefault, dbPath, 1) != -1)
292 if(itzam_true == itzam_btree_find(&btreeConfDefault, key, &search)) // read db
294 read_size = search.m_data_size;
295 if(read_size > buffer_size)
297 read_size = buffer_size; // truncate data size to buffer size
299 memcpy(buffer, search.m_data, read_size);
305 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));
308 state = itzam_btree_close(&btreeConfDefault);
309 if (state != ITZAM_OKAY)
311 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> default: itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
315 // 2. check if default data is available
316 // --------------------------------
319 if(pers_db_open_default(&btreeDefault, dbPath, 0) != -1)
321 if(itzam_true == itzam_btree_find(&btreeDefault, key, &search)) // read db
323 read_size = search.m_data_size;
324 if(read_size > buffer_size)
326 read_size = buffer_size; // truncate data size to buffer size
328 memcpy(buffer, search.m_data, read_size);
332 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> 3. reasoure not found in both default db's"), DLT_STRING(key) );
333 read_size = EPERS_NOKEY; // the key is not available neither in regular db nor in the default db's
336 state = itzam_btree_close(&btreeDefault);
337 if (state != ITZAM_OKAY)
339 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==> default: itzam_btree_close => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
344 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_read_key ==>no resource config table"), DLT_STRING(dbPath), DLT_STRING(key) );
345 read_size = EPERS_NOPRCTABLE;
353 int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
357 if( PersistenceStorage_local == info->configKey.storage
358 || PersistenceStorage_shared == info->configKey.storage )
360 write_size = buffer_size;
361 itzam_btree* btree = NULL;
362 itzam_state state = ITZAM_FAILED;
363 KeyValuePair_s insert;
365 btree = pers_db_open(info, dbPath);
369 keySize = (int)strlen((const char*)key);
370 if(keySize < DbKeySize)
373 dataSize = (int)strlen( (const char*)buffer);
374 if(dataSize < DbValueSize)
376 // -----------------------------------------------------------------------------
378 // itzam_btree_transaction_start(btree);
381 memset(insert.m_key, 0, DbKeySize);
382 memcpy(insert.m_key, key, keySize);
383 if(itzam_true == itzam_btree_find(btree, key, &insert))
385 // key already available, so delete "old" key
386 state = itzam_btree_remove(btree, (const void *)&insert);
390 memset(insert.m_data, 0, DbValueSize);
391 memcpy(insert.m_data, buffer, dataSize);
394 insert.m_data_size = buffer_size;
396 state = itzam_btree_insert(btree,(const void *)&insert);
397 if (state != ITZAM_OKAY)
399 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> itzam_btree_insert => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]) );
400 write_size = EPERS_DB_ERROR_INTERNAL;
403 // itzam_btree_transaction_commit(btree);
405 // -----------------------------------------------------------------------------
407 if(PersistenceStorage_shared == info->configKey.storage)
409 int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
412 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> failed to send notification signal"));
419 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> data to long » size:"), DLT_INT(dataSize), DLT_INT(DbValueSize) );
420 write_size = EPERS_DB_VALUE_SIZE;
425 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> key to long » size"), DLT_INT(keySize), DLT_INT(DbKeySize) );
426 write_size = EPERS_DB_KEY_SIZE;
431 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
432 write_size = EPERS_NOPRCTABLE;
435 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
437 int idx = custom_client_name_to_id(dbPath, 1);
438 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_set_data != NULL) )
440 char pathKeyString[128] = {0};
441 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
443 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
447 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
449 write_size = gPersCustomFuncs[idx].custom_plugin_set_data(pathKeyString, (char*)buffer, buffer_size);
451 if(write_size >= 0) // success ==> send deleted notification
453 int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
456 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_write_key ==> failed to send notification signal"));
463 write_size = EPERS_NOPLUGINFUNCT;
471 int pers_db_get_key_size(char* dbPath, char* key, PersistenceInfo_s* info)
475 if( PersistenceStorage_shared == info->configKey.storage
476 || PersistenceStorage_local == info->configKey.storage)
479 itzam_btree* btree = NULL;
480 KeyValuePair_s search;
482 btree = pers_db_open(info, dbPath);
485 keySize = (int)strlen((const char*)key);
486 if(keySize < DbKeySize)
488 memset(search.m_key,0, DbKeySize);
489 memcpy(search.m_key, key, keySize);
490 if(itzam_true == itzam_btree_find(btree, key, &search))
492 read_size = search.m_data_size;
496 read_size = EPERS_NOKEY;
501 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
502 read_size = EPERS_DB_KEY_SIZE;
507 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_get_key_size ==> no config table"), DLT_STRING(dbPath), DLT_STRING(key));
508 read_size = EPERS_NOPRCTABLE;
511 else if(PersistenceStorage_custom == info->configKey.storage) // custom storage implementation via custom library
513 int idx = custom_client_name_to_id(dbPath, 1);
514 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
516 char pathKeyString[128] = {0};
517 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
519 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
523 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
525 read_size = gPersCustomFuncs[idx].custom_plugin_get_size(pathKeyString);
529 read_size = EPERS_NOPLUGINFUNCT;
537 int pers_db_delete_key(char* dbPath, char* key, PersistenceInfo_s* info)
540 if(PersistenceStorage_custom != info->configKey.storage)
542 itzam_btree* btree = NULL;
543 KeyValuePair_s delete;
545 btree = pers_db_open(info, dbPath);
549 keySize = (int)strlen((const char*)key);
550 if(keySize < DbKeySize)
552 // -----------------------------------------------------------------------------
554 itzam_btree_transaction_start(btree);
558 memset(delete.m_key,0, DbKeySize);
559 memcpy(delete.m_key, key, keySize);
560 state = itzam_btree_remove(btree, (const void *)&delete);
561 if (state != ITZAM_OKAY)
563 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> itzam_btree_remove => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
564 ret = EPERS_DB_ERROR_INTERNAL;
566 itzam_btree_transaction_commit(btree);
568 // -----------------------------------------------------------------------------
570 if(PersistenceStorage_shared == info->configKey.storage)
572 ret = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
577 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> key to long"), DLT_INT(keySize), DLT_INT(DbKeySize));
578 ret = EPERS_DB_KEY_SIZE;
583 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_delete_key ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
584 ret = EPERS_NOPRCTABLE;
587 else // custom storage implementation via custom library
589 int idx = custom_client_name_to_id(dbPath, 1);
590 if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_delete_data != NULL) )
592 char pathKeyString[128] = {0};
593 if(info->configKey.customID[0] == '\0') // if we have not a customID we use the key
595 snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
599 snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
601 ret = gPersCustomFuncs[idx].custom_plugin_delete_data(pathKeyString);
602 if(ret >= 0) // success ==> send deleted notification
604 ret = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
609 ret = EPERS_NOPLUGINFUNCT;
616 int persistence_notify_on_change(char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no,
617 pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
621 if(regPolicy < Notify_lastEntry)
623 snprintf(gNotifykey, DbKeyMaxLen, "%s", key);
624 gNotifyLdbid = ldbid; // to do: pass correct ==> JUST TESTING!!!!
625 gNotifyUserNo = user_no;
626 gNotifySeatNo = seat_no;
627 gNotifyReason = regPolicy;
629 if(regPolicy == Notify_register)
632 gChangeNotifyCallback = callback;
634 else if(regPolicy == Notify_unregister)
637 gChangeNotifyCallback = NULL;
640 if(-1 == deliverToMainloop(CMD_REG_NOTIFY_SIGNAL, 0, 0))
642 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_notify_on_change => failed to write to pipe"), DLT_INT(errno));
659 int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, pclNotifyStatus_e reason)
662 if(reason < pclNotifyStatus_lastEntry)
664 snprintf(gNotifykey, DbKeyMaxLen, "%s", key);
666 gNotifyLdbid = context->ldbid; // to do: pass correct ==> JUST TESTING!!!!
667 gNotifyUserNo = context->user_no;
668 gNotifySeatNo = context->seat_no;
669 gNotifyReason = reason;
671 if(-1 == deliverToMainloop(CMD_SEND_NOTIFY_SIGNAL, 0,0) )
673 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal => failed to write to pipe"), DLT_INT(errno));
674 rval = EPERS_NOTIFY_SIG;
679 rval = EPERS_NOTIFY_SIG;
686 //---------------------------------------------------------------------------------------------------------
687 // C U R S O R F U N C T I O N S
688 //---------------------------------------------------------------------------------------------------------
690 int get_cursor_handle()
694 if(pthread_mutex_lock(&gMtx) == 0)
696 if(gFreeCursorHandleIdxHead > 0) // check if we have a free spot in the array before the current max
698 handle = gFreeCursorHandleArray[--gFreeCursorHandleIdxHead];
702 if(gHandleIdx < MaxPersHandle-1)
704 handle = gHandleIdx++; // no free spot before current max, increment handle index
708 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_cursor_handle ==> Reached maximum of open handles:"), DLT_INT(MaxPersHandle));
712 pthread_mutex_unlock(&gMtx);
718 void close_cursor_handle(int handlerDB)
720 if(pthread_mutex_lock(&gMtx) == 0)
722 if(gFreeCursorHandleIdxHead < MaxPersHandle)
724 gFreeCursorHandleArray[gFreeCursorHandleIdxHead++] = handlerDB;
726 pthread_mutex_unlock(&gMtx);
732 int pers_db_cursor_create(char* dbPath)
735 itzam_state state = ITZAM_FAILED;
737 handle = get_cursor_handle();
739 if(handle < MaxPersHandle && handle >= 0)
742 state = itzam_btree_open(&gCursorArray[handle].m_btree, dbPath, itzam_comparator_string, error_handler, 1/*recover*/, 0/*read_only*/);
743 if (state != ITZAM_OKAY)
745 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_create ==> itzam_btree_open"), DLT_STRING(STATE_MESSAGES[state]));
751 state = itzam_btree_cursor_create(&gCursorArray[handle].m_cursor, &gCursorArray[handle].m_btree);
752 if(state == ITZAM_OKAY)
754 gCursorArray[handle].m_empty = 0;
758 gCursorArray[handle].m_empty = 1;
767 int pers_db_cursor_next(unsigned int handlerDB)
770 //if(handlerDB < MaxPersHandle && handlerDB >= 0)
771 if(handlerDB < MaxPersHandle )
773 if(gCursorArray[handlerDB].m_empty != 1)
776 success = itzam_btree_cursor_next(&gCursorArray[handlerDB].m_cursor);
778 if(success == itzam_true)
784 rval = EPERS_LAST_ENTRY_IN_DB;
789 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> invalid handle: "), DLT_INT(handlerDB));
794 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_next ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
801 int pers_db_cursor_get_key(unsigned int handlerDB, char * bufKeyName_out, int bufSize)
804 KeyValuePair_s search;
806 if(handlerDB < MaxPersHandle)
808 if(gCursorArray[handlerDB].m_empty != 1)
811 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
812 length = strlen(search.m_key);
815 memcpy(bufKeyName_out, search.m_key, length);
820 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_key ==> buffer to small » keySize: "), DLT_INT(bufSize));
825 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> invalid handle:"), DLT_INT(handlerDB));
830 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_key ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
837 int pers_db_cursor_get_data(unsigned int handlerDB, char * bufData_out, int bufSize)
840 KeyValuePair_s search;
842 if(handlerDB < MaxPersHandle)
844 if(gCursorArray[handlerDB].m_empty != 1)
847 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
849 length = strlen(search.m_data);
852 memcpy(bufData_out, search.m_data, length);
857 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data ==> buffer to small » keySize: "), DLT_INT(bufSize));
862 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> invalid handle:"), DLT_INT(handlerDB));
867 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_db_cursor_get_data ==> handle bigger than max:"), DLT_INT(MaxPersHandle));
874 int pers_db_cursor_get_data_size(unsigned int handlerDB)
877 KeyValuePair_s search;
879 if(handlerDB < MaxPersHandle)
881 if(gCursorArray[handlerDB].m_empty != 1)
883 itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
884 size = strlen(search.m_data);
888 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_get_data_size ==> 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_destroy(unsigned int handlerDB)
903 if(handlerDB < MaxPersHandle)
905 itzam_btree_cursor_free(&gCursorArray[handlerDB].m_cursor);
906 gCursorArray[handlerDB].m_empty = 1;
908 itzam_state state = ITZAM_FAILED;
909 state = itzam_btree_close(&gCursorArray[handlerDB].m_btree);
910 if (state != ITZAM_OKAY)
912 DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_cursor_destroy ==> itzam_btree_close: Itzam problem"), DLT_STRING(STATE_MESSAGES[state]));
915 close_cursor_handle(handlerDB);
925 //-----------------------------------------------------------------------------
926 // code to print database content (for debugging)
927 //-----------------------------------------------------------------------------
931 itzam_btree_cursor cursor;
932 state = itzam_btree_cursor_create(&cursor, &btree);
933 if(state == ITZAM_OKAY)
935 printf("==> Database content ==> db size: %d\n", (int)itzam_btree_count(&btree));
938 // get the key pointed to by the cursor
939 state = itzam_btree_cursor_read(&cursor,(void *)&rec);
940 if (state == ITZAM_OKAY)
942 printf(" Key: %s \n ==> data: %s\n", rec.m_key, rec.m_data);
945 fprintf(stderr, "\nItzam problem: %s\n", STATE_MESSAGES[state]);
947 while (itzam_btree_cursor_next(&cursor));
949 state = itzam_btree_cursor_free(&cursor);
952 //-----------------------------------------------------------------------------