/* * * 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 "Main.hpp" #include #include #include #include "DataRef.hpp" #include "RepositoryCommand.hpp" #include "DataAccess.hpp" #ifndef BUILD_DATA extern char *dataEndPoint; extern int dataCompressionLevel; #endif extern DataModelPtr dmPtr; extern BiAppnPtr biAppnPtr; extern CaDataSessionPtr caDataSesPtr; extern BiSqlInfoPtr biSqlInfoPtr; extern BiSqlReturnPtr biSqlReturnPtr; xmlDocPtr DC_Exec(xmlDocPtr docReq) { xmlDocPtr docRes; /* Process Request */ #ifdef BUILD_DATA docRes = DataAccess(docReq); #else docRes = DataAccess(docReq, dataEndPoint, dataCompressionLevel); #endif /* Return */ return docRes; } xmlDocPtr dataConnect(void) { xmlDocPtr docData; xmlNodePtr curData; /* Create DC connect 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 *)"Connect"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); /* Return */ return docData; } xmlDocPtr dataDisconnect(const char *sessionId) { xmlDocPtr docData; xmlNodePtr curData; /* Create DC disconnect 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 *)"Disconnect"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)sessionId); /* Return */ return docData; } xmlDocPtr dataOpenDataSource(const char *sessionId, const char *extName, const char *userName, const char *password, const char *readOnly, const char *sqlcase, const char *threadsafe) { xmlDocPtr docData; xmlNodePtr curData; /* Create DC Open Data Source 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 *)"OpenDataSource"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)sessionId); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)extName); xmlNewTextChild(curData, NULL, (const xmlChar *)"UserName", (const xmlChar *)userName); xmlNewTextChild(curData, NULL, (const xmlChar *)"Password", (const xmlChar *)password); xmlNewTextChild(curData, NULL, (const xmlChar *)"ReadOnlyConnection", (const xmlChar *)readOnly); xmlNewTextChild(curData, NULL, (const xmlChar *)"SqlIdentifiersCaseSensitive", (const xmlChar *)sqlcase); xmlNewTextChild(curData, NULL, (const xmlChar *)"ThreadSafe", (const xmlChar *)threadsafe); /* Return */ return docData; } xmlDocPtr dataCloseDataSource(const char *sessionId, const char *extName) { xmlDocPtr docData; xmlNodePtr curData; /* Create DC Close Data Source 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 *)"CloseDataSource"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)sessionId); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)extName); /* Return */ return docData; } xmlDocPtr dataManageData(const char *sessionId, const char *appnName, const char *dsrcExtName, const char *tableName, const int option) { xmlDocPtr docData = NULL, docDef = NULL, docIdx = NULL, docRec = NULL, docDic = NULL; xmlNodePtr curData, curKey; xmlXPathContextPtr ctxDef, ctxIdx, ctxRec, ctxDic; xmlXPathObjectPtr resDef, resIdx, resRec, resDic; char tmpValue[255], *interfaceType, *retString, *dictName, *length, *recordName, *indexName, *storageType, *decimals; int i, j, hits, hits2; /* Get Table Layout Details */ docDef = RC_Get(appnName, "Table", tableName); /* Init XPath */ xmlXPathInit(); /* Create XPath environment */ ctxDef = xmlXPathNewContext(docDef); /* Find Out interface type */ resDef = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Table/DataInterfaceType", ctxDef); interfaceType = (char *)xmlXPathCastToString(resDef); /* Check interface type */ if (strcmp(interfaceType, DI_GDA) != 0) return NULL; /* Create new Manage Data 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 *)"ManageData"); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)"Request"); xmlNewProp(curData, (const xmlChar *)"SessionId", (const xmlChar *)sessionId); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"DataSource", (const xmlChar *)dsrcExtName); xmlNewProp(curData, (const xmlChar *)"Table", (const xmlChar *)tableName); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"ManageData", (const xmlChar *)""); if (option == 3) xmlNewProp(curData, (const xmlChar *)"Option", (const xmlChar *)"Create"); else xmlNewProp(curData, (const xmlChar *)"Option", (const xmlChar *)"Invalid"); resDef = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Table/ExternalName", ctxDef); retString = (char *)xmlXPathCastToString(resDef); xmlNewTextChild(curData, NULL, (const xmlChar *)"ExternalTableName", (const xmlChar *)retString); curData = curData->parent; /* Add IndexInstances */ curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"IndexInstances", (const xmlChar *)""); resDef = xmlXPathEval((const xmlChar *)"count(/ProLinga/Repository/Command/Object/Table/OccurrencesTableIndexEntry/TableIndexEntry)", ctxDef); hits = (int)xmlXPathCastToNumber(resDef); for (i = 1; i<=hits; i++) { curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"IndexInstance", (const xmlChar *)""); /* Add Index header */ sprintf(tmpValue, "%d", i); xmlNewProp(curData, (const xmlChar *)"SequenceNo", (const xmlChar *)tmpValue); sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Table/OccurrencesTableIndexEntry/TableIndexEntry[%d]/@Primary", i); resDef = xmlXPathEval((const xmlChar *)tmpValue, ctxDef); retString = (char *)xmlXPathCastToString(resDef); xmlNewProp(curData, (const xmlChar *)"Primary", (const xmlChar *)retString); sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Table/OccurrencesTableIndexEntry/TableIndexEntry[%d]/IndexName", i); resDef = xmlXPathEval((const xmlChar *)tmpValue, ctxDef); indexName = (char *)xmlXPathCastToString(resDef); xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)indexName); sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Table/OccurrencesTableIndexEntry/TableIndexEntry[%d]/Unique", i); resDef = xmlXPathEval((const xmlChar *)tmpValue, ctxDef); retString = (char *)xmlXPathCastToString(resDef); xmlNewProp(curData, (const xmlChar *)"Unique", (const xmlChar *)retString); sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Table/OccurrencesTableIndexEntry/TableIndexEntry[%d]/Sort", i); resDef = xmlXPathEval((const xmlChar *)tmpValue, ctxDef); retString = (char *)xmlXPathCastToString(resDef); xmlNewProp(curData, (const xmlChar *)"Sort", (const xmlChar *)retString); /* Get Index Details */ docIdx = RC_Get(appnName, "Index", indexName); /* Create XPath environment */ ctxIdx = xmlXPathNewContext(docIdx); /* Find out Dictionary names */ resIdx = xmlXPathEval((const xmlChar *)"count(/ProLinga/Repository/Command/Object/Index/OccurrencesIndexEntry/IndexEntry)", ctxIdx); hits2 = (int)xmlXPathCastToNumber(resIdx); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"KeyInstances", (const xmlChar *)""); curKey = curData; for (j=1; j<=hits2;j++) { /* Find Out DataDictionary */ sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Index/OccurrencesIndexEntry/IndexEntry[%d]/DataDictionaryName", j); resIdx = xmlXPathEval((const xmlChar *)tmpValue, ctxIdx); dictName = (char *)xmlXPathCastToString(resIdx); /* Get DataDictionary Layout Details */ docDic = RC_Get(appnName, "DataDictionary", dictName); /* Create XPath environment */ ctxDic = xmlXPathNewContext(docDic); /* Find Out length */ resDic = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataDictionary/MaximumLength", ctxDic); length = (char *)xmlXPathCastToString(resDic); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"KeyInstance", (const xmlChar *)""); sprintf(tmpValue, "%d", j); xmlNewProp(curData, (const xmlChar *)"SequenceNo", (const xmlChar *)tmpValue); xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)dictName); curData = curData->parent; } curData = curData->parent; curData = curData->parent; } curData = curData->parent; /* Add DataInstances */ curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataInstances", (const xmlChar *)""); resDef = xmlXPathEval((const xmlChar *)"count(/ProLinga/Repository/Command/Object/Table/OccurrencesTableRecordEntry/TableRecordEntry)", ctxDef); hits = (int)xmlXPathCastToNumber(resDef); for (i=1;i<=hits;i++) { sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Table/OccurrencesTableRecordEntry/TableRecordEntry[%d]/RecordName", i); resDef = xmlXPathEval((const xmlChar *)tmpValue, ctxDef); recordName = (char *)xmlXPathCastToString(resDef); /* Get Record Layout Details */ docRec = RC_Get(appnName, "Record", recordName); /* Create XPath environment */ ctxRec = xmlXPathNewContext(docRec); /* Find out Dictionary names */ resRec = xmlXPathEval((const xmlChar *)"count(/ProLinga/Repository/Command/Object/Record/OccurrencesDataDictionaryEntry/DataDictionaryEntry)", ctxRec); hits2 = (int)xmlXPathCastToNumber(resRec); for (j=1; j<=hits2;j++) { /* Find Out DataDictionary */ sprintf(tmpValue, "/ProLinga/Repository/Command/Object/Record/OccurrencesDataDictionaryEntry/DataDictionaryEntry[%d]/DataDictionaryName", j); resRec = xmlXPathEval((const xmlChar *)tmpValue, ctxRec); dictName = (char *)xmlXPathCastToString(resRec); /* Get DataDictionary Layout Details */ docDic = RC_Get(appnName, "DataDictionary", dictName); /* Create XPath environment */ ctxDic = xmlXPathNewContext(docDic); /* Find Out Storage Type */ resDic = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataDictionary/ExternalStorageType", ctxDic); storageType = (char *)xmlXPathCastToString(resDic); /* Find Out length */ resDic = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataDictionary/MaximumLength", ctxDic); length = (char *)xmlXPathCastToString(resDic); /* Find Out Decimal Places */ resDic = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataDictionary/DecimalPlaces", ctxDic); decimals = (char *)xmlXPathCastToString(resDic); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"DataInstance", (const xmlChar *)""); sprintf(tmpValue, "%d", j); xmlNewProp(curData, (const xmlChar *)"SequenceNo", (const xmlChar *)tmpValue); xmlNewProp(curData, (const xmlChar *)"Name", (const xmlChar *)dictName); if (strncmp(storageType, "Long", 4) == 0) xmlNewProp(curData, (const xmlChar *)"StorageType", (const xmlChar *)"Long"); else if (strncmp(storageType, "Single", 6) == 0) { xmlNewProp(curData, (const xmlChar *)"StorageType", (const xmlChar *)"Single"); if ((decimals != NULL) && (strlen(decimals) > 0)) xmlNewProp(curData, (const xmlChar *)"Decimals", (const xmlChar *)decimals); else xmlNewProp(curData, (const xmlChar *)"Decimals", (const xmlChar *)"0"); } else if (strncmp(storageType, "Double", 6) == 0) { xmlNewProp(curData, (const xmlChar *)"StorageType", (const xmlChar *)"Double"); if ((decimals != NULL) && (strlen(decimals) > 0)) xmlNewProp(curData, (const xmlChar *)"Decimals", (const xmlChar *)decimals); else xmlNewProp(curData, (const xmlChar *)"Decimals", (const xmlChar *)"0"); } else xmlNewProp(curData, (const xmlChar *)"StorageType", (const xmlChar *)storageType); xmlNewProp(curData, (const xmlChar *)"Size", (const xmlChar *)length); xmlNewProp(curData, (const xmlChar *)"AllowNulls", (const xmlChar *)"False"); /* Go up */ curData = curData->parent; } } /* Cleanup */ xmlFreeDoc(docDef); xmlFreeDoc(docDic); xmlFreeDoc(docRec); /* Return */ return docData; } int dataCreateDataSession(const char *dataSource) { xmlDocPtr docData, docRes = NULL; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; char *sessionId, *rcStatus; char dsrcExtName[255]; char dsrcUserName[255], dsrcPassword[255], dsrcReadOnly[255], dsrcSqlCase[255], dsrcThreadSafe[255]; int retStatus; /* Get Data Source */ retStatus = repGet(&docRes, biAppnPtr->getAppn(), "DataSource", dataSource); if (retStatus != 0) { /* Error loading data source.\n */ return 10209; } /* Create XPath environment */ ctxRes = xmlXPathNewContext(docRes); /* Find external data source name */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/ExternalName", ctxRes); strcpy(dsrcExtName, (char *)xmlXPathCastToString(resRes)); /* Get other data source properties while we here anyway */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/UserName", ctxRes); strcpy(dsrcUserName, (char *)xmlXPathCastToString(resRes)); resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/Password", ctxRes); strcpy(dsrcPassword, (char *)xmlXPathCastToString(resRes)); resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/ReadOnlyConnection", ctxRes); strcpy(dsrcReadOnly, (char *)xmlXPathCastToString(resRes)); resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/SqlIdentifiersCaseSensitive", ctxRes); strcpy(dsrcSqlCase, (char *)xmlXPathCastToString(resRes)); resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/DataSource/ThreadSafe", ctxRes); strcpy(dsrcThreadSafe, (char *)xmlXPathCastToString(resRes)); /* Create connect command */ docData = dataConnect(); /* 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) { /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10210; } /* Get Session Id */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/@SessionId", ctxRes); sessionId = (char *)xmlXPathCastToString(resRes); /* Set Session Id */ caDataSesPtr->putDataSession(&caDataSesPtr, sessionId, dataSource, dsrcExtName); /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Create DC Open DataSource document */ docData = dataOpenDataSource(sessionId, dsrcExtName, dsrcUserName, dsrcPassword, dsrcReadOnly, dsrcSqlCase, dsrcThreadSafe); /* 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) { caDataSesPtr->deleteDataSession(&caDataSesPtr, dsrcExtName); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10211; } /* Clean up request document */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return 0; } int dataClearDataSession(const char *dataSource) { xmlDocPtr docData, docRes; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; char *rcStatus; int retStatus = 0; /* Create DC Data Source Close document */ docData = dataCloseDataSource( caDataSesPtr->getDataSessionId(caDataSesPtr, dataSource), caDataSesPtr->getExternalDataSource(caDataSesPtr, dataSource)); /* 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) { printf("5Something is wrong with datamanager!\n"); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10212; } /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Create connect command */ docData = dataDisconnect(caDataSesPtr->getDataSessionId(caDataSesPtr, dataSource)); /* 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) { /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10213; } /* Clear Session Id */ retStatus = caDataSesPtr->deleteDataSession(&caDataSesPtr, dataSource); /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return retStatus; } int dataExecuteAction(const char *dataSource, const char *sqlCommand) { xmlDocPtr docData, docRes; xmlNodePtr curData; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; int retStatus = 0; char *rcStatus; //printf("NON COMMAND %s\n", sqlCommand); /* Create new Execute Non Query 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 *)"ExecuteNonQuery"); 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)); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"NonQuery", (const xmlChar *)""); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Sql", (const xmlChar *)sqlCommand); /* 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); /* 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) { /* Get Error Id */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/@Id", ctxRes); /* If 3rd party error, display external error */ if ((int)xmlXPathCastToNumber(resRes) == 90001) { resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/ExternalDescription", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); biSqlInfoPtr->setSqlInfo(rcStatus); biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10203; } else { biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10204; } } else { /* Get number of rows affected */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/NonQuery/RowsAffected", ctxRes); biSqlReturnPtr->setSqlReturn( (int)xmlXPathCastToNumber(resRes) ); } /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return retStatus; } int dataDataModelGetRow(const char *dataModel, const int rowNo) { xmlDocPtr docData, docRes; xmlNodePtr curData; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; int retStatus = 0, numCols, i, dmeColNo, dmeLength; char *dataSource, int2str[10], *rcStatus, evalString[1024], *dmeColName, *dmeDataValue; /* Get Data Source */ dataSource = dmPtr->getDataSource(dmPtr, dataModel); /* Create new DataModel Get Row 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 *)"DataModelGetRow"); 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 *)"DataModelRow", (const xmlChar *)""); sprintf(int2str, "%d", rowNo); xmlNewProp(curData, (const xmlChar *)"RowId", (const xmlChar *)int2str); /* Execute DC */ docRes = DC_Exec(docData); /* DEBUG */ // xmlBufferPtr bufData; // bufData = xmlBufferCreate(); // curData = xmlDocGetRootElement(docData); // xmlNodeDump(bufData, docData, curData, 0, 1); // printf("%s\n", (char *)xmlBufferContent(bufData)); // xmlBufferFree(bufData); /* 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) { /* Get Error Id */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/@Id", ctxRes); /* If 3rd party error, display external error */ if ((int)xmlXPathCastToNumber(resRes) == 90001) { resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/ExternalDescription", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); biSqlInfoPtr->setSqlInfo(rcStatus); biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10205; } else biSqlReturnPtr->setSqlReturn(0); } else { /* Get return data and put in data model */ /* Get number of Columns */ resRes = xmlXPathEval((const xmlChar *)"count(/ProLinga/Data/Command/Object/DataModelRow/Result/ColumnHeaderInstances/ColumnHeaderInstance)", ctxRes); numCols = (int)xmlXPathCastToNumber(resRes); for (i=1; i<=numCols; i++) { /* Get Col No */ dmeColNo = i; /* Get Col Name */ sprintf(evalString,"/ProLinga/Data/Command/Object/DataModelRow/Result/ColumnHeaderInstances/ColumnHeaderInstance[@SequenceNo='%d']/@Name", i); resRes = xmlXPathEval((const xmlChar *)evalString, ctxRes); dmeColName = new char[(strlen((char *)xmlXPathCastToString(resRes)) + 1)]; strcpy(dmeColName, (char *)xmlXPathCastToString(resRes)); /* Get Data Length */ sprintf(evalString,"/ProLinga/Data/Command/Object/DataModelRow/Result/ColumnHeaderInstances/ColumnHeaderInstance[@SequenceNo='%d']/@Size", i); resRes = xmlXPathEval((const xmlChar *)evalString, ctxRes); dmeLength = (int)xmlXPathCastToNumber(resRes); /* Get Data Value */ sprintf(evalString,"/ProLinga/Data/Command/Object/DataModelRow/Result/DataInstances/DataInstance/%s", dmeColName); resRes = xmlXPathEval((const xmlChar *)evalString, ctxRes); dmeDataValue = new char[(strlen((char *)xmlXPathCastToString(resRes)) + 1)]; strcpy(dmeDataValue, (char *)xmlXPathCastToString(resRes)); /* Add to Data Model Entry Class */ dmPtr->putDataValue(&dmPtr, dataModel, dmeColNo, dmeColName, dmeDataValue, dmeLength); /* Delete */ delete dmeColName; delete dmeDataValue; } } /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return retStatus; } int dataExecuteQueryDataModel(const char *dataSource, const char *sqlCommand, const char *dataModel) { xmlDocPtr docData, docRes; xmlNodePtr curData; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; int retStatus = 0, cols = 0, rows = 0; char *rcStatus; //printf("COMMAND %s\n", sqlCommand); /* Create new Execute Non Query 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 *)"ExecuteQueryDataModel"); 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 *)"Query", (const xmlChar *)""); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Sql", (const xmlChar *)sqlCommand); /* 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) { /* Get Error Id */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/@Id", ctxRes); /* If 3rd party error, display external error */ if ((int)xmlXPathCastToNumber(resRes) == 90001) { resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/ExternalDescription", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); biSqlInfoPtr->setSqlInfo(rcStatus); biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10205; } else { biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10206; } } else { /* Delete Data Model if present */ dmPtr->deleteOne(&dmPtr, dataModel); /* Set Data Source of Data Model */ dmPtr->putDataSource(&dmPtr, dataModel, dataSource); /* 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 */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return retStatus; } int dataTransaction(const char *dataSource, const char *mode, const char *isolationLevel) { xmlDocPtr docData = NULL, docRes; xmlNodePtr curData; xmlXPathContextPtr ctxRes; xmlXPathObjectPtr resRes; int retStatus = 0; char *rcStatus; /* Create new DataModel Get Row 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 *)"Transaction"); 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)); curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"Transaction", (const xmlChar *)""); xmlNewProp(curData, (const xmlChar *)"Mode", (const xmlChar *)mode); if (strcmp(mode, "Begin") == 0) curData = xmlNewTextChild(curData, NULL, (const xmlChar *)"IsolationLevel", (const xmlChar *)isolationLevel); /* 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) { /* Get Error Id */ resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/@Id", ctxRes); /* If 3rd party error, display external error */ if ((int)xmlXPathCastToNumber(resRes) == 90001) { resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Data/Command/Object/Error/ExternalDescription", ctxRes); rcStatus = (char *)xmlXPathCastToString(resRes); printf("3Something is wrong!!!\n"); biSqlInfoPtr->setSqlInfo(rcStatus); biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10207; } else { biSqlReturnPtr->setSqlReturn(0); /* Clean up */ if (docRes != NULL) xmlFreeDoc(docRes); xmlFreeDoc(docData); return 10208; } } else { /* Return OK */ biSqlReturnPtr->setSqlReturn(0); } /* Clean up */ xmlFreeDoc(docRes); xmlFreeDoc(docData); /* Return */ return retStatus; }