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