summaryrefslogtreecommitdiff
path: root/src/sql/xbstmt.cpp
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2023-08-14 19:45:36 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2023-08-14 19:45:36 +0200
commitbfa452a375ea0a0a3f95304a69186936567e5263 (patch)
treeaade062a143c1afcc4ea06ee27905ffc34a9217b /src/sql/xbstmt.cpp
parentdd70ff8bf32c2d7ed365004b1770058265db1978 (diff)
New upstream version 4.1.4
Diffstat (limited to 'src/sql/xbstmt.cpp')
-rwxr-xr-xsrc/sql/xbstmt.cpp679
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 */
-