Last active
March 9, 2019 14:11
-
-
Save vgheo/d58465b980b633c38c072e43a6478666 to your computer and use it in GitHub Desktop.
db-config-mapping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
DB Model | |
table config | |
app code desc | |
app1 map.0.k1 EUR | |
app1 map.0.k2 EDC | |
app1 map.0.v X | |
app1 map.1.k1 RON | |
app1 map.1.k2 PLT | |
app1 map.1.v Y | |
*/ | |
#include "map.h" | |
#include "splitStrng.h" | |
#define DB_CODE_SIZE 100 | |
#define DB_DESC_SIZE 100 | |
#define CODE_TOKEN_COUNT 3 | |
#define CODE_DELIM "." | |
#define DB_KEY1 "k1" | |
#define DB_KEY2 "k2" | |
#define DB_VAL "v" | |
/* assuming DB_model_1.txt | |
@return if load ok | |
*/ | |
int loadMap(Map* map) { | |
char code[DB_CODE_SIZE]; | |
char desc[DB_DESC_SIZE]; | |
/* esql... | |
SELECT code, desc | |
INTO $code, $desc | |
FROM config | |
WHERE app='app1' | |
AND code like 'map.%' | |
ORDER BY code | |
-- order not really needed.. | |
*/ | |
// for each (code, desc): | |
{ | |
MapEntry* e; | |
// Tokeinze code | |
char codeTokens[CODE_TOKEN_COUNT][DB_CODE_SIZE]; | |
int tokens=splitString(codeTokens, CODE_TOKEN_COUNT, DB_CODE_SIZE, code, CODE_DELIM); | |
if(tokens!=CODE_TOKEN_COUNT) { | |
// config error - abort | |
return 0; | |
} | |
// "map" = tokens[0] - unused | |
const char* entryIndexStr=codeTokens[1]; | |
const char* field=codeTokens[2]; | |
// convert index | |
int entryIndex; | |
if( sscanf(entryIndexStr,"%d", &entryIndex) !=1 ) { | |
return 0; | |
} | |
// ensure entry is allocated | |
while( ! (entryIndex < Map_size(map))) { | |
MapEntry * newEntry=Map_add(); | |
if(newEntry==NULL) { | |
// error - required index cannot be allocated in map | |
return 0; | |
} | |
} | |
e=Map_getEntry(entryIndex); | |
// write field to map entry | |
if( strcmp(field, DB_KEY1)==0) { | |
MapEntry_setKey(0, desc); | |
} else if( strcmp(field, DB_KEY2)==0) { | |
MapEntry_setKey(1, desc); | |
} else if( strcmp(field, DB_VAL)==0) { | |
MapEntry_setValue(desc); | |
} else { | |
// error - invalid key field name | |
return 0; | |
} | |
} // end for | |
// if needed, could also verify that there are no null keys | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
DB Model - Variant 2 | |
table config | |
app code desc | |
app1 map.0 EUR:EDC:X | |
app1 map.1 RON:PLT:Y | |
*/ | |
#include "splitStrng.h" | |
#define DB_CODE_SIZE 100 | |
#define DB_DESC_SIZE 100 | |
#define DB_CODE "map" | |
#define DB_DESC_DELIM ":" | |
#define DB_DESC_FIELD_COUNT 3 | |
/** | |
@return if load ok | |
*/ | |
int loadMap(Map* map) { | |
char code[DB_CODE_SIZE]; | |
char desc[DB_DESC_SIZE]; | |
Map_init(map); | |
/* esql... | |
SELECT code, desc | |
INTO $code, $desc | |
FROM config | |
WHERE app='app1' | |
AND code like 'map.%' | |
*/ | |
// for each (code, desc): | |
{ | |
// add entry | |
MapEntry* e = Map_add(map); | |
char descFields[DB_DESC_FIELD_COUNT][DB_DESC_SIZE]; | |
int tokens=splitString(codeFields, DB_DESC_FIELD_COUNT, DB_DESC_SIZE, desc, DB_DESC_DELIM); | |
if(tokens!=DB_DESC_FIELD_COUNT) { | |
// config error - abort | |
return 0; | |
} | |
MapEntry_setKey(0, tokens[0]); | |
MapEntry_setKey(1, tokens[1]); | |
MapEntry_setValue(tokens[2]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---- map.h ------ | |
#include <stddef.h> | |
#define MAX_FIELD_LEN 10 | |
#define FIELD_SIZE (MAX_FIELD_LEN+1) | |
#define KEY_COUNT 2 | |
#define MAP_SIZE=100; | |
typedef struct { | |
char key[KEY_COUNT][FIELD_SIZE]; | |
char value[FIELD_SIZE]; | |
} MapEntry; | |
typedef struct { | |
size_t entryCount; | |
MapEntry entries[MAP_SIZE]; | |
} Map; | |
void MapEntry_init(MapEntry* e); | |
void MapEntry_setKey(MapEntry* e, size_t idx, const char* k); | |
void MapEntry_setValue(MapEntry* e, size_t idx, const char* v); | |
void Map_init(Map* map); | |
size_t Map_size(Map* map); | |
MapEntry* Map_add(); | |
MapEntry* Map_getEntry(Map map, size_t idx); | |
const char* Map_get(Map* map, const char* key[]); | |
//-------- map.c | |
void MapEntry_init(MapEntry* e) { | |
memset(e, sizeof(MapEntry), 0); | |
} | |
void MapEntry_setKey(MapEntry* e, size_t idx, const char* k) { | |
strncpy(e->key[idx], desc, FIELD_SIZE) | |
// truncate to FIELD_LEN | |
e->key[idx][MAX_FIELD_LEN]=0; | |
} | |
void MapEntry_setValue(MapEntry* e, size_t idx, const char* v) { | |
strncpy(e->value, desc, FIELD_SIZE) | |
// truncate to FIELD_LEN | |
e->value[MAX_FIELD_LEN]=0; | |
} | |
void Map_init(Map* map) { | |
map->entryCount=0; | |
memset(map->entries, sizeof(map->entries), 0); | |
} | |
size_t Map_size(Map* map) { | |
return map->entryCount; | |
} | |
MapEntry* Map_add() { | |
if(map->entryCount<MAP_SIZE) { | |
map->entryCount++; | |
// initialize entry | |
MapEntry* e=&map->entries[map->entryCount-1]; | |
MapEntry_init(e); | |
return e; | |
} else { | |
return NULL; | |
} | |
} | |
MapEntry* Map_getEntry(Map map, size_t idx) { | |
return (idx<map->entryCount) ? &map[idx] : NULL; | |
} | |
/** | |
@returns the vaue mapped to key if exists, NULL otherwise | |
*/ | |
const char* Map_get(Map* map, const char* key[]) { | |
for( size_t idx=0; idx<map->entryCount; idx++) { | |
int match=1; | |
for(kIdx=0; kIdx<KEY_COUNT && match; kIdx++) { | |
match = match && strcmp(key[kIdx], map->entries[idx].key[kIdx])==0); | |
} | |
if(match) { | |
return map->entries[idx].value; | |
} | |
} | |
return NULL; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
/** | |
@param tokens | |
@param maxTokens maximum tokens that can be stored in the tokens array | |
@oaram tokenSize allocated size of each element in the tokens array | |
@param str string to be tokenized | |
@param delims string with delimiter characters that define the tokenization | |
@return resulting token count | |
@note If str contains more tokens than maxTokens, only maxTokens tokens are returned. | |
@note If parsed tokens is longer than tokenSize, truncation will occur at tokenSize-1 maximum length. | |
ref: http://www.cplusplus.com/reference/cstring/strtok/ | |
*/ | |
int splitString(char *tokens[], size_t maxTokens, size_t tokenSize, const char* str, const char* delims) { | |
// copy original string into parse buffer | |
size_t strSize=strlen(str)+1; | |
char * buffer = malloc(strSize); | |
memcpy(buffer, str, strSize); | |
// parse using buffer | |
int idx=0; | |
char* newToken=strtok(buffer, delims); | |
while( idx < maxTokens && token!=NULL) { | |
strncpy(tokens[idx], newToken, tokenSize); | |
// ensure terminator | |
tokens[idx][tokenSize-1]=0; | |
token=strtok(NULL, delims); | |
idx++ | |
} | |
free(buffer); | |
return idx | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment