Fixed bug 202
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_db_access.c
index 545f005..9fde5e8 100644 (file)
  * @see            
  */
 
-#include "../include_protected/persistence_client_library_db_access.h"
-#include "../include_protected/persistence_client_library_rc_table.h"
+#include "persistence_client_library_db_access.h"
 #include "persistence_client_library_custom_loader.h"
-#include "persistence_client_library_itzam_errors.h"
+#include "persistence_client_library_dbus_service.h"
+#include "persistence_client_library_prct_access.h"
 
+#include <persComErrors.h>
+#include <persComDataOrg.h>
+#include <persComDbAccess.h>
+
+#include <dbus/dbus.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
+
+
+
+/// btree array
+static int gHandlesDB[DbTableSize][PersistencePolicy_LastEntry];
+static int gHandlesDBCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
 
 
-/// definition of a key-value pair stored in the database
-typedef struct _KeyValuePair_s
+// function prototype
+int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, unsigned int reason);
+
+
+char* pers_get_raw_key(char *key)
 {
-    char m_key[DbKeySize];       /// the key
-    char m_data[DbValueSize];    /// the data
-    unsigned int m_data_size;   /// the size of the data
+   char *temp = NULL;
+   char *rawKey = key;
+
+   temp = strrchr(key, (int)'/');
+   
+   if (NULL != temp)
+   {
+         rawKey = temp + 1;
+   }
+
+   return rawKey;
 }
-KeyValuePair_s;
 
 
-// definition of a cursor entry
-typedef struct _CursorEntry_s
+int pers_db_open_default(const char* dbPath, PersDefaultType_e DefaultType)
 {
-   itzam_btree_cursor m_cursor;
-   itzam_btree        m_btree;
-   int                m_empty;
+   int ret = 0;
+   char path[DbPathMaxLen] = {0};
+
+   if (PersDefaultType_Configurable == DefaultType)
+   {
+      snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalConfigurableDefault);
+   }
+   else if (PersDefaultType_Factory== DefaultType)
+   {
+      snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalFactoryDefault);
+   }
+   else
+   {
+      DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_db_open_default ==> unknown DefaultType"));
+      ret = EPERS_COMMON;
+   }
+
+   if (EPERS_COMMON != ret)
+   {
+      ret = persComDbOpen(path, 0);
+      if (ret < 0)
+      {
+         ret = EPERS_COMMON;
+         DLT_LOG(gPclDLTContext, DLT_LOG_WARN,
+                              DLT_STRING("pers_db_open_default() -> persComDbOpen() -> problem open db: "),
+                              DLT_STRING(path),
+                              DLT_STRING(" Code: "),
+                              DLT_INT(ret));
+      }
+   }
+
+   return ret;
 }
-CursorEntry_s;
 
-// cursor array handle
-CursorEntry_s gCursorArray[MaxPersHandle];
 
-/// handle index
-static int gHandleIdx = 1;
+int pers_get_defaults(char* dbPath, char* key, unsigned char* buffer, unsigned int buffer_size, PersGetDefault_e job)
+{
+   PersDefaultType_e i = PersDefaultType_Configurable;
+   int handleDefaultDB = -1;
+   int read_size = EPERS_NOKEY;
+
+   key = pers_get_raw_key(key); /* We need only the raw key without a prefixed '/node/' or '/user/1/seat/0' etc... */
+
+   for(i=0; i<PersDefaultType_LastEntry; i++)
+   {
+      handleDefaultDB = pers_db_open_default(dbPath, i);
+      if(handleDefaultDB >= 0)
+      {
+         if (PersGetDefault_Data == job)
+         {
+         }
+         else if (PersGetDefault_Size == job)
+         {
+            read_size = persComDbGetKeySize(handleDefaultDB, key);
+         }
+         else
+         {
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_get_defaults ==> unknown job"));
+            break;
+         }
+
+         if (0 > persComDbClose(handleDefaultDB))
+         {
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_get_defaults ==> persComDbClose returned with error"));
+         }
 
-/// free handle array
-int gFreeCursorHandleArray[MaxPersHandle];
-// free head index
-int gFreeCursorHandleIdxHead = 0;
+         if(read_size < 0) // check read_size
+         {
+            if (PersDefaultType_Configurable == i)
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Key '"),
+                                                  DLT_STRING(key),
+                                                  DLT_STRING("' not found in "),
+                                                  DLT_STRING(dbPath),
+                                                  DLT_STRING(gLocalConfigurableDefault));
+            }
+            else if (PersDefaultType_Factory == i)
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Key '"),
+                                                  DLT_STRING(key),
+                                                  DLT_STRING("' not found in "),
+                                                  DLT_STRING(dbPath),
+                                                  DLT_STRING(gLocalFactoryDefault));
+            }
+            else
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_get_defaults ==> unknown PersDefaultType: "),
+                                                   DLT_INT(i));
+            }
 
