Removed findings after code review; removed memset for arrays, let the compiler do...
[profile/ivi/persistence-client-library.git] / src / persistence_client_library_prct_access.c
1 /******************************************************************************
2  * Project         Persistency
3  * (c) copyright   2012
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 ******************************************************************************/
11  /**
12  * @file           persistence_client_library_prct_access.c
13  * @ingroup        Persistence client library
14  * @author         Ingo Huerner
15  * @brief          Implementation of persistence resource configuration config
16  *                 table access functions
17  * @see
18  */
19
20
21 #include "persistence_client_library_prct_access.h"
22 #include "persistence_client_library_itzam_errors.h"
23 #include "../include_protected/persistence_client_library_db_access.h"
24 #include <stdlib.h>
25
26
27
28 /// pointer to resource table database
29 itzam_btree gResource_table[PrctDbTableSize];
30 /// array to hold the information of database is already open
31 int gResourceOpen[PrctDbTableSize] = {0};
32
33
34 PersistenceRCT_e get_table_id(int ldbid, int* groupId)
35 {
36    PersistenceRCT_e rctType = PersistenceRCT_LastEntry;
37
38    if(ldbid < 0x80)
39    {
40       // S H A R E D  database
41       if(ldbid != 0)
42       {
43          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
44          *groupId = ldbid;  // assign group ID
45          rctType = PersistenceRCT_shared_group;
46       }
47       else
48       {
49          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
50          *groupId = 0;      // no group ID for public data
51          rctType = PersistenceRCT_shared_public;
52       }
53    }
54    else
55    {
56       // L O C A L   database
57       *groupId = 0;      // no group ID for local data
58       rctType = PersistenceStorage_local;   // we have a local database
59    }
60    return rctType;
61 }
62
63
64 itzam_btree* get_resource_cfg_table_by_idx(int i)
65 {
66    return &gResource_table[i];
67 }
68
69
70 // status: OK
71 itzam_btree* get_resource_cfg_table(PersistenceRCT_e rct, int group)
72 {
73    int arrayIdx = 0;
74    itzam_btree* tree = NULL;
75
76    // create array index: index is a combination of resource config table type and group
77    arrayIdx = rct + group;
78
79    if(arrayIdx < PrctDbTableSize)
80    {
81       if(gResourceOpen[arrayIdx] == 0)   // check if database is already open
82       {
83          itzam_state  state;
84          char filename[DbPathMaxLen] = {0};
85
86          switch(rct)    // create db name
87          {
88          case PersistenceRCT_local:
89             snprintf(filename, DbPathMaxLen, gLocalWtPath, gAppId, gResTableCfg);
90             break;
91          case PersistenceRCT_shared_public:
92             snprintf(filename, DbPathMaxLen, gSharedPublicWtPath, gAppId, gResTableCfg);
93             break;
94          case PersistenceRCT_shared_group:
95             snprintf(filename, DbPathMaxLen, gSharedWtPath, gAppId, group, gResTableCfg);
96             break;
97          default:
98             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_resource_cfg_table - error: no valid PersistenceRCT_e"));
99             break;
100          }
101
102          state = itzam_btree_open(&gResource_table[arrayIdx], filename, itzam_comparator_string, error_handler, 0 , 0);
103          if(state != ITZAM_OKAY)
104          {
105             DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_resource_cfg_table => itzam_btree_open => Itzam problem"), DLT_STRING(STATE_MESSAGES[state]) );
106             tree = NULL;
107          }
108          else
109          {
110             gResourceOpen[arrayIdx] = 1;  // remember the index has an DB entry
111             tree = &gResource_table[arrayIdx];
112          }
113       }
114       else
115       {
116          tree = &gResource_table[arrayIdx];
117       }
118
119    }
120
121    return tree;
122 }
123
124
125 // status: OK
126 int get_db_context(PersistenceInfo_s* dbContext, const char* resource_id, unsigned int isFile, char dbKey[], char dbPath[])
127 {
128    int rval = 0, resourceFound = 0, groupId = 0;
129
130    PersistenceRCT_e rct = PersistenceRCT_LastEntry;
131
132    rct = get_table_id(dbContext->context.ldbid, &groupId);
133
134    // get resource configuration table
135    itzam_btree* resource_table = get_resource_cfg_table(rct, groupId);
136
137    if(resource_table != NULL)
138    {
139       PersistenceRctEntry_s search;
140       // check if resouce id is in write through table
141       if(itzam_true == itzam_btree_find(resource_table, resource_id, &search))
142       {
143          memset(dbContext->configKey.reponsible,  0, MaxConfKeyLengthResp);
144          memset(dbContext->configKey.custom_name, 0, MaxConfKeyLengthCusName);
145          memset(dbContext->configKey.customID,    0,  MaxRctLengthCustom_ID);
146
147          dbContext->configKey.policy      = search.data.policy;
148          dbContext->configKey.storage     = search.data.storage;
149          dbContext->configKey.permission  = search.data.permission;
150          dbContext->configKey.max_size    = search.data.max_size;
151          dbContext->configKey.type        = search.data.type;
152          memcpy(dbContext->configKey.reponsible, search.data.reponsible, MaxConfKeyLengthResp);
153          memcpy(dbContext->configKey.custom_name, search.data.custom_name, MaxConfKeyLengthCusName);
154          memcpy(dbContext->configKey.customID, search.data.customID, MaxRctLengthCustom_ID);
155
156          if(dbContext->configKey.storage != PersistenceStorage_custom )
157          {
158             rval = get_db_path_and_key(dbContext, resource_id, dbKey, dbPath);
159          }
160          else
161          {
162             int len = strlen(resource_id);
163
164             // if customer storage, we use the custom name as dbPath
165             strncpy(dbPath, dbContext->configKey.custom_name, strlen(dbContext->configKey.custom_name));
166
167             if(len > DbKeyMaxLen)
168             {
169                len = DbKeyMaxLen;
170             }
171             // and the resource_id as dbKey
172             strncpy(dbKey, resource_id, len);
173
174          }
175          resourceFound = 1;
176       }
177       else
178       {
179          DLT_LOG(gDLTContext, DLT_LOG_WARN, DLT_STRING("get_db_context => itzam_btree_open => resource_table: no value for key:"), DLT_STRING(resource_id) );
180          rval = EPERS_NOKEYDATA;
181       }
182    }  // resource table
183    else
184    {
185       DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("get_db_context =>error resource table"));
186       rval = EPERS_NOPRCTABLE;
187    }
188
189    if(resourceFound == 0)
190    {
191       //
192       // resource NOT found in resource table ==> default is local cached key
193       //
194       dbContext->configKey.policy      = PersistencePolicy_wc;
195       dbContext->configKey.storage     = PersistenceStorage_local;
196       dbContext->configKey.permission  = 0;           // TODO define default permission
197       dbContext->configKey.max_size    = defaultMaxKeyValDataSize;
198       if(isFile == PersistenceResourceType_file)
199       {
200          dbContext->configKey.type = PersistenceResourceType_file;
201        }
202       else
203       {
204          dbContext->configKey.type  = PersistenceResourceType_key;
205       }
206
207       memcpy(dbContext->configKey.customID, "A_CUSTOM_ID", strlen("A_CUSTOM_ID"));
208       memcpy(dbContext->configKey.reponsible, "default", strlen("default"));
209       memcpy(dbContext->configKey.custom_name, "default", strlen("default"));
210
211       DLT_LOG(gDLTContext, DLT_LOG_INFO, DLT_STRING("get_db_context => create resource not in PRCT => key:"), DLT_STRING(resource_id) );
212
213       // send create notification
214       rval = pers_send_Notification_Signal(dbKey, &dbContext->context, pclNotifyStatus_created);
215
216       rval = get_db_path_and_key(dbContext, resource_id, dbKey, dbPath);
217    }
218
219    return rval;
220 }
221
222
223
224 // status: OK
225 int get_db_path_and_key(PersistenceInfo_s* dbContext, const char* resource_id, char dbKey[], char dbPath[])
226 {
227    int storePolicy = PersistenceStorage_LastEntry;
228
229    //
230    // create resource database key
231    //
232    if((dbContext->context.ldbid < 0x80) || (dbContext->context.ldbid == 0xFF) )
233    {
234       // The LDBID is used to find the DBID in the resource table.
235       if((dbContext->context.user_no == 0) && (dbContext->context.seat_no == 0))
236       {
237          //
238          // Node is added in front of the resource ID as the key string.
239          //
240          snprintf(dbKey, DbKeyMaxLen, "%s/%s", gNode, resource_id);
241       }
242       else
243       {
244          //
245          // Node is added in front of the resource ID as the key string.
246          //
247          if(dbContext->context.seat_no == 0)
248          {
249             // /User/<user_no_parameter> is added in front of the resource ID as the key string.
250             snprintf(dbKey, DbKeyMaxLen, "%s%d/%s", gUser, dbContext->context.user_no, resource_id);
251          }
252          else
253          {
254             // /User/<user_no_parameter>/Seat/<seat_no_parameter> is added in front of the resource ID as the key string.
255             snprintf(dbKey, DbKeyMaxLen, "%s%d%s%d/%s", gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
256          }
257       }
258       storePolicy = PersistenceStorage_local;
259    }
260
261    if((dbContext->context.ldbid >= 0x80) && (dbContext->context.ldbid != 0xFF))
262    {
263       // The LDBID is used to find the DBID in the resource table.
264       // /<LDBID parameter> is added in front of the resource ID as the key string.
265       //  Rational: Creates a namespace within one data base.
266       //  Rational: Reduction of number of databases -> reduction of maintenance costs
267       // /User/<user_no_parameter> and /Seat/<seat_no_parameter> are add after /<LDBID parameter> if there are different than 0.
268
269       if(dbContext->context.seat_no != 0)
270       {
271          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
272       }
273       else
274       {
275          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, resource_id);
276       }
277       storePolicy = PersistenceStorage_local;
278    }
279
280    //
281    // create resource database path
282    //
283    if(dbContext->context.ldbid < 0x80)
284    {
285       // S H A R E D  database
286
287       if(dbContext->context.ldbid != 0)
288       {
289          // Additionally /GROUP/<LDBID_parameter> shall be added inside of the database path listed in the resource table. (Off target)
290          //
291          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
292          //
293          if(PersistencePolicy_wc == dbContext->configKey.policy)
294          {
295             if(dbContext->configKey.type == PersistenceResourceType_key)
296                snprintf(dbPath, DbPathMaxLen, gSharedCachePath, gAppId, dbContext->context.ldbid, gSharedCached);
297             else
298                snprintf(dbPath, DbPathMaxLen, gSharedCachePath, gAppId, dbContext->context.ldbid, dbKey);
299          }
300          else if(PersistencePolicy_wt == dbContext->configKey.policy)
301          {
302             if(dbContext->configKey.type == PersistenceResourceType_key)
303                snprintf(dbPath, DbPathMaxLen, gSharedWtPath, gAppId, dbContext->context.ldbid, gSharedWt);
304             else
305                snprintf(dbPath, DbPathMaxLen, gSharedWtPath, gAppId, dbContext->context.ldbid, dbKey);
306          }
307       }
308       else
309       {
310          // Additionally /Shared/Public shall be added inside of the database path listed in the resource table. (Off target)
311          //
312          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
313          //
314          if(PersistencePolicy_wc == dbContext->configKey.policy)
315          {
316             if(dbContext->configKey.type == PersistenceResourceType_key)
317                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePath, gAppId, gSharedCached);
318             else
319                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePath, gAppId, dbKey);
320          }
321          else if(PersistencePolicy_wt == dbContext->configKey.policy)
322          {
323             if(dbContext->configKey.type == PersistenceResourceType_key)
324                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPath, gAppId, gSharedWt);
325             else
326                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPath, gAppId, dbKey);
327          }
328       }
329
330       storePolicy = PersistenceStorage_shared;   // we have a shared database
331    }
332    else
333    {
334       // L O C A L   database
335
336       if(PersistencePolicy_wc == dbContext->configKey.policy)
337       {
338          if(dbContext->configKey.type == PersistenceResourceType_key)
339             snprintf(dbPath, DbPathMaxLen, gLocalCachePath, gAppId, gLocalCached);
340          else
341             snprintf(dbPath, DbPathMaxLen, gLocalCachePath, gAppId, dbKey);
342       }
343       else if(PersistencePolicy_wt == dbContext->configKey.policy)
344       {
345          if(dbContext->configKey.type == PersistenceResourceType_key)
346             snprintf(dbPath, DbPathMaxLen, gLocalWtPath, gAppId, gLocalWt);
347          else
348             snprintf(dbPath, DbPathMaxLen, gLocalWtPath, gAppId, dbKey);
349       }
350
351       storePolicy = PersistenceStorage_local;   // we have a local database
352    }
353
354    //printf("get_db_path_and_key - dbKey  : [key ]: %s \n",  dbKey);
355    //printf("get_db_path_and_key - dbPath : [path]: %s\n\n", dbPath);
356    return storePolicy;
357 }
358
359
360
361
362
363