1231-1235

Previous Table of Contents Next

Page 1231

 boolean   * bAuthorized; {   char  *       UserID        ,*       Password;   WRBReturnCode Ret;   /* Get the UserID and Password from WRB */   UserID   = WRBGetUserID   (WRBCtx);   Password = WRBGetPassword (WRBCtx);   /* Check to see if this user has access */   *bAuthorized = ((userID   != (char*)0) && !strcmp(UserID,   "scott") &&                   (password != (char*)0) && !strcmp(Password, "tiger"))   ;   Return (WRB_DONE); } WRBReturnCode Hello_Shut (WRBCtx, clientcxp) void   * WRBCtx; void   * clientcxp; {   return (WRB_DONE); } WRBReturnCode Hello_Exec (WRBCtx, clientcxp) void   * WRBCtx; void   * clientcxp; {   /* set up the response HTML */   char * HTML = "Content-type: text/html\n<HTML>\n<HEAD>\n<TITLE>Hello, world! </TITLE>\n</HEAD>\n<BODY>Hello, world!</BODY>\n</HTML>";   /* Write the response to the WRB */   WRBClientWrite(WRBCtx, HTML, strlen(HTML));   return (WRB_DONE); } 

Now I dissect the Hello_WRB.c code:

  • Include headers: The first two include statements indicate standard Web Application Server files. These header files contain the prototypes , constants, and structures required by the program.
  • Set up callback prototypes: The four prototypes are created. These correspond with the function declarations lower in the source code.
  • Hello_entry function: This function assigns the callbacks so the WRB can interact with the appropriate routines.
  • Hello_Init function: This function simply returns. There is no initialization needed for this simple example.

Page 1232

  • Hello_Auth function: This function checks the user/password to see if it is valid. If it is, scott/tiger, in this case, the bAuthorized parameter is set to true. This indicates that the user has access to the cartridge.
  • Hello_Shut function: This function simply returns. There is no cleanup required.
  • Hello_Exec function: This function performs the request. All the rest of the functions mentioned are simply overhead for the cartridge. They manage initialization, cleanup, and authority. The Hello_Exec function formats the output and writes it to the WRB. It is ultimately sent back to the browser and displayed for the client.

Essentially, the cartridge does not do much at this point. I now concentrate on performing transactions within the Oracle database via a cartridge. To show the true power of the Oracle development tools, I implement a thin layer of Pro*C code that in turn calls into a stored packaged procedure to execute the transaction. Listing 54.3 contains the package.

Listing 54.3. A PL/SQL package to insert a new customer.

 CREATE OR REPLACE PACKAGE pkgCustomer as   procedure InsertNew (     inName                in      varchar2    ,inAddress             in      varchar2    ,inCity                in      varchar2    ,inState               in      varchar2    ,inPhone               in      varchar2   ); end; / show errors; create or replace package body pkgCustomer as   procedure InsertNew (     inName                in      varchar2    ,inAddress             in      varchar2    ,inCity                in      varchar2    ,inState               in      varchar2    ,inPhone               in      varchar2   ) as   begin     INSERT INTO Customer     (         ID        ,Name        ,Address        ,City        ,State        ,Phone     )     values     ( 

Page 1233

 CustomerSeq.nextval        ,inName        ,inAddress        ,inCity        ,inState        ,inPhone     );   end; end; / show errors 

This simple package contains a single procedure InsertNew that inserts a new row into the customer table. Next, Listing 54.4 creates some Pro*C code that provides the interface between Oracle and the cartridge.

Listing 54.4. Pro*C can become your bridge between Oracle and the cartridge code.

 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlproto.h> #define TO_VARCHAR(Arr, C)  \      strcpy((Arr).arr, (C)); (Arr).len = strlen((C)) EXEC SQL INCLUDE sqlca; char  * GetError           (void); int     OracleErrorHandler (char *Buffer); int     OracleLogin        (char *usr, char *pwd); void    OracleLogout       (); void    InsertCustomer     (char *szName,  char *szAddress, char *szCity                            ,char *szState  char *szPhone); EXEC SQL BEGIN DECLARE SECTION;     VARCHAR         UserName [30];     VARCHAR         Password [30];     VARCHAR         Name     [40];     VARCHAR         Address  [35];     VARCHAR         City     [27];     VARCHAR         State    [ 2];     VARCHAR         Phone    [12]; EXEC SQL END DECLARE SECTION; char    ErrorBuffer         [512]; 
 continues 

Page 1234