-// mutex to controll access to the cursor array
-pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
+            if(PERS_COM_ERR_NOT_FOUND == read_size)
+            {
+               read_size = EPERS_NOKEY;
+            }
+         }
+         else
+         {
+            break;
+         }
+      }
+   }
 
+   return read_size;
 
-/// btree array
-static itzam_btree gBtree[DbTableSize][PersistencePolicy_LastEntry];
-static int gBtreeCreated[DbTableSize][PersistencePolicy_LastEntry] = { {0} };
+}
 
 
-itzam_btree* pers_db_open(PersistenceInfo_s* info, const char* dbPath)
+int database_get(PersistenceInfo_s* info, const char* dbPath)
 {
    int arrayIdx = 0;
-   itzam_btree* btree = NULL;
+   int handleDB = -1;
 
    // create array index: index is a combination of resource config table type and group
    arrayIdx = info->configKey.storage + info->context.ldbid ;
@@ -77,122 +179,134 @@ itzam_btree* pers_db_open(PersistenceInfo_s* info, const char* dbPath)
    //if(arrayIdx <= DbTableSize)
    if(arrayIdx < DbTableSize)
    {
-      if(gBtreeCreated[arrayIdx][info->configKey.policy] == 0)
+      if(gHandlesDBCreated[arrayIdx][info->configKey.policy] == 0)
       {
-         itzam_state  state = ITZAM_FAILED;
-         state = itzam_btree_open(&gBtree[arrayIdx][info->configKey.policy], dbPath,
-                                  itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
-         if (state != ITZAM_OKAY)
+
+         char path[DbPathMaxLen] = {0};
+
+         if(PersistencePolicy_wt == info->configKey.policy)
+         {
+            snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalWt);
+         }
+         else if(PersistencePolicy_wc == info->configKey.policy)
+         {
+            snprintf(path, DbPathMaxLen, "%s%s", dbPath, gLocalCached);
+         }
+         else
+         {
+            handleDB = -2;
+         }
+
+         if (handleDB == -1)
+         {
+            handleDB = persComDbOpen(path, 0x01);
+            if(handleDB >= 0)
+            {
+               gHandlesDB[arrayIdx][info->configKey.policy] = handleDB ;
+               gHandlesDBCreated[arrayIdx][info->configKey.policy] = 1;
+            }
+            else
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> persComDbOpen() failed"));
+            }
+         }
+         else
          {
-            fprintf(stderr, "pers_db_open ==> Open Itzam problem: %s\n", STATE_MESSAGES[state]);
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> wrong policy! Cannot extend dbPath wit database."));
          }
-         gBtreeCreated[arrayIdx][info->configKey.policy] = 1;
       }
-      // assign database
-      btree = &gBtree[arrayIdx][info->configKey.policy];
+      else
+      {
+         handleDB = gHandlesDB[arrayIdx][info->configKey.policy];
+      }
    }
    else
    {
-      printf("btree_get ==> invalid storage type\n");
+      DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_get ==> invalid storage type"), DLT_STRING(dbPath));
    }
-   return btree;
-}
 
 
 
-void pers_db_close(PersistenceInfo_s* info)
+   return handleDB;
+}
+
+
+void database_close(PersistenceInfo_s* info)
 {
    int arrayIdx = info->configKey.storage + info->context.ldbid;
 
    if(info->configKey.storage <= PersistenceStorage_shared )
    {
-      itzam_state  state = ITZAM_FAILED;
-      state = itzam_btree_close(&gBtree[arrayIdx][info->configKey.policy]);
-      if (state != ITZAM_OKAY)
+      int iErrorCode = persComDbClose(gHandlesDB[arrayIdx][info->configKey.policy]) ;
+      if (iErrorCode < 0)
       {
-         fprintf(stderr, "pers_db_close ==> Close Itzam problem: %s\n", STATE_MESSAGES[state]);
+         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close ==> persComDbClose() failed"));
+      }
+      else
+      {
+        gHandlesDBCreated[arrayIdx][info->configKey.policy] = 0;
       }
-      gBtreeCreated[arrayIdx][info->configKey.policy] = 0;
    }
    else
    {
-      printf("pers_db_close ==> invalid storage type\n");
+      DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close ==> invalid storage type"), DLT_INT(info->context.ldbid ));
    }
 }
 
