Using Sessions in a Sample Web Application

Overview of the Sample Web Application

The following sample Web application demonstrates some of the features of stored process sessions. The sample application is an online library. Users can log on, select one or more items to check out of the library, and request by e-mail that the selected items be delivered. The sample code shows how to create a session and then create, modify, and view macro variables and data sets in that session. For more information, see Using Sessions.

Sample Data

This sample requires a LIB_INVENTORY data set in the SAMPDAT library that is used for other SAS Integration Technologies samples. You can create the data set in Windows using the following code. You can also use the code in other operating environments by making the appropriate modifications to the SAMPDAT LIBNAME statement.
 libname SAMPDAT 'C:\My Demos\Library';
 data SAMPDAT.LIB_INVENTORY;
 length type $10 desc $80;
 input refno 1-5 type 7-16 desc 17-80;
 datalines4;
 17834 BOOK SAS/GRAPH Software: Reference
 32345 BOOK SAS/GRAPH Software: User's Guide
 52323 BOOK SAS Procedures Guide
 54337 BOOK SAS Host Companion for UNIX Environments
 35424 BOOK SAS Host Companion for OS/390 Environment
 93313 AUDIO The Zen of SAS
 34222 VIDEO Getting Started with SAS
 34223 VIDEO Introduction to AppDev Studio
 34224 VIDEO Building Web Applications with 
 SAS Stored Processes
 70001 HARDWARE Cellphone - Model 5153
 70002 HARDWARE Video Projector - Model 79F15
 ;;;;

Main Aisle Stored Process

The main aisle page is generated by the Main Aisle stored process. This page acts as a welcome page to new users. A session is created the first time a user executes this stored process.
 /* Main Aisle of the Online Library */
 data _null_;
 file _webout;
 if libref('SAVE') ne 0 then
 rc = stpsrv_session('create');
 put '<HTML>';
 put '<HEAD><TITLE>Online Library 
 Main Aisle</TITLE></HEAD>';
 put;
 put '<BODY vlink="#004488" link="#0066AA" 
 bgcolor="#E0E0E0">';
 put '<H1>Online Library Main Aisle</H1>';
 put;
 put 'Select one of the following 
 areas of the library:';
 put '<UL>';
 length hrefroot $400;
 hrefroot = symget('_THISSESSION') || 
 '&_PROGRAM=/WebApps/Library/';
 put '<LI><A HREF="' hrefroot +(-1)
 'Aisles&type=Book">Book Aisle</A></LI>';
 put '<LI><A HREF="' hrefroot +(-1)
 'Aisles&type=Video">Video Aisle</A></LI>';
 put '<LI><A HREF="' hrefroot +(-1)
 'Aisles&type=Audio">Audio Aisle</A></LI>';
 put '<LI><A HREF="' hrefroot +(-1)
 'Aisles&type=Hardware">Hardware Aisle</A></LI>';
 put '<LI><A HREF="' hrefroot +(-1)
 'Shopping Cart">View my shopping cart</A></LI>';
 put '<LI><A HREF="' hrefroot +(-1)
 'Logout">Logout</A></LI>';
 put '</UL>';
 put '</BODY>';
 put '</HTML>';
 run;
The main aisle page consists of a list of links to specific sections of the Online Library.
Main aisle page
Each link in this page is built using the _THISSESSION macro variable. This variable includes both the _URL value pointing back to the Stored Process Web Application and the _SESSIONID value that identifies the session.

Aisles Stored Process

The library is divided into aisles for different categories of library items. The pages for each aisle are generated by one shared Aisles stored process. The stored process accepts a TYPE input variable that determines which items to display.
 /* Aisles - List items in a specified aisle.
 The aisle is specified by the TYPE variable. */
 libname SAMPDAT 'C:\My Demos\Library';
 
 /* Build a temporary data set that contains the 
 selected type, and add links for selecting 
 and adding items to the shopping cart. */
 data templist;
 if libref('SAVE') ne 0 then
 rc = stpsrv_session('create');
 set SAMPDAT.LIB_INVENTORY;
 where type="%UPCASE(&type)";
 length select $200;
 select = '<A HREF="' || symget("_THISSESSION") ||
 '&_program=/WebApps/Library/Add+Item&REFNO=' ||
 trim(left(refno)) || '&TYPE=' || "&TYPE" ||
 '">Add to cart</A>';
 run;
 ods html body=_webout(nobot) rs=none;
 title Welcome to the &type Aisle;
 proc print data=templist noobs label;
 var refno desc select;
 label refno='RefNo' desc='Description' select='Select';
 run;
 ods html close;
 data _null_;
 file _webout;
 put '<P>';
 put 'Return to <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Main+Aisle'
 '">main aisle</A><BR>';
 put 'View my <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Shopping+Cart'
 '">shopping cart</A><BR>';
 put '</BODY>';
 put '</HTML>';
 run;
