PV1_MakeProject/Framework/Configure/config_engine.c

1043 lines
28 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/file.h>
#include <unistd.h>
#include <errno.h>
#include "log.h"
#include "config_engine.h"
#include "libuv_dbus.h"
#define PROCESS_MUTEX_KEY ("/root/config_server.pid")
#define CFG_SYNC_TIME_OF_SECONDS (1)
static PCFG_ITEM __cfgAddItem(const char *pKeyName, const char *pKeyValue, int iType, int overWrite, int saveToDB, int* pErr);
typedef struct
{
char keyName[MAX_CFG_KEY_NAME];
uint32_t tmCached;
UT_hash_handle hh; ///< UT Hash handle
} CFG_CACHE_ITEM, *PCFG_CACHE_ITEM;
static sqlite3* g_pSqlFileDB = NULL;
static PCFG_ITEM g_pCfgItems = NULL;
static PCFG_CACHE_ITEM g_pCfgCacheItems = NULL;
static int g_bIsCfgSvr = FALSE;
static uv_rwlock_t g_uvHashRwLock;
static uv_rwlock_t g_uvCacheRwLock;
static uv_timer_t g_uvSyncSvr;
#if 0
#define INT_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS integer(" \
"keyName TEXT PRIMARY KEY NOT NULL," \
"keyValue INTEGER NOT NULL," \
"keyModule INTEGER NOT NULL," \
"CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));")
#define STRING_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS string(" \
"keyName TEXT PRIMARY KEY NOT NULL," \
"keyValue TEXT NOT NULL," \
"keyModule INTEGER NOT NULL," \
"CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));")
#define FLOAT_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS double(" \
"keyName TEXT PRIMARY KEY NOT NULL," \
"keyValue NUMERIC NOT NULL," \
"keyModule INTEGER NOT NULL," \
"CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));")
#endif
#define FIRMWARE_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS %s (" \
"ID INTEGER PRIMARY KEY AUTOINCREMENT," \
"keyName TEXT UNIQUE NOT NULL," \
"keyValue TEXT NOT NULL," \
"keyType INTEGER NOT NULL);")
static const char* __cfgGetKeyTypeString(int keyType)
{
switch(keyType)
{
case 0:
return ("string");
case 1:
return ("integer");
case 2:
return ("double");
}
return ("Unknown Type");
}
static int __cfgItem2CfgRsp(PCFG_ITEM pCfgItem, PCFG_API_RSP pRsp)
{
if(pCfgItem == NULL || pRsp == NULL)
{
return (-ERR_INPUT_PARAMS);
}
memset(pRsp->keyValue, 0, MAX_CFG_KEY_VALUE);
pRsp->keyType = pCfgItem->keyType;
if(pCfgItem->keyType == CFG_TYPE_STRING)
{
strncpy(pRsp->keyValue, pCfgItem->pStrValue, MAX_CFG_KEY_VALUE);
}
else if(pCfgItem->keyType == CFG_TYPE_INT)
{
sprintf(pRsp->keyValue, "%d", pCfgItem->intValue);
}
else if(pCfgItem->keyType == CFG_TYPE_DOUBLE)
{
sprintf(pRsp->keyValue, "%f", pCfgItem->doubleValue);
}
pRsp->errNo = 0;
return (0);
}
static int __cfgMsg2CfgItem(int keyType, const char *pKeyName, const char *pKeyValue, PCFG_ITEM pCfgItem)
{
int iValue;
double dValue;
char *pEndPtr = NULL;
if(pKeyName == NULL || pKeyValue == NULL || pCfgItem == NULL)
{
return (-ERR_INPUT_PARAMS);
}
strcpy(pCfgItem->pKeyName, pKeyName);
pCfgItem->keyType = keyType;
pCfgItem->keyModule = DBusLibuvGetRuntime()->modName;
switch(keyType)
{
case CFG_TYPE_STRING:
strcpy(pCfgItem->pStrValue, pKeyValue);
break;
case CFG_TYPE_INT:
iValue = strtol(pKeyValue, NULL, 10);
if(errno == ERANGE || errno == EINVAL)
{
return (-ERR_STR_CONVERT);
}
else
{
pCfgItem->intValue = iValue;
}
break;
case CFG_TYPE_DOUBLE:
dValue = strtod(pKeyValue, &pEndPtr);
if((errno == ERANGE) || (dValue == 0 && (strcmp(pKeyValue, pEndPtr) == 0)))
{
return (-ERR_STR_CONVERT);
}
else
{
pCfgItem->doubleValue = dValue;
}
break;
default :
return (-ERR_UNKNOWN_TYPE);
}
return (0);
}
static int __cfgMsg2CfgItemV2(int keyType, const char *pKeyName, const char *pKeyValue, PCFG_ITEM* pItem)
{
int iSize;
PCFG_ITEM pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM));
char* pCache = NULL;
if(pKeyName == NULL || pKeyValue == NULL || pCfgItem == NULL)
{
free(pCfgItem);
return (-ERR_INPUT_PARAMS);
}
switch(keyType)
{
case CFG_TYPE_STRING:
iSize += strlen(pKeyValue) + 1;
pCache = (char*)malloc(iSize);
memset(pCache, 0, iSize);
pCfgItem->pKeyName = pCache;
pCfgItem->pStrValue = pCache + strlen(pKeyName) + 1;
__cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);;
break;
case CFG_TYPE_INT:
pCfgItem->pKeyName = (char*)malloc(iSize);
memset(pCfgItem->pKeyName, 0, iSize);
strcpy(pCfgItem->pKeyName, pKeyName);
__cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);;
break;
case CFG_TYPE_DOUBLE:
pCfgItem->pKeyName = (char*)malloc(iSize);
memset(pCfgItem->pKeyName, 0, iSize);
strcpy(pCfgItem->pKeyName, pKeyName);
__cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);;
break;
default:
free(pCfgItem);
return -ERR_UNKNOWN_TYPE;
}
*pItem = pCfgItem;
return 0;
}
int Sqlite3SyncDB(sqlite3* pSqlMemory, const char* pMemDbName, const char* pDBFilePath, const char* pFileDbName, int isSave)
{
int rc;
sqlite3* pSqlFile;
sqlite3_backup* pSqlBackup;
sqlite3* pSyncDest;
sqlite3* pSyncSrc;
rc = sqlite3_open(pDBFilePath, &pSqlFile);
if(rc != SQLITE_OK)
{
return -ERR_OPEN_SQLITE3_DB;
}
if(pDBFilePath == NULL || strlen(pDBFilePath) == 0)
{
pMemDbName = "main";
}
if(pFileDbName == NULL || strlen(pFileDbName) == 0)
{
pFileDbName = "main";
}
pSyncSrc = isSave ? pSqlMemory : pSqlFile;
pSyncDest = isSave ? pSqlFile : pSqlMemory;
pSqlBackup = sqlite3_backup_init(pSyncDest, pMemDbName, pSyncSrc, pFileDbName);
if(pSqlBackup != NULL)
{
#if 1
do
{
rc = sqlite3_backup_step(pSqlBackup, 10);
if(rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
{
sqlite3_sleep(100);
}
} while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
#else
sqlite3_backup_step(pSqlBackup, -1);
#endif
sqlite3_backup_finish(pSqlBackup);
}
else
{
LOG_EX(LOG_Error, "Backup Database Error\n");
}
rc = sqlite3_errcode(pSyncDest);
return rc;
}
static int __sqlite3LoadCb(void* data, int argc, char** argv, char** azColName)
{
if(argc == 4)
{
int iSize;
PCFG_ITEM pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM));
char* pCache = NULL;
int ret = 0;
pCfgItem->keyType = atoi(argv[3]);
pCfgItem->keyModule = *(int*)data;
iSize = strlen(argv[1]) + 1;
switch(pCfgItem->keyType)
{
case CFG_TYPE_STRING:
iSize += strlen(argv[2]) + 1;
pCache = (char*)malloc(iSize);
memset(pCache, 0, iSize);
pCfgItem->pKeyName = pCache;
pCfgItem->pStrValue = pCache + strlen(argv[1]) + 1;
ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);;
break;
case CFG_TYPE_INT:
pCfgItem->pKeyName = (char*)malloc(iSize);
memset(pCfgItem->pKeyName, 0, iSize);
strcpy(pCfgItem->pKeyName, argv[1]);
ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);;
break;
case CFG_TYPE_DOUBLE:
pCfgItem->pKeyName = (char*)malloc(iSize);
memset(pCfgItem->pKeyName, 0, iSize);
strcpy(pCfgItem->pKeyName, argv[1]);
ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);;
break;
default:
free(pCfgItem);
return -ERR_UNKNOWN_TYPE;
}
uv_rwlock_wrlock(&g_uvHashRwLock);
HASH_ADD_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_wrunlock(&g_uvHashRwLock);
if(ret == 0)
{
CfgItemPrint("Load Configure: ", pCfgItem);
}
}
else
{
LOG_EX(LOG_Error, "argc = %d\n", argc);
}
return 0;
}
static int __cfgLoadGlobalConfig(void)
{
int rc = 0;
char* pErrMsg = NULL;
char sqlCmd[1024];
PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime();
memset(sqlCmd, 0, 1024);
sprintf(sqlCmd, "SELECT * FROM %s", MODULE_ALIAS_NAME(MODULE_CONFIGURE));
// get global configure
rc = sqlite3_exec(g_pSqlFileDB, sqlCmd, __sqlite3LoadCb, (void*)MODULE_CONFIGURE, &pErrMsg);
if(rc != SQLITE_OK)
{
LOG_EX(LOG_Error, "SQLite3 Query Error: %s\n", pErrMsg);
return -ERR_SQL_QUERY;
}
if(pContext->modName != MODULE_CONFIGURE)
{
memset(sqlCmd, 0, 1024);
sprintf(sqlCmd, "SELECT * FROM %s", MODULE_ALIAS_NAME(pContext->modName));
// get local configure
rc = sqlite3_exec(g_pSqlFileDB, sqlCmd, __sqlite3LoadCb, (void*)&pContext->modName, &pErrMsg);
if(rc != SQLITE_OK)
{
LOG_EX(LOG_Error, "SQLite3 Query Error: %s\n", pErrMsg);
sqlite3_free(pErrMsg);
return -ERR_SQL_QUERY;
}
}
return 0;
}
void CfgItemPrint(const char* pPrefix, PCFG_ITEM pCfgItem)
{
if(pCfgItem == NULL)
{
fprintf(stderr, "CfgItemPrint: NULL\n");
return;
}
switch(pCfgItem->keyType)
{
case 0:
LOG_EX(LOG_Debug, "%s[%s] = \"%s\", \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "",
pCfgItem->pKeyName, pCfgItem->pStrValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule));
break;
case 1:
LOG_EX(LOG_Debug, "%s[%s] = %d, \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "",
pCfgItem->pKeyName, pCfgItem->intValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule));
break;
case 2:
LOG_EX(LOG_Debug, "%s[%s] = %f, \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "",
pCfgItem->pKeyName, pCfgItem->doubleValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule));
break;
default:
LOG_EX(LOG_Error, "Unknown type = %d\n", pCfgItem->keyType);
break;
}
}
int CfgAddGlobalConfig(const char *pKeyName, const char *pKeyValue, CFG_DATA_TYPE keyType)
{
CFG_API_REQ req;
int ret;
if(pKeyName == NULL || pKeyValue == NULL || strlen(pKeyName) == 0 || strlen(pKeyValue) == 0)
{
return (-ERR_INPUT_PARAMS);
}
if(keyType < 0 || keyType > CFG_TYPE_DOUBLE)
{
return (-ERR_INPUT_PARAMS);
}
memset(&req, 0, sizeof(CFG_API_REQ));
strncpy(req.keyName, pKeyName, MAX_CFG_KEY_NAME);
strncpy(req.keyValue, pKeyValue, MAX_CFG_KEY_VALUE);
ret = DBusJsonSendToCommand(NULL,
g_pModInfoTable[MODULE_CONFIGURE].modAliase,
CMD_CFG_ADD_REQ,
JSON_ENGINE_CFG_REQ,
&req, TRUE);
if(ret == 0)
{
return (-ERR_CFG_WAIT_RSP);
}
else
{
return (ret);
}
}
int CfgAddKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB)
{
int err = 0;
PCFG_ITEM pCfgItem = NULL;
if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0)
{
return (-ERR_INPUT_PARAMS);
}
uv_rwlock_rdlock(&g_uvHashRwLock);
HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_rdunlock(&g_uvHashRwLock);
if(pCfgItem != NULL)
{
return (-ERR_CFG_ITEM_EXIST);
}
if(pItem->keyType == CFG_TYPE_STRING)
{
__cfgAddItem(pKeyName, (const char*)pItem->pStrValue, pItem->keyType, FALSE, saveToDB, &err);
}
else
{
char buf[256];
memset(buf, 0, 256);
if(pItem->keyType == CFG_TYPE_INT)
{
sprintf(buf, "%d", pItem->intValue);
}
else if(pItem->keyType == CFG_TYPE_DOUBLE)
{
sprintf(buf, "%f", pItem->doubleValue);
}
__cfgAddItem(pKeyName, (const char*)buf, pItem->keyType, FALSE, saveToDB, &err);
}
return (err);
}
int CfgChangeKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB)
{
int err = 0;
PCFG_ITEM pCfgItem = NULL;
if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0)
{
return (-ERR_INPUT_PARAMS);
}
uv_rwlock_rdlock(&g_uvHashRwLock);
HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_rdunlock(&g_uvHashRwLock);
if(pCfgItem == NULL)
{
return (-ERR_CFG_NOITEM);
}
HASH_DEL(g_pCfgItems, pCfgItem);
if(pItem->keyType == CFG_TYPE_STRING)
{
__cfgAddItem(pKeyName, (const char*)pItem->pStrValue, pItem->keyType, FALSE, saveToDB, &err);
}
else
{
char buf[256];
memset(buf, 0, 256);
if(pItem->keyType == CFG_TYPE_INT)
{
sprintf(buf, "%d", pItem->intValue);
}
else if(pItem->keyType == CFG_TYPE_DOUBLE)
{
sprintf(buf, "%f", pItem->doubleValue);
}
__cfgAddItem(pKeyName, (const char*)buf, pItem->keyType, FALSE, saveToDB, &err);
}
return (err);
}
int CfgGetKeyValue(const char* pKeyName, PCFG_ITEM* pItem)
{
PCFG_ITEM pCfgItem = NULL;
PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime();
if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0)
{
return (-ERR_INPUT_PARAMS);
}
uv_rwlock_rdlock(&g_uvHashRwLock);
HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_rdunlock(&g_uvHashRwLock);
if(pCfgItem == NULL)
{
if(pContext->modName == MODULE_CONFIGURE)
{
return (-ERR_CFG_NOITEM);
}
else
{
CFG_API_REQ req;
int ret = 0;
memset(&req, 0, sizeof(CFG_API_REQ));
strncpy(req.keyName, pKeyName, MAX_CFG_KEY_NAME);
ret = DBusJsonSendToCommand(NULL, g_pModInfoTable[MODULE_CONFIGURE].modAliase, CMD_CFG_GET_REQ, JSON_ENGINE_CFG_REQ, &req, TRUE);
if(ret == 0)
{
return (-ERR_CFG_WAIT_RSP);
}
else
{
return (ret);
}
}
}
*pItem = pCfgItem;
return 0;
}
static int __cfgCreateCfgFile(const char* pCfgFilePath)
{
/*const char* pSqlIntDB = NULL;
const char* pSqlFloatDB = NULL;
const char* pSqlStringDB = NULL; */
char* pErrMsg = NULL;
int rc = 0;
int i = 0;
rc = sqlite3_open_v2(pCfgFilePath, &g_pSqlFileDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if(rc)
{
LOG_EX(LOG_Error, "sqlite3_open_v2 error: %s\n", pCfgFilePath);
return -ERR_OPEN_SQLITE3_DB;
}
for(i = 0; (i < sizeof(g_pModInfoTable) / sizeof(g_pModInfoTable[0])); i++)
{
char sqlBuf[1024];
memset(sqlBuf, 0, 1024);
sprintf(sqlBuf, FIRMWARE_TBL_SQL_CMD, MODULE_ALIAS_NAME(i));
rc = sqlite3_exec(g_pSqlFileDB, sqlBuf, NULL, 0, &pErrMsg);
if(rc != SQLITE_OK)
{
uv_fs_t uvFs;
LOG_EX(LOG_Error, "Create Tbl[%d] Error: %s\n", i, pErrMsg);
sqlite3_free(pErrMsg);
uv_fs_unlink(GetDBusDefaultLoop(), &uvFs, pCfgFilePath, NULL);
return -ERR_SQLITE3_CREATE_TABLE;
}
}
return 0;
}
#if 0
static void onSigTermProgressExit(int sign)
{
if(g_bIsCfgSvr)
{
}
kill(getpid(), SIGKILL);
}
static void onProgressExit(void)
{
onSigTermProgressExit(0);
}
#endif
static int __cfgCheckCfgSvrRun(void)
{
int rc;
int fd = open(PROCESS_MUTEX_KEY, O_CREAT | O_RDWR, 0666);
if(fd == -1)
{
LOG_EX(LOG_Debug, "Open File Error\n");
}
rc = flock(fd, LOCK_EX | LOCK_NB);
if(rc == -1)
{
LOG_EX(LOG_Debug, "Configure server running\n");
return FALSE;
}
else
{
LOG_EX(LOG_Debug, "Configure server stoped\n");
return TRUE;
}
}
static int __cfgAddToCache(const char *pKeyName)
{
PCFG_CACHE_ITEM pItem = NULL;
uv_rwlock_rdlock(&g_uvCacheRwLock);
HASH_FIND_STR(g_pCfgCacheItems, pKeyName, pItem);
uv_rwlock_rdunlock(&g_uvCacheRwLock);
if(pItem != NULL)
{
HASH_DEL(g_pCfgCacheItems, pItem);
free(pItem);
}
pItem = (PCFG_CACHE_ITEM)malloc(sizeof(CFG_CACHE_ITEM));
strncpy(pItem->keyName, pKeyName, MAX_CFG_KEY_NAME);
pItem->tmCached = LIBUV_CURRENT_TIME_MS();
uv_rwlock_wrlock(&g_uvCacheRwLock);
HASH_ADD_STR(g_pCfgCacheItems, keyName, pItem);
uv_rwlock_wrunlock(&g_uvCacheRwLock);
return (0);
}
static PCFG_ITEM __cfgAddItem(const char *pKeyName, const char *pKeyValue, int iType, int overWrite, int saveToDB, int* pErr)
{
PCFG_ITEM pCfgItem = NULL;
int iSize = 0;
char *pCache = NULL;
uv_rwlock_rdlock(&g_uvHashRwLock);
HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_rdunlock(&g_uvHashRwLock);
if(pCfgItem != NULL)
{
if(overWrite)
{
HASH_DEL(g_pCfgItems, pCfgItem);
free(pCfgItem->pKeyName);
free(pCfgItem);
}
else
{
if(pErr)
{
*pErr = -ERR_CFG_NOITEM;
}
return NULL;
}
}
if(iType == CFG_TYPE_STRING)
{
iSize = strlen(pKeyName) + strlen(pKeyValue) + 2;
}
else
{
iSize = strlen(pKeyName) + 1;
}
pCache = (char *)malloc(iSize);
memset(pCache, 0, iSize);
pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM));
pCfgItem->pKeyName = pCache;
if(iType == CFG_TYPE_STRING)
{
pCfgItem->pStrValue = pCache + strlen(pKeyName) + 1;
}
__cfgMsg2CfgItem(iType, pKeyName, pKeyValue, pCfgItem);
uv_rwlock_wrlock(&g_uvHashRwLock);
HASH_ADD_STR(g_pCfgItems, pKeyName, pCfgItem);
uv_rwlock_wrunlock(&g_uvHashRwLock);
// if need save this configure item to database
if(saveToDB)
{
__cfgAddToCache(pKeyName);
}
if(pErr)
{
*pErr = 0;
}
return (pCfgItem);
}
static void __cfgSyncServer(void)
{
if(HASH_COUNT(g_pCfgCacheItems) > 0)
{
PCFG_CACHE_ITEM pItem = NULL, pTemp = NULL;
sqlite3_exec(g_pSqlFileDB, "BEGIN TRANSACTION;", NULL, NULL, NULL);
HASH_ITER(hh, g_pCfgCacheItems, pItem, pTemp)
{
PCFG_ITEM pCfgItem = NULL;
if(CfgGetKeyValue(pItem->keyName, &pCfgItem) == 0)
{
char* pSqlInsertCmd = (char*)malloc(1024 * 4);
char* pSqlUpgradeCmd = (char*)malloc(1024 * 4);
memset(pSqlInsertCmd, 0, 1024 * 4);
memset(pSqlUpgradeCmd, 0, 1024 * 4);
if(pCfgItem->keyType == CFG_TYPE_STRING)
{
sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%s\', %d)",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->pStrValue, pCfgItem->keyType);
sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%s\', keyType = %d WHERE keyName = \'%s\'",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pStrValue, pCfgItem->keyType, pCfgItem->pKeyName);
}
else if(pCfgItem->keyType == CFG_TYPE_INT)
{
sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%d\', %d)",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->intValue, pCfgItem->keyType);
sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%d\', keyType = %d WHERE keyName = \'%s\'",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->intValue, pCfgItem->keyType, pCfgItem->pKeyName);
}
else if(pCfgItem->keyType == CFG_TYPE_DOUBLE)
{
sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%f\', %d)",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->doubleValue, pCfgItem->keyType);
sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%f\', keyType = %d WHERE keyName = \'%s\'",
MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->doubleValue, pCfgItem->keyType, pCfgItem->pKeyName);
}
if((sqlite3_exec(g_pSqlFileDB, pSqlInsertCmd, NULL, NULL, NULL) == SQLITE_OK)
&& (sqlite3_exec(g_pSqlFileDB, pSqlUpgradeCmd, NULL, NULL, NULL) == SQLITE_OK))
{
// Delete this Key
HASH_DEL(g_pCfgCacheItems, pItem);
LOG_EX(LOG_Debug, "Sync Configure %s To Database\n", pCfgItem->pKeyName);
}
else
{
free(pSqlInsertCmd);
free(pSqlUpgradeCmd);
return;
}
free(pSqlInsertCmd);
free(pSqlUpgradeCmd);
}
else
{
// Delete this Key
HASH_DEL(g_pCfgCacheItems, pItem);
}
}
sqlite3_exec(g_pSqlFileDB, "END TRANSACTION;", NULL, NULL, NULL);
}
}
static void __uvThreadSyncCfg(void *pParams)
{
while(TRUE)
{
__cfgSyncServer();
sleep(CFG_SYNC_TIME_OF_SECONDS);
}
pthread_detach(pthread_self());
}
static void __cfgStartSyncGlobalCfgSvr(void)
{
uv_thread_t uvSyncThread;
uv_rwlock_init(&g_uvCacheRwLock);
uv_thread_create(&uvSyncThread, __uvThreadSyncCfg, NULL);
}
static PCFG_ITEM __onCMD_CFG_GET_REQ(const char* pKeyName, int* pErr)
{
PCFG_ITEM pItem = NULL;
*pErr = CfgGetKeyValue(pKeyName, &pItem);
if(*pErr == 0)
{
return (pItem);
}
return (NULL);
}
static int __onCMD_CFG_ADD_REQ(const char* pKeyName, const char* pKeyValue, int keyType)
{
PCFG_ITEM pCfgItem = NULL;
int ret;
if(pKeyName == NULL || pKeyValue == NULL || strlen(pKeyName) == 0 || strlen(pKeyValue) == 0)
{
return (-ERR_INPUT_PARAMS);
}
if(keyType < 0 || keyType > CFG_TYPE_DOUBLE)
{
return (-ERR_INPUT_PARAMS);
}
ret = __cfgMsg2CfgItemV2(keyType, pKeyName, pKeyValue, &pCfgItem);
if(ret != 0)
{
return (ret);
}
return CfgAddKeyValue(pKeyName, pCfgItem, TRUE);
}
static void __cfgSvrProcessCmd(DBUS_CMD cmd, const char* pKeyName, const char* pKeyValue, int keyType, PCFG_API_RSP pRsp)
{
PCFG_ITEM pItem = NULL;
int err;
memset(pRsp, 0, sizeof(CFG_API_RSP));
pRsp->errNo = -ERR_UNKNOWN_TYPE;
if(pKeyName == NULL)
{
pRsp->errNo = -ERR_INPUT_PARAMS;
return;
}
strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME);
switch(cmd)
{
case CMD_CFG_ADD_REQ:
err = __onCMD_CFG_ADD_REQ(pKeyName, pKeyValue, keyType);
pRsp->keyType = keyType;
pRsp->errNo = err;
strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME);
strncpy(pRsp->keyValue, pKeyValue, MAX_CFG_KEY_VALUE);
break;
case CMD_CFG_GET_REQ:
pItem = __onCMD_CFG_GET_REQ(pKeyName, &err);
if(pItem == NULL || err != 0)
{
pRsp->keyType = -1;
pRsp->errNo = err;
strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME);
return;
}
else
{
__cfgItem2CfgRsp(pItem, pRsp);
return;
}
break;
}
return;
}
int CfgGlobalEnvInit(void)
{
int rc = 0;
uv_rwlock_init(&g_uvHashRwLock);
rc = __cfgCreateCfgFile(GLOBAL_CFG_FILE_PATH);
if(rc != SQLITE_OK)
{
return rc;
}
#if 0
rc = sqlite3_open_v2(":memory:", &g_pSqlMemDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if(rc != SQLITE_OK)
{
LOG_EX(LOG_Error, "Create Memory SQLite3 DB Error\n");
return -ERR_CREATE_SQLITE3_DB;
}
//rc = sqlite3SyncDatabase(g_pSqlMemDB, GLOBAL_CFG_FILE_PATH, 0);
#endif
rc = __cfgLoadGlobalConfig();
if(rc != SQLITE_OK)
{
return (-ERR_OPEN_SQLITE3_DB);
//sqlite3_close(g_pSqlFileDB);
}
#if 0
g_bIsCfgSvr = cfgCheckCfgSvrRun();
if(atexit(onProgressExit) != 0)
{
fprintf(stderr, "atexit error\n");
}
signal(SIGINT, onSigTermProgressExit);
#endif
__cfgStartSyncGlobalCfgSvr();
return 0;
}
void OnCfgMsgProcess(MODULE_NAME dest, DBUS_CMD busCmd, const char* pJsonStr)
{
CFG_API_RSP cfgRsp;
int err = 0;
PCFG_API_REQ pReq = NULL;
PCFG_API_RSP pRsp = NULL;
PLIBUV_DBUS_PARAMS pParams = DBusLibuvGetRuntime();
switch(busCmd)
{
case CMD_CFG_ADD_REQ:
case CMD_CFG_GET_REQ:
pReq = Json2Struct(pJsonStr, JSON_ENGINE_CFG_REQ, TRUE, &err);
if(pReq != NULL && err == 0)
{
pRsp = &cfgRsp;
__cfgSvrProcessCmd(busCmd, pReq->keyName, pReq->keyValue, pReq->keyType, pRsp);
DBusJsonSendToCommand(NULL, g_pModInfoTable[dest].modAliase, busCmd + 1, JSON_ENGINE_CFG_RSP, pRsp, TRUE);
}
free(pReq);
break;
#if 0
case CMD_CFG_GET_REQ:
pReq = Json2Struct(pJsonStr, JSON_ENGINE_CFG_REQ, TRUE, &err);
if(pReq != NULL && err == 0)
{
pRsp = &cfgRsp;
__cfgSvrProcessCmd(busCmd, pReq->keyName, NULL, pReq->keyType, pRsp);
DBusJsonSendToCommand(NULL, g_pModInfoTable[dest].modAliase, CMD_CFG_GET_RSP, JSON_ENGINE_CFG_RSP, pRsp, TRUE);
}
break;
#endif
case CMD_CFG_ADD_RSP:
case CMD_CFG_GET_RSP:
pRsp = Json2Struct(pJsonStr, JSON_ENGINE_CFG_RSP, TRUE, &err);
if(pRsp != NULL && err == 0 && pRsp->errNo == 0)
{
// Add to local Hash Table cache
PCFG_ITEM pCfgItem = __cfgAddItem(pRsp->keyName, pRsp->keyValue, pRsp->keyType, TRUE, FALSE, &err);
if(err == 0 && pCfgItem != NULL)
{
if(pParams->onCfgCb)
{
pParams->onCfgCb(busCmd, pCfgItem, 0);
}
}
else
{
LOG_EX(LOG_Error, "Add Configure {[%s]<%d> = \"%s\"} Error: %d\n",
pRsp->keyName, pRsp->keyValue, pRsp->keyType, err);
}
}
else
{
if(pParams->onCfgCb)
{
pParams->onCfgCb(busCmd, NULL, (err == 0) ? pRsp->errNo : err);
}
LOG_EX(LOG_Error, "pRsp = %p, err = %d, rspErr = %d\n", pRsp, err, pRsp ? pRsp->errNo : -err);
}
free(pRsp);
break;
}
}