⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 executestack.cpp

📁 一个经典的词法分析器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <afxwin.h>
#include "EMBSQL.h"

//
// An execution class for SQL stacks
//

void *CEStack::operator new(size_t size)
{
	return (CEStack*)shared_malloc(size);
}

void CEStack::operator delete(void *p)
{
	shared_free((char*)p);
}

//
// Constructor, assign the stack
CEStack::CEStack()
{
	rowInQuestion = NULL;
	tableInQuestion = NULL;
	result = new SCCollection();
}

void CEStack::Load(SCCollection *stk)
{
	stack = stk;
}

//
// Parent owns the stack, don't mess with it
CEStack::~CEStack()
{
	DeleteResult();
}

//
// Delete the items in the result stack. 
void CEStack::DeleteResult()
{
	int nCols = 0;
	void** voids = NULL;
	if (tableInQuestion == NULL || result == NULL)
		return;
	nCols = tableInQuestion->Columns();
	result->RemoveAll();
	delete result;
}

//
// Execute a stack
SCCollection* CEStack::Execute()
{
	CString *value = NULL;
	bool rc = false;
	while((value=stack->Pop()) != NULL) {
		if (*value ==		 "SELECT") rc = ExecuteSelect();
		if (!rc && *value == "INSERT") rc = ExecuteInsert(); 
		if (!rc && *value == "UPDATE") rc = ExecuteUpdate();
		if (!rc && *value == "DELETE") rc = ExecuteDelete();
		if (!rc && *value == "ASSIGNMENTS") rc = ExecuteAssign();
		if (!rc && *value == "CREATE TABLE") rc = ExecuteCreate();
		if (!rc) 
			errorString = "Runtime error in " + *value + "() " + errorString;
		if (errorString != "") {
			delete result;
			result = NULL;
			stack->Clear();
			stack->Push(errorString);
			stack->Push("ERROR");
			return NULL;
		}
	}
	stack->Push("OK");
	return result;
}

//
// Pop a production off the stack, Can be called recursively
CString* CEStack::PopProduction()
{
	CString* value = stack->Pop();
	if (!value) return NULL;
	if (IsOperator(*value)) { ExecuteOperator(*value); value = stack->Pop(); return value; }

	return value;
}

//
// Create a new table. Requires some remembering as the parent Sql() method in CESql will
// make the table, we can't do it in here.
bool CEStack::ExecuteCreate()
{
	CString *table = NULL;
	CString *value = NULL, *type = NULL, *size = NULL;
	int sz = 0, i = 0;
	SCColumn** cols;

	DeleteResult();						// prepare for new result
	result = new SCCollection();
	errorString		= "";				// no error, yet
	table = stack->Pop();				// get the table to use
	tableInQuestion = CESql::FindTable(*table);
	if (tableInQuestion) {
		errorString = "Table " + *table + " already exists!";
		return true;
	}
	tableName = *table;					// remember the name, parent will need this
	sz = 1 + atoi((LPCSTR)*stack->Pop());// allocate the columns
	cols = new SCColumn*[sz];
	i = sz-2;							// columns are loaded in reverse so that allocations will match the order defined
	while((value = stack->Pop()) != NULL) {	// create the columns
		type = stack->Pop();
		if (*type == "float")				// float type
			cols[i--] = new SCColumn(*value,CFLOAT,12);
		if (*type == "char") {
			size = stack->Pop();			// char type
			cols[i--] = new SCColumn(*value,CSTRING,atoi(*size));
		}
		if (*type == "long" || *type == "int") 
			cols[i--] = new SCColumn(*value,CLONG,12);
		if (*type == "unsigned")
			cols[i--] = new SCColumn(*value,CUNSIGNED,12);
		if (*type == "time")
			cols[i--] = new SCColumn(*value,CTIME,20);
	}
	cols[sz-1] = NULL;						// mark the end of the list
	result = (SCCollection*)cols;			// return the cast of the columns
	return true;
}
//
// The select execution method
bool CEStack::ExecuteSelect()
{
	CString *value = NULL;
	CString *table = NULL;
	SCCollection* list = NULL;				// attribute list
	SCCollection *saveStack = NULL, *copyStack = NULL;

	DeleteResult();						// prepare for new result
	result = new SCCollection();
	errorString		= "";				// no error, yet
	table = stack->Pop();				// get the table to use
	tableInQuestion = CESql::FindTable(*table);
	if (!tableInQuestion) {
		errorString = "No such table " + *table;
		return true;
	}
	list = new SCCollection();
	value = stack->Pop();				// the attributes list
	if (*value == "LIST") {				
		while(*value != "EOLIST") {
			value = stack->Pop();
			if (*value != "EOLIST")
				list->Add((CObject*)value);
		}
	}

	value = stack->Pop();		// where
	if (value == NULL) {		// select all records if null
		list->Clear();
		delete list;
		for (int i=0;i<tableInQuestion->NRows();i++) {
			rowInQuestion = (void **)tableInQuestion->GetRow(i);
			result->Add((CObject*)rowInQuestion);
		}
		return true;
	}
//
// Iterate through each of the records in the table. At each record
// Execute the stack.
// If the result is true, then select this record into the return set
// Else don't select into the return set
//
	saveStack = stack;						// save stack at this point
	copyStack = stack->Copy();

	for (int i=0;i<tableInQuestion->NRows();i++) {
		rowInQuestion = tableInQuestion->GetRow(i);
		stack = copyStack->Copy();	// restore the stack for each record test
		value = stack->Pop();
		ExecuteOperator(*value);
		if (errorString != "") { 
			list->Clear();
			copyStack->Clear();
			stack = saveStack;
			delete list;
			delete copyStack;
			return true;
		}
		value = stack->Pop();
		if (Numberize(*value) > 0.0) {
			result->Add((CObject*)rowInQuestion);
		}
		stack->Clear();
		delete stack;
	}
	saveStack = stack;
	list->Clear();
	copyStack->Clear();
	delete list;
	delete copyStack;
	return true;
}

