/*
*
* ProLinga-Data
*
* Copyright (C) 2002-2008 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-Data.
*
* ProLinga-Data is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProLinga-Data is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProLinga-Data. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "DatCommon.h"
#include
#include
#include "DatMain.hpp"
#include "DCDataCommand.hpp"
#include "DCAdmin.hpp"
#include "DCDataModel.hpp"
#include "DCDataSource.hpp"
#include "DCExecuteQuery.hpp"
#include "DCExecuteNonQuery.hpp"
#include "DCManageData.hpp"
#include "DCTransaction.hpp"
#include "DCSession.hpp"
#include "DatError.hpp"
extern DCSessionPtr sesPtr;
xmlDocPtr DCCreateResponse(void)
{
xmlDocPtr docRes;
xmlNodePtr curRes;
/* Set up Response file */
docRes = xmlNewDoc((const xmlChar *)XML_VERSION);
(docRes)->children = xmlNewDocNode(docRes, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curRes = xmlDocGetRootElement(docRes);
xmlNewTextChild (curRes, NULL, (const xmlChar *)"Data", (const xmlChar *)"");
curRes = (curRes)->xmlChildrenNode;
xmlNewProp (curRes, (const xmlChar *)"Version", (const xmlChar *)DAT_DOC_VERSION);
/* return */
return docRes;
}
xmlDocPtr DCCreateCommandDoc(xmlNodePtr curReq)
{
xmlDocPtr docCmd = NULL;
xmlNodePtr curCmd;
/* Set node pointer to object in file command */
curReq = curReq->xmlChildrenNode;
while (curReq != NULL)
{
if (!xmlStrcmp(curReq->name, (const xmlChar *) "Object"))
break;
curReq = curReq->next;
}
/* Create new Command Doc */
docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
//(**docCmd).children = xmlNewDocNode(*docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
(docCmd)->children = xmlNewDocNode(docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(docCmd);
curCmd->xmlChildrenNode = xmlCopyNodeList(curReq);
/* Return */
return docCmd;
}
void DCCreateObjectDoc(const xmlNodePtr curReqCmd, xmlDocPtr *docObj)
{
xmlNodePtr curObj;
/* Create new Object Doc */
*docObj = xmlNewDoc((const xmlChar *)XML_VERSION);
(*docObj)->children = xmlNewDocNode(*docObj, NULL, (const xmlChar *)ROOT_ELEM, NULL);
/* Set node pointer */
curObj = xmlDocGetRootElement(*docObj);
/* Copy Object Node list */
curObj->xmlChildrenNode = xmlCopyNode(curReqCmd, 1);
}
void DCCreateResponseCommand(const char *cmdName, const char *sessionId, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Create Command Response */
**docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
(***docCmd).children = xmlNewDocNode(**docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(**docCmd);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Command", (const xmlChar *)"");
curCmd = curCmd->xmlChildrenNode;
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)cmdName);
xmlNewProp (curCmd, (const xmlChar *)"Mode", (const xmlChar *)"Response");
if ((sessionId != NULL) && (strlen(sessionId) > 0))
xmlNewProp (curCmd, (const xmlChar *)"SessionId", (const xmlChar *)sessionId);
}
void DCInsertResponseObjectHeaderOnly(const char *objName, const char *objDataSource, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Insert DataSource, Table and Lock in Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
if (xmlNodeIsText(curCmd) == 1)
curCmd = curCmd->next;
curCmd = curCmd->xmlChildrenNode;
if (xmlNodeIsText(curCmd) == 1)
curCmd = curCmd->next;
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
if ((objName != NULL) && (strlen(objName) > 0))
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)objName);
if ((objDataSource != NULL) && (strlen(objDataSource) > 0))
xmlNewProp (curCmd, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource);
}
void DCInsertResponseObjectDoc(const xmlDocPtr docObj, xmlDocPtr **docCmd)
{
xmlNodePtr curObj, curCmd;
//xmlAttrPtr attrCmd;
/* Set Pointer Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
/* Set Pointer Object */
curObj = xmlDocGetRootElement(docObj);
curObj = curObj->xmlChildrenNode;
while (curObj != NULL)
{
if (!xmlStrcmp(curObj->name, (const xmlChar *) "Object"))
break;
curObj = curObj->next;
}
/* Merge */
xmlAddChild(curCmd, xmlCopyNodeList(curObj));
}
void DCInsertObjectResponseError(const int id, const char *severity, const char *description, const char *externalDesc, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
char dummyId[10]="";
/* Set Pointer */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
curCmd = xmlGetLastChild(curCmd);
/* Insert Error */
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
sprintf(dummyId, "%d", id);
xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)dummyId);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Description", (const xmlChar *)description);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"ExternalDescription", (const xmlChar *)externalDesc);
}
void DCInsertResponseError(const int id, const char *severity, const char *description, const char *externalDesc, xmlDocPtr *docCmd)
{
xmlNodePtr curCmd;
char dummyId[10]="";
/* Set Pointer */
curCmd = xmlDocGetRootElement(*docCmd);
//curCmd = curCmd->xmlChildrenNode;
curCmd = xmlGetLastChild(curCmd);
/* Insert Error */
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
sprintf(dummyId, "%d", id);
xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)dummyId);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Description", (const xmlChar *)description);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"ExternalDescription", (const xmlChar *)externalDesc);
}
void DCSetResponseCommandStatus(const int cmdStatus, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Write Status */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
if (cmdStatus == 0)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Ok");
else if (cmdStatus == 1)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Warning");
else if (cmdStatus == 2)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Error");
}
int DCCommandExec(const char *cmdName, const char *sessionId, const xmlDocPtr docReqCmd, xmlDocPtr *docResCmd)
{
xmlDocPtr docReturn = NULL, docObj;
xmlNodePtr curReqCmd;
char *objDataSource = NULL, *objName = NULL;
char *externalError;
int dbStatus = 0, cmdStatus = 0;
/* Create Command Response */
DCCreateResponseCommand(cmdName, sessionId, &docResCmd);
/* Set pointer to command */
curReqCmd = xmlDocGetRootElement(docReqCmd);
/* Check if Connect command */
if (!strcmp(cmdName, "Connect"))
{
/* Set Status */
DCSetResponseCommandStatus(0, &docResCmd);
/* Return */
return 0;
}
/* Check if Disconnect command */
if (!strcmp(cmdName, "Disconnect"))
{
/* Destroy Session Id */
dbStatus = sesPtr->destroySession(&sesPtr, sessionId);
/* Set Status */
DCSetResponseCommandStatus(0, &docResCmd);
/* Return */
return 0;
}
/* Loop through all Objects */
for (curReqCmd = curReqCmd->xmlChildrenNode; curReqCmd != NULL; curReqCmd = curReqCmd->next)
{
if (xmlStrcmp(curReqCmd->name, (const xmlChar *) "Object")) continue;
/* Get Object Details */
/* Get Name / Filter */
objName = (char *)xmlGetProp(curReqCmd, (const xmlChar *)"Name");
if (objName == NULL)
objName = "*";
/* Get DataSource */
objDataSource = (char *)xmlGetProp(curReqCmd, (const xmlChar *)"DataSource");
if (objDataSource == NULL)
objDataSource = "Default";
// objDataSource = (char *)xmlGetProp(curReqCmd, (const xmlChar *)"DataSource");
// objDataSource = "TEST";
/* Check if file has been opened */
/* Determine command and call appropriate function */
if (!strcmp(cmdName, "ListProviders"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCListProviders(objName, docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(objName, NULL, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ListDataSources"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCListDataSources(objName, docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(objName, NULL, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "OpenDataSource"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCOpenDataSource(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "CloseDataSource"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCCloseDataSource(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ExecuteQuery"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCExecuteQuery(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ExecuteNonQuery"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCExecuteNonQuery(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "Transaction"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCTransaction(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ExecuteQueryDataModel"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCExecuteQueryDataModel(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ExecuteQueryTableDataModel"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCExecuteQueryTableDataModel(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "DataModelGetRow"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCDataModelGetRow(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "DataModelAppendRow"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCDataModelAppendRow(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "DataModelUpdateRow"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCDataModelUpdateRow(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "DataModelRemoveRow"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCDataModelRemoveRow(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "DataModelClose"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCDataModelClose(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "ManageData"))
{
/* Create Object Document */
DCCreateObjectDoc(curReqCmd, &docObj);
/* Exec Command */
dbStatus = DCManageData(docObj, sessionId, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
DCInsertResponseObjectDoc(docReturn, &docResCmd);
}
else
{
/* Insert Object line in response */
DCInsertResponseObjectHeaderOnly(NULL, objDataSource, &docResCmd);
}
/* Clean up */
if (docReturn != NULL)
xmlFreeDoc(docReturn);
}
else if (!strcmp(cmdName, "Ping"))
{
/* Dummy to test if service is available */
dbStatus = 0;
}
else
{
/* Invalid Command */
dbStatus = 0;
continue;
}
/* Error handling */
if (dbStatus != 0)
{
/* If external / 3rd party error */
if (dbStatus == 90001)
{
DCInsertObjectResponseError(dbStatus, "Error", "External warning/error", externalError, &docResCmd);
delete externalError;
cmdStatus = 2;
}
else
{
DCInsertObjectResponseError(dbStatus, errorSeverity[errorTable70000[(dbStatus-70000)].severity], errorTable70000[(dbStatus-70000)].description, "", &docResCmd);
cmdStatus = 2;
}
}
}
/* Write Status */
DCSetResponseCommandStatus(cmdStatus, &docResCmd);
return 0;
}
void DCMergeResponse(const xmlDocPtr docSrc, xmlDocPtr *docDest)
{
xmlNodePtr curSrc, curDest;
/* Set pointer in source document */
curDest = xmlDocGetRootElement(*docDest);
curDest = curDest->xmlChildrenNode;
while (curDest != NULL)
{
if (!xmlStrcmp(curDest->name, (const xmlChar *) "Data"))
break;
curDest = curDest->next;
}
/* Set pointer in destination document */
curSrc = xmlDocGetRootElement(docSrc);
curSrc = curSrc->xmlChildrenNode;
while (curSrc != NULL)
{
if (!xmlStrcmp(curSrc->name, (const xmlChar *) "Command"))
break;
curSrc = curSrc->next;
}
/* Merge */
xmlAddChild(curDest, xmlCopyNodeList(curSrc));
}
xmlDocPtr DCDataCommand(const xmlDocPtr docReq)
{
xmlDocPtr docReqCmd = NULL, docRes = NULL, docResCmd = NULL;
xmlNodePtr curReq = NULL;
char *cmdName, *sessionId = NULL, retValue[255];
int dbStatus;
bool sessionExists = false;
/* Set up response document */
docRes = DCCreateResponse();
/* Point to root element */
curReq = xmlDocGetRootElement(docReq);
/* Down 1 level (/ProLinga/Data) */
curReq = curReq->xmlChildrenNode;
while (curReq != NULL)
{
if (xmlNodeIsText(curReq) == 0)
break;
curReq = curReq->next;
}
/* Loop through all Data Commands */
for (curReq = curReq->xmlChildrenNode; curReq != NULL; curReq = curReq->next)
{
if (xmlStrcmp(curReq->name, (const xmlChar *) "Command")) continue;
/* Get command name */
cmdName = (char *)xmlGetProp(curReq, (const xmlChar *)"Name");
/* Check Session Id */
sessionId = (char *)xmlGetProp(curReq, (const xmlChar *) "SessionId");
if (sessionId == NULL)
{
if (strcmp(cmdName, "Connect") == 0)
{
/* Create Session Id */
sessionId = sesPtr->createSession(&sesPtr, retValue);
}
else if (strcmp(cmdName, "Ping") == 0)
{
dbStatus = 0;
}
else
{
/* Error */
dbStatus = 70009;
DCInsertResponseError(dbStatus, errorSeverity[errorTable70000[(dbStatus-70000)].severity], errorTable70000[(dbStatus-70000)].description, "", &docRes);
/* Clean up */
//xmlCleanupParser();
/* Return */
return docRes;
}
}
else
{
/* Check Session Id */
sessionExists = sesPtr->sessionExists(&sesPtr, sessionId);
if (sessionExists == false)
{
/* Error */
dbStatus = 70009;
DCInsertResponseError(dbStatus, errorSeverity[errorTable70000[(dbStatus-70000)].severity], errorTable70000[(dbStatus-70000)].description, "", &docRes);
/* Clean up */
//xmlCleanupParser();
/* Return */
return docRes;
}
}
/* Create Command Document */
docReqCmd = DCCreateCommandDoc(curReq);
/* Execute Command */
dbStatus = DCCommandExec(cmdName, sessionId, docReqCmd, &docResCmd);
/* Merge response level 2 in level 1 */
DCMergeResponse(docResCmd, &docRes);
/* Clean up */
xmlFreeDoc(docReqCmd);
xmlFreeDoc(docResCmd);
}
/* Clean up */
//xmlCleanupParser();
/* Return */
return docRes;
}