The stored process selects a subset of the LIB_INVENTORY data set by using a WHERE clause, and then uses PROC PRINT to create an HTML table. A temporary data set is created. This data set contains the selected items that users can use to add items. An additional column is generated from the LIB_INVENTORY data set that has an HTML link that users can use to add the item to their shopping cart.
In this stored process, both ODS and a DATA step are used to generate HTML. The ODS HTML statement includes the NOBOT option that indicates that more HTML is appended after the ODS HTML CLOSE statement. The navigation links are then added using a DATA step. The following display shows the contents of the Book Aisle.
Book aisle page

Add Item Stored Process

The Add Item stored process is run when the user clicks the Add to cart link in the aisle item table. The specified item is copied from the LIB_INVENTORY data set to a shopping cart data set in the session library (SAVE.CART). The session and the data set remain accessible to all programs in the same session until the session is deleted or it times out.
 /* Add Item - Add a selected item to the shopping cart.
 This stored process uses REFNO and TYPE input 
 variables to identify the item. */
 libname SAMPDAT 'C:\My Demos\Library';
 /* Perform REFNO and TYPE verification here. */
 /* Append the selected item. */
 proc append base=SAVE.CART data=SAMPDAT.LIB_INVENTORY;
 where refno=&refno;
 run;
 /* Print the page. */
 data _null_;
 file _webout;
 put '<HTML>';
 put '<HEAD><TITLE>Selected Item Added to 
 Shopping Cart</TITLE></HEAD>';
 put '<BODY vlink="#004488" link="#0066AA" 
 bgcolor="#E0E0E0">';
 put "<H1>Item &refno Added</H1>";
 put 'Return to <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Aisles'
 '&TYPE=' "&TYPE" '">' "&TYPE aisle</A><BR>";
 put 'Return to <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Main+Aisle'
 '">main aisle</A><BR>';
 put 'View my <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Shopping+Cart'
 '">shopping cart</A><BR>';
 put '</BODY>';
 put '</HTML>';
 run;
The program prints an information page that has navigation links.
Add item page

Shopping Cart Stored Process

The Shopping Cart stored process displays the contents of the shopping cart.
 /* Shopping Cart - Display contents of the shopping cart
 * (SAVE.CART data set). */
 %macro lib_cart;
 %let CART=%sysfunc(exist(SAVE.CART));
 %if &CART %then %do;
 /* This program could use the same technique as the 
 LIB_AISLE program in order to add a link to each 
 line of the table that removes items from the 
 shopping cart. */
 /* Print the CART contents. */
 ods html body=_webout(nobot) rs=none;
 title Your Selected Items;
 proc print data=SAVE.CART noobs label;
 var refno desc;
 label refno='RefNo' desc='Description';
 run;
 ods html close;
 %end;
 %else %do;
 /* No items in the cart. */
 data _null_;
 file _webout;
 put '<HTML>';
 put '<HEAD><TITLE>No items 
 selected</TITLE></HEAD>';
 put '<BODY vlink="#004488" link="#0066AA" 
 bgcolor="#E0E0E0">';
 put '<H1>No Items Selected</H1>';
 put;
 run;
 %end;
 /* Print navigation links. */
 data _null_;
 file _webout;
 put '<P>';
 if &CART then do;
 put '<FORM ACTION="' "&_url" '">';
 put '<INPUT TYPE="HIDDEN" NAME="_program" 
 VALUE="/WebApps/Library/Logout">';
 put '<INPUT TYPE="HIDDEN" NAME="_sessionid" 
 VALUE="' "&_sessionid" '">';
 put '<INPUT TYPE="HIDDEN" NAME="CHECKOUT" 
 VALUE="YES">';
 put '<INPUT TYPE="SUBMIT" 
 VALUE="Request these items">';
 put '</FORM><P>';
 end;
 put 'Return to <A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Main+Aisle'
 '">main aisle</A><BR>';
 put '<A HREF="' "&_THISSESSION"
 '&_PROGRAM=/WebApps/Library/Logout'
 '&CHECKOUT=NO">Logout</A><BR>';
 put '</BODY>';
 put '</HTML>';
 run;
 %mend;
 %lib_cart;
