/* * * 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 #include #include "DatMain.hpp" #include "DCDataSource.hpp" #include "DCDataModel.hpp" #include "ExecuteSql.hpp" #include "DCSession.hpp" #include "DatConfig.hpp" #include "Utility.hpp" extern DCSessionPtr sesPtr; int DCExecuteQueryDataModel(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; char *objDataSource, *dataModel, *sqlBuffer, tmpString[1024]; int noRows = 0, noCols = 0; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get SQL statement */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/Query/Sql", ctxObj); sqlBuffer = new char[(strlen((char *)xmlXPathCastToString(resObj))+1)]; strcpy(sqlBuffer, (char *)xmlXPathCastToString(resObj)); /* Execute Statement */ dm = ExecuteSqlSingleCommand(connection, sqlBuffer, sesPtr, sessionId); if (dm == NULL) { delete sqlBuffer; *externalError = ConnectionError(connection); return 90001; } /* No longer needed */ delete sqlBuffer; /* xmlDocPtr docAbc; xmlNodePtr curAbc; docAbc = xmlNewDoc((const xmlChar *)XML_VERSION); docAbc->children = xmlNewDocNode(docAbc, NULL, (const xmlChar *)ROOT_ELEM, NULL); curAbc = xmlDocGetRootElement(docAbc); xmlAddChild(curAbc, xmlCopyNodeList(gda_data_model_to_xml_node(dm, "abcdef"))); xmlSaveFile("/tmp/bas.xml", docAbc); */ /* Put Datamodel in list */ sesPtr->putDataModel(sesPtr, sessionId, dataModel, dm); /* Get number of columns and rows */ noRows = gda_data_model_get_n_rows(dm); noCols = gda_data_model_get_n_columns(dm); /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Query", (const xmlChar *)""); sprintf(tmpString,"%d",noCols); xmlNewTextChild(curReturn, NULL, (const xmlChar *)"ColumnsDataModel", (const xmlChar *)tmpString); sprintf(tmpString,"%d",noRows); xmlNewTextChild(curReturn, NULL, (const xmlChar *)"RowsDataModel", (const xmlChar *)tmpString); /* Return */ return 0; } int DCExecuteQueryTableDataModel(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; char *objDataSource, *dataModel, *sqlBuffer, *sqlCondition, *sqlQuery, tmpString[1024]; int noRows = 0, noCols = 0, length; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get SQL statement */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/Query/Table", ctxObj); sqlBuffer = new char[(strlen((char *)xmlXPathCastToString(resObj))+1)]; strcpy(sqlBuffer, (char *)xmlXPathCastToString(resObj)); /* Get SQL condition */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/Query/Condition", ctxObj); sqlCondition = new char[(strlen((char *)xmlXPathCastToString(resObj))+1)]; strcpy(sqlCondition, (char *)xmlXPathCastToString(resObj)); /* Get total length */ length = strlen(sqlBuffer) + strlen(sqlCondition) + 1; /* Get complete query + include 14 length for the select * from part + spaces */ sqlQuery = new char[(length+14)]; strcpy(sqlQuery, "select * from "); //strcpy(sqlQuery, "select group_id, \"desc\" from "); strcat(sqlQuery, sqlBuffer); strcat(sqlQuery, " "); strcat(sqlQuery, sqlCondition); /* Execute Statement */ dm = ExecuteSqlDataModelCommand(connection, sqlQuery, sesPtr, sessionId); if (dm == NULL) { *externalError = ConnectionError(connection); delete sqlQuery; delete sqlCondition; delete sqlBuffer; return 90001; } /* Clean up query */ delete sqlQuery; delete sqlCondition; delete sqlBuffer; /* Put Datamodel in list */ sesPtr->putDataModel(sesPtr, sessionId, dataModel, dm); /* Get number of columns and rows */ noRows = gda_data_model_get_n_rows(dm); noCols = gda_data_model_get_n_columns(dm); /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Query", (const xmlChar *)""); sprintf(tmpString,"%d",noCols); xmlNewTextChild(curReturn, NULL, (const xmlChar *)"ColumnsDataModel", (const xmlChar *)tmpString); sprintf(tmpString,"%d",noRows); xmlNewTextChild(curReturn, NULL, (const xmlChar *)"RowsDataModel", (const xmlChar *)tmpString); /* Return */ return 0; } int DCDataModelGetRow(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn, curTmp; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; GdaColumn *fa; char *objDataSource, *dataModel, tmpString[255]; gint rowId = 0, columnId = 0; GValue *value; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get DataModel RowId */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/DataModelRow/@RowId", ctxObj); rowId = (int)xmlXPathCastToNumber(resObj); /* Get Data Model */ dm = sesPtr->getDataModel(sesPtr, sessionId, dataModel); if (dm == NULL) return 70004; /* Check if valid number of rows */ if ((rowId < 0) || (rowId > gda_data_model_get_n_rows(dm))) return 70005; /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"DataModelRow", (const xmlChar *)""); sprintf(tmpString, "%d", rowId); xmlNewProp(curReturn, (const xmlChar *)"RowId", (const xmlChar *)tmpString); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Result", (const xmlChar *)""); /* Get Column Headers */ curTmp = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"ColumnHeaderInstances", (const xmlChar *)""); for (columnId = 0; columnId < gda_data_model_get_n_columns(dm); columnId++) { /* Get Field Attributes */ fa = gda_data_model_describe_column(dm, columnId); curTmp = xmlNewTextChild(curTmp, NULL, (const xmlChar *)"ColumnHeaderInstance", (const xmlChar *)""); sprintf(tmpString, "%d", columnId + 1); xmlNewProp(curTmp, (const xmlChar *)"SequenceNo", (const xmlChar *)tmpString); xmlNewProp(curTmp, (const xmlChar *)"Name", (const xmlChar *)gda_data_model_get_column_title(dm, columnId)); xmlNewProp(curTmp, (const xmlChar *)"StorageType", (const xmlChar *)gda_g_type_to_string (gda_column_get_g_type (fa))); // sprintf(tmpString, "%ld", gda_column_get_defined_size(fa)); // xmlNewProp(curTmp, (const xmlChar *)"Size", (const xmlChar *)tmpString); // sprintf(tmpString, "%ld", gda_column_get_scale(fa)); // xmlNewProp(curTmp, (const xmlChar *)"Decimals", (const xmlChar *)tmpString); curTmp = curTmp->parent; // g_object_unref(fa); } /* Get Data */ curTmp = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"DataInstances", (const xmlChar *)""); curTmp = xmlNewTextChild(curTmp, NULL, (const xmlChar *)"DataInstance", (const xmlChar *)""); xmlNewProp(curTmp, (const xmlChar *)"SequenceNo", (const xmlChar *)"1"); for (columnId = 0; columnId < gda_data_model_get_n_columns(dm); columnId++) { if (rowId == 0) { xmlNewTextChild(curTmp, NULL, (const xmlChar *)gda_data_model_get_column_title(dm, columnId), (const xmlChar *)""); } else { value = (GValue *) gda_data_model_get_value_at(dm, columnId, (rowId-1), NULL); xmlNewTextChild(curTmp, NULL, (const xmlChar *)gda_data_model_get_column_title(dm, columnId), (const xmlChar *)gda_value_stringify (value)); } } curTmp = curTmp->parent; /* Return */ return 0; } int DCDataModelAppendRow(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; char *objDataSource, *dataModel, *dataValue, tmpString[255]; gint rowId = 0, columnId = 0; GdaColumn *fa; GList *values = NULL; // GdaRow *dmRowNew; // gboolean retStatus; GError *errStatus = NULL; GValue *val; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get Data Model */ dm = sesPtr->getDataModel(sesPtr, sessionId, dataModel); if (dm == NULL) return 70004; /* Append Row */ /* Process the columns */ for (columnId = 0; columnId < gda_data_model_get_n_columns(dm); columnId++) { /* Get Field Attributes */ fa = gda_data_model_describe_column(dm, columnId); /* Double check column types */ // sprintf(tmpString, "/ProLinga/Object/DataModelAppendRow/ColumnHeaderInstances/ColumnHeaderInstance[@SequenceNo='%d']/@StorageType", columnId+1); // resObj = xmlXPathEval((const xmlChar *)tmpString, ctxObj); // storageType = (char *)xmlXPathCastToString(resObj); // if (strcmp(gda_type_to_string (gda_data_model_column_attributes_get_gda_type (fa)), storageType) != 0) // return 70017; /* Get Data */ sprintf(tmpString, "/ProLinga/Object/DataModelAppendRow/DataInstances/DataInstance/%s", gda_data_model_get_column_title(dm, columnId)); resObj = xmlXPathEval((const xmlChar *)tmpString, ctxObj); dataValue = (char *)xmlXPathCastToString(resObj); /* Call matching function */ if (gda_column_get_g_type(fa) == G_TYPE_DATE) val = GValueFromString(dataValue, G_TYPE_STRING); else val = GValueFromString(dataValue, gda_column_get_g_type(fa)); /* Get values */ values = g_list_append(values, val); } /* Add Row to data model */ rowId = gda_data_model_append_values (dm, values, &errStatus); if (errStatus != NULL) { printf ("ERROR append: %s\n", errStatus->message); //g_error_free (errStatus); return 70016; } /* Clean up */ g_list_foreach (values, (GFunc) gda_value_free, NULL); g_list_free (values); /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"DataModelAppendRow", (const xmlChar *)""); sprintf(tmpString, "%d", (rowId+1)); xmlNewProp(curReturn, (const xmlChar *)"RowId", (const xmlChar *)tmpString); /* Return */ return 0; } int DCDataModelUpdateRow(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; char *objDataSource, *dataModel, *dataValue, tmpString[255]; gint rowId = 0, columnId = 0; GdaColumn *fa; GValue *value, *value_new; gboolean retStatus; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get DataModel RowId */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/DataModelUpdateRow/@RowId", ctxObj); rowId = (int)xmlXPathCastToNumber(resObj); /* Get Data Model */ dm = sesPtr->getDataModel(sesPtr, sessionId, dataModel); if (dm == NULL) return 70004; /* Update Row */ /* Check if valid number of rows */ if ((rowId < 1) || (rowId > gda_data_model_get_n_rows(dm))) return 70005; /* row id 1 = 0 */ rowId--; /* Process the columns */ for (columnId = 0; columnId < gda_data_model_get_n_columns(dm); columnId++) { /* Get Field Attributes */ fa = gda_data_model_describe_column(dm, columnId); /* Double check column types */ // sprintf(tmpString, "/ProLinga/Object/DataModelUpdateRow/ColumnHeaderInstances/ColumnHeaderInstance[@SequenceNo='%d']/@StorageType", columnId+1); // resObj = xmlXPathEval((const xmlChar *)tmpString, ctxObj); // storageType = (char *)xmlXPathCastToString(resObj); // if (strcmp(gda_type_to_string (gda_data_model_column_attributes_get_gda_type (fa)), storageType) != 0) // return 70017; /* Get Data */ sprintf(tmpString, "/ProLinga/Object/DataModelUpdateRow/DataInstances/DataInstance/%s", gda_data_model_get_column_title(dm, columnId)); resObj = xmlXPathEval((const xmlChar *)tmpString, ctxObj); dataValue = (char *)xmlXPathCastToString(resObj); /* Set new value if changed */ value = (GValue *)gda_data_model_get_value_at(dm, columnId, rowId, NULL); if (strcmp(dataValue, gda_value_stringify(value)) != 0) { value_new = GValueFromString(dataValue, gda_column_get_g_type(fa)); retStatus = gda_data_model_set_value_at(dm, columnId, rowId, value_new, NULL); if (retStatus == FALSE) return 70020; } } /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"DataModelUpdateRow", (const xmlChar *)""); sprintf(tmpString, "%d", (rowId+1)); xmlNewProp(curReturn, (const xmlChar *)"RowId", (const xmlChar *)tmpString); /* Return */ return 0; } int DCDataModelRemoveRow(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; GdaDataModel *dm; char *objDataSource, *dataModel; gint rowId = 0; gboolean dmStatus; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); /* Get DataModel RowId */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/DataModelRemoveRow/@RowId", ctxObj); rowId = (int)xmlXPathCastToNumber(resObj); /* Get Data Model */ dm = sesPtr->getDataModel(sesPtr, sessionId, dataModel); if (dm == NULL) return 70004; /* Check if valid number of rows */ if ((rowId < 1) || (rowId > gda_data_model_get_n_rows(dm))) return 70005; /* row id 1 = 0 */ rowId--; GError *errStatus = NULL; dmStatus = gda_data_model_remove_row(dm,rowId,&errStatus); if (dmStatus == FALSE) { printf ("ERROR append: %s\n", errStatus->message); return 70015; } /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); xmlNewProp(curReturn, (const xmlChar *)"DataModel", (const xmlChar *)dataModel); /* Return */ return 0; } int DCDataModelClose(const xmlDocPtr docObj, const char *sessionId, char **externalError, xmlDocPtr *docReturn) { xmlNodePtr curReturn; xmlXPathContextPtr ctxObj; xmlXPathObjectPtr resObj; GdaConnection *connection; char *objDataSource, *dataModel; int dbStatus = 0; /* Create XPath Environment */ ctxObj = xmlXPathNewContext(docObj); /* Get DataSource name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataSource", ctxObj); objDataSource = (char *)xmlXPathCastToString(resObj); /* Get Connection Object to Data Source */ connection = sesPtr->getGdaConnection(sesPtr, sessionId, objDataSource); if (connection == NULL) return 70002; /* Get DataModel name */ resObj = xmlXPathEval((const xmlChar *)"/ProLinga/Object/@DataModel", ctxObj); dataModel = (char *)xmlXPathCastToString(resObj); if (dataModel[0] =='*') sesPtr->deleteAllDataModels(sesPtr, sessionId); else { dbStatus = sesPtr->deleteOneDataModel(sesPtr, sessionId, dataModel); if (dbStatus == -1) return 70004; } /* Create return document */ *docReturn = xmlNewDoc((const xmlChar *)XML_VERSION); (*docReturn)->children = xmlNewDocNode(*docReturn, NULL, (const xmlChar *)ROOT_ELEM, NULL); curReturn = xmlDocGetRootElement(*docReturn); curReturn = xmlNewTextChild(curReturn, NULL, (const xmlChar *)"Object", (const xmlChar *)""); xmlNewProp(curReturn, (const xmlChar *)"DataSource", (const xmlChar *)objDataSource); /* Return */ return dbStatus; }