-
-
-void pers_db_close_all()
+void database_close_all()
 {
    int i = 0;
 
    for(i=0; i<DbTableSize; i++)
    {
       // close write cached database
-      if(gBtreeCreated[i][PersistencePolicy_wc] == 1)
+      if(gHandlesDBCreated[i][PersistencePolicy_wc] == 1)
       {
-         itzam_state  state = ITZAM_FAILED;
-         state = itzam_btree_close(&gBtree[i][PersistencePolicy_wc]);
-         if (state != ITZAM_OKAY)
+         int iErrorCode = persComDbClose(gHandlesDB[i][PersistencePolicy_wc]);
+         if (iErrorCode < 0)
          {
-            fprintf(stderr, "pers_db_close_all ==> Close WC: Itzam problem: %s\n", STATE_MESSAGES[state]);
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close_all => failed to close db => persComDbClose"));
+         }
+         else
+         {
+             gHandlesDBCreated[i][PersistencePolicy_wc] = 0;
          }
-         gBtreeCreated[i][PersistencePolicy_wc] = 0;
       }
 
       // close write through database
-      if(gBtreeCreated[i][PersistencePolicy_wt] == 1)
+      if(gHandlesDBCreated[i][PersistencePolicy_wt] == 1)
       {
-         itzam_state  state = ITZAM_FAILED;
-         state = itzam_btree_close(&gBtree[i][PersistencePolicy_wt]);
-         if (state != ITZAM_OKAY)
+         int iErrorCode = persComDbClose(gHandlesDB[i][PersistencePolicy_wt]);
+         if (iErrorCode < 0)
+         {
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("database_close_all => failed to close db => persComDbClose"));
+         }
+         else
          {
-            fprintf(stderr, "pers_db_close_all ==> Close WT: Itzam problem: %s\n", STATE_MESSAGES[state]);
+            gHandlesDBCreated[i][PersistencePolicy_wt] = 0;
          }
-         gBtreeCreated[i][PersistencePolicy_wt] = 0;
       }
    }
 }
 
 
 
-int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
+int persistence_get_data(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
 {
    int read_size = -1;
+   int ret_defaults = -1;
 
    if(   PersistenceStorage_shared == info->configKey.storage
       || PersistenceStorage_local == info->configKey.storage)
    {
-      itzam_btree* btree = NULL;
-      itzam_state  state = ITZAM_FAILED;
-      KeyValuePair_s search;
-
-      btree = pers_db_open(info, dbPath);
-      if(btree != NULL)
+      int handleDB = database_get(info, dbPath);
+      if(handleDB >= 0)
       {
-         if(itzam_true == itzam_btree_find(btree, key, &search))
-         {
-            read_size = search.m_data_size;
-            if(read_size > buffer_size)
-            {
-               read_size = buffer_size;   // truncate data size to buffer size
-            }
-            memcpy(buffer, search.m_data, read_size);
-         }
-         else
+         read_size = persComDbReadKey(handleDB, key, (char*)buffer, buffer_size) ;
+         if(read_size < 0)
          {
-            read_size = EPERS_NOKEY;
+            read_size = pers_get_defaults(dbPath, key, buffer, buffer_size, PersGetDefault_Data); /* 0 ==> Get data */
          }
-
-         //
-         // workaround till lifecycle is working correctly
-         //
-         pers_db_close(info);
-      }
-      else
-      {
-         read_size = EPERS_NOPRCTABLE;
-         fprintf(stderr, "\npersistence_get_data ==> Open Itzam problem: %s\n", STATE_MESSAGES[state]);
       }
    }
    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
@@ -201,95 +315,105 @@ int pers_db_read_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned
       char workaroundPath[128];  // workaround, because /sys/ can not be accessed on host!!!!
       snprintf(workaroundPath, 128, "%s%s", "/Data", dbPath  );
 
-      if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_get_data != NULL) )
+      if( (idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_data != NULL) )
       {
-         gPersCustomFuncs[idx].custom_plugin_get_data(key, (char*)buffer, buffer_size);
+         char pathKeyString[128] = {0};
+         if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
+         }
+         else
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
+         }
+         read_size = gPersCustomFuncs[idx].custom_plugin_get_data(pathKeyString, (char*)buffer, buffer_size);
       }
       else
       {
          read_size = EPERS_NOPLUGINFUNCT;
       }
