📄 stepexec.cpp
字号:
// StepExec.cpp : implementation file
//
#include "stdafx.h"
#include "miniSQL.h"
#include "MainFrm.h"
#include "StepExec.h"
#include "LogDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CMD(DO) m_Cmd.GetAt( m_Cmd.FindIndex( DO ) )
extern CMiniSQLApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CStepExec
CStepExec::CStepExec( CString& str ) :
CLexAnalyzer( str )
{
}
CStepExec::~CStepExec()
{
}
void CStepExec::ErrorKey( int i )
{
Lex temp = CMD(i);
if( temp.key == User )
throw Error( UNKNOWN_ID, 0, temp.str );
else throw Error( SYNTAX_ERROR, 0, temp.str );
}
CString CStepExec::GetID( int& i )
{
Lex temp = CMD(++i);
if( temp.key != User )
throw Error( SYNTAX_ERROR, 0, temp.str );
return temp.str;
}
CEntryAttr CStepExec::GetDef( int& i )
{
CEntryAttr attr;
if( CMD(++i).key != LEFT_PAR )
ErrorKey( i );
do
{
CString id_name = GetID( i );
CItemType type;
switch( CMD(++i).key )
{
case _INT : type = _INT; break;
case _LONG : type = _LONG; break;
case _FLOAT : type = _FLOAT; break;
case _DATE : type = _DATE; break;
case _STRING :
if( CMD(++i).key != LEFT_PAR ||
CMD(++i).key != Digit ||
CMD(++i).key != RIGHT_PAR )
ErrorKey( i );
type = CItemType( _STRING, atoi( (LPCTSTR)CMD(i-1).str ) );
if( type.size > 0 ) break;
default : Error( SYNTAX_ERROR, 0, CMD(i).str );
}
attr.push( CItemAttr( (LPCTSTR)id_name, type ) );
} while( CMD(++i).key == SEPARATOR );
--i;
if( CMD(++i).key != RIGHT_PAR )
ErrorKey( i );
return attr;
}
int CStepExec::GetStrs( int& i, STR_LIST& ret, bool id, bool par )
{
if( par && CMD(++i).key != LEFT_PAR )
ErrorKey( i );
do
{
i++;
if( ( id && CMD(i).key != User && CMD(i).key != MUL ) ||
( !id && CMD(i).key != String && CMD(i).key != Digit && CMD(i).key != NUL ) )
ErrorKey( i );
if( CMD(i).key == MUL )
{
ret.RemoveAll();
return 0;
}
if( CMD(i).key != NUL )
ret.AddTail( CMD(i).str );
else
{
char str = -1;
ret.AddTail( CString(str) );
}
} while( CMD(++i).key == SEPARATOR );
--i;
if( par && CMD(++i).key != RIGHT_PAR )
ErrorKey( i );
return ret.GetCount();
}
CString CStepExec::GetStr( int& i, bool id, bool par )
{
CString str;
if( par && CMD(++i).key != LEFT_PAR )
ErrorKey( i );
i++;
if( ( id && CMD(i).key != User ) ||
( !id && CMD(i).key != String && CMD(i).key != Digit && CMD(i).key != NUL ) )
ErrorKey( i );
if( CMD(i).key != NUL )
str = CMD(i).str;
else
{
char a = -1;
str= CString( a );
}
if( par && CMD(++i).key != RIGHT_PAR )
ErrorKey( i );
return str;
}
void CStepExec::GetCondition( CTable& table, int& i, RESULT& ret )
{
if( CMD(i+1).key != WHERE )
{
table.search( ret );
return ;
}
i++;
STR_PAIR equ, bet1, bet2;
CString str;
do
{
switch( CMD(i+2).key )
{
case EQU:
equ.first.AddTail( GetStr( i, true ) );
i++;
equ.second.AddTail( GetStr( i, false ) );
break;
case BETWEEN:
str = GetStr( i, true );
bet1.first.AddTail( str );
bet2.first.AddTail( str );
i++;
bet1.second.AddTail( GetStr( i, false ) );
if( CMD(++i).key != AND )
ErrorKey( i );
bet2.second.AddTail( GetStr( i, false ) );
break;
default:
ErrorKey( i+2 );
}
}while( CMD(++i).key == AND );
i--;
if( equ.first.GetCount() && !bet1.first.GetCount() )
{
table.search( ret, equ );
return ;
}
else if( !equ.first.GetCount() && bet1.first.GetCount() )
table.search( ret, bet1, bet2 );
else if( equ.first.GetCount() && bet1.first.GetCount() )
table.search( ret, equ, bet1, bet2 );
else
throw Error();
}
void CStepExec::GetSet( int& i, STR_PAIR& ret )
{
do
{
ret.first.AddTail( GetStr( i, true ) );
if( CMD(++i).key != EQU )
ErrorKey( i );
ret.second.AddTail( GetStr( i, false ) );
}while( CMD(++i).key == SEPARATOR );
i--;
}
void CStepExec::Exec()
{
m_Cmd.RemoveAll();
m_Cmd.AddTail( CLexAnalyzer::NextToken() );
while( m_Cmd.GetTail().key != EndOfFile )
{
if( m_Cmd.GetTail().key == SEMICOLON )
{
StepExec();
m_Cmd.RemoveAll();
}
m_Cmd.AddTail( CLexAnalyzer::NextToken() );
}
}
void CStepExec::SingleExec()
{
m_Cmd.RemoveAll();
do
m_Cmd.AddTail( CLexAnalyzer::NextToken() );
while( m_Cmd.GetTail().key != EndOfFile && m_Cmd.GetTail().key != SEMICOLON );
if( m_Cmd.GetTail().key == SEMICOLON )
StepExec();
}
void CStepExec::StepExec()
{
int i = 0;
switch( CMD(i++).key )
{
case CREATE:
if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) )
if( CMD(i).key == _TABLE )
{
CString tname = GetID( i );
CEntryAttr attr = GetDef( i );
if ( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CTable table( (LPCTSTR)tname, attr );
theApp.OnRefreshFileTree();
table.close();
Message( (CString)"Successful : Created table \"" + tname +"\"\n" );
}
else if( CMD(i).key == INDEX ||
CMD(i).key == UNIQUE && CMD(i+1).key == INDEX )
{
bool dup = true;
if( CMD(i).key == UNIQUE )
dup = false, ++i;
CString iname = GetID( i );
if( CMD(++i).key != ON )
ErrorKey( i );
CString tname = GetID( i );
STR_LIST name_list;
GetStrs( i, name_list, true, true );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CTable( (LPCTSTR)tname ).create_index( (LPCTSTR)iname, name_list, dup );
CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd();
pMainFrm->m_FileBar.InsertIndex( tname, iname );
Message( (CString)"Successful : Created index \"" + iname +".bpt\" on table \"" + tname + "\"\n" );
}
else ErrorKey( i );
else
throw Error( ERROR_AUTHOR, 0, _T("") );
break;
case INSERT:
if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) )
{
if( CMD(i).key != INTO )
i--;
CString tname = GetID( i );
STR_PAIR input;
if( CMD(i+1).key == LEFT_PAR )
GetStrs( i, input.first, true, true );
if( CMD(++i).key != VALUES )
ErrorKey( i );
GetStrs( i, input.second, false, true );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CTable table( (LPCTSTR)tname );
table.insert( input );
Message( "Operation insert successful.\n" );
}
else
throw Error( ERROR_AUTHOR, 0, _T("") );
break;
case SELECT:
{
STR_LIST name_list;
GetStrs( --i, name_list, true );
if( CMD(++i).key != FROM )
ErrorKey( i );
CString tname = GetID( i );
if( !name_list.GetCount() && CMD(i+1).key == SEMICOLON )
{
CString tpath( theApp.dir );
tpath = tpath + "\\" + tname + ".msl";
CMSLDoc* pDoc;
if( pDoc = theApp.IsDocExist( tname + ".msl" ) )
pDoc->OnCloseDocument();
theApp.OpenDocumentFile( tpath );
break;
}
CTable table( (LPCTSTR) tname );
RESULT res;
GetCondition( table, i, res );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
table.select( res, name_list );
table.close();
CString temp;
temp.Format( "Select successful : Total %d entries selected.\n", res.GetCount() );
Message( temp );
}
break;
case _DELETE:
if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) )
if( CMD(i).key == FROM )
{
CTable table( (LPCTSTR) GetID( i ) );
RESULT res;
GetCondition( table, i, res );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
table.remove( res );
CString temp;
temp.Format( "Delete successful : Total %d entries deleted.\n", res.GetCount() );
Message( temp );
}
else ErrorKey( i );
else
throw Error( ERROR_AUTHOR, 0, _T("") );
break;
case UPDATE:
if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) )
{
CTable table( (LPCTSTR)GetID( --i ) );
if( CMD(++i).key != SET )
ErrorKey( i );
STR_PAIR set;
GetSet( i, set );
RESULT res;
GetCondition( table, i, res );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
table.update( res, set );
CString temp;
temp.Format( "Update successful : Total %d entries updated.\n", res.GetCount() );
Message( temp );
}
else
throw Error( ERROR_AUTHOR, 0, _T("") );
break;
case DROP:
if( (theApp.m_LogType & LOG_SUPERUSER) || (theApp.m_LogType & LOG_ADMIN) )
if( CMD(i).key == _TABLE )
{
CString tname = GetID( i );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CTable( (LPCTSTR)tname ).drop();
CMainFrame* pMainFrm = ( CMainFrame* )theApp.m_pMainWnd;
pMainFrm->m_FileBar.DelFile( tname );
Message( (CString)"Successful : Dropped table \"" + tname +"\"\n" );
}
else if( CMD(i).key == INDEX )
{
CString iname = GetID( i );
if( CMD(++i).key != ON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CString tname = GetID( i );
if( CMD(++i).key != SEMICOLON )
throw Error( SYNTAX_ERROR, 0, CMD(i).str );
CTable( (LPCTSTR)tname ).drop_index( (LPCTSTR)iname );
CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd();
pMainFrm->m_FileBar.DropIndex( tname, iname );
Message( (CString)"Successful : Dropped index \"" + iname + ".bpt\" on table\"" + tname + "\"\n" );
}
else
ErrorKey( i );
else
throw Error( ERROR_AUTHOR, 0, _T("") );
break;
case EXIT:
theApp.Exit();
break;
default:
ErrorKey( --i );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -