eb3f8c2f62f7fd5fd4c618bcd29bc4bc6e3d4c81
[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
22 #include "persistence_client_library_prct_access.h"
23 #include "persistence_client_library_db_access.h"
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <persComRct.h>
28 #include <persComDbAccess.h>
29 #include <persComErrors.h>
30
31
32 /// pointer to resource table database
33 int gResource_table[PrctDbTableSize] = {[0 ... PrctDbTableSize-1] = -1};
34 /// array to hold the information of database is already open
35 int gResourceOpen[PrctDbTableSize] = { [0 ... PrctDbTableSize-1] = 0 };
36
37
38 /// persistence resource config table type definition
39 typedef enum _PersistenceRCT_e
40 {
41    PersistenceRCT_local         = 0,
42    PersistenceRCT_shared_public = 1,
43    PersistenceRCT_shared_group  = 2,
44
45    PersistenceRCT_LastEntry                // last Entry
46
47 } PersistenceRCT_e;
48
49
50
51 PersistenceRCT_e get_table_id(int ldbid, int* groupId)
52 {
53    PersistenceRCT_e rctType = PersistenceRCT_LastEntry;
54
55    if(ldbid < 0x80)
56    {
57       // S H A R E D  database
58       if(ldbid != 0)
59       {
60          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
61          *groupId = ldbid;  // assign group ID
62          rctType = PersistenceRCT_shared_group;
63       }
64       else
65       {
66          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
67          *groupId = 0;      // no group ID for public data
68          rctType = PersistenceRCT_shared_public;
69       }
70    }
71    else
72    {
73       // L O C A L   database
74       *groupId = 0;      // no group ID for local data
75       rctType = PersistenceRCT_local;   // we have a local database
76    }
77    return rctType;
78 }
79
80
81 int get_resource_cfg_table_by_idx(int i)
82 {
83    return gResource_table[i];
84 }
85
86
87 void invalidate_resource_cfg_table(int i)
88 {
89    gResource_table[i] = -1;
90 }
91
92 // status: OK
93 int get_resource_cfg_table(PersistenceRCT_e rct, int group)
94 {
95    int arrayIdx = 0;
96
97    // create array index: index is a combination of resource config table type and group
98    arrayIdx = rct + group;
99
100    if(arrayIdx < PrctDbTableSize)
101    {
102       if(gResourceOpen[arrayIdx] == 0)   // check if database is already open
103       {
104          char filename[DbPathMaxLen] = { [0 ... DbPathMaxLen-1] = 0};
105
106          switch(rct)    // create db name
107          {
108          case PersistenceRCT_local:
109             snprintf(filename, DbPathMaxLen, gLocalWtPathKey, gAppId, gResTableCfg);
110             break;
111          case PersistenceRCT_shared_public:
112             snprintf(filename, DbPathMaxLen, gSharedPublicWtPathKey, gAppId, gResTableCfg);
113             break;
114          case PersistenceRCT_shared_group:
115             snprintf(filename, DbPathMaxLen, gSharedWtPathKey, gAppId, group, gResTableCfg);
116             break;
117          default:
118             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("get_resource_cfg_table - error: no valid PersistenceRCT_e"));
119             break;
120          }
121
122          gResource_table[arrayIdx] = persComRctOpen(filename, 0x00);
123
124          if(gResource_table[arrayIdx] < 0)
125          {
126                 gResourceOpen[arrayIdx] = -1;
127             DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("get_resource_cfg_table => RCT problem"), DLT_INT(gResource_table[arrayIdx] ));
128          }
129          else
130          {
131              gResourceOpen[arrayIdx] = 1 ;
132          }
133       }
134    }
135
136    return gResource_table[arrayIdx];
137 }
138
139
140 // status: OK
141 int get_db_context(PersistenceInfo_s* dbContext, const char* resource_id, unsigned int isFile, char dbKey[], char dbPath[])
142 {
143    int rval = 0, resourceFound = 0, groupId = 0;
144
145    PersistenceRCT_e rct = PersistenceRCT_LastEntry;
146
147    rct = get_table_id(dbContext->context.ldbid, &groupId);
148
149    // get resource configuration table
150    int handleRCT = get_resource_cfg_table(rct, groupId);
151
152    if(handleRCT >= 0)
153    {
154       PersistenceConfigurationKey_s sRctEntry ;
155
156       // check if resouce id is in write through table
157       int iErrCode = persComRctRead(handleRCT, resource_id, &sRctEntry) ;
158       
159       if(sizeof(PersistenceConfigurationKey_s) == iErrCode)
160       {
161          //printf("get_db_context ==> data: %s\n", search.data);
162            memcpy(&dbContext->configKey, &sRctEntry, sizeof(dbContext->configKey)) ;
163          if(sRctEntry.storage != PersistenceStorage_custom )
164          {
165             rval = get_db_path_and_key(dbContext, resource_id, dbKey, dbPath);
166          }
167          else
168          {
169             // if customer storage, we use the custom name as dbPath
170             strncpy(dbPath, dbContext->configKey.custom_name, strlen(dbContext->configKey.custom_name));
171
172             // and resource_id as dbKey
173             strncpy(dbKey, resource_id, strlen(resource_id));
174          }
175          resourceFound = 1;
176       }
177       else
178       {
179          DLT_LOG(gPclDLTContext, DLT_LOG_WARN, DLT_STRING("get_db_context => persComRctRead => resource_table: no value for key:"), DLT_STRING(resource_id) );
180          rval = EPERS_NOKEYDATA;
181       }
182    }  // resource table
183    else
184    {
185       DLT_LOG(gPclDLTContext, DLT_LOG_ERROR, DLT_STRING("get_db_context =>error resource table"));
186       rval = EPERS_NOPRCTABLE;
187    }
188
189    if((resourceFound == 0) && (dbContext->context.ldbid == 0xFF) ) // create only when the resource is local data
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  = PersistencePermission_ReadWrite;
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(gPclDLTContext, DLT_LOG_INFO, DLT_STRING("get_db_context => create resource not in PRCT => key:"), DLT_STRING(resource_id) );
212
213       rval = get_db_path_and_key(dbContext, resource_id, dbKey, dbPath);
214    }
215    /* rval contains the return value of function get_db_path_and_key() if positive structure content 'dbContext' is valid.
216     * rval can be 0,1 or 2 but get_db_context should only return '0' for success. */
217    if (0 < rval)
218    {
219            rval = 0;
220    }
221
222    return rval;
223 }
224
225
226
227 // status: OK
228 int get_db_path_and_key(PersistenceInfo_s* dbContext, const char* resource_id, char dbKey[], char dbPath[])
229 {
230    int storePolicy = PersistenceStorage_LastEntry;
231
232    //
233    // create resource database key
234    //
235    if(((dbContext->context.ldbid < 0x80) || (dbContext->context.ldbid == 0xFF)) &&  (NULL != dbKey))
236    {
237       // The LDBID is used to find the DBID in the resource table.
238       if((dbContext->context.user_no == 0) && (dbContext->context.seat_no == 0))
239       {
240          //
241          // Node is added in front of the resource ID as the key string.
242          //
243          snprintf(dbKey, DbKeyMaxLen, "%s/%s", gNode, resource_id);
244       }
245       else
246       {
247          //
248          // Node is added in front of the resource ID as the key string.
249          //
250          if(dbContext->context.seat_no == 0)
251          {
252             // /User/<user_no_parameter> is added in front of the resource ID as the key string.
253             snprintf(dbKey, DbKeyMaxLen, "%s%d/%s", gUser, dbContext->context.user_no, resource_id);
254          }
255          else
256          {
257             // /User/<user_no_parameter>/Seat/<seat_no_parameter> is added in front of the resource ID as the key string.
258             snprintf(dbKey, DbKeyMaxLen, "%s%d%s%d/%s", gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
259          }
260       }
261       storePolicy = PersistenceStorage_local;
262    }
263
264    if((dbContext->context.ldbid >= 0x80) && (dbContext->context.ldbid != 0xFF) && (NULL != dbKey))
265    {
266       // The LDBID is used to find the DBID in the resource table.
267       // /<LDBID parameter> is added in front of the resource ID as the key string.
268       //  Rational: Creates a namespace within one data base.
269       //  Rational: Reduction of number of databases -> reduction of maintenance costs
270       // /User/<user_no_parameter> and /Seat/<seat_no_parameter> are add after /<LDBID parameter> if there are different than 0.
271
272       if(dbContext->context.seat_no != 0)
273       {
274          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
275       }
276       else
277       {
278          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, resource_id);
279       }
280       storePolicy = PersistenceStorage_local;
281    }
282
283    //
284    // create resource database path
285    //
286    if(dbContext->context.ldbid < 0x80)
287    {
288       // S H A R E D  database
289
290       if(dbContext->context.ldbid != 0)
291       {
292          // Additionally /GROUP/<LDBID_parameter> shall be added inside of the database path listed in the resource table. (Off target)
293          //
294          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
295          //
296          if(PersistencePolicy_wc == dbContext->configKey.policy)
297          {
298             if(dbContext->configKey.type == PersistenceResourceType_key)
299                snprintf(dbPath, DbPathMaxLen, gSharedCachePath, gAppId, dbContext->context.ldbid, "");
300             else
301                snprintf(dbPath, DbPathMaxLen, gSharedCachePathKey, gAppId, dbContext->context.ldbid, dbKey);
302          }
303          else if(PersistencePolicy_wt == dbContext->configKey.policy)
304          {
305             if(dbContext->configKey.type == PersistenceResourceType_key)
306                snprintf(dbPath, DbPathMaxLen, gSharedWtPath, gAppId, dbContext->context.ldbid);
307             else
308                snprintf(dbPath, DbPathMaxLen, gSharedWtPathKey, gAppId, dbContext->context.ldbid, dbKey);
309          }
310       }
311       else
312       {
313          // Additionally /Shared/Public shall be added inside of the database path listed in the resource table. (Off target)
314          //
315          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
316          //
317          if(PersistencePolicy_wc == dbContext->configKey.policy)
318          {
319             if(dbContext->configKey.type == PersistenceResourceType_key)
320                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePath, gAppId, "");
321             else
322                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePathKey, gAppId, dbKey);
323          }
324          else if(PersistencePolicy_wt == dbContext->configKey.policy)
325          {
326             if(dbContext->configKey.type == PersistenceResourceType_key)
327                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPath, gAppId, "");
328             else
329                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPathKey, gAppId, dbKey);
330          }
331       }
332
333       storePolicy = PersistenceStorage_shared;   // we have a shared database
334    }
335    else
336    {
337       // L O C A L   database
338       if(PersistencePolicy_wc == dbContext->configKey.policy)
339       {
340          if(dbContext->configKey.type == PersistenceResourceType_key)
341             snprintf(dbPath, DbPathMaxLen, gLocalCachePath, gAppId, "");
342          else
343             snprintf(dbPath, DbPathMaxLen, gLocalCachePathKey, gAppId, dbKey);
344       }
345       else if(PersistencePolicy_wt == dbContext->configKey.policy)
346       {
347          if(dbContext->configKey.type == PersistenceResourceType_key)
348             snprintf(dbPath, DbPathMaxLen-1, gLocalWtPath, gAppId, "");
349          else
350             snprintf(dbPath, DbPathMaxLen-1, gLocalWtPathKey, gAppId, dbKey);
351       }
352
353       storePolicy = PersistenceStorage_local;   // we have a local database
354    }
355
356    //printf("get_db_path_and_key - dbKey  : [key ]: %s \n",  dbKey);
357    //printf("get_db_path_and_key - dbPath : [path]: %s\n", dbPath);
358
359    return storePolicy;
360 }
361
362
363
364
365
366