+
+      if (1 > read_size)
+      {
+         info->configKey.policy = PersistencePolicy_wc;                        /* Set the policy */
+         info->configKey.type   = PersistenceResourceType_key;  /* Set the type */
+         (void)get_db_path_and_key(info, key, NULL, dbPath);
+         DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Custom Key not available. Try to get default keys from:"),
+                                            DLT_STRING(dbPath),
+                                            DLT_STRING(key));
+         ret_defaults = pers_get_defaults(dbPath, key, buffer, buffer_size, PersGetDefault_Data);
+         if (0 < ret_defaults)
+         {
+                read_size = ret_defaults;
+         }
+      }
    }
    return read_size;
 }
 
 
 
-int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
+int persistence_set_data(char* dbPath, char* key, PersistenceInfo_s* info, unsigned char* buffer, unsigned int buffer_size)
 {
    int write_size = -1;
 
-   if(   PersistenceStorage_shared == info->configKey.storage
-      || PersistenceStorage_local == info->configKey.storage)
+   if(   PersistenceStorage_local == info->configKey.storage
+      || PersistenceStorage_shared == info->configKey.storage )
    {
-      write_size = buffer_size;
-      itzam_btree* btree = NULL;
-      itzam_state  state = ITZAM_FAILED;
-      KeyValuePair_s insert;
+      int handleDB = -1 ;
+
 
-      btree = pers_db_open(info, dbPath);
-      if(btree != NULL)
+      handleDB = database_get(info, dbPath);
+      if(handleDB >= 0)
       {
-         int keySize = 0;
-         keySize = (int)strlen((const char*)key);
-         if(keySize < DbKeySize)
+         write_size = persComDbWriteKey(handleDB, key, (char*)buffer, buffer_size) ;
+         if(write_size < 0)
          {
-            int dataSize = 0;
-            dataSize = (int)strlen( (const char*)buffer);
-            if(dataSize < DbValueSize)
-            {
-               // key
-               memset(insert.m_key, 0, DbKeySize);
-               memcpy(insert.m_key, key, keySize);
-               if(itzam_true == itzam_btree_find(btree, key, &insert))
-               {
-                  // key already available, so delete "old" key
-                  state = itzam_btree_remove(btree, (const void *)&insert);
-               }
-
-               // data
-               memset(insert.m_data, 0, DbValueSize);
-               memcpy(insert.m_data, buffer, dataSize);
-
-               // data size
-               insert.m_data_size = buffer_size;
-
-               state = itzam_btree_insert(btree,(const void *)&insert);
-               if (state != ITZAM_OKAY)
-               {
-                  fprintf(stderr, "\npersistence_set_data ==> Insert Itzam problem: %s\n", STATE_MESSAGES[state]);
-                  write_size = EPERS_DB_ERROR_INTERNAL;
-               }
-            }
-            else
-            {
-               fprintf(stderr, "\npersistence_set_data ==> set_value_to_table_itzam => data to long » size %d | maxSize: %d\n", dataSize, DbKeySize);
-               write_size = EPERS_DB_VALUE_SIZE;
-            }
-
-            //
-            // workaround till lifecycle is working correctly
-            //
-            pers_db_close(info);
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> persComDbWriteKey() failure"));
          }
-         else
+
+         if(PersistenceStorage_shared == info->configKey.storage)
          {
-            fprintf(stderr, "\nset_value_to_table_itzam => key to long » size: %d | maxSize: %d\n", keySize, DbKeySize);
-            write_size = EPERS_DB_KEY_SIZE;
+            int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
+            if(rval <= 0)
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> failed to send notification signal"));
+               write_size = rval;
+            }
          }
+
       }
       else
       {
+         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
          write_size = EPERS_NOPRCTABLE;
-         fprintf(stderr, "\npersistence_set_data ==> Open Itzam problem: %s\n", STATE_MESSAGES[state]);
       }
    }
    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
    {
       int idx = custom_client_name_to_id(dbPath, 1);
-      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data) )
+      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_set_data != NULL) )
       {
-         gPersCustomFuncs[idx].custom_plugin_set_data(key, (char*)buffer, buffer_size);
+         char pathKeyString[128] = {0};
+         if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
+         }
+         else
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
+         }
+         write_size = gPersCustomFuncs[idx].custom_plugin_set_data(pathKeyString, (char*)buffer, buffer_size);
+
+         if (write_size == buffer_size) /* Check return value and send notification if OK */
+         {
+            int rval = pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_changed);
+            if(rval <= 0)
+            {
+               DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_set_data ==> failed to send notification signal"));
+               write_size = rval;
+            }
+         }
       }
       else
       {
@@ -301,398 +425,214 @@ int pers_db_write_key(char* dbPath, char* key, PersistenceInfo_s* info, unsigned
 
 
 
-int pers_db_get_key_size(char* dbPath, char* key, PersistenceInfo_s* info)
+int persistence_get_data_size(char* dbPath, char* key, PersistenceInfo_s* info)
 {
    int read_size = -1;
+   int ret_defaults = -1;
 
    if(   PersistenceStorage_shared == info->configKey.storage
       || PersistenceStorage_local == info->configKey.storage)
    {
-      int keySize = 0;
-      itzam_btree*  btree = NULL;
-      itzam_state  state = ITZAM_FAILED;
-      KeyValuePair_s search;
-
-      btree = pers_db_open(info, dbPath);
-      if(btree != NULL)
+      int handleDB = database_get(info, dbPath);
+      if(handleDB >= 0)
       {
-         keySize = (int)strlen((const char*)key);
-         if(keySize < DbKeySize)
+         read_size = persComDbGetKeySize(handleDB, key);
+         if(read_size < 0)
          {
-            memset(search.m_key,0, DbKeySize);
-            memcpy(search.m_key, key, keySize);
-            if(itzam_true == itzam_btree_find(btree, key, &search))
-            {
-               read_size = strlen(search.m_data);
-            }
-            else
-            {
-               read_size = EPERS_NOKEY;
-            }
+            read_size = pers_get_defaults(dbPath, key, NULL, 0, PersGetDefault_Size);
          }
-         else
-         {
-            fprintf(stderr, "persistence_get_data_size => key to long » size: %d | maxSize: %d\n", keySize, DbKeySize);
-            read_size = EPERS_DB_KEY_SIZE;
-         }
-         //
-         // workaround till lifecycle is working correctly
-         //
-         pers_db_close(info);
-      }
-      else
-      {
-         read_size = EPERS_NOPRCTABLE;
-         fprintf(stderr, "\npersistence_get_data_size ==> Open Itzam problem: %s\n", STATE_MESSAGES[state]);
       }
    }
    else if(PersistenceStorage_custom == info->configKey.storage)   // custom storage implementation via custom library
    {
       int idx = custom_client_name_to_id(dbPath, 1);
-      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data) )
+      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_get_size != NULL) )
       {
-         gPersCustomFuncs[idx].custom_plugin_get_size(key);
+         char pathKeyString[128] = {0};
+         if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
+         }
+         else
+         {
+            snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
+         }
+         read_size = gPersCustomFuncs[idx].custom_plugin_get_size(pathKeyString);
       }
       else
       {
          read_size = EPERS_NOPLUGINFUNCT;
       }
