/* xbfilter.cpp XBase64 Software Library Copyright (c) 1997,2003,2014,2022 Gary A Kunkel The xb64 software library is covered under the terms of the GPL Version 3, 2007 license. Email Contact: XDB-devel@lists.sourceforge.net XDB-users@lists.sourceforge.net This module handles uda (user data area) methods */ #include "xbase.h" // might need to change thisto XB_EXPRESSION_SUPPORT #ifdef XB_FILTER_SUPPORT namespace xb{ /************************************************************************/ xbFilter::xbFilter( xbXBase *xbase, xbDbf *dbf ) { this->xbase = xbase; this->dbf = dbf; this->exp = NULL; lLimit = 0; // max number of responses lCurQryCnt = 0; // current number, this query + = moving fwd // - = moving backwards #ifdef XB_INDEX_SUPPORT pIx = NULL; // if index is set, the class uses the index tag, otherwise table vpTag = NULL; #endif // XB_INDEX_SUPPORT } /************************************************************************/ xbFilter::~xbFilter() { if( exp ) delete exp; } /************************************************************************/ xbInt32 xbFilter::GetLimit() const { return lLimit; } /************************************************************************/ xbInt32 xbFilter::GetQryCnt() const { return lCurQryCnt; } /************************************************************************/ void xbFilter::SetLimit( xbInt32 lLimit ){ this->lLimit = lLimit; } /************************************************************************/ void xbFilter::ResetQryCnt(){ this->lCurQryCnt = 0; } /************************************************************************/ xbInt16 xbFilter::Set( xbString &sFilter ) { xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( exp ) delete exp; exp = new xbExp( xbase, dbf ); if(( iRc = exp->ParseExpression( sFilter.Str() )) != XB_NO_ERROR ){ iErrorStop = 10; throw iRc; } if( exp->GetReturnType() != XB_EXP_LOGICAL ){ iErrorStop = 20; iRc = XB_INVALID_EXPRESSION; delete exp; exp = NULL; throw iRc; } } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::SetExpression() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetFirstRecord( xbInt16 iOption ) { xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } #ifdef XB_INDEX_SUPPORT if( dbf->GetCurIx() && dbf->GetCurTag() ) return GetFirstRecordIx( iOption ); #endif lCurQryCnt = 0; if(( iRc = dbf->GetFirstRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_EMPTY || iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt++; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetFirstRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetNextRecord( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } #ifdef XB_INDEX_SUPPORT if( dbf->GetCurIx() && dbf->GetCurTag()) return GetNextRecordIx( iOption ); #endif if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit ) return XB_LIMIT_REACHED; if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ if(( iRc = dbf->GetNextRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt++; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetNextRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetPrevRecord( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } #ifdef XB_INDEX_SUPPORT //if( pIx && vpTag ) if( dbf->GetCurIx() && dbf->GetCurTag()) return GetPrevRecordIx( iOption ); #endif if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit ) return XB_LIMIT_REACHED; if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt--; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetPrevRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetLastRecord( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } #ifdef XB_INDEX_SUPPORT if( dbf->GetCurIx() && dbf->GetCurTag()) return GetLastRecordIx( iOption ); #endif lCurQryCnt = 0; if(( iRc = dbf->GetLastRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ if(( iRc = dbf->GetPrevRecord( iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt--; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetLastRecord() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ #ifdef XB_INDEX_SUPPORT //void xbFilter::Set( xbIx *pIx, void *vpTag ) { // this->pIx = pIx; // this->vpTag = vpTag; //} /************************************************************************/ xbInt16 xbFilter::GetFirstRecordIx( xbInt16 iOption ) { xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } lCurQryCnt = 0; if(( iRc = dbf->GetCurIx()->GetFirstKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_EMPTY || iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ // if(( iRc = pIx->GetNextKey( vpTag, iOption )) != XB_NO_ERROR ){ if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt++; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetFirstRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetNextRecordIx( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit ) return XB_LIMIT_REACHED; if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ // if(( iRc = pIx->GetNextKey( vpTag, iOption )) != XB_NO_ERROR ){ if(( iRc = dbf->GetCurIx()->GetNextKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt++; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetNextRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetPrevRecordIx( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } if( lLimit != 0 && abs( lCurQryCnt ) >= lLimit ) return XB_LIMIT_REACHED; if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ //if(( iRc = pIx->GetPrevKey( vpTag, iOption )) != XB_NO_ERROR ){ if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt--; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetPrevRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } /************************************************************************/ xbInt16 xbFilter::GetLastRecordIx( xbInt16 iOption ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; try{ if( !exp ){ iErrorStop = 10; throw iRc; } lCurQryCnt = 0; if(( iRc = dbf->GetCurIx()->GetLastKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_EOF ) return iRc; else{ iErrorStop = 20; throw iRc; } } xbBool bFound = xbFalse; while( !bFound && iRc == XB_NO_ERROR ){ if(( iRc = exp->ProcessExpression()) != XB_NO_ERROR ){ iErrorStop = 30; throw iRc; } if(( iRc = exp->GetBoolResult( bFound )) != XB_NO_ERROR ){ iErrorStop = 40; throw iRc; } if( !bFound ){ if(( iRc = dbf->GetCurIx()->GetPrevKey( dbf->GetCurTag(), iOption )) != XB_NO_ERROR ){ if( iRc == XB_BOF ){ return iRc; } else { iErrorStop = 50; throw iRc; } } } } lCurQryCnt--; } catch (xbInt16 iRc ){ xbString sMsg; sMsg.Sprintf( "xbFilter::GetLastRecordIx() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( xbase->GetErrorMessage( iRc )); } return iRc; } #endif // XB_INDEX_SUPPORT /************************************************************************/ } /* namespace */ #endif /* XB_FILTER_SUPPORT */