/* * * ProLinga-Data * * Copyright (C) 2002-2009 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 "DCMetaStore.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, "MetaStore")) { /* Create Object Document */ DCCreateObjectDoc(curReqCmd, &docObj); /* Exec Command */ dbStatus = DCMetaStore(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; }