+
+      if (1 > read_size)
+      {
+         info->configKey.policy = PersistencePolicy_wc;                        /* Set the policy */
+         info->configKey.type   = PersistenceResourceType_key;  /* Set the type */
+         (void)get_db_path_and_key(info, key, NULL, dbPath);
+         DLT_LOG(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("Custom Key not available. Try to get default keys from:"),
+                                            DLT_STRING(dbPath),
+                                            DLT_STRING(key));
+         ret_defaults = pers_get_defaults(dbPath, key, NULL, 0, PersGetDefault_Size);
+         if (0 < ret_defaults)
+         {
+                read_size = ret_defaults;
+         }
+      }
    }
    return read_size;
 }
 
 
 
-int pers_db_delete_key(char* dbPath, char* dbKey, PersistenceInfo_s* info)
+int persistence_delete_data(char* dbPath, char* key, PersistenceInfo_s* info)
 {
    int ret = 0;
    if(PersistenceStorage_custom != info->configKey.storage)
    {
-      itzam_btree*  btree = NULL;
-      KeyValuePair_s delete;
-
-      //printf("delete_key_from_table_itzam => Path: \"%s\" | key: \"%s\" \n", dbPath, key);
-      btree = pers_db_open(info, dbPath);
-      if(btree != NULL)
+      int handleDB = database_get(info, dbPath);
+      if(handleDB >= 0)
       {
-         int keySize = 0;
-         keySize = (int)strlen((const char*)dbKey);
-         if(keySize < DbKeySize)
+         ret = persComDbDeleteKey(handleDB, key) ;
+         if(ret < 0)
          {
-            itzam_state  state;
-
-            memset(delete.m_key,0, DbKeySize);
-            memcpy(delete.m_key, dbKey, keySize);
-            state = itzam_btree_remove(btree, (const void *)&delete);
-            if (state != ITZAM_OKAY)
+            DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_delete_data => persComDbDeleteKey failed: "), DLT_STRING(key));
+            if(PERS_COM_ERR_NOT_FOUND == ret)
             {
-               fprintf(stderr, "persistence_delete_data ==> Remove Itzam problem: %s\n", STATE_MESSAGES[state]);
-               ret = EPERS_DB_ERROR_INTERNAL;
+                ret = EPERS_NOKEY ;
+            }
+            else
+            {
+                ret = EPERS_DB_ERROR_INTERNAL ;
             }
          }
-         else
+
+         if(PersistenceStorage_shared == info->configKey.storage)
          {
-            fprintf(stderr, "persistence_delete_data => key to long » size: %d | maxSize: %d\n", keySize, DbKeySize);
-            ret = EPERS_DB_KEY_SIZE;
+            pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
          }
-         //
-         // workaround till lifecycle is working correctly
-         //
-         pers_db_close(info);
       }
       else
       {
-         fprintf(stderr, "persistence_delete_data => no prct table\n");
+         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_delete_data ==> no resource config table"), DLT_STRING(dbPath), DLT_STRING(key));
          ret = EPERS_NOPRCTABLE;
       }
    }
    else   // custom storage implementation via custom library
    {
       int idx = custom_client_name_to_id(dbPath, 1);
-      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_handle_set_data) )
-      {
-         gPersCustomFuncs[idx].custom_plugin_delete_data(dbKey);
-      }
-      else
-      {
-         ret = EPERS_NOPLUGINFUNCT;
-      }
-   }
-   return ret;
-}
-
-
-int persistence_reg_notify_on_change(char* dbPath, char* key)
-{
-   int rval = -1;
-
-   return rval;
-}
-
-
-
-//---------------------------------------------------------------------------------------------------------
-// C U R S O R    F U N C T I O N S
-//---------------------------------------------------------------------------------------------------------
-
-int get_cursor_handle()
-{
-   int handle = 0;
-
-   if(pthread_mutex_lock(&gMtx) == 0)
-   {
-      if(gFreeCursorHandleIdxHead > 0)   // check if we have a free spot in the array before the current max
+      if((idx < PersCustomLib_LastEntry) && (gPersCustomFuncs[idx].custom_plugin_delete_data != NULL) )
       {
-         handle = gFreeCursorHandleArray[--gFreeCursorHandleIdxHead];
-      }
-      else
-      {
-         if(gHandleIdx < MaxPersHandle-1)
+         char pathKeyString[128] = {0};
+         if(info->configKey.customID[0] == '\0')   // if we have not a customID we use the key
          {
-            handle = gHandleIdx++;  // no free spot before current max, increment handle index
+            snprintf(pathKeyString, 128, "0x%08X/%s/%s", info->context.ldbid, info->configKey.custom_name, key);
          }
          else
          {
-            handle = -1;
-            printf("get_persistence_handle_idx => Reached maximum of open handles: %d \n", MaxPersHandle);
+            snprintf(pathKeyString, 128, "0x%08X/%s", info->context.ldbid, info->configKey.customID);
          }
-      }
-      pthread_mutex_unlock(&gMtx);
-   }
-   return handle;
-}
+         ret = gPersCustomFuncs[idx].custom_plugin_delete_data(pathKeyString);
 