//
// Update rows based on a where criteria. HOOK: INCOMPLETE
bool CEStack::ExecuteUpdate()
{
	CString *value = NULL;
	CString *table = NULL;

	DeleteResult();							// prepare for new result
	result = new SCCollection();
	errorString = "";						// no error, yet
	SCCollection* assignStack = new SCCollection();
	SCCollection *copyStack = NULL, *saveStack = NULL;
	table = stack->Pop();
	tableInQuestion = CESql::FindTable(*table);
	if (!tableInQuestion) {
		errorString = "No such table " + *table;
		return true;
	}
	value = stack->Pop();
	if (*value == "ASSIGNMENTS") {
		while( value != NULL &&*value != "WHERE") {
			value = stack->Pop();
			if (value != NULL && *value != "WHERE") {
				if (IsOperator(*value)) { 
					ExecuteOperator(*value); 
					value = stack->Pop(); 
				}
				assignStack->Add((CObject*)value);
			}
		}
	}
//
// Iterate through each of the records in the table. 
// At each record execute the stack.
// If the result is true, then execute the assignment stack 
// Else don't execute the assignmentStack
//
	copyStack = stack->Copy();
	saveStack = stack;

	for (int i=0;i<tableInQuestion->NRows();i++) {
		rowInQuestion = tableInQuestion->GetRow(i);
		stack = copyStack->Copy();
		value = stack->Pop();
		if (value) {
			ExecuteOperator(*value);
			value = stack->Pop();
			if (Numberize(*value) > 0.0) {
				stack->Clear();
				delete stack;
				stack = assignStack->Copy();
				ExecuteAssign();
			}
		}
		else {				// no where clause, unconditional assign
			stack = assignStack->Copy();
			ExecuteAssign();
		}
		stack->Clear();
		delete stack;
	}

	copyStack->Clear();
	delete copyStack;
	stack = saveStack;
	stack->Clear();
	return true;
}

//
// Insert a record into into the data set
bool CEStack::ExecuteInsert()
{
	CString *value = NULL;
	CString *table = NULL;
	CString *attr  = NULL;
	SCColumn *col   = NULL;
	int i = 0;

	DeleteResult();							// prepare for new result
	result = new SCCollection();
	errorString = "";						// no error
	SCCollection* attrStack = new SCCollection();
	SCCollection* valueStack = new SCCollection();
	table = stack->Pop();					// table name
	tableInQuestion = CESql::FindTable(*table);
	if (!tableInQuestion) {
		errorString = "No such table " + *table;
		return true;
	}
	value = stack->Pop();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -