diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2023-08-14 19:45:36 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2023-08-14 19:45:36 +0200 |
commit | bfa452a375ea0a0a3f95304a69186936567e5263 (patch) | |
tree | aade062a143c1afcc4ea06ee27905ffc34a9217b /src/sql/xbstmt.cpp | |
parent | dd70ff8bf32c2d7ed365004b1770058265db1978 (diff) |
New upstream version 4.1.4
Diffstat (limited to 'src/sql/xbstmt.cpp')
-rwxr-xr-x | src/sql/xbstmt.cpp | 679 |
1 files changed, 0 insertions, 679 deletions
diff --git a/src/sql/xbstmt.cpp b/src/sql/xbstmt.cpp deleted file mode 100755 index 61c84fd..0000000 --- a/src/sql/xbstmt.cpp +++ /dev/null @@ -1,679 +0,0 @@ -/* xbsql.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 - -*/ - -#include "xbase.h" - -#ifdef XB_SQL_SUPPORT - -namespace xb{ - -/***********************************************************************/ -xbStmt::xbStmt( xbXBase *x ){ - xbase = x; - pTblList = NULL; - fl = NULL; - ulFromPos = 0; - ulWherePos = 0; - ulOrderByPos = 0; - ulGroupByPos = 0; - ulHavingPos = 0; -} - -/***********************************************************************/ -xbStmt::~xbStmt(){ - - std::cout << "xbStmt::~xbStmt() - need to release all allocated structures and memory here\n"; - -} - -/***********************************************************************/ -xbInt16 xbStmt::CvtSqlExp2DbaseExp( const xbString &sExpIn, xbString &sExpOut ){ - - // convert Ansi SQL expression to a DBase compatible expression - - xbInt16 iRc = 0; - xbInt16 iErrorStop = 0; - - try{ - - // convert tablename.fieldname to tablename->fieldname - sExpOut = sExpIn[1]; - xbUInt32 ulPos = 2; - while( ulPos < sExpIn.Len() ){ - if( sExpIn[ulPos] == '.' && sExpIn[ulPos-1] != ' ' && sExpIn[ulPos+1] != ' ' ) - sExpOut += "->"; - else - sExpOut += sExpIn[ulPos]; - ulPos++; - } - sExpOut += sExpIn[ulPos]; - - sExpOut.Replace( " AND ", " .AND. ", 0 ); - sExpOut.Replace( " and ", " .AND. ", 0 ); - sExpOut.Replace( " OR ", " .OR. ", 0 ); - sExpOut.Replace( " or ", " .OR. ", 0 ); - } - catch (xbInt16 iRc ){ - xbString sMsg; - sMsg.Sprintf( "xbStmt::CvtSqlExp2DbaseExp() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc ); - xbase->WriteLogMessage( sMsg.Str() ); - xbase->WriteLogMessage( GetErrorMessage( iRc )); - } - return iRc; -} - - -/***********************************************************************/ -#ifdef XB_DEBUG_SUPPORT -xbInt16 xbStmt::DumpStmtInternals(){ - - std::cout << "************** Dump Statment Internals ***************" << std::endl; - std::cout << "Statement [" << sStmt << "]\n"; - std::cout << "Fields [" << sFields << "]\n"; - std::cout << "From [" << sFrom << "]\n"; - std::cout << "Where [" << sWhere << "]\n"; - std::cout << "Order By [" << sOrderBy << "]\n"; - std::cout << "Group By [" << sGroupBy << "]\n"; - std::cout << "Having [" << sHaving << "]\n"; - - xbTblJoin *p = pTblList; - if( p ){ - std::cout << "Tbl List\n"; - std::cout << "Type,Name,Alias,Exp\n"; - while( p ){ - std::cout << p->cJoinType << "," << p->sTableName.Str() << "," << p->sAlias.Str() << "," << p->sJoinExp.Str() << "\n"; - p = p->next; - } - } - std::cout << "*************** End of Internals ************" << std::endl; - return 0; -} - -xbInt16 xbStmt::Test(){ - xbString s; - - s = "(ABC)"; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - s = "(ABC) )"; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - s = "("; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - s = "( ("; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - s = "aaa)"; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - s = "aaa"; - std::cout << "[" << s.Str() << "][" << GetParenCnt( s ) << "]\n"; - - return 0; - -} -#endif // XB_DEBUG_SUPPORT - - -/***********************************************************************/ -xbInt16 xbStmt::GetNextFromSeg( const xbString &sLineIn, xbString &sFromSegOut ){ - - xbInt16 iRc = 0; - xbInt16 iErrorStop = 0; - xbInt16 iParenCtr = 0; - xbUInt32 ulPos = 1; - xbUInt32 ulTsp = 0; // token start position - xbBool bDone = xbFalse; - xbString sToken; - - try{ - sFromSegOut = ""; - while( !bDone ){ - ulTsp = GetNextToken( sLineIn, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - - } else { - iParenCtr += GetParenCnt( sToken ); - if( iParenCtr == 0 && ulPos > 1 ){ - sToken.ToUpperCase(); - if( sToken == "LEFT" || sToken == "RIGHT" || sToken == "FULL" || - sToken == "INNER" || sToken == "OUTER" || sToken[1] == '(' ){ - bDone = xbTrue; - } - } - } - ulPos += (sToken.Len() + 1); - } - if( ulTsp > 1 ) - sFromSegOut.Assign( sLineIn, 1, ulTsp - 2 ); - } - catch (xbInt16 iRc ){ - xbString sMsg; - sMsg.Sprintf( "xbStmt::GetNextFromSeg() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc ); - xbase->WriteLogMessage( sMsg.Str() ); - xbase->WriteLogMessage( GetErrorMessage( iRc )); - } - return iRc; -} - -/***********************************************************************/ - -xbUInt32 xbStmt::GetNextToken( const xbString &sCmdLineIn, xbString &sTokenOut, xbUInt32 ulStartPos ){ - - // input - // sCmdLine - Entire Command line - // ulStartPos - Where to start searching for the next token - // returns the position of the beginning of the token in the main command line - - xbUInt32 ul = ulStartPos; - xbUInt32 ulTokenStartPos = 0; - sTokenOut = ""; - - while( ul <= sCmdLineIn.Len() && sCmdLineIn[ul] == ' ' ) - ul++; - ulTokenStartPos = ul; - - while( ul <= sCmdLineIn.Len() && sCmdLineIn[ul] != ' ' ){ - sTokenOut += sCmdLineIn[ul]; - ul++; - } - - return ulTokenStartPos; -} -/***********************************************************************/ -xbInt16 xbStmt::GetParenCnt( const xbString &sToken ){ - - xbInt16 iParenCnt = 0; - - for( xbUInt32 i = 1; i <= sToken.Len(); i++ ){ - if( sToken[i] == '(' ) - iParenCnt++; - else if( sToken[i] == ')' ) - iParenCnt--; - } - return iParenCnt; -} - - -/***********************************************************************/ -xbInt16 xbStmt::ParseFromStmt( const xbString &sFromLine ){ - - xbInt16 iRc = 0; - xbInt16 iErrorStop = 0; - xbBool bDone = xbFalse; - xbString sFromSeg; - xbString sLine = sFromLine; - - try{ - std::cout << "ParseFromSeg [" << sFromLine.Str() << "]\n"; - - while( !bDone ){ - if(( iRc = GetNextFromSeg( sLine, sFromSeg)) != XB_NO_ERROR ){ - iErrorStop = 100; - throw iRc; - } - if( sFromSeg.Len() == 0 ){ - bDone = xbTrue; - } else { - if(( iRc = ProcessFromSeg( sFromSeg )) != XB_NO_ERROR ){ - iErrorStop = 110; - throw iRc; - } - sLine.Ltrunc( sFromSeg.Len() ); - sLine.Ltrim(); - } - } - } - catch (xbInt16 iRc ){ - xbString sMsg; - sMsg.Sprintf( "xbStmt::ParseFromSeg() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc ); - xbase->WriteLogMessage( sMsg.Str() ); - xbase->WriteLogMessage( GetErrorMessage( iRc )); - } - - return iRc; -} -/***********************************************************************/ -xbInt16 xbStmt::ParseStmt( const xbString &sCmdLine ){ - - xbInt16 iRc = 0; - xbInt16 iErrorStop = 0; - xbInt16 iParenCnt = 0; - xbUInt32 ulStartPos = 7; - xbUInt32 ulLen = 0; - - - xbBool bFromFound = xbFalse; - xbBool bWhereFound = xbFalse; - xbBool bOrderByFound = xbFalse; - xbBool bGroupByFound = xbFalse; - xbBool bHavingFound = xbFalse; - xbBool bDone = xbFalse; - - xbString sToken; - - sStmt.Set( sCmdLine ); - sStmt.Trim(); - - try{ - - std::cout << "ParseStmt - [" << sStmt << "]\n"; - - xbUInt32 ulPos = ulStartPos; - - while( !bFromFound && !bDone ){ - ulPos = GetNextToken( sStmt, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - } else { - iParenCnt += GetParenCnt( sToken ); - if( iParenCnt == 0 ){ - sToken.ToUpperCase(); - if( sToken == "FROM" ){ - bFromFound = xbTrue; - ulFromPos = ulPos; - sFrom.Assign( sStmt, ulFromPos ); - } - } - ulPos += sToken.Len() + 1; - } - } - - // look for the where clause - if( bFromFound ) - ulPos = ulFromPos + 5; - else - ulPos = ulStartPos; - - bDone = xbFalse; - while( !bWhereFound && !bDone ){ - ulPos = GetNextToken( sStmt, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - } else { - iParenCnt += GetParenCnt( sToken ); - if( iParenCnt == 0 ){ - sToken.ToUpperCase(); - if( sToken == "WHERE" ){ - bWhereFound = xbTrue; - ulWherePos = ulPos; - sWhere.Assign( sStmt, ulWherePos+6 ); - } - } - ulPos += sToken.Len() + 1; - } - } - - - // look for the order clause - if( bWhereFound ) - ulPos = ulWherePos + 6; - else if( bFromFound ) - ulPos = ulFromPos + 5; - else - ulPos = ulStartPos; - - bDone = xbFalse; - while( !bOrderByFound && !bDone ){ - ulPos = GetNextToken( sStmt, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - } else { - iParenCnt += GetParenCnt( sToken ); - if( iParenCnt == 0 ){ - sToken.ToUpperCase(); - if( sToken == "ORDER" ){ - xbString sToken2; - xbUInt32 ulPos2 = GetNextToken( sStmt, sToken2, ulPos + 6 ); - if( sToken2 != "" ){ - sToken2.ToUpperCase(); - if( sToken2 == "BY" ){ - bOrderByFound = xbTrue; - ulOrderByPos = ulPos; - sOrderBy.Assign( sStmt, ulPos2 + 3 ); - } - } - } - } - ulPos += sToken.Len() + 1; - } - } - - - bDone = xbFalse; - while( !bGroupByFound && !bDone ){ - ulPos = GetNextToken( sStmt, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - } else { - iParenCnt += GetParenCnt( sToken ); - if( iParenCnt == 0 ){ - sToken.ToUpperCase(); - if( sToken == "GROUP" ){ - xbString sToken2; - xbUInt32 ulPos2 = GetNextToken( sStmt, sToken2, ulPos + 6 ); - if( sToken2 != "" ){ - sToken2.ToUpperCase(); - if( sToken2 == "BY" ){ - bGroupByFound = xbTrue; - ulGroupByPos = ulPos; - sGroupBy.Assign( sStmt, ulPos2 + 3 ); - } - } - } - } - ulPos += sToken.Len() + 1; - } - } - - bDone = xbFalse; - while( !bHavingFound && !bDone ){ - ulPos = GetNextToken( sStmt, sToken, ulPos ); - if( sToken == "" ){ - bDone = xbTrue; - } else { - iParenCnt += GetParenCnt( sToken ); - if( iParenCnt == 0 ){ - sToken.ToUpperCase(); - if( sToken == "HAVING" ){ - bHavingFound = xbTrue; - ulHavingPos = ulPos; - sHaving.Assign( sStmt, ulHavingPos + 7 ); - } - } - ulPos += sToken.Len() + 1; - } - } - - - // do the fields part - if( bFromFound ) - ulLen = ulFromPos - 7; - else if( bWhereFound ) - ulLen = ulWherePos - 7; - else if( bOrderByFound ) - ulLen = ulOrderByPos - 7; - else if( bGroupByFound ) - ulLen = ulGroupByPos - 7; - else if( bHavingFound ) - ulLen = ulHavingPos - 7; - else - ulLen = sStmt.Len() - 7; - sFields.Assign( sStmt, 7, ulLen ); - sFields.Trim(); - - // do the FROM part - if( bFromFound ){ - if( bWhereFound ) - ulLen = ulWherePos - ulFromPos; - else if( bOrderByFound ) - ulLen = ulOrderByPos - ulFromPos; - else if( bGroupByFound ) - ulLen = ulGroupByPos - ulFromPos; - else if( bHavingFound ) - ulLen = ulHavingPos - ulFromPos; - else - ulLen = sStmt.Len() - ulFromPos; - sFrom.Resize( ulLen ); - sFrom.Trim(); - - } - - - // do the WHERE part - if( bWhereFound ){ - ulLen = 0; - if( bOrderByFound ) - ulLen = ulOrderByPos - ulWherePos - 6; - else if( bGroupByFound ) - ulLen = ulGroupByPos - ulWherePos - 6; - else if( bHavingFound ) - ulLen = ulHavingPos - ulWherePos - 6; - - if( ulLen > 0 ) - sWhere.Resize( ulLen ); - sWhere.Trim(); - } - - // FIXME if there is more than one space between ORDER and BY then this doesn't work quite right - // do the ORDER BY part - if( bOrderByFound ){ - if( bGroupByFound ) - ulLen = ulGroupByPos - ulOrderByPos - 9; - else if( bHavingFound ) - ulLen = ulHavingPos - ulOrderByPos - 9; - else - ulLen = sStmt.Len() - ulOrderByPos - 9; - sOrderBy.Resize( ulLen ); - sOrderBy.Trim(); - } - - // FIXME if there is more than one space between ORDER and BY then this doesn't work quite right - // do the GROUP BY part - if( bGroupByFound ){ - if( bHavingFound ) - ulLen = ulHavingPos - ulGroupByPos - 9; - else - ulLen = sStmt.Len() - ulGroupByPos - 9; - sGroupBy.Resize( ulLen ); - sGroupBy.Trim(); - } - - if( bFromFound ){ - if(( iRc = ParseFromStmt( sFrom )) != XB_NO_ERROR ){ - iErrorStop = 100; - throw iRc; - } - } - - } - catch (xbInt16 iRc ){ - xbString sMsg; - sMsg.Sprintf( "xbStmt::ParseStmt() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc ); - xbase->WriteLogMessage( sMsg.Str() ); - xbase->WriteLogMessage( GetErrorMessage( iRc )); - } - - return iRc; -} - -/***********************************************************************/ -xbInt16 xbStmt::ProcessFromSeg( const xbString &sFromSeg ){ - - - xbInt16 iRc = 0; - xbInt16 iErrorStop = 0; - char cType = ' '; - xbString sToken; - xbString sTable; - xbString sAlias; - xbString sWork; - xbString sExp; - xbUInt32 iPos; - xbBool bDone; - xbExp * pJoinExp = NULL; - - try{ - - std::cout << "ProcessFromSeg for segment [" << sFromSeg.Str() << "]\n"; - - GetNextToken( sFromSeg, sToken, 1 ); - sToken.ToUpperCase(); - - std::cout << "sToken1 = [" << sToken.Str() << "]\n"; - - if( sToken == "FROM" ){ - // FROM has to be the first statement, and exist only once - if( pTblList ){ - iErrorStop = 100; - iRc = XB_PARSE_ERROR; - throw iRc; - } - cType = 'M'; - } else if( sToken == "LEFT" ) - cType = 'L'; - else if( sToken == "RIGHT" ) - cType = 'R'; - else if( sToken == "RIGHT" ) - cType = 'R'; - else if( sToken == "INNER" ) - cType = 'I'; - else if( sToken == "OUTER" || sToken == "FULL" ) - cType = 'O'; - else if( sToken[1] == '(' ) - cType = 'Q'; - else{ - iErrorStop = 100; - iRc = XB_PARSE_ERROR; - throw iRc; - } - - - if( cType == 'M' ){ - // expecting "FROM table" or "FROM table alias" - iPos = GetNextToken( sFromSeg, sToken, 5 ); - sTable = sToken; - - iPos = GetNextToken( sFromSeg, sToken, iPos + sToken.Len() + 1 ); - if( sToken.Len() > 0 ) - sAlias = sToken; - else - sAlias = ""; - - sWork = sToken; - sWork.ToUpperCase(); - iPos = sWork.Pos( ".DBF" ); - if( iPos == 0 ) - sTable += ".DBF"; - - // std::cout << "table = [" << sTable.Str() << "] alias = [" << sAlias.Str() << "]\n"; - - } else if( cType != 'Q' ){ - sWork = sFromSeg; - sWork.ToUpperCase(); - iPos = sWork.Pos( " ON " ); - if( iPos == 0 ){ - iErrorStop = 110; - iRc = XB_PARSE_ERROR; - throw iRc; - } - bDone = xbFalse; - - sWork.Assign( sFromSeg, iPos + 4 ); - CvtSqlExp2DbaseExp( sWork, sExp ); - sExp.Trim(); - std::cout << "ON = [" << sExp.Str() << "]\n"; - - - // need to get past the keywords LEFT, FULL, OUTER, RIGHT, INNER and get the table name here - iPos = sToken.Len() + 1; - while( !bDone ){ - iPos = GetNextToken( sFromSeg, sToken, iPos ); - sWork = sToken; - sWork.ToUpperCase(); - if( sWork != "LEFT" && sWork != "RIGHT" && sWork != "INNER" && sWork != "OUTER" && sWork != "FULL" && sWork != "JOIN" ) - bDone = xbTrue; - else - iPos += (sWork.Len() + 1); - } - - sTable = sToken; - GetNextToken( sFromSeg, sAlias, iPos + sTable.Len() + 1 ); - sWork.ToUpperCase(); - iPos = sWork.Pos( ".DBF" ); - if( iPos == 0 ) - sTable += ".DBF"; - sWork = sAlias; - sWork.ToUpperCase(); - if( sWork == "ON" ) - sAlias = ""; - } - - - // open table - //std::cout << "attempting to open table " << sTable.Str() << "\n"; - xbDbf *d = NULL; - if(( iRc = xbase->OpenHighestVersion( sTable, sAlias, &d )) != XB_NO_ERROR ){ - iErrorStop = 120; - throw iRc; - } - - - - // build out table linkage expression - if( cType == 'M' ) - sExp = "MASTER"; - else if( cType == 'L' ){ - pJoinExp = new xbExp( xbase ); - - // std::cout << "Parsing expression [" << sExp.Str() << "]\n"; - if(( iRc = pJoinExp->ParseExpression( d, sExp )) != XB_NO_ERROR ){ - iErrorStop = 130; - throw iRc; - } - } - - - // attach to correct location in list - - - // update the UpdateJoinList routine as appropriate -// if(( iRc = UpdateJoinList( cType, sTable, sAlias, NULL, NULL, NULL, NULL )) != XB_NO_ERROR ){ - - if(( iRc = UpdateJoinList( cType, sTable, sAlias, sExp, d, pJoinExp )) != XB_NO_ERROR ){ - iErrorStop = 110; - throw iRc; - } - - - } - catch (xbInt16 iRc ){ - xbString sMsg; - sMsg.Sprintf( "xbStmt::ProcessFromSeg() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc ); - xbase->WriteLogMessage( sMsg.Str() ); - xbase->WriteLogMessage( GetErrorMessage( iRc )); - } - return iRc; -} - -/***********************************************************************/ -xbInt16 xbStmt::UpdateJoinList( char cType, const xbString &sTableName, const xbString &sAlias, const xbString &sExp, xbDbf *d, xbExp *e ){ -// xbTag *t ){ - - - std::cout << "Update join list for table " << sTableName.Str() << "\n"; - - xbTblJoin *pTj; - if(( pTj = (xbTblJoin *) calloc( 1, sizeof( xbTblJoin ))) == NULL ) - return XB_NO_MEMORY; - - pTj->cJoinType = cType; - pTj->sTableName.Set( sTableName ); - pTj->sAlias.Set( sAlias ); - pTj->sJoinExp.Set( sExp ); - pTj->pDbf = d; - pTj->pLinkExp = e; - -/* - - pTj->pTag = t; -*/ - - if( cType == 'M' ) - pTblList = pTj; - - return 0; -} -/***********************************************************************/ -} /* namespace */ -#endif /* XB_SQL_SUPPORT */ - |