-
-void close_cursor_handle(int handlerDB)
-{
-   if(pthread_mutex_lock(&gMtx) == 0)
-   {
-      if(gFreeCursorHandleIdxHead < MaxPersHandle)
+         if(0 <= ret) /* Check return value and send notification if OK */
+         {
+            pers_send_Notification_Signal(key, &info->context, pclNotifyStatus_deleted);
+         }
+      }
+      else
       {
-         gFreeCursorHandleArray[gFreeCursorHandleIdxHead++] = handlerDB;
+         ret = EPERS_NOPLUGINFUNCT;
       }
-      pthread_mutex_unlock(&gMtx);
    }
+   return ret;
 }
 
 
-
-int pers_db_cursor_create(char* dbPath)
+int persistence_notify_on_change(char* key, unsigned int ldbid, unsigned int user_no, unsigned int seat_no,
+                                 pclChangeNotifyCallback_t callback, PersNotifyRegPolicy_e regPolicy)
 {
-   int handle = -1;
-   itzam_state  state = ITZAM_FAILED;
-
-   handle = get_cursor_handle();
+   int rval = 0;
 
-   if(handle < MaxPersHandle && handle >= 0)
+   if(regPolicy < Notify_lastEntry)
    {
-      // open database
-      state = itzam_btree_open(&gCursorArray[handle].m_btree, dbPath, itzam_comparator_string, error_handler, 0/*recover*/, 0/*read_only*/);
-      if (state != ITZAM_OKAY)
+      snprintf(gNotifykey, DbKeyMaxLen, "%s", key);
+      gNotifyLdbid  = ldbid;     // to do: pass correct ==> JUST TESTING!!!!
+      gNotifyUserNo = user_no;
+      gNotifySeatNo = seat_no;
+      gNotifyReason = regPolicy;
+
+      if(regPolicy == Notify_register)
       {
-         fprintf(stderr, "pers_db_open ==> Open Itzam problem: %s\n", STATE_MESSAGES[state]);
+         // assign callback
+         gChangeNotifyCallback = callback;
       }
-      else
+      else if(regPolicy == Notify_unregister)
       {
-         itzam_state  state;
-
-         state = itzam_btree_cursor_create(&gCursorArray[handle].m_cursor, &gCursorArray[handle].m_btree);
-         if(state == ITZAM_OKAY)
-         {
-            gCursorArray[handle].m_empty = 0;
-         }
-         else
-         {
-            gCursorArray[handle].m_empty = 1;
-         }
+         // remove callback
+         gChangeNotifyCallback = NULL;
       }
-   }
-   return handle;
-}
-
 
