www.gusucode.com > VC++编写的SQL服务端和客户端源码程序 > VC++编写的SQL服务端和客户端源码程序\code\Server\SockExec.cpp

    // SockExec.cpp : implementation file
// Download by http://www.NewXing.com

#include "stdafx.h"
#include "miniSQL.h"
#include "MainFrm.h"
#include "SockExec.h"

#include "LogDlg.h"
#include "Msg.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;
/////////////////////////////////////////////////////////////////////////////
// CSockExec

CSockExec::CSockExec( CString& str, CClientSocket* pSocket, CServerDoc* pDoc) :
	CStepExec( str ), m_pSocket( pSocket ), m_pDoc( pDoc )
{
}

CSockExec::~CSockExec()
{
}

void CSockExec::GetCondition( CTable& table, int& i, RESULT& ret )
{
	if( CMD(i+1).key != WHERE )
	{
		table.search( ret, m_pSocket, m_pDoc );
		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, m_pSocket, m_pDoc );
	else if( !equ.first.GetCount() && bet1.first.GetCount() )
		table.search( ret, bet1, bet2, m_pSocket, m_pDoc );
	else if( equ.first.GetCount() && bet1.first.GetCount() )
		table.search( ret, equ, bet1, bet2, m_pSocket, m_pDoc );
	else
		throw Error();
}