The contents of the shopping cart are displayed using a PROC PRINT statement. The page also includes a request button and navigation links. The request button is part of an HTML form. In order to connect to the same session, include the _SESSIONID value in addition to the _PROGRAM value. These values are usually specified as hidden fields. This program also has a hidden CHECKOUT field that is initialized to YES in order to indicate that the user is requesting the items in the cart.
The program prints a page that contains the contents of the shopping cart.
Shopping cart page

Logout Stored Process

The Logout stored process checks the user out of the Online Library. If the CHECKOUT input variable is YES, then all of the items in the user's shopping cart are requested through e-mail.
 /* Logout - logout of Online Library application. 
 Send e-mail to the library@abc.com account with 
 requested item if CHECKOUT=YES is specified. */
 %macro lib_logout;
 %global CHECKOUT; 
	 /* Define CHECKOUT in case it was not input. */
 %if %UPCASE(&CHECKOUT) eq YES %then %do;
 /* Checkout - send an e-mail request to the library.
 See the documentation for the email access method
 on your platform for more information on the 
 required options. */
 /* ***************** disabled for demo *************
 filename RQST EMAIL 'library@abc.com'
 SUBJECT='Online Library Request for &_username';
 ods listing body=RQST;
 title Request for &_username;
 proc print data=SAVE.CART label;
 var refno type desc;
 label refno='RefNo' type='Type' 
 desc='Description';
 run;
 ods listing close;
 * *********************************************** */
 data _null_;
 file _webout;
 put '<HTML>';
 put '<HEAD><TITLE>Library 
 Checkout</TITLE></HEAD>';
 put '<BODY vlink="#004488" link="#0066AA" 
 bgcolor="#E0E0E0">';
 put '<H1>Library Checkout</H1>';
 put;
 put 'The items in your shopping cart have 
 been requested.';
 put '<P>Requested items will normally 
 arrive via interoffice';
 put 'mail by the following day. Thank you 
 for using the Online Library.';
 put '<P><A HREF="' "&_URL"
 '?_PROGRAM=/WebApps/Library/Main+Aisle"
 >Click here</A>';
 put 'to re-enter the application.';
 put '</BODY>';
 put '</HTML>';
 run;
 %end;
 %else %do;
 /* Logout without requesting anything. */
 data _null_;
 file _webout;
 put '<HTML>';
 put '<HEAD><TITLE>Logout</TITLE></HEAD>';
 put '<BODY vlink="#004488" link="#0066AA" 
 bgcolor="#E0E0E0">';
 put '<H1>Library Logout</H1>';
 put;
 put '<P>Thank you for using the Online Library.';
 put '<P><A HREF="' "&_URL"
 '?_PROGRAM=/WebApps/Library/Main+Aisle"
 >Click here</A>';
 put 'to re-enter the application.';
 put '</BODY>';
 put '</HTML>';
 run;
 %end;
 %mend;
 %lib_logout;
 /* User is finished - delete the session. */
 %let rc=%sysfunc(stpsrv_session(delete));
An information page is displayed if the user chooses to request the shopping cart items.
Library checkout page
A logoff screen is displayed if the user selects the Logout link.
Logout page
Note: Logging off is not required. All sessions have an associated time-out (the default is 15 minutes). If the session is not accessed for the duration of the time-out, then the session and all temporary data in the session are deleted. In this sample, the SAVE.CART data set is automatically deleted when the session time-out is reached. You can change the session time-out by using the STPSRVSET('session timeout',seconds) function inside the program.