Today's post is a bit different than most. You see, the code is well written, well commented, and well documented. No less, we shall take a tour through the system which Steve L. maintained for a brief time, that had "The Little Button That Could" ...

The requirement was simple. Develop an ASP web-page with a single button that calls the Reset_Approval stored procedure in the database (passing in the approval number from the page's querystring) and display a message indicating success or failure.

To meet this requirement, many of us would have whipped together a simple ASP page that POSTed back to itself, calling the stored procedure directly or through a COM object depending on how the rest of the system functioned. This method would however have the undesired side-effect of *not* being the most complicated way ever to call a stored procedure ...

First, a page was built with a single button that called the following JavaScript function ...

function resetApproval(approvalNum)
{
    //create a xml document containing the request
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.documentElement = xmlDoc.createElement("reset_approval");
    xmlDoc.documentElement.appendChild ( xmlDoc.createElement("approval_num") );
    xmlDoc.selectSingleNode("/reset_approval/approval_num").text = approvalNum;

    //post the xml request to the receiver page
    var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    xmlHttp.Open("POST","/admin/approval_reset/reset_approval_process.asp",false);
    xmlHttp.Send( xmlDoc.xml )

    //make sure the receiver page accepted it
    if (xmlHttp.status != 200)
    {
        alert("There was an error reseting the approval:\n\n" + xmlHttp.statusText);
        return;
    }

    //load the response and extract the message node
    var responseXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    responseXmlDoc.LoadXML( xmlHttp.responseText );
    var messageNode = xmlDoc.selectSingleNode("/reset_approval_response/response_message");

    //make sure there is a message node
    if ( messageNode == null )
    {
        alert("There was an error reseting the approval:\n\n" + xmlHttp.responseText);
        return;
    }

    //notify if there was an error
    if ( messageNode.text != "success" )
    {
        alert("There was an error reseting the approval:\n\n" + messageNode.text);
        return;
    }

    //success, transfer to confirmation page
    location = 'process_approval_success.asp?approvalNum=' + approvalNum;
}

This had the effect of POSTing 42 to another page. I'll spare you the code, but that page would extract the approval number (42) from the XML, instantiate a COM Object named ResetApprovalManager, and pass the approval number to the ResetApproval method on the COM object.

From there, the ResetApprovalManager component instantiated the ResetApprovalDA object and passed the very same approval number to its ResetApproval method. Of course, the normally over-architected solution would end here and directly call the stored procedure. But you know I wouldn't be talking about it if it fell anywhere near the norm.

In any case, the ResetApprovalDA instantiated another class called XmlDbProcedure. This was a general purpose class which loaded XML files from disk (in this case, ProcedureDef_ResetApproval.xml) containing the stored procedure's name and it's parameters. The ResetApprovalDA set the text of the "approval_num" node and passed the XmlDbProcedure object to yet another class, XmlDbManager.

The XmlDbManager looked at the XMLDOM within the XmlDbProcedure and created the ADODB Command object and it's ADODB paramaters. This Command object was then finally passed to the AdoDbManager class, which actually executed the procedure.

I'll also spare you the description of the return trip worked, but suffice it to say it involved quite a bit more XML. Oh, and so you don't have to make any assumptions about the system ... it was designed to always run on SQL Server and despite having only around only 500 users, it requires three stacks of four servers. And it still runs a bit slow.