/*here are the classes that are needed for the function below*/ class data { public : int points; void addPoint(int x) { dataPoints.push_back(x); } std::vector dataPoints; }; class node { public : node(node * nxt, node * prv, node * chld, data * d, double val) { nextInLine = nxt; prevInLine = prv; child = chld; value = val; dataPoint = d; } void setNext(node * next) { nextInLine = next; } node * getNext() { return nextInLine; } void setPrev(node * prev) { prevInLine = prev; } node * getPrev() { return prevInLine; } void setChild(node * child2) { child = child2; } node * getChild() { return child; } void setValue(double newVal) { value = newVal; } double getValue() { return value; } void setData(data * d) { dataPoint = d; } data * getData() { return dataPoint; } protected : node *nextInLine; node *prevInLine; node *child; double value; data *dataPoint; }; /*This is the main engine behind my senior design project. I have *not included the full source as this is the only really interesting part*/ /* Function bool createModel(IADOTierPtr dbConn, node **firstNode, std::string *FieldList, int fieldListArraySize, std::string * dependentField, std::string * startDates, int startDateArraySize, std::string * endDates, int endDateArraySize, std::string * machineName) * This function accesses the database and pulls all information collected about a machine. It * then creates a model built on this and following parameters set by the user*/ bool createModel(IADOTierPtr dbConn, node **firstNode, std::string *FieldList, int fieldListArraySize, std::string * dependentField, std::string * startDates, int startDateArraySize, std::string * endDates, int endDateArraySize, std::string * machineName) { std::stringstream intBuff; *firstNode = new node(NULL,NULL,NULL,NULL, -1);//initialize the firstNode pointer node * nodePtr = NULL; std::string tempStr = ""; std::string SQLStr; bool found = false; try { /*construct SQL string to figure out the table name for this machine*/ SQLStr = "SELECT TargetFile FROM DSJobsConfig WHERE JobName = '" + *machineName + "' AND JobType = 1"; /*run the SQL*/ dbConn->ExecuteConnection(SQLStr.c_str(), VARIANT_FALSE); dbConn->OpenRecordset(SQLStr.c_str()); if(!dbConn->GetEmpty()){ dbConn->First(); /*create the SQL statement to get all valid data from the table*/ SQLStr = "SELECT "; for (int i = 0; i < fieldListArraySize;i++) { /*list the fields to select*/ SQLStr = SQLStr + FieldList[i] + ", "; } /*tack on the dependent field*/ SQLStr = SQLStr + *dependentField; SQLStr = SQLStr + " FROM "; SQLStr = SQLStr + (std::string)(_bstr_t)dbConn->GetField("TargetFile"); /*set the minimum line speed*/ intBuff << MIN_LINESPEED; intBuff >> tempStr; SQLStr = SQLStr + " WHERE linespeed >= " + tempStr; /*add the date exclusions*/ for (int j = 0; j < startDateArraySize; j++) { SQLStr = SQLStr + " AND NOT (CurrentDateTime >= #"; SQLStr = SQLStr + startDates[j] + "# AND CurrentDateTime <= #"; SQLStr = SQLStr + endDates[j] + "#)"; } dbConn->CloseRecordset(); } /*run the newly formed SQL string and get all the data*/ dbConn->OpenRecordset(SQLStr.c_str()); if (!dbConn->Empty) { dbConn->First(); while (!dbConn->ADOEOF) { try{ /*try accessing all the fields. will fail if one is null. this is good*/ for(int theField2 = 0; theField2 < fieldListArraySize; theField2++) { tempStr = (std::string)(_bstr_t)dbConn->GetField(FieldList[theField2].c_str()); } tempStr = (std::string)(_bstr_t)dbConn->GetField(dependentField->c_str()); /*reset the node pointer to point to the first node*/ nodePtr = *firstNode; /*If it hasn't thrown an error, we have data in all fields*/ for(int theField = 0; theField < fieldListArraySize; theField++) { /*get the value of this field*/ tempStr = (std::string)(_bstr_t)dbConn->GetField(FieldList[theField].c_str()); /*if the node has no children we'll set the new node here*/ if (nodePtr->getChild() == NULL) { /*create the new node*/ node *theNode = new node(NULL,nodePtr,NULL,NULL, (double)atoi(tempStr.c_str())); /*set the prev value of the child to point to the parent*/ nodePtr->setChild(theNode); /*set the pointer to the child for the next pass*/ nodePtr = nodePtr->getChild(); } /*if it has children, pop in and traverse*/ else { /*become the child*/ nodePtr = nodePtr->getChild(); /*if the current valud is less than the smallest value, put node here*/ if((atoi(tempStr.c_str()) < (int)nodePtr->getValue())) { /*create the new node, pointing it's "next" to the parent's old child*/ node *theNode = new node(nodePtr,nodePtr->getPrev(),NULL,NULL, (double)atoi(tempStr.c_str())); /*set this node as the parent's new child*/ nodePtr->getPrev()->setChild(theNode); /*set the parent as this node's previous*/ nodePtr->setPrev(theNode); /*set the pointer for the next pass*/ nodePtr = theNode; } /*if the current value is greater than current node, find position and insert*/ else { found = false; while(!found) { /*if we're not at the end of the line yet*/ if(nodePtr->getNext() != NULL) { /*while the value is greater than the next one, increment*/ if((atoi(tempStr.c_str()) >= (int)nodePtr->getNext()->getValue())) { nodePtr = nodePtr->getNext(); } else { found = true; } } else { /*we're at the end of the line. the new node goes here*/ found = true; } } /*if it's equal to the current node, then we're in the right place*/ if((atoi(tempStr.c_str()) == (int)nodePtr->getValue())) { found = true; } /*it is larger than the node we're at one, but smaller than the next*/ else { /*create node with correct pointers*/ node *theNode = new node(nodePtr->getNext(),nodePtr,NULL,NULL, (double)atoi(tempStr.c_str())); if (nodePtr->getNext() != NULL) { /*set the next node to point to new node*/ nodePtr->getNext()->setPrev(theNode); } /*set the pointer to the new node*/ nodePtr->setNext(theNode); /*set the pointer for the next pass*/ nodePtr = theNode; } } } } /*we're pointing to the last of the nodes. now we tack on the data*/ tempStr = (std::string)(_bstr_t)dbConn->GetField(dependentField->c_str()); if(nodePtr->getData() == NULL) { /*there is no point array yet, create it*/ data * dataPoint = new data; nodePtr->setData(dataPoint); nodePtr->getData()->addPoint(atoi(tempStr.c_str())); nodePtr->getData()->points = 1; } else { /*if the point array exists, add to the data point array*/ nodePtr->getData()->points = nodePtr->getData()->points + 1; nodePtr->getData()->addPoint(atoi(tempStr.c_str())); } } catch (_com_error& e) { /* on error do nothing. this error is expected. It happens whenever * there is a null entry in a field*/ } dbConn->Next(); } } dbConn->CloseRecordset(); } catch (_com_error& e) { return false; } return true; }