-
-int pers_db_cursor_next(unsigned int handlerDB)
-{
-   int rval = -1;
-   if(handlerDB < MaxPersHandle && handlerDB >= 0)
-   {
-      if(gCursorArray[handlerDB].m_empty != 1)
+      if(-1 == deliverToMainloop(CMD_REG_NOTIFY_SIGNAL, 0, 0))
       {
-         itzam_bool success;
-         success = itzam_btree_cursor_next(&gCursorArray[handlerDB].m_cursor);
-
-         if(success == itzam_true)
-         {
-            rval = 0;
-         }
-         else
-         {
-            rval = EPERS_LAST_ENTRY_IN_DB;
-         }
-      }
-      else
-      {
-         printf("persistence_db_cursor_get_key ==> invalid handle: %u \n", handlerDB);
+         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("persistence_notify_on_change => failed to write to pipe"), DLT_INT(errno));
+         rval = -1;
       }
    }
    else
    {
-      printf("persistence_db_cursor_get_key ==> handle bigger than max » handleDB: %u | max: : %d \n", handlerDB, MaxPersHandle);
+      rval = -1;
    }
+
    return rval;
 }
 
 
 
-int pers_db_cursor_get_key(unsigned int handlerDB, char * bufKeyName_out, int bufSize)
-{
-   int rval = -1;
-   KeyValuePair_s search;
 
-   if(handlerDB < MaxPersHandle)
-   {
-      if(gCursorArray[handlerDB].m_empty != 1)
-      {
-         int length = 0;
-         itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
-         length = strlen(search.m_key);
-         if(length < bufSize)
-         {
-            memcpy(bufKeyName_out, search.m_key, length);
-            rval = 0;
-         }
-         else
-         {
-            printf("persistence_db_cursor_get_key ==> buffer to small » keySize: %d | bufSize: %d \n", length, bufSize);
-         }
-      }
-      else
-      {
-         printf("persistence_db_cursor_get_key ==> invalid handle: %u \n", handlerDB);
-      }
-   }
-   else
-   {
-      printf("persistence_db_cursor_get_key ==> handle bigger than max » handleDB: %u | max: : %d \n", handlerDB, MaxPersHandle);
-   }
-   return rval;
-}
 
 
-
-int pers_db_cursor_get_data(unsigned int handlerDB, char * bufData_out, int bufSize)
+int pers_send_Notification_Signal(const char* key, PersistenceDbContext_s* context, pclNotifyStatus_e reason)
 {
-   int rval = -1;
-   KeyValuePair_s search;
-
-   if(handlerDB < MaxPersHandle)
+   int rval = 1;
+   if(reason < pclNotifyStatus_lastEntry)
    {
-      if(gCursorArray[handlerDB].m_empty != 1)
-      {
-         int length = 0;
-         itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
+      snprintf(gNotifykey,  DbKeyMaxLen,       "%s", key);
 
-         length = strlen(search.m_data);
-         if(length < bufSize)
-         {
-            memcpy(bufData_out, search.m_data, length);
-            rval = 0;
-         }
-         else
-         {
-            printf("persistence_db_cursor_get_data ==> buffer to small » keySize: %d | bufSize: %d \n", length, bufSize);
-         }
-      }
-      else
+      gNotifyLdbid  = context->ldbid;     // to do: pass correct ==> JUST TESTING!!!!
+      gNotifyUserNo = context->user_no;
+      gNotifySeatNo = context->seat_no;
+      gNotifyReason = reason;
+
+      if(-1 == deliverToMainloop(CMD_SEND_NOTIFY_SIGNAL, 0,0) )
       {
-         printf("persistence_db_cursor_get_data ==> invalid handle: %u \n", handlerDB);
+         DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("pers_send_Notification_Signal => failed to write to pipe"), DLT_INT(errno));
+         rval = EPERS_NOTIFY_SIG;
       }
    }
    else
    {
-      printf("persistence_db_cursor_get_data ==> handle bigger than max » handleDB: %u | max: : %d \n", handlerDB, MaxPersHandle);
+      rval = EPERS_NOTIFY_SIG;
    }
