Changed file and key-value API according GENIVI naming conventions
[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 <stdlib.h>
24
25
26
27 /// pointer to resource table database
28 itzam_btree gResource_table[PrctDbTableSize];
29 /// array to hold the information of database is already open
30 int gResourceOpen[PrctDbTableSize] = {0};
31
32
33 PersistenceRCT_e get_table_id(int ldbid, int* groupId)
34 {
35    PersistenceRCT_e rctType = PersistenceRCT_LastEntry;
36
37    if(ldbid < 0x80)
38    {
39       // S H A R E D  database
40       if(ldbid != 0)
41       {
42          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
43          *groupId = ldbid;  // assign group ID
44          rctType = PersistenceRCT_shared_group;
45       }
46       else
47       {
48          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
49          *groupId = 0;      // no group ID for public data
50          rctType = PersistenceRCT_shared_public;
51       }
52    }
53    else
54    {
55       // L O C A L   database
56       *groupId = 0;      // no group ID for local data
57       rctType = PersistenceStorage_local;   // we have a local database
58    }
59    return rctType;
60 }
61
62
63 itzam_btree* get_resource_cfg_table_by_idx(int i)
64 {
65    return &gResource_table[i];
66 }
67
68
69 // status: OK
70 itzam_btree* get_resource_cfg_table(PersistenceRCT_e rct, int group)
71 {
72    int arrayIdx = 0;
73    itzam_btree* tree = NULL;
74
75    // create array index: index is a combination of resource config table type and group
76    arrayIdx = rct + group;
77
78    if(arrayIdx < PrctDbTableSize)
79    {
80       if(gResourceOpen[arrayIdx] == 0)   // check if database is already open
81       {
82          itzam_state  state;
83          char filename[DbPathMaxLen];
84          memset(filename, 0, DbPathMaxLen);
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             printf("get_resource_cfg_table - error: no valid PersistenceRCT_e\n");
99             break;
100          }
101
102          //printf("get_resource_cfg_table => %s \n", filename);
103          state = itzam_btree_open(&gResource_table[arrayIdx], filename, itzam_comparator_string, error_handler, 0 , 0);
104          if(state != ITZAM_OKAY)
105          {
106             fprintf(stderr, "\nget_resource_cfg_table => Itzam problem: %s\n", STATE_MESSAGES[state]);
107          }
108          gResourceOpen[arrayIdx] = 1;  // remember the index has an DB entry
109       }
110       tree = &gResource_table[arrayIdx];
111    }
112
113    return tree;
114 }
115
116
117 // status: OK
118 int get_db_context(PersistenceInfo_s* dbContext, const char* resource_id, unsigned int isFile, char dbKey[], char dbPath[])
119 {
120    int rval = 0, resourceFound = 0, groupId = 0;
121
122    PersistenceRCT_e rct = PersistenceRCT_LastEntry;
123
124    rct = get_table_id(dbContext->context.ldbid, &groupId);
125
126    // get resource configuration table
127    itzam_btree* resource_table = get_resource_cfg_table(rct, groupId);
128
129    if(resource_table != NULL)
130    {
131       PersistenceRctEntry_s search;
132       // check if resouce id is in write through table
133       if(itzam_true == itzam_btree_find(resource_table, resource_id, &search))
134       {
135          //printf("get_db_context ==> data: %s\n", search.data);
136          memset(dbContext->configKey.reponsible,  0, MaxConfKeyLengthResp);
137          memset(dbContext->configKey.custom_name, 0, MaxConfKeyLengthCusName);
138
139          dbContext->configKey.policy      = search.data.policy;
140          dbContext->configKey.storage     = search.data.storage;
141          dbContext->configKey.permission  = search.data.permission;
142          dbContext->configKey.max_size    = search.data.max_size;
143          memcpy(dbContext->configKey.reponsible, search.data.reponsible, MaxConfKeyLengthResp);
144          memcpy(dbContext->configKey.custom_name, search.data.custom_name, MaxConfKeyLengthCusName);
145
146          if(dbContext->configKey.storage != PersistenceStorage_custom )
147          {
148             rval = get_db_path_and_key(dbContext, resource_id, isFile, dbKey, dbPath);
149          }
150          else
151          {
152             // if customer storage, we use the custom name as path
153             strncpy(dbPath, dbContext->configKey.custom_name, strlen(dbContext->configKey.custom_name));
154          }
155          resourceFound = 1;
156       }
157       else
158       {
159          printf("get_db_context - resource_table: no value for key: %s \n", resource_id);
160          rval = EPERS_NOKEYDATA;
161       }
162    }  // resource table
163    else
164    {
165       printf("get_db_context - error resource table\n");
166       rval = EPERS_NOPRCTABLE;
167    }
168
169    if(resourceFound == 0)
170    {
171       //
172       // resource NOT found in resource table ==> default is local cached
173       //
174       dbContext->configKey.policy      = PersistencePolicy_wc;
175       dbContext->configKey.storage     = PersistenceStorage_local;
176       dbContext->configKey.permission  = 0;           // TODO define default permission
177       dbContext->configKey.max_size    = defaultMaxKeyValDataSize;
178       memcpy(dbContext->configKey.reponsible, "default", MaxConfKeyLengthResp);
179       memcpy(dbContext->configKey.custom_name, "default", MaxConfKeyLengthCusName);
180       //printf("get_db_context ==> R E S O U R C E  N O T found: %s \n", resource_id);
181
182       rval = get_db_path_and_key(dbContext, resource_id, isFile, dbKey, dbPath);
183    }
184
185    return rval;
186 }
187
188
189
190 // status: OK
191 int get_db_path_and_key(PersistenceInfo_s* dbContext, const char* resource_id, unsigned int isFile, char dbKey[], char dbPath[])
192 {
193    int storePolicy = PersistenceStoragePolicy_LastEntry;
194
195    //
196    // create resource database key
197    //
198    if((dbContext->context.ldbid < 0x80) || (dbContext->context.ldbid == 0xFF) )
199    {
200       // The LDBID is used to find the DBID in the resource table.
201       if((dbContext->context.user_no == 0) && (dbContext->context.seat_no == 0))
202       {
203          //
204          // Node is added in front of the resource ID as the key string.
205          //
206          snprintf(dbKey, DbKeyMaxLen, "%s/%s", gNode, resource_id);
207       }
208       else
209       {
210          //
211          // Node is added in front of the resource ID as the key string.
212          //
213          if(dbContext->context.seat_no == 0)
214          {
215             // /User/<user_no_parameter> is added in front of the resource ID as the key string.
216             snprintf(dbKey, DbKeyMaxLen, "%s%d/%s", gUser, dbContext->context.user_no, resource_id);
217          }
218          else
219          {
220             // /User/<user_no_parameter>/Seat/<seat_no_parameter> is added in front of the resource ID as the key string.
221             snprintf(dbKey, DbKeyMaxLen, "%s%d%s%d/%s", gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
222          }
223       }
224       storePolicy = PersistenceStorage_local;
225    }
226
227    if((dbContext->context.ldbid >= 0x80) && (dbContext->context.ldbid != 0xFF))
228    {
229       // The LDBID is used to find the DBID in the resource table.
230       // /<LDBID parameter> is added in front of the resource ID as the key string.
231       //  Rational: Creates a namespace within one data base.
232       //  Rational: Reduction of number of databases -> reduction of maintenance costs
233       // /User/<user_no_parameter> and /Seat/<seat_no_parameter> are add after /<LDBID parameter> if there are different than 0.
234
235       if(dbContext->context.seat_no != 0)
236       {
237          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, gSeat, dbContext->context.seat_no, resource_id);
238       }
239       else
240       {
241          snprintf(dbKey, DbKeyMaxLen, "/%x%s%d/%s", dbContext->context.ldbid, gUser, dbContext->context.user_no, resource_id);
242       }
243       storePolicy = PersistenceStorage_local;
244    }
245
246    //
247    // create resource database path
248    //
249    if(dbContext->context.ldbid < 0x80)
250    {
251       // S H A R E D  database
252
253       if(dbContext->context.ldbid != 0)
254       {
255          // Additionally /GROUP/<LDBID_parameter> shall be added inside of the database path listed in the resource table. (Off target)
256          //
257          // shared  G R O U P  database * * * * * * * * * * * * *  * * * * * *
258          //
259          if(PersistencePolicy_wc == dbContext->configKey.policy)
260          {
261             if(isFile == ResIsNoFile)
262                snprintf(dbPath, DbPathMaxLen, gSharedCachePath, gAppId, dbContext->context.ldbid, gSharedCached);
263             else
264                snprintf(dbPath, DbPathMaxLen, gSharedCachePath, gAppId, dbContext->context.ldbid, dbKey);
265          }
266          else if(PersistencePolicy_wt == dbContext->configKey.policy)
267          {
268             if(isFile == ResIsNoFile)
269                snprintf(dbPath, DbPathMaxLen, gSharedWtPath, gAppId, dbContext->context.ldbid, gSharedWt);
270             else
271                snprintf(dbPath, DbPathMaxLen, gSharedWtPath, gAppId, dbContext->context.ldbid, dbKey);
272          }
273       }
274       else
275       {
276          // Additionally /Shared/Public shall be added inside of the database path listed in the resource table. (Off target)
277          //
278          // shared  P U B L I C  database * * * * * * * * * * * * *  * * * * *
279          //
280          if(PersistencePolicy_wc == dbContext->configKey.policy)
281          {
282             if(isFile == ResIsNoFile)
283                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePath, gAppId, gSharedCached);
284             else
285                snprintf(dbPath, DbPathMaxLen, gSharedPublicCachePath, gAppId, dbKey);
286          }
287          else if(PersistencePolicy_wt == dbContext->configKey.policy)
288          {
289             if(isFile == ResIsNoFile)
290                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPath, gAppId, gSharedWt);
291             else
292                snprintf(dbPath, DbPathMaxLen, gSharedPublicWtPath, gAppId, dbKey);
293          }
294       }
295
296       storePolicy = PersistenceStorage_shared;   // we have a shared database
297    }
298    else
299    {
300       // L O C A L   database
301
302       if(PersistencePolicy_wc == dbContext->configKey.policy)
303       {
304          if(isFile == ResIsNoFile)
305             snprintf(dbPath, DbPathMaxLen, gLocalCachePath, gAppId, gLocalCached);
306          else
307             snprintf(dbPath, DbPathMaxLen, gLocalCachePath, gAppId, dbKey);
308       }
309       else if(PersistencePolicy_wt == dbContext->configKey.policy)
310       {
311          if(isFile == ResIsNoFile)
312             snprintf(dbPath, DbPathMaxLen, gLocalWtPath, gAppId, gLocalWt);
313          else
314             snprintf(dbPath, DbPathMaxLen, gLocalWtPath, gAppId, dbKey);
315       }
316
317       storePolicy = PersistenceStorage_local;   // we have a local database
318    }
319
320    //printf("get_db_path_and_key - dbKey  : [key ]: %s \n",  dbKey);
321    //printf("get_db_path_and_key - dbPath : [path]: %s\n\n", dbPath);
322    return storePolicy;
323 }
324
325
326
327
328
329