Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

autodescstreamer.cpp

Go to the documentation of this file.
00001 //============================================================================= 
00002 //
00003 // XDFLengine library
00004 //
00005 //-----------------------------------------------------------------------------
00006 //  AUTODESCSTREAMER.CPP
00007 //-----------------------------------------------------------------------------
00013 //_____________________________________________________________________________
00014 //
00015 //  Copyright (C) 2003 Guillaume Baurand. All Rights Reserved.
00016 //
00017 //  This file is part of the XDFLengine project.
00018 //
00019 //  The XDFLengine is free software; you can redistribute it and/or modify
00020 //  it under the terms of the GNU General Public License as published by
00021 //  the Free Software Foundation; either version 2 of the License, or
00022 //  (at your option) any later version.
00023 //
00024 //  This program is distributed in the hope that it will be useful,
00025 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 //  GNU General Public License for more details.
00028 //
00029 //  You should have received a copy of the GNU General Public License
00030 //  along with this program; if not, write to the Free Software
00031 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
00032 //  USA.
00033 //
00034 //  For more information, 
00035 //      contact  : guillaume@baurand.net 
00036 //      or visit : http://xdflengine.sourceforge.net
00037 //
00038 //=============================================================================
00039 
00040 #   include "autodescstreamer.hpp"
00041 #   include "processor/xmlflowcontext.hpp"
00042 #   include "streamers/db/dbobject/dbobjdefinition.hpp"
00043 
00044 BEGIN_XDFLENGINE_NS
00045 
00046 //=============================================================================
00047 //  CLASS AUTODESCSTREAMER
00048 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00049 
00050 
00051     //_____________________________________________________________________
00052     //  AUTODESCSTREAMER
00053     //---------------------------------------------------------------------
00054     AutodescStreamer::AutodescStreamer( const XMLStreamerFactory* p_pParent, StreamerParams* p_pParameters, XMLFlowContext* p_pContext, XMLStreamConsumer* p_pOutput, ContentHandler* p_pHandler, bool p_fCopyStreamToOutput)
00055     :SaxStreamer( p_pParent, p_pParameters, p_pContext, p_pOutput, p_pHandler, p_fCopyStreamToOutput)
00056     {
00057         DEBUG_CREATE(AutodescStreamer)
00058     }
00059     
00060     //_____________________________________________________________________
00061     //  ~AUTODESCSTREAMER
00062     //---------------------------------------------------------------------     
00063     AutodescStreamer::~AutodescStreamer()
00064     {
00065         DEBUG_DEL(AutodescStreamer)
00066     }
00067 
00068     //_____________________________________________________________________
00069     //  COMMITSTREAM
00070     //---------------------------------------------------------------------
00071     bool AutodescStreamer::commitStream(bool p_fFinal)
00072     {
00073         //---------------------------------------------------------------------
00074         bool    l_fOK;
00075         const char*             l_pszConnName = 0;
00076         DBOBJDefinitionNode*    l_pDefinitionRoot=0;
00077         otl_connect*            l_pConnection=0;
00078         //---------------------------------------------------------------------
00079 
00080         PREP_CATCH_XML_FLOW_ERROR;
00081 
00082         DEBUG_IN(AutodescStreamer::commitStream)
00083 
00084         WATCH_XML_FLOW_ERROR
00085         {
00086             l_fOK = SaxStreamer::commitStream( p_fFinal);
00087 
00088             if(l_fOK && p_fFinal)
00089             {   
00090                 logout << "\t" << AUTODESCSTREAMER_TAGNAME<< "   :   " << "Building definition...\n";
00091                 l_pDefinitionRoot =  ((SAXDBOBJDefinitionBuilder*) m_pHandler)->getDefinition();
00092 
00093                 // get connection
00094                 l_pszConnName = getParamValue(m_pParameters, AUTODESCSTREAMER_CONNECTION); 
00095                 l_pConnection = ((DBStreamerFactory*) m_pParent)->getConnection(l_pszConnName, m_pContext->getThreadId()  );
00096                 m_fExpandFields = false;
00097                 if( strcmp(getParamValue(m_pParameters, AUTODESCSTREAMER_EXPAND, REQ_TRUE) , REQ_TRUE) == 0) m_fExpandFields=true;
00098 
00099                 logout << "\t" << AUTODESCSTREAMER_TAGNAME<< "   :   " << "Completing definition.\n";
00100 
00101                 // process definition completion
00102                 completeDefinitionNode( l_pDefinitionRoot, l_pConnection); 
00103 
00104                 
00105                 l_pDefinitionRoot->getXML( m_pOutput);
00106                 logout << "\t" << AUTODESCSTREAMER_TAGNAME<< "   :   " << "Definition completed.\n";
00107             }
00108         } 
00109         CATCH_XML_FLOW_ERROR_RELEASE_AND_RETURN ;
00110 
00111     RELEASE_AND_RETURN:
00112     
00113         // release connection
00114         if(l_pConnection) ((DBStreamerFactory*) m_pParent)->releaseConnection(l_pszConnName, m_pContext->getThreadId());
00115 
00116         // CACHE DE DEFINITIONS DESACTIVE !!!!
00117         delete l_pDefinitionRoot;
00118         
00119         ON_XML_FLOW_ERROR_DO l_fOK = false;
00120         ON_XML_FLOW_ERROR_THROW;    
00121 
00122         DEBUG_OUT(AutodescStreamer::commitStream)
00123 
00124         return l_fOK;       
00125     }
00126 
00127 
00128 
00129     //_________________________________________________________________________
00130     //  COMPLETEDEFINITIONNODE
00131     //-------------------------------------------------------------------------
00132     void AutodescStreamer::completeDefinitionNode( DBOBJDefinitionNode* p_pDefinitionNode, otl_connect* p_pConnection) const
00133     {
00134         //---------------------------------------------------------------------
00135         VAarray<DBOBJDefinitionField*>      l_vaDefinedFields;
00136         DBOBJDefinitionField*               l_pDefinitionField=0;
00137         otl_stream*                         l_prsData=0;
00138         otl_column_desc*                    l_pColumnDesc=0;
00139 
00140         char                l_cDBSpec[ AUTODESCSTREAMER_DBSPECBUF];
00141         char*               l_pszTableName=0;
00142         const char*         l_pszSep=0;
00143         char*               l_pszSelectStmt=0;
00144         char*               l_pszFieldName=0;   
00145         char*               l_pszFieldReducedType=0;
00146 
00147         int                 l_iDescLen;  
00148         unsigned int        l_uiFieldsCount;
00149         int                 l_intFieldOTLType;      
00150         int                 l_intDBType;
00151         int                 l_intDBSize;
00152         int                 l_intDBScale;
00153         int                 l_intDBPrec;
00154         int                 l_intNullOK;
00155         unsigned int        l_uiChildCount;
00156         unsigned int        j;
00157         int                 i;
00158         //-------------------------------------------------------------------------
00159 
00160         DEBUG_IN(AutodescStreamer::completeDefinitionNode)
00161         PREP_CATCH_XML_FLOW_ERROR;
00162 
00163         WATCH_XML_FLOW_ERROR {
00164 
00165             l_pszTableName =  copyCharBuffer( p_pDefinitionNode->getDBTable());
00166             upperize( l_pszTableName);
00167 
00168             // build map of the already defined fields 
00169             l_uiFieldsCount = p_pDefinitionNode->getFieldsCount();
00170             for( j=0 ; j< l_uiFieldsCount ; j++)
00171             {
00172                 l_pDefinitionField=p_pDefinitionNode->getField(j);
00173                 l_vaDefinedFields.add( l_pDefinitionField,l_pDefinitionField->getDBField());
00174             }
00175 
00176             //  select a row of the node table to get fields properties
00177             l_pszSelectStmt=copyCharBuffer( "SELECT ");
00178             if (DBStreamerFactory::getSQLSyntax()==SQL_SYNTAX_MSSQL)
00179             {
00180                 l_pszSelectStmt=concatCharBuffer( l_pszSelectStmt, " TOP 1 ");
00181             }
00182             l_pszSelectStmt=concatCharBuffer( l_pszSelectStmt, "* FROM ");
00183             l_pszSelectStmt=concatCharBuffer( l_pszSelectStmt, l_pszTableName);
00184             if (DBStreamerFactory::getSQLSyntax()==SQL_SYNTAX_ORA)
00185             {
00186                 l_pszSelectStmt=concatCharBuffer( l_pszSelectStmt, " WHERE ROWNUM <=1");
00187             }
00188 
00189             try
00190             {
00191                 // execute statement
00192                 DEBUG_ECHO << "SQL: " << l_pszSelectStmt << "\n";
00193                 l_prsData=new otl_stream();
00194                 l_prsData->open(AUTODESCSTREAMER_OTLBUF, l_pszSelectStmt, *p_pConnection );
00195                 l_prsData->flush(); //  force execution
00196                 DEBUG_ECHO << "select ok\n";
00197             }
00198             catch(otl_exception& p)
00199             { 
00200                 // ERRCHECK : DB error ?
00201                 MAKE_XMLFLOW_EXCEPTION ( ERRCODE_LOC_AUTODESCHANDLER + ERRCODE_CAUSE_DATAACCESS ,"Unable to retrieve table info to DB." , (char*)(&(p.msg)), "AUTODESCHandler::completeDefinitionNode", "", false);
00202                 p.~otl_tmpl_exception();
00203                 goto RELEASE_AND_RETURN;
00204             }
00205 
00206             // Get description
00207             l_pColumnDesc = l_prsData->describe_select(l_iDescLen);
00208             //logout << "\t" << AUTODESCSTREAMER_TAGNAME<< "   :   " << "\t\t get description ok\n";
00209             for( i=0 ; i< l_iDescLen ; i++)
00210             {
00211                 l_pszFieldName= copyCharBuffer(l_pColumnDesc[i].name);
00212                 lowerize( l_pszFieldName);
00213                 l_intFieldOTLType=l_pColumnDesc[i].otl_var_dbtype;
00214                 l_pDefinitionField = l_vaDefinedFields.get( l_pszFieldName);
00215 
00216                 if( (! l_pDefinitionField) && m_fExpandFields && ( !p_pDefinitionNode->isLocked()) )
00217                 {
00218                     l_pszFieldReducedType = getReducedType( l_intFieldOTLType );
00219 
00220                     DEBUG_ECHO << l_pszFieldName << "(" << l_pszFieldReducedType << ")\n";
00221 
00222                     // create def field object
00223                     l_pDefinitionField=new DBOBJDefinitionField;
00224                     
00225                     // set def field props
00226                     l_pDefinitionField->setAttribute(false);
00227                     l_pDefinitionField->setName( l_pszFieldName);
00228                     l_pDefinitionField->setDBAlias( l_pszFieldName);
00229                     l_pDefinitionField->setDBField( l_pszFieldName);
00230                     l_pDefinitionField->setMap( l_pszFieldReducedType); 
00231                     if( strcmp( l_pszFieldReducedType, DBOBJDEFFIELD_MAP_DATE) == 0 )
00232                     {
00233                         if (DBStreamerFactory::getSQLSyntax()==SQL_SYNTAX_ORA)
00234                         {
00235                             l_pDefinitionField->setDateFormat( DBOBJDEFFIELD_DATE_FORMAT_DEF_ORA);
00236                         }
00237                         else if (DBStreamerFactory::getSQLSyntax()==SQL_SYNTAX_MSSQL)
00238                         {
00239                             l_pDefinitionField->setDateFormat( DBOBJDEFFIELD_DATE_FORMAT_DEF_MSSQL);
00240                         }
00241                     }
00242 
00243                     // add to definition node
00244                     p_pDefinitionNode->addField( l_pDefinitionField);
00245 
00246                     l_pszFieldReducedType = releaseCharBuffer( l_pszFieldReducedType);
00247                 }
00248 
00249 
00250                 if(l_pDefinitionField)
00251                 {
00252                     l_intDBType=l_pColumnDesc[i].dbtype;
00253                     l_intDBSize=l_pColumnDesc[i].dbsize;
00254                     l_intDBScale=l_pColumnDesc[i].scale;
00255                     l_intDBPrec=l_pColumnDesc[i].prec;
00256                     l_intNullOK=l_pColumnDesc[i].nullok;
00257 
00258                     sprintf((char*) &l_cDBSpec,"%d%s%d%s%d%s%d%s%d%s%d",l_intFieldOTLType, DBOBJDEFFIELD_DBSPECSEP, l_intDBType, DBOBJDEFFIELD_DBSPECSEP, l_intDBSize, DBOBJDEFFIELD_DBSPECSEP, l_intDBScale, DBOBJDEFFIELD_DBSPECSEP, l_intDBPrec, DBOBJDEFFIELD_DBSPECSEP, l_intNullOK);
00259                     
00260                     //logout << "\t" << AUTODESCSTREAMER_TAGNAME<< "   :   " << "\t\t db spec : " << l_cDBSpec << "\n";
00261                     l_pDefinitionField->setDBSpecProps( l_cDBSpec);
00262                 }
00263 
00264                 l_pszFieldName = releaseCharBuffer( l_pszFieldName);
00265 
00266             }
00267             //delete(l_pColumnDesc);
00268 
00269             // recurse to child nodes
00270             l_uiChildCount=p_pDefinitionNode->getChildNodesCount();
00271             for( j=0 ; j<l_uiChildCount ; j++) {
00272                 DEBUG_ECHO << "recurse " << j << "/" << l_uiChildCount <<"\n";
00273                 completeDefinitionNode( p_pDefinitionNode->getChildNode(j) , p_pConnection);
00274             }
00275 
00276             l_vaDefinedFields.flush();
00277 
00278         } CATCH_XML_FLOW_ERROR_RELEASE_AND_RETURN;  
00279 
00280         // release recordset
00281         l_prsData->clean();
00282         l_prsData->close();
00283                 
00284     RELEASE_AND_RETURN: 
00285 
00286         l_pszTableName = releaseCharBuffer( l_pszTableName);
00287         l_pszFieldReducedType = releaseCharBuffer( l_pszFieldReducedType);
00288         l_pszFieldName = releaseCharBuffer( l_pszFieldName);
00289         l_pszSelectStmt = releaseCharBuffer(l_pszSelectStmt);
00290 
00291         delete(l_prsData);
00292 
00293         DEBUG_OUT(AutodescStreamer::completeDefinitionNode)
00294         ON_XML_FLOW_ERROR_THROW;    
00295     }
00296 
00297     //_________________________________________________________________________
00298     //  GETREDUCEDTYPE
00299     //-------------------------------------------------------------------------
00300     char* AutodescStreamer::getReducedType(int l_intOTLType) const
00301     {
00302         //---------------------------------------------------------------------
00303         const char* l_pszRet;
00304         //---------------------------------------------------------------------
00305 
00306         DEBUG_FUNC(AutodescStreamer::getReducedType)
00307 
00308         switch( l_intOTLType)
00309         {
00310             case otl_var_char:        // null terminated string (code=1) 
00311                 l_pszRet = DBOBJDEFFIELD_MAP_STRING;
00312                 break;
00313             case otl_var_double:        // 8-byte floating point number (code=2) 
00314                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00315                 break; 
00316             case otl_var_float:      // 4-byte floating point number (code=3) 
00317                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00318                 break;  
00319             case otl_var_int:          // 32-bit signed integer (code=4) 
00320                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00321                 break;  
00322             case otl_var_unsigned_int:  // 32-bit unsigned integer (code=5) 
00323                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00324                 break;  
00325             case otl_var_short:      // 16-bit signed integer (code=6) 
00326                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00327                 break;  
00328             case otl_var_long_int:    // 32-signed integer (code=7) 
00329                 l_pszRet = DBOBJDEFFIELD_MAP_NUM;
00330                 break;  
00331             case otl_var_timestamp:  // datatype that is mapped into TIMESTAMP_STRUCT, ODBC and DB2-CLI only (code=8)  
00332                 l_pszRet = DBOBJDEFFIELD_MAP_DATE;
00333                 break; 
00334             case otl_var_varchar_long:  // datatype that is mapped into LONG in Oracle 7/8, TEXT in MS SQL Server and Sybase, CLOB in DB2 (code=9), 
00335                 l_pszRet = DBOBJDEFFIELD_MAP_STRING;
00336                 break;
00337             case otl_var_raw_long:    // datatype that is mapped into LONG RAW in Oracle 7/8, IMAGE in MS SQL Server ad Sybase, BLOB in DB2 (code=10) 
00338                 l_pszRet = DBOBJDEFFIELD_MAP_STRING;
00339                 break;
00340             case otl_var_clob:        // datatype that is mapped into CLOB in Oracle 8 (code=11) 
00341                 l_pszRet = DBOBJDEFFIELD_MAP_STRING;
00342                 break;
00343             case otl_var_blob:        // datatype that is mapped into BLOB in Oracle 8 (code=12) 
00344                 l_pszRet = DBOBJDEFFIELD_MAP_STRING;
00345                 break;
00346         }
00347         return copyCharBuffer( l_pszRet);
00348 
00349     }
00350 
00351 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00352 //=============================================================================
00353 
00354 
00355 //=============================================================================
00356 //  CLASS AUTODESCSTREAMERFACTORY
00357 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00358 
00359     XMLStreamer* AutodescStreamerFactory::getStreamer(
00360         StreamerParams*         p_pParameters, 
00361         XMLFlowContext* p_pStreamContext, 
00362         XMLStreamConsumer*      p_pStreamConsumer) const
00363     {
00364         SAXDBOBJDefinitionBuilder*  l_pSAXDefinitionBuilder = 0;
00365 
00366         l_pSAXDefinitionBuilder = new SAXDBOBJDefinitionBuilder( p_pStreamContext);
00367         return (XMLStreamer*) new AutodescStreamer( this, p_pParameters, p_pStreamContext, p_pStreamConsumer, l_pSAXDefinitionBuilder, false);
00368     }
00369 
00370 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00371 //=============================================================================
00372 
00373 
00374 END_XDFLENGINE_NS
00375 
00376 
00377 

Generated on Sat Oct 4 13:19:54 2003 for XDFLengine by doxygen1.3-rc2