Listing 54.4. continued

 int OracleLogin(char *usr, char *pwd) {     TO_VARCHAR(UserName,  usr);     TO_VARCHAR(Password,  pwd);     EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer);     EXEC SQL CONNECT :UserName IDENTIFIED BY :Password;     if (ErrorBuffer[0] != ` 
 int OracleLogin(char *usr, char *pwd) { TO_VARCHAR(UserName, usr); TO_VARCHAR(Password, pwd); EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer); EXEC SQL CONNECT :UserName IDENTIFIED BY :Password; if (ErrorBuffer[0] != `\0') return -1; // if error return 0; // success } void OracleLogout() { EXEC SQL COMMIT WORK RELEASE; } char * GetError (void) { return ErrorBuffer; } void InsertCustomer (char *szName, char *szAddress, char *szCity ,char *szState char *szPhone) { memset (ErrorBuffer, `\0', sizeof(ErrorBuffer)); TO_VARCHAR(Name, szName ); TO_VARCHAR(Address, szAddress ); TO_VARCHAR(City, szCity ); TO_VARCHAR(State, szState ); TO_VARCHAR(Phone, szPhone ); EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer); EXEC SQL EXECUTE BEGIN pkgCustomer.InsertNew ( :Name ,:Address ,:City ,:State ,:Phone ); END; END-EXEC; EXEC SQL COMMIT WORK; return; } 
') return -1; // if error return 0; // success } void OracleLogout() { EXEC SQL COMMIT WORK RELEASE; } char * GetError (void) { return ErrorBuffer; } void InsertCustomer (char *szName, char *szAddress, char *szCity ,char *szState char *szPhone) { memset(ErrorBuffer, `
 int OracleLogin(char *usr, char *pwd) { TO_VARCHAR(UserName, usr); TO_VARCHAR(Password, pwd); EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer); EXEC SQL CONNECT :UserName IDENTIFIED BY :Password; if (ErrorBuffer[0] != `\0') return -1; // if error return 0; // success } void OracleLogout() { EXEC SQL COMMIT WORK RELEASE; } char * GetError (void) { return ErrorBuffer; } void InsertCustomer (char *szName, char *szAddress, char *szCity ,char *szState char *szPhone) { memset (ErrorBuffer, `\0', sizeof(ErrorBuffer)); TO_VARCHAR(Name, szName ); TO_VARCHAR(Address, szAddress ); TO_VARCHAR(City, szCity ); TO_VARCHAR(State, szState ); TO_VARCHAR(Phone, szPhone ); EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer); EXEC SQL EXECUTE BEGIN pkgCustomer.InsertNew ( :Name ,:Address ,:City ,:State ,:Phone ); END; END-EXEC; EXEC SQL COMMIT WORK; return; } 
', sizeof(ErrorBuffer)); TO_VARCHAR(Name, szName ); TO_VARCHAR(Address, szAddress ); TO_VARCHAR(City, szCity ); TO_VARCHAR(State, szState ); TO_VARCHAR(Phone, szPhone ); EXEC SQL WHENEVER SQLERROR DO OracleErrorHandler (ErrorBuffer); EXEC SQL EXECUTE BEGIN pkgCustomer.InsertNew ( :Name ,:Address ,:City ,:State ,:Phone ); END; END-EXEC; EXEC SQL COMMIT WORK; return; }

Page 1235

 int OracleErrorHandler (char* Buffer) {     EXEC SQL WHENEVER SQLERROR CONTINUE;     sprintf(&Buffer[strlen(Buffer)], "Database Error: % .70s",                    sqlca.sqlerrm.sqlerrmc);     EXEC SQL ROLLBACK RELEASE;     return(-1); } 

Listing 54.4 is the full source module required for the interface. The InsertCustomer function provides a mechanism to take in C scalar variables and pass them to a stored procedure in Oracle. The other functions are required to connect and disconnect as well as handle errors. This module, after it is precompiled and then compiled into object code, can be linked with a cartridge object. It is good to employ a standard template such as this when building a library of cartridges. The preceding cartridge can call these native C functions directly.

This seems on the surface to be a trivial architecture, but here is why it is so powerful. State information for a given session can be stored at any level. The C layer can store state information in variables as well as to some form of disk storage. The packaged subprograms can store information in variables as well as maintain database locks and cursor states. The lifetime of both of these layers is the lifetime of the session.

Java

Web Application Server provides a runtime environment for server-side Java applications to run. This is a cartridge that provides instances of the Java virtual machine. All Java code is processed as a Java application, not a Java applet. This means that the Java security manager is not used. Because the Java application resides on the server, there is really no security threat. The Java cartridge provides a Web toolkit containing class libraries for creating dynamic HTML and RDBMS access. No development environment is provided to develop the Java source code. Other tools are required for development and testing, such as Symantec Visual Caf , SunSoft Java Development Kit (JDK), or others. The current version of the Java language supported is 1.0.2. Version 1.1 will be supported when Web Application Server version 3.1 is released in late 1997.

The Java cartridge is invoked only by the Web server. It routes a HTTP request to Java. The Java cartridge runs the Java request. The response of the Java application is an HTTP stream commonly in the form of HTML. The HTML is ultimately routed back to the client browser.

Creating a Simple Java Application

The following Java application code displays "Hello, world!" as standard output:

 Class HelloWorld {     public static void main (String args[]) {         System.out.println ("Hello, world!");     } } 
Previous Table of Contents Next


Oracle Unleashed
Oracle Development Unleashed (3rd Edition)
ISBN: 0672315750
EAN: 2147483647
Year: 1997
Pages: 391

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net