📄 executestack.cpp
字号:
#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 + -