Once a Windows DNA application's business operations and respective request syntaxes have been defined, the next step is to create the executants that will ultimately perform the application's business operations. The DNA PurchaseOrder application relies on the AccountsExec, InventoryExec, LineItemExec, and PurchaseOrderExec executants to perform the business operations defined earlier in Tables 6-9, and relies on the UniqueIDGen and UniqueIDAllocBatch objects to generate the primary key values for each row inserted into the application's underlying database tables. While executants are ultimately responsible for performing business operations, they are free to use whatever means necessary. Some Windows DNA applications issue batches of SQL statements to manipulate and update their underlying data source(s), while others like the DNA PurchaseOrder application rely on the increased performance offered by SQL stored procedures. The SQL stored procedures required to perform the business operations of the DNA PurchaseOrder application are described in the following table.
Table 15. The Stored Procedures Required by the DNA PurchaseOrder Application
Stored procedure | Description |
sp_AllocBatchOfUniqueIDs | Allocates a batch of 100 unique IDs. |
sp_decrementBalance_Accounts | Decrements the balance of a particular account by a user-defined amount. |
sp_decrementQOH_Inventory | Decrements the quantities on hand of a particular inventory item by a user-defined amount. |
sp_delete_Accounts | Deletes an account from the underlying Accounts database table. |
sp_delete_Inventory | Deletes an inventory item from the underlying Inventory database table. |
sp_delete_LineItems | Deletes a line item from the underlying LineItems database table. |
sp_delete_PurchaseOrders | Deletes a purchase order from the underlying PurchaseOrders database table. |
sp_deleteByPurchaseOrder_LineItems | Deletes all of the line items associated with a particular purchase order from the underlying LineItems database table. |
sp_incrementBalance_Accounts | Increments the balance of a particular account by a user-defined amount. |
sp_incrementQOH_Inventory | Increments the quantities on hand of a particular inventory item by a user-defined amount. |
sp_insert_Accounts | Inserts a new account into the underlying Accounts database table. |
sp_insert_Inventory | Inserts a new inventory item into the underlying Inventory database table. |
sp_insert_LineItems | Inserts a new line item into the underlying LineItems database table. |
sp_insert_PurchaseOrders | Inserts a new purchase order into the underlying PurchaseOrders database table. |
sp_update_Accounts | Modifies an account that already exists in the underlying Accounts database table. |
sp_update_Inventory | Modifies an inventory item that already exists in the underlying Inventory database table. |
sp_update_LineItems | Modifies a line item that already exists in the underlying LineItems database table. |
sp_update_PurchaseOrders | Modifies a purchase order that already exists in the underlying PurchaseOrders database table. |
To create the stored procedures required by the DNA PurchaseOrder application
If everything is successful, you should be able to select the Databases\DNADesign\Stored Procedures node in the left-hand pane of the SQL Server Enterprise Manager and see the stored procedures listed in Table 15 in the right-hand pane.
Regardless of whether an application issues batches of SQL statements or executes SQL stored procedures, the business operations performed by Windows DNA application executants should be performed inside MTS transactions. MTS transactions allow developers to concentrate on implementing business operations without having to worry about problems caused by partially completed operations, operations leaving the underlying data source in an unexpected state, concurrently executing operations, or results not surviving system failure. Besides providing transactions, MTS also provides resource pooling, process isolation, and role-based security. The DNA PurchaseOrder executants use MTS's role-based security to ensure sensitive business operations are only accessible by authorized personnel.
' Only Administrators can create accounts
If Not GetObjectContext.IsCallerInRole("Administrators") Then GoTo ErrorHandler
To implement the DNA PurchaseOrder executants
Option Explicit
' Use the native SQL OLEDB provider
Public Const gstrCONNECT = "Provider=SQLOLEDB;Database=DNADesign;UID=sa;PWD="
Early-binding clients like those developed using Visual Basic, C/C++, and Java will most likely communicate with the executants using the custom interfaces just defined for performance and type safety reasons. However, the executants must also be accessible from late-binding clients, which includes ActiveX Scripting hosts like Microsoft Internet Explorer and Active Server Pages (ASP). Typically, such late-binding clients have a limited range of supported data types, and are only capable of accessing an object's default Automation interface. Because these late-binding clients will not be able to access the executant through the custom interface, the executant must implement a scriptable default interface. The scriptable default interface implemented by the executant should contain the same properties and methods as those defined by the custom interface, albeit with a few minor adjustments to accommodate the way Microsoft Visual Basic® Scripting Edition (VBScript) handles ByRef arguments (See Knowledge Base Article ID: Q172214). Implementing the properties and methods that are copied from the custom interface is usually a simple matter of delegating to the custom interface implementation, although occasionally preliminary data type coercion is required.
Public Function Destroy(ByVal lngAccountID As Long) As Boolean
' Delegate the default interface implementation
' to the appropriate interface implementation
Destroy = IAccountExec_Destroy(lngAccountID)
End Function
To implement a scriptable default interface for each executant
Once the scriptable default interface for each executant has been implemented, the UniqueIDAllocBatch and UniqueIDGen objects that are used to generate unique identifiers for use as primary key values for each row in the Accounts, Inventory, LineItems, and PurchaseOrders tables must be created.
To create the UniqueIDAllocBatch and UniqueIDGen objects
Before the DNA PurchaseOrder executants can be compiled, each executant must declare the type of transactional support it requires from MTS. The types of transactional support offered by MTS are described in the following table.
Table 16. Transactional Support Offered by MTS
Transactional support | Description |
Requires a transaction | Objects must execute within the scope of a transaction. When a new object is created, it inherits the transaction from the client. If the client does not have a transaction, MTS automatically creates a new transaction for the object. |
Requires a new transaction | Objects must execute within their own transactions. When a new object is created, MTS automatically creates a new transaction for the object, regardless of whether its client has a transaction. |
Supports transactions | Objects can execute within the scope of their client's transactions. When a new object is created, it inherits the transaction from the client, if the client has a transaction; otherwise the new object is created without a transaction. |
Does not support transactions | Objects do not run within the scope of transactions. When a new object is created, it is created without a transaction, regardless of whether its client has a transaction. |
For the DNA PurchaseOrder application, the AccountExec, InventoryExec, LineItemExec, PurchaseOrderExec, and UniqueIDGen objects all "Require a Transaction," while the UniqueIDAllocBatch object "Requires a New Transaction."
To declare the transactional support required by the DNA PurchaseOrder executants
Once each executant has been completely implemented, save your work, and compile the ActiveX DLL into POExecutants.dll.