void CSockExec::StepExec()
{
	int i = 0;
	switch( CMD(i++).key )
	{
	case CREATE:
		if( (m_pSocket->m_type & LOG_SUPERUSER) || (m_pSocket->m_type & 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 );
				CString		text( "<WRITE " );
				text += tname + ">";
				m_pDoc->Message( text );

				theApp.OnRefreshFileTree();
				table.close();
				text = "<CLOSE ";
				text += tname + ">\r\n\tSuccessful : Created table \"" + tname + "\"";
				m_pDoc->Message( text );

				CMsg msg( TABLE_CREATED );
				msg.m_msgList.AddTail( tname );
				m_pDoc->SendMsg( m_pSocket, msg );
			}
			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 );
				CString		text( "<WRITE " );
				text += iname + "> on TABLE: " + tname;
				m_pDoc->Message( text );

				CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd();
				pMainFrm->m_FileBar.InsertIndex( tname, iname );
				text = "<CLOSE ";
				text += iname + "> on TABLE: " + tname +
					"\r\n\tSuccessful : Created index \"" + iname + ".bpt\" on table \"" + tname + "\"";
				m_pDoc->Message( text );

				CMsg msg( INDEX_CREATED );
				msg.m_msgList.AddTail( tname );
				msg.m_msgList.AddTail( iname );
				m_pDoc->SendMsg( m_pSocket, msg );
			}
			else ErrorKey( i );
		else
			throw Error( ERROR_AUTHOR, 0, _T("") );
		break;
	case INSERT:
		if( (m_pSocket->m_type & LOG_SUPERUSER) || (m_pSocket->m_type & 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 );
			CString		text( "<WRITE " );
			text += tname + ">";
			m_pDoc->Message( text );

			table.insert( input );
			text = "<CLOSE ";
			text += tname + ">\r\n\tOperation insert successful.";
			m_pDoc->Message( text );

			CMsg msg( SUCCESSFUL );
			msg.m_msgList.AddTail( "Operation insert successful.\n" );
			m_pDoc->SendMsg( m_pSocket, msg );
		}
		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 );
			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, m_pSocket, m_pDoc );
			table.close();

			CString text( "<CLOSE " ), temp;
			temp.Format( "Select successful : Total %d entries selected.", res.GetCount() );
			text += tname + "> :\r\n\t" + temp;
			m_pDoc->Message( text );

			CMsg msg( SEL_SUCCESSFUL );
			msg.m_msgList.AddTail( temp + "\n" );
			m_pDoc->SendMsg( m_pSocket, msg );
		}
		break;
	case _DELETE:
		if( (m_pSocket->m_type & LOG_SUPERUSER) || (m_pSocket->m_type & LOG_ADMIN) )
			if( CMD(i).key == FROM )
			{
				CString tname = GetID( i );
				CTable table( (LPCTSTR)tname );
				CString		text( "<READ " );
				text += tname + ">";
				m_pDoc->Message( text );

				RESULT res;
				CStepExec::GetCondition( table, i, res );
				if( CMD(++i).key != SEMICOLON )
					throw Error( SYNTAX_ERROR, 0, CMD(i).str );

				table.remove( res );
				text = "<WRITE ";
				text += tname + ">";
				m_pDoc->Message( text );

				CString temp;
				temp.Format( "Delete successful : Total %d entries deleted.", res.GetCount() );
				text = "<CLOSE ";
				text += tname + ">\r\n\t" + temp;
				m_pDoc->Message( text );

				CMsg msg( SUCCESSFUL );
				msg.m_msgList.AddTail( temp + "\n" );
				m_pDoc->SendMsg( m_pSocket, msg );
			}
			else ErrorKey( i );
		else
			throw Error( ERROR_AUTHOR, 0, _T("") );
		break;
	case UPDATE:
		if( (m_pSocket->m_type & LOG_SUPERUSER) || (m_pSocket->m_type & LOG_ADMIN) )
		{
			CString tname = GetID( --i );
			CTable table( (LPCTSTR)tname );
			CString		text( "<READ " );
			text += tname + ">";
			m_pDoc->Message( text );

			if( CMD(++i).key != SET )
				ErrorKey( i );
			STR_PAIR set;
			GetSet( i, set );
			RESULT res;
			CStepExec::GetCondition( table, i, res );
			if( CMD(++i).key != SEMICOLON )
				throw Error( SYNTAX_ERROR, 0, CMD(i).str );

			table.update( res, set );
			text = "<WRITE ";
			text += tname + ">";
			m_pDoc->Message( text );

			CString temp;
			temp.Format( "Update successful : Total %d entries updated.", res.GetCount() );
			text = "<CLOSE ";
			text += tname + ">\r\n\t" + temp;
			m_pDoc->Message( text );

			CMsg msg( SUCCESSFUL );
			msg.m_msgList.AddTail( temp + "\n" );
			m_pDoc->SendMsg( m_pSocket, msg );
		}
		else
			throw Error( ERROR_AUTHOR, 0, _T("") );
		break;
	case DROP:
		if( (m_pSocket->m_type & LOG_SUPERUSER) || (m_pSocket->m_type & 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();
				CString		text( "<READ " );
				text += tname + ">";
				m_pDoc->Message( text );

				text = "<DELETE ";
				text += tname + ">\r\n\tSuccessful : Dropped table \"" + tname +"\"";
				m_pDoc->Message( text );

				CMainFrame* pMainFrm = ( CMainFrame* )theApp.m_pMainWnd;
				pMainFrm->m_FileBar.DelFile( tname );

				CMsg msg( TABLE_DROP );
				msg.m_msgList.AddTail( tname );
				m_pDoc->SendMsg( m_pSocket, msg );
			}
			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 );
				CString		text( "<READ " );
				text += iname + "> on TABLE: " + tname;
				m_pDoc->Message( text );

				text = "<DELETE ";
				text += iname + "> on TABLE: " + tname + "\r\n\tSuccessful : Dropped index \"" + iname + 
					".bpt\" on table\"" + tname + "\"";
				m_pDoc->Message( text );

				CMainFrame* pMainFrm = ( CMainFrame* )AfxGetMainWnd();
				pMainFrm->m_FileBar.DropIndex( tname, iname );

				CMsg msg( INDEX_DROP );
				msg.m_msgList.AddTail( tname );
				msg.m_msgList.AddTail( iname );
				m_pDoc->SendMsg( m_pSocket, msg );
			}
			else
				ErrorKey( i );
		else
			throw Error( ERROR_AUTHOR, 0, _T("") );
		break;
	case EXIT:
		theApp.Exit();
		break;
	default:
		ErrorKey( --i );
	}
}

void CSockExec::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() );
	}

	CMsg msg( COMPLETED );
	m_pDoc->SendMsg( m_pSocket, msg );
}

void CSockExec::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();

	CMsg msg( COMPLETED );
	m_pDoc->SendMsg( m_pSocket, msg );
}