+
    return rval;
 }
 
 
-
-int pers_db_cursor_get_data_size(unsigned int handlerDB)
+void pers_rct_close_all()
 {
-   int size = -1;
-   KeyValuePair_s search;
-
-   if(handlerDB < MaxPersHandle)
-   {
-      if(gCursorArray[handlerDB].m_empty != 1)
-      {
-         itzam_btree_cursor_read(&gCursorArray[handlerDB].m_cursor ,(void *)&search);
-         size = strlen(search.m_data);
-      }
-      else
-      {
-         printf("persistence_db_cursor_get_data ==> invalid handle: %u \n", handlerDB);
-      }
-   }
-   else
-   {
-      printf("persistence_db_cursor_get_data ==> handle bigger than max » handleDB: %u | max: : %d \n", handlerDB, MaxPersHandle);
-   }
-   return size;
-}
-
-
+   int i = 0;
 
-int pers_db_cursor_destroy(unsigned int handlerDB)
-{
-   int rval = -1;
-   if(handlerDB < MaxPersHandle)
+   // close open persistence resource configuration table
+   for(i=0; i< PrctDbTableSize; i++)
    {
-      itzam_btree_cursor_free(&gCursorArray[handlerDB].m_cursor);
-      gCursorArray[handlerDB].m_empty = 1;
-
-      itzam_btree_close(&gCursorArray[handlerDB].m_btree);
-      close_cursor_handle(handlerDB);
-
-      rval = 0;
+       if(gResource_table[i] != -1)
+       {
+                       if(persComRctClose(i) == -1)
+                       {
+                               DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("process_prepare_shutdown => failed to close db => index:"), DLT_INT(i));
+                       }
+
+                       gResource_table[i] = -1;
+       }
    }
-   return rval;
-}
-
-
-
-
-//-----------------------------------------------------------------------------
-// code to print database content (for debugging)
-//-----------------------------------------------------------------------------
-// walk the database
-/*
-KeyValuePair_s  rec;
-itzam_btree_cursor cursor;
-state = itzam_btree_cursor_create(&cursor, &btree);
-if(state == ITZAM_OKAY)
-{
-  printf("==> Database content ==> db size: %d\n", (int)itzam_btree_count(&btree));
-  do
-  {
-     // get the key pointed to by the cursor
-     state = itzam_btree_cursor_read(&cursor,(void *)&rec);
-     if (state == ITZAM_OKAY)
-     {
-       printf("   Key: %s \n     ==> data: %s\n", rec.m_key, rec.m_data);
-     }
-     else
-        fprintf(stderr, "\nItzam problem: %s\n", STATE_MESSAGES[state]);
-  }
-  while (itzam_btree_cursor_next(&cursor));
-
-  state = itzam_btree_cursor_free(&cursor);
 }
-*/
-//-----------------------------------------------------------------------------
-
-
-
-