/* * * ProLinga-Run * * Copyright (C) 2002-2009 Xobas Software. * All rights reserved. * * This file is part of ProLinga-Run. * * ProLinga-Run 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-Run 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-Run. If not, see . * * More information is available at the following addresses: * * Website : http://www.prolinga.org * * Email : prolinga-list@prolinga.org * * */ #include "RunCommon.h" #include #include #include #include "DataCommand.hpp" #include "DataRef.hpp" #include "BuiltIn.hpp" extern CaDataSessionPtr caDataSesPtr; extern BiDataModelStatusPtr biDataModelStatusPtr; extern DataModelPtr dmPtr; extern TablePtr tablePtr; extern BiSqlReturnPtr biSqlReturnPtr; /* Command : DATAMODEL */ /* Syntax : DATAMODEL APPEND data_model_name */ /* DATAMODEL REMOVE data_model_name */ /* DATAMODEL UPDATE data_model_name */ /* DATAMODEL SELECT data_model_name TABLE table_name [CONDITION condition [condition...]]*/ void CmdDatamodel(const char **argList, int argHits, bool isMainThread) { xmlDocPtr docData, docRes; xmlNodePtr curData; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; char dataModel[255], dataTable[32], dataTableExt[64], dataConditionTmp[1024], dataCondition[10240], tmpRef[255]; char *dataSource, *rcStatus; char dataSourceName[64]; int i, rows, cols, retStatus = 0; /* Init */ biDataModelStatusPtr->setDataModelStatus(0); /* Get Data Model Name */ getDataRef(argList[2], isMainThread, dataModel, false); /* APPEND or UPDATE */ if ( (strcmp(argList[1], "APPEND") == 0) || (strcmp(argList[1], "UPDATE") == 0) ) { /* Check if Data Model Name has been previously loaded */ if (dmPtr->existsDataModel(dmPtr, dataModel) == false ) { biDataModelStatusPtr->setDataModelStatus(10101); return; } /* Get Data Source Name */ dataSource = dmPtr->getDataSource(dmPtr, dataModel); /* Create DC Datamodel document */ docData = xmlNewDoc((const xmlChar *)"1.0"); docData->children = xmlNewDocNode(docData, NULL, (const xmlChar *)"ProLinga", NULL); curData = xmlDocGetRootElement(docData); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Data", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Version", (const xmlChar *)"1.0"); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Command", (const xmlChar *)""); if (strcmp(argList[1], "APPEND") == 0) xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)"DataModelAppendRow"); else if (strcmp(argList[1], "UPDATE") == 0) xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)"DataModelUpdateRow"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)caDataSesPtr->getDataSessionId(caDataSesPtr, dataSource)); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)caDataSesPtr->getExternalDataSource(caDataSesPtr, dataSource)); xmlNewProp(curData, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); if (strcmp(argList[1], "APPEND") == 0) { curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataModelAppendRow", (const xmlChar *)""); } else if (strcmp(argList[1], "UPDATE") == 0) { curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataModelUpdateRow", (const xmlChar *)""); sprintf(tmpRef,"%d",dmPtr->getCurrentRow(dmPtr, dataModel)); xmlNewProp(curData, (const xmlChar *)"RowId", (const xmlChar *)tmpRef); } curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataInstances", (const xmlChar *)""); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataInstance", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"SequenceNo", (const xmlChar *)"1"); cols = dmPtr->getColumns(dmPtr, dataModel); /* Get properties columns */ for (i=1;i<=cols;i++) { xmlNewTextChild(curData, NULL, (const xmlChar *)dmPtr->getColName(dmPtr, dataModel, i), \ (const xmlChar *)dmPtr->getDataValueColNo(dmPtr, dataModel, i)); } /* DEBUG */ /* xmlBufferPtr bufData; bufData = xmlBufferCreate(); curData = xmlDocGetRootElement(docData); xmlNodeDump(bufData, docData, curData, 0, 1); printf("%s\n", (char *)xmlBufferContent(bufData)); xmlBufferFree(bufData); */ /* Execute DC */ docRes = DC_Exec(docData); /* DEBUG */ /* xmlBufferPtr bufRes; bufRes = xmlBufferCreate(); xmlNodePtr curRes = xmlDocGetRootElement(docRes); xmlNodeDump(bufRes, docRes, curRes, 0, 1); printf("%s\n", (char *)xmlBufferContent(bufRes)); xmlBufferFree(bufRes); */ /* Create XPath environment */ ctxRes = xmlXPathNewContext(docRes); /* Check Status */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/@Status", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); if ( strcmp(rcStatus, "Ok") != 0) { biDataModelStatusPtr->setDataModelStatus(10101); } /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); } /* REMOVE */ else if (strcmp(argList[1], "REMOVE") == 0) { /* Check if Data Model Name has been previously loaded */ if (dmPtr->existsDataModel(dmPtr, dataModel) == false ) { biDataModelStatusPtr->setDataModelStatus(10101); return; } /* Get Data Source Name */ dataSource = dmPtr->getDataSource(dmPtr, dataModel); /* Create DC datamodel document */ docData = xmlNewDoc((const xmlChar *)"1.0"); docData->children = xmlNewDocNode(docData, NULL, (const xmlChar *)"ProLinga", NULL); curData = xmlDocGetRootElement(docData); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Data", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Version", (const xmlChar *)"1.0"); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Command", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)"DataModelRemoveRow"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)caDataSesPtr->getDataSessionId(caDataSesPtr, dataSource)); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)caDataSesPtr->getExternalDataSource(caDataSesPtr, dataSource)); xmlNewProp(curData, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataModelRemoveRow", (const xmlChar *)""); sprintf(tmpRef,"%d",dmPtr->getCurrentRow(dmPtr, dataModel)); xmlNewProp(curData, (const xmlChar *)"RowId", (const xmlChar *)tmpRef); /* Execute DC */ docRes = DC_Exec(docData); /* Create XPath environment */ ctxRes = xmlXPathNewContext(docRes); /* Check Status */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/@Status", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); if ( strcmp(rcStatus, "Ok") != 0) { biDataModelStatusPtr->setDataModelStatus(10101); } /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); } /* SELECT */ else if (strcmp(argList[1], "SELECT") == 0) { /* Get Table Name */ getDataRef(argList[4], isMainThread, dataTable, false); /* Get Data Source */ if (tablePtr->getDataSourceName(&tablePtr, dataTable) == NULL) dataSourceName[0] = '\0'; else strcpy(dataSourceName, tablePtr->getDataSourceName(&tablePtr, dataTable)); /* Get External Table Name */ if (tablePtr->getExternalName(&tablePtr, dataTable) == NULL) dataTableExt[0] = '\0'; else strcpy(dataTableExt, tablePtr->getExternalName(&tablePtr, dataTable)); /* Create DC datamodel document */ docData = xmlNewDoc((const xmlChar *)"1.0"); docData->children = xmlNewDocNode(docData, NULL, (const xmlChar *)"ProLinga", NULL); curData = xmlDocGetRootElement(docData); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Data", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Version", (const xmlChar *)"1.0"); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Command", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)"ExecuteQueryTableDataModel"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)caDataSesPtr->getDataSessionId(caDataSesPtr, dataSourceName)); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)caDataSesPtr->getExternalDataSource(caDataSesPtr, dataSourceName)); xmlNewProp(curData, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Query", (const xmlChar *)""); xmlNewTextChild(curData, NULL, (const xmlChar *)"Table", (const xmlChar *)dataTableExt); /* Concatenate 1 big string for condition */ dataCondition[0] = '\0'; for (i = 6; i <= argHits; i++) { /* Get Condition */ getDataRef(argList[i], isMainThread, dataConditionTmp, false); if (i == 6) strcpy(dataCondition, dataConditionTmp); else strcat(dataCondition, dataConditionTmp); } /* Set condition */ xmlNewTextChild(curData, NULL, (const xmlChar *)"Condition", (const xmlChar *)dataCondition); /* DEBUG */ // xmlBufferPtr bufData; // bufData = xmlBufferCreate(); // curData = xmlDocGetRootElement(docData); // xmlNodeDump(bufData, docData, curData, 0, 1); // printf("%s\n", (char *)xmlBufferContent(bufData)); // xmlBufferFree(bufData); /* Execute DC */ docRes = DC_Exec(docData); // xmlBufferPtr bufRes; // bufRes = xmlBufferCreate(); // xmlNodePtr curRes = xmlDocGetRootElement(docRes); // xmlNodeDump(bufRes, docRes, curRes, 0, 1); // printf("%s\n", (char *)xmlBufferContent(bufRes)); // xmlBufferFree(bufRes); /* Create XPath environment */ ctxRes = xmlXPathNewContext(docRes); /* Check Status */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/@Status", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); if ( strcmp(rcStatus, "Ok") != 0) { biDataModelStatusPtr->setDataModelStatus(10101); } /* Delete Data Model if present */ dmPtr->deleteOne(&dmPtr, dataModel); /* Set Data Source of Data Model */ dmPtr->putDataSource(&dmPtr, dataModel, dataSourceName); /* Get and set number of columns in data model */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Query/ColumnsDataModel", ctxRes); cols = (int)xmlXPathCastToNumber(resRes); dmPtr->putColumns(&dmPtr, dataModel, cols); /* Get and set number of rows in data model */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Query/RowsDataModel", ctxRes); rows = (int)xmlXPathCastToNumber(resRes); biSqlReturnPtr->setSqlReturn(rows); dmPtr->putRows(&dmPtr, dataModel, rows); /* Load active datamodel row with either 0 (dummy) or the first */ if (rows > 0) retStatus = dataDataModelGetRow(dataModel, 1); else retStatus = dataDataModelGetRow(dataModel, 0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); } }