+ All Categories
Home > Documents > ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE 9 ......

ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE 9 ......

Date post: 29-Jul-2018
Category:
Upload: dinhthu
View: 215 times
Download: 0 times
Share this document with a friend
31
Please visit the Web sites of our advertising partners who make it possible for us to bring you this Digital Edition (PDF) of PBDJ ADVERTISER URL PH PG ADVERTISER INDEX DUTTON SOFTWARE WWW.DUTTONSOFTWARE.COM 9 E. CRANE COMPUTING WWW.ECRANE.COM 603-226-4041 39 INTERNET WORLD FALL 2000 WWW.PENTONEVENTS.COM 800-500-1959 13 JAVA DEVELOPER’S JOURNAL WWW.JAVADEVELOPERSJOURNAL.COM 201-802-3020 11 JDJSTORE WWW.JDJSTORE.COM 888-303-JAVA 32,33 NEW MOON WWW.NEWMOON.COM/DESTINY/PDJ 888-ORBIT66 2 NEXUS GROUP WWW.NEXUSGROUP.COM 212-554-4189 37 PRIMAVERA WWW.PRIMAVERA.COM 610-667-8600 37 STARBASE WWW.STARBASE.COM 888-STAR700 7 SYBASE WWW.SYBASE.COM/PBSUCCESS 978-287-1871 40 SYS-CON PUBLICATIONS WWW.SYS-CON.COM 800-513-7111 37 WIRELESS DEVCON 2000 WWW.WIRELESSDEVCON2000.COM 800-513-7111 19
Transcript
Page 1: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

Please visit

the Web sites

of our

advertising

partners

who make it

possible for us

to bring you this

Digital Edition

(PDF) of PBDJ

ADVERTISER URL PH PG ADVERTISER INDEX

DUTTON SOFTWARE WWW.DUTTONSOFTWARE.COM 9

E. CRANE COMPUTING WWW.ECRANE.COM 603-226-4041 39

INTERNET WORLD FALL 2000 WWW.PENTONEVENTS.COM 800-500-1959 13

JAVA DEVELOPER’S JOURNAL WWW.JAVADEVELOPERSJOURNAL.COM 201-802-3020 11

JDJSTORE WWW.JDJSTORE.COM 888-303-JAVA 32,33

NEW MOON WWW.NEWMOON.COM/DESTINY/PDJ 888-ORBIT66 2

NEXUS GROUP WWW.NEXUSGROUP.COM 212-554-4189 37

PRIMAVERA WWW.PRIMAVERA.COM 610-667-8600 37

STARBASE WWW.STARBASE.COM 888-STAR700 7

SYBASE WWW.SYBASE.COM/PBSUCCESS 978-287-1871 40

SYS-CON PUBLICATIONS WWW.SYS-CON.COM 800-513-7111 37

WIRELESS DEVCON 2000 WWW.WIRELESSDEVCON2000.COM 800-513-7111 19

Page 2: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

Focus Story: Creating a Generic Kevin Ridley

Retrieval/Update Component in JaguarIt’s simple, it’s easy – and here’s how to do it 4

DataWindow Magic: Sherlock II Richard Brooks

Logging In Advanced DataWindow technology 16

Introduction to PowerBuilder: Using Bob Hendry

the PFC Application/Utility Services Services you can use throughout the development cycle 18

PBDJ Feature: Introduction Richard Brooks

to TreeViews A usable example 22

DropDownDataWindows: Kaushik Datta

DropDownDataWindows Using HTML and JavaScript A popular look and feel in client/server applications 26

Distributed Technologies: Sanity Checking Michael Barlotta

an EAServer Connection Cache Avoid getting dropped connections from the database cache 28

PB & Java: PB May Hide Its OO Features… Atul Kane…but developers can benefit by uncovering them 30

Popup Menus: And Now, Something Nermin Tanovic

Completely Different… Easy DW popup menu technique 34

www.PowerBuilderJournal.com

Enterprise Application Studio OCTOBER 2000 - Volume: 7 Issue: 10

U.S. $14.00 (CANADA $15.00)

WIRELESSDEVCONCONFERENCE DEC.3–5WIRELESSDEVCONCONFERENCE DEC.3–5PowerBuilderJournal.com

November 12–15, 2000

Announcing...December 3–5, 2000

PBDJ Newsby Bruce Armstrong pg. 36

IMHOFrenzy Projects – Howto Survive a Season

in the Lion’s Den by Michael Deasy pg. 38

Product ReviewEnterprise Application

Frameworkby John Olson pg. 12

From the EditorThe Rebirthof Sybase

by John Olson pg. 3

From SybaseJust Some of What’s

New in PBby Michael Salerno pg. 10

Connection

Connection

Connection

DBMS

Component Component

Component

DBMS string(30)

Database string(30)

dbParm string(60)

DBMS string(30)

Database string(30)

dbParm string(60)

Page 3: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

3www.PowerBuilderJournal.com PBDJ volume7 issue10

E D I T O R I A L A D V I S O R Y B O A R DBRUCE ARMSTRONG, MICHAEL BARLOTTA, ANDY BLUM,

RICHARD BROOKS, KOUROS GORGANI, BAHADIR KARUV, PH.D.,BERNIE METZGER, JOHN OLSON, SEAN RHODY

EDITOR-IN-CHIEF: JOHN OLSONART DIRECTOR: JIM MORGAN

EXECUTIVE EDITOR: M’LOU PINKHAMMANAGING EDITOR: CHERYL VAN SISE

EDITOR/COPY CHIEF: NANCY VALENTINEASSOCIATE EDITOR: JAMIE MATUSOWASSOCIATE EDITOR: BETTY LETIZIATECHNICAL EDITOR: BERNIE METZGER

NEWS EDITOR: BRUCE ARMSTRONGDATA WINDOWS EDITOR: RICHARD BROOKS

W R I T E R S I N T H I S I S S U EBRUCE ARMSTRONG, MICHAEL BARLOTTA, RICHARD BROOKS,KAUSHIK DATTA, MICHAEL DEASY, BOB HENDRY, ATUL KANE,

JOHN OLSON, KEVIN RIDLEY, MICHAEL SALERNO, NERMIN TANOVIC

S U B S C R I P T I O N SFOR SUBSCRIPTIONS AND REQUESTS FOR BULK ORDERS,

PLEASE SEND YOUR LETTERS TO SUBSCRIPTION DEPARTMENT

SUBSCRIPTION HOTLINE: 800 513-7111COVER PRICE: $14/ISSUE

DOMESTIC: $149/YR. (12 ISSUES) CANADA/MEXICO: $169/YR.OVERSEAS: BASIC SUBSCRIPTION PRICE PLUS AIRMAIL POSTAGE

(U.S. BANKS OR MONEY ORDERS). BACK ISSUES: $12 EACH

PRESIDENT AND CEO: FUAT A. KIRCAALIVICE PRESIDENT, PRODUCTION: JIM MORGAN

VICE PRESIDENT, MARKETING: CARMEN GONZALEZGROUP PUBLISHER: LISE ST. AMANT

ADVERTISING ACCOUNT MANAGER: ROBYN FORMAADVERTISING ACCOUNT MANAGER: MEGAN RING

ASSOCIATE SALES MANAGER: CARRIE GEBERTADVERTISING ASSISTANT: CHRISTINE RUSSELL

ART DIRECTOR: ALEX BOTEROASSISTANT ART DIRECTOR: ABRAHAM ADDOASSISTANT ART DIRECTOR: CATHRYN BURAKASSISTANT ART DIRECTOR: LOUIS F. CUFFARIGRAPHIC DESIGN INTERN: AARATHI VENKATARAMAN

WEBMASTER: ROBERT DIAMONDWEB DESIGNER: STEPHEN KILMURRAYWEB DESIGNER: GINA ALAYYAN

CUSTOMER SERVICE: ELLEN MOSKOWITZSYS-CON EVENTS MANAGER: ANTHONY D. SPITZER

JDJ STORE: AMANDA MOSKOWITZ

E D I T O R I A L O F F I C E SSYS-CON PUBLICATIONS, INC.

135 CHESTNUT RIDGE ROAD MONTVALE, NJ 07645TELEPHONE: 201 802-3000 FAX: 201 782-9600

[email protected]

POWERBUILDER DEVELOPER’S JOURNAL (ISSN#1078-1889) is published monthly (12 times a year) for $149.00 by

SYS-CON Publications, Inc.,135 Chestnut Ridge Rd., Montvale, NJ 07645 Periodicals Postage rates are paid at

Montvale, NJ 07645 and additional mailing offices.POSTMASTER: Send address changes to:

POWERBUILDER DEVELOPER’S JOURNAL, SYS-CON Publications, Inc.,135 Chestnut Ridge Rd., Montvale, NJ 07645

© C O P Y R I G H TCopyright © 2000 by SYS-CON Publications, Inc. All rights reserved.

No part of this publication may be reproduced or transmitted in any form or by anymeans, electronic or mechanical, including photocopy or any information storage andretrieval system, without written permission. For promotional reprints, contact reprint coordinator. SYS-CON Publications, Inc., reserves the right to revise, republish and

authorize its readers to use the articles submitted for publication.

W O R L D W I D E D I S T R I B U T I O N B YCURTIS CIRCULATION COMPANY

730 RIVER ROAD, NEW MILFORD NJ 07646-3048 PHONE: 201 634-7400

All brand and product names used on these pages are trade names,service marks or trademarks of their respective companies.

SYS-CON Publications, Inc., is not affiliated with the companies or products covered in PowerBuilder Developer’s Journal.

JOHN OLSON, EDITOR-IN-CHIEF

My forecasts for the future of Sybase have been through a renaissance. More than anevolution, they’ve been reborn.

In last month’s PBDJ (Vol. 7, issue 9) my editorial, as well as my TechWave review article,recounted what John Chen and Raj Nathan had to say about the past and future of Sybase.The vision itself wasn’t new to me; it had been conveyed very clearly by Eric Miles in an inter-view I did in November 1998. I hadn’t bought into the vision because I didn’t see any concreteevidence that it was culminating in Sybase taking leadership positions in existing and newmarkets. My “wait and see” approach had landed me in the skeptic’s camp. I privately heldthe opinion that Chen’s sole purpose as CEO was to return Sybase to short-term profitabilityto boost the perceived value of the company so it could be broken up and sold in pieces. Thatseemed to be supported by both large cuts in marketing budgets and the divi-sionalization of the company. Severe market-ing cuts make the bottom line look better, butoften result in long-term revenue reductions…something that long-term planners wouldavoid. Breaking the company into divisionsappeared to be preparation for the sell-off.

I was looking for hard evidence that Sybase’schanges signified positive effects for the com-pany. As time passed, my private fear remainedsteady, not alleviated by anything Sybase wasdoing. Now, suddenly, Sybase appears to be a newcompany, with new initiatives, a leader in newmarkets. The change in direction wasn’t sudden,but the arrival of positive results has been. Statisti-cally proven market leadership, recent financialstatements, and press and analyst excitement arethe hard indicators I’d been waiting for. They’re in.

This time, when I again heard them convey their vision at TechWave, they had proof toshow that their changes are having the desired effect. Their vision is no longer just words,but a plan in action. Their dominance of the mobile and embedded database marketscould by itself vault Sybase into the elite ranks of companies with multibillion-dollar rev-enues per year. Add to that the new initiatives in the telecommunications, healthcare,financial services, and application server markets, and Sybase looks like a top contender.

Chen’s goal was to make Sybase a leader in new markets while maintaining its position inold markets. Now that the evidence is in, I no longer believe his goal was to break up Sybase.

Though Sybase has a history of being a database company, that accounts for a steadi-ly decreasing percentage of overall revenues. The old markets aren’t dead, but they’vetaken a back seat to the new markets. While the past was dominated by SQL Server andPowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.Sybase is not the company it was five years ago. It is much, much more. ▼

F R O M T H E E D I T O R

[email protected]

AUTHOR BIOJohn Olson is principal of Developower, Inc., a consulting company specializing in software solutions using Sybase development tools. A CPD

professional and charter member of TeamSybase, he is a coauthor of SYS-CON’s Secrets of the PowerBuilder Masters books.

The Rebirth of Sybase

Page 4: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

4 www.PowerBuilderJournal.comPBDJ volume7 issue10

When designing distributed applications, developers typically createcomponents based on required functionality, or related services. Somecomponents will be entirely service oriented, but most will be standardcomponents with a mix of retrieves, updates, and some processing logic.

Typically, these components reside in many different packages. Asyour enterprise grows, more and more components and packages areadded, while simultaneously maintaining existing components. Theprocess can get quite complex. One way to simplify this scenario is toreduce the number of components on the server. Since probably 75% ofall retrievals done in applications are simple and don’t require a lot ofbusiness logic, why create multiple components? The answer? Don’t.

Generic ComponentI’ll show you how to create a single component to handle most of

your retrievals and even do updates. This component will take argu-ments at runtime to determine what to retrieve. Our component willhave four basic methods: Retrieve( ), RetrieveEx( ), Save( ), andSaveChgs( ). For our example we’ll use an ASA database and createan ODBC connection cache called “mycache” for it in Jaguar. Thecachename will be stored as an instance variable of the component.We’ll connect/disconnect in the activate/deactivate events, butadvanced users will probably want to pass the cachename as anargument for each function. This will allow the use of multiplecaches, but will require coding the connect/disconnect separately.

RETRIEVE ( )Create a method called Retrieve that takes a string “as_dwo” and

returns a BLOB. We use a DataStore, ids_data, that we’ve set up as aninstance variable and coded the create statement in the compo-nent’s constructor event (destroy in the destructor, unless you’re agarbagecollect fan). Listing 1 provides the code for the Constructor

event, Activate event, and Retrieve method.Simple, you say? That’s the point! Just remember to include a PBL

with all of your DataWindows in the component’s library list, andcheck “Include Unreferenced Objects” when deploying it.

RETRIEVEEX()For retrieval with arguments create a method called RetrieveEx( ),

which takes two arguments – string “as_dwo” and string “as_arguments”– and returns a BLOB. This method is used in the same manner asRetrieve( ), except that you’ll convert all of your arguments on the clientto strings, and build a single delimited string to pass to the component.The as_dwo argument will contain the name of your DataWindow object,as above. The second argument will be a single string of arguments thatyou’ll need to build. Use the String( ) function to convert all otherdatatypes to a string, and build a single string made up of your convertedarguments. Separate each argument with a delimiter, such as ~n.

For example, let’s assume we need to pass three fields for our retrieve:Order Number (long: 12345), Item Code (string: ABC34), and Quantity(integer: 5). The variables holding these values will be ll_order,ls_item_cd, and li_qty, respectively. Build the argument string as follows:ls_argstring = String(ll_order) + “~n” + ls_item_cd + “~n” + String(li_qty) .The resulting string in this case would be 12345~nABC34~n5. The com-ponent will parse this argument string to separate the arguments. Toprocess the string in the component, create an array of type “any”. Parsethe argument string, placing each argument value into the array. Thenext step is to determine each argument’s datatype. Since we’re gettingthe dwo as the other argument, we can assign it to a DataStore, then doa describe on it to return the “datawindow.table.arguments”:

//datawindow object argument passed – as_dwo

String ls_args

Datastore lds_args

lds_args = CREATE datastore

lds_args.DataObject = as_dwo

ls_args = lds_args.Describe("datawindow.table.arguments")

This returns a delimited string consisting of argument name, fol-lowed by ~t, followed by argument type, then ~n. You’ll need to parsethis string to get the datatype for each argument. Then convert each

It’s simple, it’s easy – and here’s how to do itIt’s simple, it’s easy – and here’s how to do it

WRITTEN BY Kevin Ridley

Page 5: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

5www.PowerBuilderJournal.com PBDJ volume7 issue10

argument to its appropriate datatype. Note: The argument typesreturned from the describe statement are the types specified whenbuilding the DataWindow. All numeric arguments will return type“number”. The most generic way to deal with the number type is toconvert it to a Double. A great example of this process can be foundin the PowerBuilder examples \Powerbuilder7.0\ Code\Examples\HTMLDW\PBDWRMT.PBL See the nv_remote _dw RetrieveEx andof_parseargs methods.

SAVE ( )Create a method called Save that takes a BLOB as an argument

and returns an integer. We’ll reuse the ids_data DataStore. The clientwill do a GetFullstate and pass the BLOB to the component. Follow-ing is the code for the Save method:

// generic component Save method

Integer li_return

li_return = ids_data.SetFullState(ablb_data)

li_return = ids_data.SetTransObject(SQLCA)

li_return = ids_data.Update()

// use jag trans mgmt.

if li_return = 1 then

its_jag.SetComplete()

else

its_jag.SetAbort()

end if

Return li_return

A successful update should be followed by a datawindow.ResetUp-date( ) on the client.

SAVECHGS ( )As you might expect, sending large BLOBs back and forth between

the client and Jaguar isn’t the most efficient way to update data. If youdon’t require a complete resultset of data to enforce business rules,you’ll want to pass only the DataWindow changes from the client toJaguar. The client will use datawindow. GetChanges( ) and pass theBLOB to the component. Create a method called SaveChgs that takesa BLOB as an argument and returns an integer. The functionality willbe the same as the Save method, except it’ll use SetChanges insteadof SetFullState. Following is the code for the SaveChgs method:

Integer li_return

ids_data.Reset()

li_return = ids_data.SetChanges(ablb_data)

li_return = ids_data.SetTransObject(SQLCA)

li_return = ids_data.Update()

// use jag trans mgmt.

if li_return = 1 then

its_jag.SetComplete()

else

//Your error stuff goes here

its_jag.SetAbort()

end if

Return li_return

Again, a successful update will be followed by adatawindow.ResetUpdate( ) on the client. The component shouldnow be deployed to Jaguar. For the examples below, we’ll assume acomponent name: n_generic in package: riverton. When the com-ponent has been successfully deployed, create a proxy for it and putit in a PBL in the client library list. Note: Since the code is so similarfor Save( ) and SaveChgs( ), advanced users may want to create a pri-vate method called Update( ) that contains identical lines of codethat can be called from both Save and SaveChgs.

DEPLOYMENTCreate a new project to deploy the generic component using the

Jaguar Component Wizard. When selecting the nonvisual object todeploy to Jaguar, select only our generic component. Any other NVOsin the library list should remain unchecked. Enter the location of yourJaguar machine, then select a package. For our example I used a pack-age name of riverton. Select Standard Component and SupportsInstance Pooling. For Transaction Support Option, deploy it the firsttime using Supports Transactions. As you extend the functionality ofthe component, you may want to use Requires or Requires New. Besure to check Auto Demarcation/Deactivation. This is what makes thecomponent stateless. Jaguar will automatically activate and deacti-vate our component when needed. Interface Options should be leftunchecked, and for testing purposes Supports Remote Debuggingshould be checked. Be sure to remove this option when deploying toa production server, as it’s unnecessary overhead. Check Build Con-solidated Dynamic Library (pbd), and Include Unreferenced Objectsin Consolidated PBD. This will compile our DataWindows and anyother NVOs into the pbd so they can be accessed dynamically whilerunning in Jaguar. Select Finish. This creates a project object for usthat then needs to be run so as to deploy the component to our Jaguarserver. Note that, to deploy the component, Jaguar must be running.Once the component is deployed, adding new retrievals/updates is aseasy as creating a new DataWindow, and adding that DataWindow toone of the pbls in the deployment build.

Client ImplementationOVERVIEW

We’ll now set up a PFC client that will use the generic componentwe just designed. Retrievals are easy…we’ll just call the compo-nent.Retrieve( ) or RetrieveEx( ) method, depending on whether ornot we have arguments. We’ll pass the DataWindow object name toour component and get a BLOB in return. The data will be displayedby using datawindow.SetFullState( ). Updates can be handled with rel-ative ease as well, incorporating most of the functionality of thepfc_save process. Simply override the pfc_update event of theDataWindow, get its FullState, and send it to the generic component.To facilitate this, we’ll create a standard NVO called n_cst_uilink. Forour examples we’ll assume the client has a valid connection to Jaguardeclared globally as gcn_jaguar.

DESIGNThe uilink NVO will have three instance variables as follows:

// n_cst_uilink declare instance variables

PowerObject ipo_data[]

String is_dwo[]

protected:

n_generic inv_generic_proxy // proxy object generated from Jaguar above

Create a method called RegisterData on n_cst_uilink, which takesa PowerObject apo_dsdata and a String as_dwo. This method will beused to register each DataWindow and its associated dwo name foruse with the generic component. Create another method calledRetrieve that takes a PowerObject named apo_dsdata as an argu-ment and returns a long. Create another method called Update thattakes a PowerObject named apo_dsdata as an argument and returnsan integer. Listing 2 contains the code for RegisterData; Listing 3,Retrieve; Listing 4, Update.

The SaveChgs method is identical to Save except that it usesGetChanges instead of GetFullstate. Uilink will be an instance variableon each window. In the window’s pfc_preopen call the uilink.Register-Data( ) method for each DataWindow/DataStore to be used, passingthe DataWindow/DataStore and the dwo name. When ready toretrieve, call the uilink.Retrieve( ) and pass the DataWindow/DataStoreto be retrieved. Following is sample code for the window to retrieve:

Page 6: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

6 PBDJ volume7 issue10

inv_uilink.RegisterData (dw_1, "d_mydwo")

inv_uilink.Retrieve(dw_1)

For updating, override the pfc_update event on the DataWindowas follows:

//override

// Use uilink

Return inv_uilink.Update(this)

When new DataWindows are added to the component on the server,simply register a DataWindow with the uilink using the new dwo name.The retrieve will pick up the new dwo from the server component.

Business Rules/ValidationThe update process works fine for simple updates, but what if you

have business logic that needs to be applied prior to an update? Youmay need to invoke item-level validation or enforce business rules. Sup-pose we have a shopping cart–type application and our user, havingselected various quantities of different items, has decided to check out.Our component needs to check stock level for each item, and may alsoneed to calculate a discount for total orders above a certain threshold.To use the current component we’d have to extend the Save func-tionality to call other components or NVOs. The problem withthis approach is that it’s difficult to design it so it’ll be con-sistent for every update or retrieval. Some retrievals andupdates will require business rules, others won’t. Ourmethods must be “smart” enough to know what othercomponents or NVOs to call for every retrieve/update.This sounds like a difficult task…and it is. The solutionis to use a framework.

FRAMEWORKA framework is a prebuilt hierarchy of objects you

either purchase or build yourself that encapsulatecommon, sometimes very complex, functionality, likethe PFC. Frameworks are often organized into classlibraries that group the components according to gener-al organization principles, such as all visual ancestorobjects and all nonvisual ancestor objects. Typically, youinherit from ancestor framework objects, then modifydescendants to provide your own specific functionality. Myfavorite framework for Jaguar is Riverton’s Openframe that comeswith the HOW modeling tool.

About OpenFrameOpenFrame provides a hierarchically organized set of class objects

used to build partitioned applications in which business logic is encap-sulated within nonvisual objects. Each NVO maps directly to objectsrepresented in an object model. In addition to encapsulation of busi-ness logic, all data access can be performed through the business enti-ty object layer, thereby abstracting the presentation layer from the spe-cific details of the database. The four main objects in Openframe are theBusiness Collection Manager (BCM), Business Entity Object (BEO),Business Service Object (BSO), and DataLink Object (DLK). Following isa brief description of each:• Business Collection Manager (BCM): Central OpenFrame NVO

that marshals data; creates objects for retrieval, update, and vali-dation; not generated; accessed directly through Openframe.

• Business Entity Object (BEO): Generated object that encapsulates theattribute values, relationship connections, and business logic of a per-sistent class. For relational database applications there will generally bea correspondence between a BEO and a database table, with aninstance of the BEO representing a record in the table. Consequently,applications built using the OpenFrame architecture typically use BEOsto validate and update individual rows of a DataWindow/DataStore.

• Business Service Object (BSO): Generated object that providesmethods that encapsulate complex business logic spanning mul-tiple types or instances of BEOs. The methods provided by theBSO are user-defined. HOW generates a BSO for each HOW classtyped as a Business Service Object. This Jaguar component cre-ates the BCM and passes it the DLK name.

• DataLink Object (DLK): Generated object that encapsulates thedatabase-specific information and logic necessary to execute data-base queries that return data and related update operations, andhandles mapping DataWindow columns to BEOs. DLKs are createdautomatically by HOW when you generate from a HOW-built query.

GENERIC COMPONENT WITH OPENFRAMEThe generic component is inherited from OpenFrame’s BSO.

Designed and generated out from HOW, it will have the same fourmethods as the non-OpenFrame generic component (Retrieve,RetrieveEx, Save, SaveChgs). The OpenFrame component uses theDataLink as the key for retrieval. The DLK name, instead of the dwoname, is passed as an argument. The generic BSO creates aninstance of the BCM. The BSO passes the DLK name to the BCM,which creates an instance of the DLK and uses it to execute theretrieve. In standard mode the BCM is serialized to a BLOB andreturned to the client, where it is deserialized. The BCM is used to

create the BEOs on the client. Standard mode allows process-ing of business rules on the client side, while still preserving

a partitioned application. When the client issues a Saveon the BCM, it is then serialized and passed back to the

BSO where the database update occurs. In new “PBThin Client” Jaguar mode, GetFullState is used toreturn a BLOB from the BSO to the client. This isquickly becoming the standard for Jaguar Open-Frame processing.

Since the DataWindow BLOB is passed back tothe client instead of a BCM, OpenFrame is nolonger needed on the client. The update processworks the same on the client side, except that theDLK name is passed back to the BSO, along with theBLOB, in both the Save and SaveChgs. The reason is

that the BSO is stateless, so it won’t know the DLKname. The BSO creates a new BCM, which uses the

DLK to create the BEOs and map the DataWindowcolumns to BEO attributes, and executes BEO methods

for validation and application of business rules. If success-ful, the BCM updates the database.

Because all of the processing occurs on the server, it’s much eas-ier to port a thin PB client to the Web. Deployment is simple. First,build your query and BEO in HOW and generate out to PB. The BEOgenerates a BEO object, while the query generates a DataWindowand a DLK object. Add the BEO object, DataWindow, and DLK objectto a pbl in the project. I usually keep the component in one PBL, andall BEOs, DLKs, and DataWindows in another. Use the same options asthe generic PB component. Be sure the two OpenFrame PBLs(How_srv.pbl and How_srve.pbl) are included in the library list, anddeploy. Anytime you want to add another retrieve/update, just addthe new BEO, DLK, and DataWindow to the same PBL.

SummaryCreating a generic component to handle most of your retrieves

and updates has many advantages. At the top of the list is that it’ssimple. Create one component, then add additional DataWindowsas needed. It’s much easier to add a DataWindow object to a PBL inan existing component’s library list and redeploy than to keep creat-ing new components. There’s also much less chance of redundantfunctionality – just compare DataWindows on a regular basis. Sinceit’s so easy, less experienced developers can be productive sooner.Not everyone can build a Jaguar component, but most can build aDataWindow. The turnaround time for requests will be faster as well.

www.PowerBuilderJournal.com

Page 7: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

PBDJ volume7 issue108 www.PowerBuilderJournal.com

// Constructor of generic component// remember to declare protected instance variables:// TransactionServer its_jag// Datastore ids_data this.GetContextService("TransactionServer", its_jag)ids_data = CREATE datastore

// Activate// remember to code disconnect on deactivate.SQLCA.DBMS = "ODBC"SQLCA.DBParm = "UseContextObject='Yes',CacheName='mycache'"CONNECT using SQLCA;

// Retrieve(String as_dwo)// Datawindow Object name is passed as an argumentBlob lblb_datalong ll_return

ids_data.DataObject = as_dwoids_data.SetTransObject(SQLCA)ids_data.Retrieve()ll_return = ids_data.GetFullState(lb_data)

Return lblb_data

// n_cst_uilink Registerdata methodlong ll_new

/* verify the arguments */if NOT ((apo_dsdata.TypeOf() = DataWindow!) OR (apo_dsdata.Type-Of() = DataStore!)) thenReturn (-1)end if

if IsNull (as_dwo) or (as_dwo = "") thenReturn (-1)end if

/* get a new pointer into the array */ll_new = UpperBound (ipo_data[]) + 1

/* add in the data object and the dwo */ipo_data[ll_new] = apo_datais_dwo[ll_new] = as_dwo

Return 1

// n_cst_uilink Retrieve method// assumes connection to Jaguar (gcn_jaguar and proxy inv_gener-ic_proxy)blob lblb_fullstatelong ll_curr_data, ll_num_data, ll_return = -1string ls_dwo

/* check argument */if IsNull (apo_dsdata) thenReturn -1end if

/* create the proxy */if NOT IsValid(inv_generic_proxy) thenll_return = gcn_jaguar.CreateInstance (inv_generic_proxy, "river-ton/n_generic")if (ll_return <> 0) thenMessageBox("", "Create of Proxy failed, code: " +

String(ll_return))Return -1

end ifend if

ll_num_data = UpperBound (ipo_data[])

/* find dwo and retrieve it */for ll_curr_data = 1 to ll_num_data

/* check for the passed data control */if (ipo_data[ll_curr_data] = apo_dsdata) then

/* get the dwo */

ls_dwo = is_dwo[ll_curr_data]

/* retrieve using the proxy */lblb_fullstate = inv_generic_proxy.Retrieve (ls_dwo)/* get the blob to set the state of the data */ll_return = ipo_data[ll_curr_data].DYNAMIC SetFullState

(lblb_fullstate)

/* if set full state worked, get the number of rows */if (ll_return <> -1) thenll_return = ipo_data[ll_curr_data].DYNAMIC RowCount()

end if

/* exit the loop */EXIT

end ifnext

Return ll_return

// n_cst_uilink Update method

blob lblb_datalong ll_num_data, ll_return = -1string ls_dwoboolean lb_found=FALSE, lb_dw=FALSEdatawindow ldw_updatedatastore lds_update

/* check argument */if apo_dsdata.TypeOf() = DataWindow! thenldw_update = apo_datalb_dw = TRUEelseif apo_dsdata.TypeOf() = DataStore! thenlds_update = apo_datalb_dw = FALSEelseReturn -1end if

FOR ll_num_data = 1 TO UpperBound(ipo_data)if apo_dsdata = ipo_data[ll_num_data] thenls_dwo = is_dwo[ll_num_data]if lb_dw thenldw_update.AcceptText()ll_return = ldw_update.GetFullState(lblb_data)

elselds_update.AcceptText()ll_return = lds_update.GetFullState(lblb_data)

end iflb_found = TRUEexit

end ifNEXT

if NOT lb_found thenReturn -1end if

/* create the proxy */if NOT IsValid(inv_generic_proxy) thenll_return = gcn_jaguar.CreateInstance (inv_generic_proxy, "river-ton/n_generic")if (ll_return <> 0) thenMessageBox("", "Create of Proxy failed, code: " +

String(ll_return))Return -1

end ifend if

ll_return = inv_generic_proxy.Save(lblb_data)if ll_return >= 0 THENapo_data.Dynamic ResetUpdate()elseMessageBox("Error", "Update Failed")end if

Return ll_return

Listing 4

Listing 3

Listing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

On the client side it’s much simpler too. Once developers becomefamiliar with the uilink object, they can quickly “drop” the function-ality onto any window. The client side no longer needs dwos sincethe entire presentation is included with the SetFullState. This makesmaintaining (and in most cases deploying) clients easier. Again, aless experienced developer can be productive sooner, possibly free-ing up a more experienced developer for more complex tasks. Themost important advantage on the client side is that you’ll only needone proxy object for most of your retrieves and updates. Further-more, when you add a new DataWindow to the server component

and rebuild it, you’re not adding new methods, which would changethe signature of the component and require you to build and deploya new proxy object. The four methods are static, so the proxyremains static as well. ▼

AUTHOR BIOKevin Ridley is a senior technical architect at Riverton Corporation in Burlington, Massachusetts, specializing indesign of Web-enabled application server components. Kevin also provides Jaguar/Openframe training for Riverton.

[email protected]

Page 8: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

10 www.PowerBuilderJournal.comPBDJ volume7 issue10

F R O M S Y B A S E

WRITTEN BYMICHAEL SALERNO

E-business solutions with Web functionality withina single interface, plus enhancements

Just Some of What’s New in PB

Just as PowerBuilder pioneered the 4GL approach to client/server Windows applicationdevelopment, version 8.0, currently in limited beta, brings a similar 4GL experience to n-tier Web development. PowerBuilder 8.0, scheduled to ship by Q2 2001, delivers featuresaimed at developers of both client/server and component-based applications.

This article gives just a brief sampleof what’s new in version 8.0.

Integration of Web Development Functionality

To allow for seamless developmentof Web client applications in today’se-business environments, Sybaseincorporated Web development func-tionality similar to that of PowerSiteinto PowerBuilder 8.0, resulting in aunified IDE for multitier rapid appli-cation development.

WORKSPACES AND TARGETSDevelopers can use PowerBuilder 8.0

to create Web applications – or “targets” –

in addition to client-executable applica-tions and Sybase EAServer components.

In previous releases the developercould only work on objects in onePowerBuilder application at a time.PowerBuilder 8.0 introduces the“workspace,” within which develop-ers can work on several applications(targets) at once.

There are two fundamental typesof targets in PowerBuilder 8.0: Power-Script targets and Web targets. Theformer can be any of the traditionalapplication types, such as a Power-Builder client-executable or anEAServer component. A Web target isa Web application type. It can containall the assets required for building a

Web site – HTML files, scripts, images,downloaded components – as well assettings for build options, databaseconnections, and deployment. Webtargets are available only in the Enter-prise Edition of PowerBuilder.

FOR EXAMPLE...When you start PowerBuilder 8.0

for the first time, you create a newworkspace with, or without, targets.

Once you’ve created a workspace,you may add targets to it. For exam-ple, if you’re writing business objectsand deploying them to EAServer, youcan work with EAServer componentsand a client application in the sameworkspace. If you plan to access theEAServer components from a Webclient, you can add the Web target tothe same workspace.

The System Tree, a new feature ofthe PowerBuilder interface, displaysthe contents of the current workspacein the Workspace tab (see Figure 1).FIGURE 1 PowerBuilder 8.0 System Tree

If you plan to

accessthe EAServer

components from

a Web client,

you can add the

Web target to the

same workspace

Page 9: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

11PBDJ volume7 issue10

[email protected]

The System Tree provides an easy andaccessible way to edit objects, checkthem in and out of source control, andbuild and deploy targets.

Productivity EnhancementsNo version of PowerBuilder would

be complete without incorporatingthe enhancement feedback and newfeature requests from the PB commu-nity. With the assistance of the Inter-

national Sybase User Group, new fea-ture enhancements were selectedand incorporated into PowerBuilder8.0. A number of usability enhance-ments have been incorporated, includ-ing both development and runtimeenhancements.

Exception HandlingWhen a runtime or system error

occurs in earlier versions of Power-

Builder, a single application event isfired to handle the error, no matterwhere in the application the errortakes place.

With PowerBuilder 8.0 exception-handling classes and syntax are nowavailable for context-sensitive errorhandling in PB applications (see Fig-ure 2). This means that the developercan deal with errors closer to theirsource by embedding error-handlingcode anywhere in the application,instead of in a single, global errorevent.

Something for EveryonePowerBuilder 7 simplified the process

of building distributed applications.PowerBuilder 8.0 completes the storyby enabling PB developers to quicklybuild e-business solutions incorpo-rating Web functionality, all within asingle interface. In addition, it offersenhancements for all developersregardless of the type of applicationbeing developed. The usability enhance-ments alone are considered a majorstrength of the new, much anticipatedrelease. Development productivity is,and always will be, a fundamental focusfor PowerBuilder. ▼

FIGURE 2 Example of exception handling in PowerBuilder 8.0

AUTHOR BIOMichael Salerno is thegroup product manager for the Internet ApplicationDivision at Sybase, Inc.

www.PowerBuilderJournal.com

Don’t Miss JDJ’s LINUX Focus Issue!COMING IN DECEMBER

www.JavaDeveloper’sJournal.com

Java Developer’s Journal Announces Special LINUX Focus Issue

For Advertising Information Contact:

Carmen GonzalezVice President, Advertising Sales

Java Developer’s Journal

Call (201) 802-3021 or email [email protected]

Insertion Order Due: OCTOBER 19, 2000

Artwork at Our Press: OCTOBER 26, 2000

Page 10: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

12 www.PowerBuilderJournal.com

Client/server is fading, supplanted by dis-tributed architectures and Web clients; thenew generation of architecture is here tostay. Fortunately, the latest generation ofclient/server object designs prepareddevelopers and code for the transition to adistributed environment. Along with thenew architecture, however, comes a needfor framework and service objects designedfor this environment.

The PFC isn’t appropriate becauseit’s too fat. To fill the void many companieshave built their own, but there haven’tbeen any widely distributed libraries ofthis type. This may now be changing.with Cynergy Systems’ (formerly Dynam-ic Data Solutions) Enterprise ApplicationFramework (EAF). It is designed to servethe need and become the standard.

EAF didn’t evolve, but rather wasplanned from the start to be the bestfoundation for distributed develop-ment with PowerBuilder. Carson Hager,founder and president of CYNERGY,envisioned a class library that incor-porated the proven design methodol-ogy of the PFC but was thin enoughfor use in component development.Hager designed and developed EAFalong with Alex Whitney and ClaudioQuant, former Sybase employees inti-mately involved in the design and devel-opment of the PFC itself. It’s no coinci-dence that EAF looks a lot like the PFC.

CYNERGY says: “EAF is to EAS as PFCis to PowerBuilder… Its purpose is togive developers a leg up on the devel-opment process and to allow them tospend their time on solving businessproblems, not technical ones.”

Composition LIBRARIES

EAF is composed of server-side andclient-side libraries. It offers extensionlayers, like the PFC, so there are exten-sion libraries to hold your customiza-tions. The server-side libraries containthe basic functionality you’d expect for

component development and don’t containanything GUI related. This keeps the compo-nents small by not weighing them down withfeatures needed only for client-side code.

The client libraries contain the servicesnecessary to interact with components plussome GUI features. This shows that theemphasis in creating the EAF was put on theserver side. Unfortunately, the GUI featuresand services aren’t even close to the breadthof the PFC, so you’d have to add quite a fewenhancements to build PFC-like feature-richclients. This highlights the fact that it wasdesigned and built as an EAS class libraryrather than as a PB client class library withsome component interface capabilities.

FeaturesI don’t have the space to cover every feature

or even all the important features, but I’ll list afew of the most notable ones and describesome of their most important aspects.

SUPPORT FOR MULTIPLE CLIENTSAn important feature of EAF is that compo-

nents can be called not only from PB clients,but also from HTML clients and any clientsthat are CORBA compliant. Therefore, you canbuild your components in PowerBuilder butcall them from PowerBuilder, Java, HTML, C++,and so forth (see Figure 1). Though it supportsmultiple clients, it’s not application-serverindependent. Since EAF is written mostly inPowerBuilder and supports DataWindows,EAF components can be run only on EAServer.

DATAWINDOW SUPPORTDataWindows are supported for both

PowerBuilder clients and HTML clients (seeFigure 2). For the former, a very smart EAFdesign provides management of update logicwhile minimizing traffic to the server.

LOGICAL UNIT OF WORKEAF uses Interface Manager components to

allow the client to interact with one or morecomponents. The IMs are smart enough toallow multiple business object components tobe included in a single LUW.

[email protected]

Enterprise Application FrameworkCynergy Systems, Inc.4350 North Fairfax Drive, Suite 420Arlington,VA 22203Phone: 703 524-9100www.cynergysystems.com

Pricing:Free

Enterprise Application

FrameworkREVIEWED BY JOHN OLSON,

EDITOR-IN-CHIEF

PR

OD

UC

T

RE

VI

EW

PR

OD

UC

T

RE

VI

EW

AUTHOR BIOJohn Olson is principal of Developower, Inc., a consulting company specializing in software solutions using Sybase

development tools. A CPD professional and charter member of TeamSybase, he’s a coauthor of SYS-CON’s

Secrets of the PowerBuilder Masters books.

ActiveXClient

C++Client

PowerBuilderClient

WebClient

JavaClient

Interface Manager Component Dataser

SessionManager

Component

BusinessObjectComponent

Database

MessageManager

Component

FIGURE 1 Single point of entry for all clients

PBDJ volume7 issue10

PBDJAPPROVEDPRODUCT

2000PBDJSeal Of

Excellence

Page 11: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

A key to scalability is to use statelesscomponents rather than stateful ones.The limitations of stateless designsrequire that some information for eachclient instance be stored on the server. Toachieve this, EAF uses a session managerservice component.

Written in Java to allow for multi-threading, the session manager providesflexible session management capabili-ties. One negative aspect of this sessionmanager is that it doesn’t currently sup-port failover. Obviously, this isn’t rele-vant unless you’re running multipleJaguar servers in a clustered environ-ment. In that case, if the server the ses-sion manager is running on failed, allsession information held in that com-ponent would be lost. CYNERGY saysstate replication will be addressed in afuture release.

Another minor deficiency is thatthe session manager doesn’t currentlyfree up resources for abnormally ter-minated sessions. Over time thiscould result in a resource problem.However, if you occasionally bouncethe Jaguar server (nightly or weekly),this should never be a problem. CYN-ERGY says they’ll add session timeoutcleanup in a future release.

TRACING AND BUGGING SUPPORTOne feature that stands out is the

Error Logging service. It’s a typical log-ging service except that unique num-bers are assigned and logged for eachobject instance. Since multiple com-ponent instances may exist at any onetime, this use of unique instance iden-tifiers allows for better debugging.

A second feature of the ErrorLogging service is that it’s controlledby Jaguar properties on the compo-nent rather than in values or registrysettings. This is a smart design andshows that the EAF designers knewwhat they were doing. (To learn moreabout this technique, see Ken Howe’sarticle on Error Logging for Jaguarobjects (PBDJ, Vol. 7, issue 5).

PFC Integration?With the EAF designed specifically for

development of components usingPowerBuilder, and PFC being the founda-tion of most current PB developmentefforts, it makes sense that EAF wouldwork with the PFC. Though it was designedusing PFC principles, it’s not integratedwith the PFC. I think this is its biggest short-coming. The PFC isn’t considered a goodclass library for development of compo-nents because it’s way too fat. However, it’sjust right when it comes to client develop-ment for client/server applications.

EAF, on the other hand, is great for com-ponent development but doesn’t provide afull complement of features for clientdevelopment. The client has everythingyou need for interacting with components,but it isn’t a full-featured client library.

If the PFC provides all the functionali-ty needed to develop full-featured clients,and the EAF client library contains all thefunctionality necessary to interact withcomponents, then merging the EAF clientfeatures into the PFC would result in anoptimal solution.

If Sybase takes notice of EAF anddecides to stand behind it as an approvedsolution, they might be led to take thenext step and integrate it with the PFC.This would be an optimal solution.

DeficienciesBelieve it or not, the problems I’ve list-

ed here constitute nearly all of the notice-able design deficiencies. Of course, thereare minor bugs that need to be fixed, butoverall EAF is solid and stable.

As with all class libraries, there aresome things that would be done differ-ently if CYNERGY built EAF again. How-ever, for EAF they mostly have to do withnaming conventions rather than designs.A few components have somewhat con-fusing names, and the PBLs could havebeen named better.

SupportCYNERGY has a news group where

EAF users can communicate with eachother and CYNERGY staff. This level ofsupport is enough for most organizations.For a greater level of support CYNERGYoffers various support contracts.

DocumentationEven very good products often have

substandard documentation. Unfortu-nately, EAF fits into this category. Thedocumentation and online help are thinat best. Fortunately, the code is internally

well documented so it’s easy to under-stand. Because the documentation isweak, it’s even more valuable to take oneor more EAF training courses when youstart using it. CYNERGY has committed todeveloping professional-quality docu-mentation, though no specific deliverydate has been stated.

Ease of UseThe fact that EAF uses the same design

principles as the PFC is a big plus. Transi-tion from PFC to EAF is minor, and PFCdevelopers can quickly become proficientwith EAF.

With an estimated 50% of all Power-Builder client/server projects based onthe PFC, most PB developers are PFCknowledgeable. That means there’s alreadya very large pool of EAF-capable program-mers and consultants.

CostIt’s free. You can’t do better than that.

CYNERGY isn’t a product company anddidn’t want to become one. Therefore,they’ve made EAF open source. Thismeans you can get it for free and cus-tomize it as much as you want. The onlystipulation is that you may not distributeany form of the source code outside yourcompany. If you need to distribute yourEAF-based components or client to yourcustomer, you must get your customer tolicense it too.

How to Get ItCYNERGY provides a way to download

it from their site: www.dyn-data.com.Before you download it, they require youto sign their licensing agreement. Simplygo to their site and follow the instructions,and you should have EAF downloadedwithin 24 hours.

SummaryEAF is a well-designed and -devel-

oped framework for developing Power-Builder components and their HTML andPB clients. Except for the lack of docu-mentation and online help, the overallquality of EAF is exceptional. EAF has avery good component library that workswith its own client-side library. I believethere will eventually be a componentlibrary that works with the PFC ratherthan independently of it. Whether thatends up being the EAF component libraryremains to be seen. Regardless, EAF is thebest class library available for distributeddevelopment using PowerBuilder. If you’recurrently developing EAServer compo-nents using PowerBuilder, you should beusing EAF. ▼

www.PowerBuilderJournal.comPBDJ volume7 issue10

FIGURE 2 HTMLDW support

PR

OD

UC

T

RE

VI

EW

14

SESSION MANAGEMENT

Page 12: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

16 www.PowerBuilderJournal.comPBDJ volume7 issue10

D A T A W I N D O W M A G I C

WRITTEN BYRICHARD BROOKS M

y first column on Sherlock appeared in the August issue ofPBDJ (Vol. 7, issue 8). In that article we set up our devel-opment environment. Now we need to log in. Before wedo that let’s review just a bit.

We have a window with only aDataWindow control. The DataWindowis external; Table 1 shows its columns.

This DataWindow is free-form andbasically used to gather informationabout the login process (see Figure 1).I’ve added some graphics that can bedownloaded from the source code onthe PBDJ Web site.

In the last article we discussed howto automatically execute events byparsing out the tag property for anycolumn the user clicks on. Listings 1and 2 repeat the string parsing rou-tine I used (and continue to usealmost daily in my own work). Theseare inside a nonvisual object (class)that I call dojo_n_cst_string. One iscase sensitive and the other isn’t.They’re both called of_getTokenized-Value. Since they have the samename, they’re polymorphic. The lastargument is optional.

I failed to show you two otherfunctions in that object that deter-mine if the object passed in as anargument is “good” (not null andvalid). Again, we have a polymorphicfunction here. In one case we’re deter-mining if the object is null and theother if it’s valid. The distinguishingcharacteristic is whether the argu-ment is a PowerObject or a type ANY.The two functions are in Listings 3and 4, both named of_good.

Now that we’re set up, let’s startadding functionality to the DataWin-dow. Note that along the top there’s acheckbox for Save To Registry. Let’sstart with that. If the user checkedthat last time, then we need to restorethat value. Clearly the next thing to do

is check the registry to see if the userdid check Save To Registry. If the userdid, then we’ll have something in theregistry giving us some default values.

We need a key under which to saveour registry entry. If you aren’t familiarwith registry functions, look up reg-istryGet in your help file. Let’s call that keyHKEY_CURRENT_USER\Software\Sher-lock. Next we add some code to theopen event of the window. That code(see Listing 5) looks for our databaseinformation in the registry. Those val-ues that are found (if any) are used insetItems for the DataWindow control.

We’re automatically populating theDataWindow in the open event if theuser saved his or her values in the reg-istry. If the user didn’t, then we’re not.

The next thing to do is make surethe user can, if he or she wishes, saveto the registry. This would happen ifthe user checked the Save To Registrywhen he or she tried to log in. Wefinally get to use our tag attribute. Goto your DataWindow painter and addthe following tag to your button:

[post] ue_login

With our functionality this willautomatically call the ue_login event (ifwe defined it) whenever that button is

clicked. Open your ancestor DataWin-dow and put the code from Listing 6 inthe Clicked event. Now go back to yourw_main, edit the clicked event of yourDataWindow control, and take out thecall to close the parent.

Create a user-defined event calledue_login and insert the code fromListing 7.

Let’s see, where are we? We nowhave a window that can be used to login. Can we enhance this window? Ofcourse we can. We could add the abil-ity to save to an ini file. That wouldrequire more code in the open eventof the window and the ue_login eventof the DataWindow. You could alsoadd a button that allows you to cancelthe application. As it stands right now,you can’t get out unless you connectto the database. That’s not acceptable.I assume you’re quite capable of han-dling these things on your own if youwant – after all, this column is aboutDataWindows, not generic applica-tion development.

In the next article we’ll move on tothe meat of this series, the dynamicreport generation. It’ll require a newwindow. Until then, you can downloadthe code and try it out on your own. ▼

Advanced DataWindow technology

FIGURE 1 Your login window

TABLE 1 The login DataWindow columns

DBMS string(30)

Database string(30)

dbParm string(60)

Database string(30)

userID string(30)

savePassword string(1)

[email protected]

AUTHOR BIORichard (Rik) Brooks isthe owner of Brooks &Young, a Sybase Code

Partner. He’s been usingPowerBuilder since 1990

and has worked as anindependent consultant

for major corporations inthe U.S. for the last fiveyears. He has authored

several books on PowerBuilder including

PFC Programmer’s Reference Manual and

The Definitive DataWindow.

Sherlock II Logging In

Page 13: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

17www.PowerBuilderJournal.com PBDJ volume7 issue10

string dojo_n_cst_string.of_getTokenizedValue(as_target,as_token)if not good(as_target) or not good(as_token) then return ""// Get the value part of a token / value pair from the target.

// First prepare both the token and the target for searching

string ls_target

as_token = lower(as_token) // Enforce case insensi-tivityls_target = lower(as_target)

long ll_valueStart, ll_valueEnd

ll_valueStart = pos(ls_target, as_token)if ll_valueStart = 0 then return "" // notoken

// look for the ending bracket so we know where the tokenends and move ll_valueStart// one beyond that.ll_valueStart = pos(ls_target, "]", ll_valueStart + 1) + 1

// Look for the start of the next tokenll_valueEnd = pos(ls_target, "[", ll_valueStart)

// There are no tokens after the one in question. Just returnthe right part of the // target.if ll_valueEnd = 0 then return trim(right(as_target,len(as_target) - ll_valueStart))

// Now we know that the value is embedded. Get it out with a midreturn trim(mid(as_target, ll_valueStart, ll_valueEnd -ll_valueStart))

string dojo_n_cst_string.of_getTokenizedValue(as_target,as_token, ab_caseSensitive)if not ab_caseSensitive thenas_target = upper(as_target)as_token = upper(as_token)end ifreturn of_getTokenizedValue(as_target, as_token)

Boolean dojo_n_cst_string.of_good(ANY aa)if not isNull(aa) thenreturn TRUEelsereturn FALSEend if

Boolean dojo_n_cst_string.of_good(powerObject apo)if isValid(apo) then return TRUEelsereturn FALSEend if

w_main::opendw_1.insertRow(0)string ls_user, ls_password, ls_dbms, ls_database, ls_dbparmstring ls_autocommit, ls_key

ls_key = "HKEY_CURRENT_USER\Software\Sherlock"

registryGet(ls_key, "username", regString!, ls_user)registryGet(ls_key, "password", regString!, ls_password)registryGet(ls_key, "dbms", regString!, ls_dbms)registryGet(ls_key, "database", regString!, ls_database)registryGet(ls_key, "dbparm", regString!, ls_dbparm)registryGet(ls_key, "autocommit", regString!, ls_autocommit)

// See if we need to set the SaveToRegistry checkbox onif len(ls_user) > 0 or len(ls_password) > 0 or len(ls_dbms) >0 or & len(ls_database) > 0 or len(ls_dbparm) > 0 thendw_1.setItem(1, "savetoregistry", "t")

if len(ls_user) > 0 then dw_1.setItem(1, "userid", ls_user)dw_1.setItem(1, "savetoregistry", "t")end if

if len(ls_password) > 0 then dw_1.setItem(1, "password", ls_password)dw_1.setItem(1, "savepassword", "t")end if

if len(ls_dbms) > 0 then dw_1.setItem(1, "dbms", ls_dbms)if len(ls_database) > 0 then dw_1.setItem(1, "database",ls_database)if len(ls_dbparm) > 0 then dw_1.setItem(1, "dbparm",ls_dbparm)if len(ls_autocommit) > 0 then dw_1.setItem(1, "autocommit",lower(left(ls_autocommit, 1)))

dojo_dw::itemChanged(long row, dwobject dwo, string data)string ls_tagls_tag = describe(dwo.name + ".Tag")

// Make sure it's a good tagif ls_tag = "!" or len(ls_tag) < 1 then return

// Now check to see if there is an event in this.dojo_n_cst_string lo_stringpostEvent(lo_string.of_getTokenizedValue(ls_tag, "post"))

w_main.dw_1::ue_loginstring ls_user, ls_password, ls_dbms, ls_database, ls_dbparm,ls_autocommit

// Get the data enteredls_user = dw_1.getItemString(1, "userid")ls_password = dw_1.getItemString(1, "password")ls_dbms = dw_1.getItemString(1, "dbms")ls_database = dw_1.getItemString(1, "database")ls_dbparm = dw_1.getItemString(1, "dbparm")ls_autocommit = dw_1.getItemString(1, "autocommit")

// If the dbparm was not entered then at least a user nameand id // is required

if len(ls_dbParm) = 0 and (len(ls_user) = 0 or len(ls_pass-word) = 0) thenmessagebox("Missing Data", "Please enter user name and pass-word")dw_1.setColumn("userid")dw_1.setFocus()returnend if

if lower(dw_1.getItemString(1, "savetoregistry")) = "t" then// Store the values in the registrystring ls_keyls_key = "HKEY_CURRENT_USER\Software\Sherlock"if registrySet(ls_key, "username", regString!, ls_user) = -1then messagebox("Registry Error", "Setting the user name")

end ifif lower(left(dw_1.getItemString(1, "savepassword"), 1)) ="t" thenif registrySet(ls_key, "password", regString!, ls_password)

= -1 thenmessagebox("Registry Error", "Setting the password")

end ifend ifif registrySet(ls_key, "dbms", regString!, ls_dbms) = -1thenmessagebox("Registry Error", "Setting the setting the

dbms")end ifif registrySet(ls_key, "database", regString!, ls_database)= -1 thenmessagebox("Registry Error", "Setting the database")

end ifif registrySet(ls_key, "dbparm", regString!, ls_dbparm) = -1thenmessagebox("Registry Error", "Setting the dbparm")

end ifif registrySet(ls_key, "autocommit", regString!, ls_autocom-mit) = -1 thenmessagebox("Registry Error", "Setting the autocommit")

end ifend if// Now try the login

SQLCA.UserID = ls_userSQLCA.DBPass = ls_passwordSQLCA.DBMS = ls_dbmsSQLCA.Database = ls_databaseSQLCA.DBParm = ls_dbParmif lower(left(ls_autocommit, 1)) = "t" thenSQLCA.AutoCommit = TRUEelseSQLCA.AutoCommit = FALSEend if

connect ;if sqlca.sqlcode = 0 thenclose(parent)elsemessagebox("Database Connection Error", &"[" + string(sqlca.sqldbcode) + "] " + sqlca.sqlerrtext)dw_1.setFocus()end if

Listing 7

Listing 6

Listing 5

Listing 4

Listing 3

Listing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

Page 14: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

18 www.PowerBuilderJournal.comPBDJ volume7 issue10

Using the PFC Application/Utility Services

In this month’s column I’ll present a simple “how to” on thePFC application and utility services,along with a simple descrip-tion and code example for each service.They’re among the leastused in the PFC, but I’ve found them to be the most useful.These services are error, debug, and SQLSpy.

T E C H N I Q U E S

WRITTEN BYBOB HENDRY

I N T R O D U C T I O N T O P O W E R B U I L D E R

Error Service

WHAT IT DOESThe error service gives the applica-

tion a standard interface in which to dis-play error messages to the user and thenlog to a disk file. In addition, the serviceallows the error to be e-mailed to a sys-tem administrator (if a MAPI compliante-mail system exists on the system).

HOW YOU USE ITLike any application service, the

developer must first turn it on. Type thefollowing code in the inherited applica-tion manager object pfc_open event:

This.of_SetError(TRUE)

When the application manager isclosed, the error service is automati-cally shut off. The developer can dothe following with the error service:• Replace messageboxes within the

application with more standardones supplied by the error service.

• Determine what errors are writtento the error log.

• Determine who gets e-mailed whenan error occurs.

• Load error messages from a disk fileor database.

SHORT DISCUSSIONThe primary job of the error ser-

vice is to provide a standard set oferror messages to an application. Inmost applications, if a validation orsystem error occurs, developers usu-ally notify the user via a messagebox.One problem with this is that the textthe developer includes within themessagebox may differ from the sameerror message written by anotherdeveloper. With this in mind, the errorservice provides a single place whereerror messages are kept. Now insteadof each developer coding his or herown messagebox, one call to the errorservice will display the messagebox.This guarantees consistent error noti-fication throughout the application.In addition, error messages can nowbe held in one place rather than scat-tered throughout the code. If the ver-biage or severity of an error haschanged, the error message can bemaintained in one stop.

The error service function that dis-plays a messagebox, of_message( ), isvery flexible. The user can overridethe title and pass arguments to themessagebox generated by the errorservice. Passing arguments is benefi-cial when the error message to be dis-played has an argument. For example,“Cannot save data until <blank> isentered.”

When using a database as yourerror-message source, a second trans-action object is needed to connect tothe database that contains error-mes-sage information. This scenario ap-plies when SQLCA (if used) is alreadyin use and pointing to a differentdatabase that’s being used by theapplication. If your application con-nects to only one database, and thatdatabase contains the error-messagetable, then the second transactionobject wouldn’t be required.

DISPLAYING ERROR MESSAGESSeveral options that relate to the

error message display are available:• Display messages in a messagebox

or PFC prebuilt dialog.• Set a time-out value so the message-

box (or dialog) will close after aspecified time if not responded to.

• Choose not to display messages(override the error service).

TYPES OF ERROR DISPLAYSError messages may be displayed

either in a messagebox or in the PFCprebuilt dialog. The command but-tons and icons that appear on bothare determined at runtime when amessage is initiated using the func-tion of_Message(). Icon choices includethe following:• Information!• StopSign!• Exclamation!• Question!• None!

The acknowledgment buttonchoices include:• OK!• OKCancel!• YesNo!• YesNoCancel!• RetryCancel!• AbortRetryIgnore!

Service: Error service

Object: n_cst_error/pfc_n_cst_error

Library: pfeapsrv.pbl/pfcapsrv.pbl

FIGURE 1 Error messagebox

Unlike the window and DataWindow

services, the utility andapplication services

were created with thedeveloper in mind

Services you can use throughout the development cycle

Page 15: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.
Page 16: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

20 www.PowerBuilderJournal.comPBDJ volume7 issue10

I N T R O D U C T I O N T O P O W E R B U I L D E R

USING THE DIALOG BOXWhen using the PFC prebuilt dia-

log, the user can include a user inputbutton and/or a print button. If used,the end user may input additionalnotes and/or send the error informa-tion to a printer. When the input but-ton is clicked, the dialog expands toinclude an additional area for end-user input. To use the PFC prebuiltdialog box, call the of_SetStyle()function:

gnv_app.inv_error.of_SetStyle(1)

AUTOMATICALLY CLOSING THE ERROR MESSAGEBOXYou may choose to automatically

close the error message if the userdoesn’t respond within a specifiednumber of seconds. To do this youneed to call the of_SetTimeout( )function. The following line of codewill close the error dialog in 10 sec-onds if the user doesn’t respond.

gnv_app.inv_error.of_SetTimeOut(10)

This feature is available only whenthe PFC dialogs are used to display theerror message.This function won’tcause dialogs to close if a standardPowerBuilder messagebox is used.

WRITING ERROR MESSAGES TO A LOG FILEYou may choose to have error

messages of a specific severity (orhigher) automatically written to atext file. For example:

// Specify the name of the log file

gnv_app.inv_error.of_SetLogFile("c:\er

rors\errlog.txt")

// Specify the severity of messages

at which logging starts

gnv_app.inv_error.of_SetLogSeverity(8)

The error file will be created if itdoesn’t already exist, as will the log filesince it’s appended to, not overwritten.

USING THE ERROR SERVICEIn this code example I’ll enable

the application error service. Afterturning the service on, I’ll add thecode to retrieve the error messagesfrom a disk file, specify a log file towrite error messages to, and code anerror-service messagebox. This is thefirst step in enabling the error ser-vice. To do this, add the followingcode to the n_cst_myappmanagerpfc_open event:

This.of_SetError(TRUE)

This.inv_error.of_SetPreDefined-

Source("c:\pfctut\errors.txt")

This.inv_error.of_SetLogFile("c:\pfc-

tut\errorfile.txt")

This.inv_error.of_SetLogSeverity(4)

CODE DESCRIPTIONThe following function turns on

the error service:

This.of_SetError(TRUE)

This function informs the errorservice that the error messages arecontained in a tab-delimited file onthe local drive:

This.inv_error.of_SetPreDefined-

Source("c:\pfctut\errors.txt")

This file is then imported into aDataStore to be used by the error ser-vice until it’s destroyed when theapplication closes. The format of thefile is:

Example

The PFC includes the d_defined-messages dataobject that containscolumns that correspond to the infor-mation above. This dataobject is usedto hold the error information if theerror message source is either a textfile or a database. Also, by default, thestandard PowerBuilder messagebox isused to display error messages.

CODE DESCRIPTIONThe error service uses the follow-

ing file to keep a log of all errors thathave occurred that are over thethreshold error amount.

This.inv_error.of_SetLogFile("c:\pfc-

tut\errorfile.txt")

The following line of code sets theerror log threshold. On a scale of one to10, one is the least severe server errorwhile 10 is the most severe. In this casethe severity is set to four. Error mes-sages with a severity less than fourwon’t be written to the error log file.

This.inv_error.of_SetLogSeverity(4)

Now that we’ve set up the errorservice, I can get the error message bysimply calling a method on theobject. The code below will showerror message “100” as it appears inthe flat file (or the database).

gnv_app.inv_error.of_message("100")

The messagebox shown in Figure 1should display.

In a real application the of_mes-sage function would be placed in aDataWindow itemerror or item-changed event. But for the sake ofsimplicity test the messages in a com-mandbutton clicked event.

Debug Service

String - Message id

String - Messagebox title

String - Messagebox text

String - Icon

String - Button style

Long - Default button

Long - Message severity

String - Print flag

String - User input flag

FIGURE 2 Debug window

100Entry ErrorThe Wrong Value has been EnteredInformation!YesNoCancel!17NN

Service: Debug service

Object: n_cst_debug/pfc_n_cst_debug

Library: pfcutil.pbl/pfeutil.pbl

Page 17: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

21PBDJ volume7 issue10

AUTHOR BIOBob Hendry is a

PowerBuilder instructor forEnvision Software Systems

and a frequent speaker at both national and

international PowerBuilderconferences. He specializes

in PFC development andhas written two books

on the subject including Programming with

the PFC 6.0.

WHAT IT DOESThe debug service allows the applica-

tion to write messages to a debug log.This debug log can be opened andclosed throughout an application. Theprogrammer determines what and whenmessages are written to the debug log.

HOW YOU USE ITLike any application service, the

developer must first turn it on. In theapplication manager object pfc_openevent, type the following code:

This.of_SetDebug(TRUE)

When the application manager isclosed, the debug service is automati-cally destroyed. The developer can dothe following with the debug service:• Write messages to the debug window.• Turn on the SQLSpy service from

within the debug service.• Control the opening and closing of

the debug log window.• Clear the log window of messages.• Print the contents of the debug

window.• Inquire of the opened status of the

debug window.

SHORT DISCUSSIONUnlike the error service, the debug

service doesn’t actually write to a diskfile. The debug messages are held in aDataWindow within the debug win-dow. Also, the developer can writemessages to the debug log anywhere ina script. The function that writes to thedebug window, of_message(), is usual-ly called during critical portions of theapplication. For example, it’s commonto write to the debug log when win-dows open and close, and after data isretrieved from the database.

The debug window is a main win-dow, not a sheet window. It can easilybe “buried” behind other windows inyour application, including the MDIframe. If you want the debug windowto be “on top,” call the functionof_setalwaysontop( ).

After turning the service on, youneed to add the code to write entries tothe debug window and then open andclose it. To enable the debug service,add the following code to then_cst_myappmanager pfc_open event:

This.of_SetDebug(True)

This.inv_debug.of_message("Debug Log

Turned On")

CODE DESCRIPTIONThe following function turns on

the debug service:

This.of_SetDebug(True)

The next function writes an entryto the debug log:

This.inv_debug.of_message("Debug Log

Turned On")

It’s the only function that can be usedto add entries to the debug window.Click on the debug command button todisplay the debug window (see Figure 2).

Any time you want to display thedebug log, simply use the followingcode:

gnv_app.inv_debug.of_OpenLog(TRUE)

SQL Spy Service

WHAT IT DOESThe SQLSpy service allows the

application to display and save SQLstatements that are submitted to thedatabase.

HOW YOU USE ITLike any application/utility ser-

vice, the developer must first turn iton. In the inherited application man-ager object pf_open event, type thefollowing code:

gnv_app.inv_debug.of_SetSQLSpy(TRUE)

When the application manager isclosed, the SQLSpy service is auto-matically destroyed. The developercan do the following with the SQLSpyservice:• Set a disk (log) file to keep a history

of SQL statements.• Print the contents on the SQL history.• Control the opening and closing of

the SQLSpy service window.• Clear the SQLSpy service history.

SHORT DISCUSSIONThe SQLSpy service is a debug ser-

vice for DataWindows. Whenever aDataWindow sqlpreview event isfired, the sqlsyntax is written to theSQLSpy service. The SQLSpy windowis a main window, not a sheet win-dow. It can easily be “buried” behindother windows in your application,including the MDI frame. If you wantthe SQLSpy window to be “on top,”call the function of_setalwayson-top( ).

To enable the SQLSpy service, thefollowing code must be added to then_cst_myappmanager pfc_open event:

gnv_app.inv_debug.of_SetSQLSpy(TRUE)

After turning the service on, codewill be added to open the SQLSpywindow and observe its contents.

To display the contents of the SQL-Spy DataWindow, simply call themethod to open it. The following codecan be put in any event:

This.inv_debug.inv_sqlspy.of_openSQL-

Spy(TRUE)

The window in Figure 3 will keep arunning history of all SQL statementsto be submitted to the database.

ConclusionThe three services discussed above

provide developers with a good set ofdevelopment tools. Unlike the win-dow and DataWindow services, theutility and application services werecreated with the developers in mind.Throughout the development cycle,these services will be very useful.

Next month I’ll cover the applica-tion caching service. This serviceallows developers to store commonlyused data in memory, thus savingdatabase retrieves.

Thank you to Ron Van Zant fromUnited Orange Growers in Gainesville,Florida, for this month’s topic. ▼

[email protected]

Service: SQL Spy service

Object: n_cst_sqlspy/pfc_n_cst_sqlspy

Library: pfcutil.pbl/pfeutil.pbl

FIGURE 3 SQLSpy DataWindow

www.PowerBuilderJournal.com

Page 18: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

22 PBDJ volume7 issue10

I’m going to take a little departure from

DataWindows here. Judging from my e-

mail over the years, I’ve discovered that

some things are just more difficult for the Power-

Builder programmer to grasp than others. The

TreeView is one of them. A recent e-mail asking

for an explanation of that object inspired me to

write this article. (Sample code for this article

can be found on the PBDJ Web site.)

Okay, let’s start off by defining what a Tree-View is. Essentially it’s a type of list. You’veseen this list in action many times. The Win-dows Explorer uses a simple TreeView toshow you the contents of your hard drive.

I want to step back and approach a Tree-View from a different perspective – think of itas a container. The TreeView control itself isa container in much the same way that aListBox is. A ListBox by itself doesn’t do any-thing. You have to add things to it to make itwork. In the case of the ListBox we’re talkingabout strings, and in the case of the TreeViewwe’re talking about structures. When you seea TreeView in action, you’ll see somethinglike Figure 1 (taken from the HTML books).

FIGURE 1 A TreeView example

P B D J F E A T U R E

UsableExample

AUsable

Example

Page 19: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

WRITTEN BY Richard Brooks

www.PowerBuilderJournal.com

In this figure you see Composers withAdams, Bach, Bartok, and Beethoven under-neath. Beethoven has another set of divi-sions under him, Chamber Music and Over-ture. However, this is part of the problem –it’s not consistent. Under Adams are twoitems. No items are under Beethoven, onlycollections of items. The actual items areunder those collections, so when we look atthis object we start to think in terms of col-lections and items. And this, I believe, is alarge part of the problem.

TreeViews are composed of structures.Whether the structure represents a collec-tion (or folder) or whether it represents anaction item, they’re all the same structure.The properties of the structurecontained in the control deter-mine if they’ll “hold” other struc-tures (and thus collapse andexpand) or if they’ll be an “action-able” item. That’s not all, though.When you add an item, you spec-ify a parent to it. That parent maybe a 0 (indicating root or left-most level) or another TreeViewitem. If the parent is anotherTreeView item, then that parent isa collection.

The basic idea is that you havea control and add items to it.Sometimes people will do this allin one script, or sometimes in anevent in the control. Personally, Ilike to do it all in one script if pos-sible, but sometimes you have alot to load and want to do it onlywhen the user expands an item.However, the choice is yours.

So, based on the precedinginformation, we’ll build a simpleexample. Let’s create a new windowand throw some items in there.We’re going to create a TreeView that repre-sents a school. The classes will be groupedunder “tracks” as in Sybase Education. Eachclass will have an instructor and an assistantinstructor. Yes, I know that a one-level listwould be the simplest of all, but I want to giveyou something you can really use. The trackswill be Accounting, Business Administration,and Computer Science. Every track will have aBeginning, Intermediate, Advanced, and Post-Graduate level. Each one of these will haveclasses, and each of these will have an instruc-tor and an assistant. So put your TreeView inyour window and let’s get started.

Let’s begin by creating the tracks. The codein Listing 1 shows what I did to create them.Let’s take this line by line. In the first line Idefined a long. TreeViewItems have handles,which are how you refer to the specific item.Items can be found in your TreeView. Insertitems before, after, or under other items; thiscan be done with all the long handles.

The first line gives me a handle. I’m going touse this two ways. I have to pass a handle to theinsertItem function, and I’ll use the return

value of the previous line to get that handle.This way I’ll know that the items will be in theproper order (unless I’ve set the sorting prop-erty of the TreeView to true).

Begin by calling insertItemFirst. The argu-ments are the level (0 being root), the text,and the picture. In this case we don’t need apicture so it’s 0 and returns a handle. This iswhat I use to call the insertItem function. Thenext line calls insertItem. It’s similar to insert-ItemFirst except it requires a handle to theitem, after which you’ll insert the item. Itreturns a handle to its own item, which I’ll useto insert the next item. I put all of this code inthe clicked event of a window. Figure 2 showsthat window after I’ve clicked the button.

Pretty cool, huh? Now, that wasn’t sohard, just a few lines of code. If you down-load the example code, you’ll find thatthere’s an example in the clicked event thatshows you how to do the whole thing withjust one line, using the return value of eachline as an argument to the next. I wouldn’tsuggest you do that, though, because it’shighly obtuse and difficult for others tomaintain – unless that’s your goal.

The next step is to put the Beginning,Intermediate, Advanced, and Post Grad undereach item. There are several ways to do this.I’ll skip the inefficient methods and just takeyou through the way I use (which might notbe the best). The first goal is to find theappropriate root item. As it turns out, it’s notquite as simple as one might think. We’regoing to create a function for it. It’ll be a win-dow-level function called of_findItem, whichwill take the text of the item that we want tofind and return a long handle to the item wewant. The code is in Listing 2.

Let’s take a look at this code. First, wedeclare a couple of variables. Then I convert

FIGURE 3 Our TreeView

FIGURE 2 Our first TreeView

PBDJ volume7 issue10 23

Page 20: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

24 www.PowerBuilderJournal.comPBDJ volume7 issue10

long ll_treeViewItem

ll_treeViewItem = tv_1.insertItemFirst(0,"Accounting", 0)ll_treeViewItem = tv_1.insertItem(0, ll_treeViewItem, "Busi-ness Admin", 0)ll_treeViewItem = tv_1.insertItem(0, ll_treeViewItem, "Com-puter Science", 0)

long w_main.of_findItem(string as_label)

long ll_item, ll_nextItemll_item = tv_1.findItem(RootTreeItem!, 0) // get the top oneif ll_item = -1 then return -1 // Nothing inserted in control// To speed up the search and make it case insensitiveas_label = lower(as_label) // Is it the top one?treeViewItem tvi_theObject // That structure that I told youabouttv_1.getItem(ll_item, tvi_theObject)if lower(tvi_theObject.label) = as_label then return ll_item

ll_nextItem = tv_1.findItem(nextTreeItem!, ll_item)do while ll_nextItem > -1

yield() // This is a tight loop. Give Windows a chanceto work

tv_1.getItem(ll_nextItem, tvi_theObject)if lower(tvi_theObject.label) = as_label then return

ll_nextItemll_nextItem = tv_1.findItem(nextTreeItem!, ll_nextitem)

loopreturn -1

w_main.cb_ok::clickedlong ll_treeViewItem

ll_treeViewItem = tv_1.insertItemFirst(0,"Accounting", 0)ll_treeViewItem = tv_1.insertItem(0, ll_treeViewItem, &"Business Admin", 0)

ll_treeViewItem = tv_1.insertItem(0, ll_treeViewItem, &"Computer Science", 0)

// Add the Beginning, Intermediate, Advanced, and Post Gradunder eachlong ll_root

ll_root = of_findItem("Accounting")ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Beginning", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Intermediate", 0)ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &

"Advanced", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Post Graduate", 0)

ll_root = of_findItem("Business Admin")

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Beginning", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Intermediate", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Advanced", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Post Graduate", 0)

ll_root = of_findItem("Computer Science")ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Beginning", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Intermediate", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Advanced", 0)

ll_treeViewItem = tv_1.insertItem(ll_root, ll_treeViewItem, &"Post Graduate", 0)

tv_1.selectionChangedtreeviewItem ltvi_old, ltvi_newstring ls_msg

if getItem(oldHandle, ltvi_old) <> -1 thenls_msg = "You switched from " + ltvi_old.label

end ifgetItem(newHandle, ltvi_new)if getItem(oldHandle, ltvi_old) <> -1 then

if len(ls_msg) > 0 thenls_msg += " to "

elsels_msg = "You are viewing "

end ifls_msg += ltvi_new.label

end ifif len(ls_msg) > 0 then messagebox("notice", ls_msg)

Listing 4Listing 3

Listing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

the argument to lowercase so the search isn’tcase sensitive. The first line of code that maybe unfamiliar to you is the call to GetItem.This function call takes a handle and fills inthe structure that you pass it; this is how youget the context of an item.

If the argument isn’t the first, then I haveto drop into the loop where I’m calling thefindItem function. The findItem returns ahandle (or -1) to the item represented by thehandle. The first argument controls the func-tionality of this function. I’d strongly suggestyou look up that function and become famil-iar with this argument. You can do lots of dif-ferent things with it. The first thing I doinside the loop is execute a yield. I do thisany time I’m in a tight loop. It helps me breakout of an infinite loop while developing.Then I do a getItem again so I can look at the

properties of the TreeView. Once this is done,I can compare the argument to the labelproperty. If it’s a match, I return the handle.

We’re down to the wire now. Let’s go backto the clicked event of the button and finishup the code, shown in Listing 3. That’s allthere is to it.

Notice I set up the root levels; then I justdo insertItem using the return value of theof_findItem to give me the handle that Iwant. Figure 3 shows the same window afterI’ve expanded all the items.

Now that we have a TreeView, how do weinteract with it? How do we know when theuser has done something with it? In otherwords, how can we make this thing work? Lookat Listing 4 in the SelectionChanged event ofthe TreeView control. It should give you a hintas to how you can use the control. Can we

improve this? Of course we can. We can createan ancestor TreeView and add our of_findItemto it. Then we can add a new version of insert-Item that will let us add an array of strings.

If there’s interest in pursuing this control,I’ll write another article that’ll show you howto deal with the pictures and how to get youritems from a database rather than hard-cod-ing them. See? I told you I don’t just doDataWindows. ▼

AUTHOR BIORichard (Rik) Brooks is the owner of Brooks & Young, a Sybase CodePartner. He’s been using PowerBuilder since 1990 and has worked as anindependent consultant for major corporations in the U.S. for the last fiveyears. He has authored several books on PowerBuilder including PFCProgrammer’s Reference Manual and The Definitive DataWindow.

[email protected]

Page 21: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

26 www.PowerBuilderJournal.comPBDJ volume7 issue10

D R O P D O W N D A T A W I N D O W S

Imagine creating a DropDownDataWindow look and feel usingHTML form elements that can show more than one column ina ListBox on a Web page.The data elements could be generat-ed using Web server-side technologies such as JavaServer Pages(JSP),Active Server Pages (ASP), and ColdFusion Markup Lan-guage (CFML).This look and feel is similar to the JTable class ofJava or the DB grid control in Visual Basic.

WRITTEN BYKAUSHIK DATTA

AUTHOR BIOKaushik Datta is a senior

technical consultantwith more than nineyears’ experience in

the software industryworking on system

software and applicationsoftware development.

Currently he’s moving aclient/server application to

intranet/Internet thin Web client architecture

using server-side Java.

In this article I’ll demonstrate how toshow an HTML element dynamically,depending on the user’s action on a Webpage. This code works both in InternetExplorer and Netscape browsers thatsupport JavaScript and HTML 4.0.

Need for DropDownDataWindowsFor Windows-based client/server

applications, PowerBuilder has a neatfeature called the DropDownData-Window that shows the multipleattributes of the data element. Forexample, in my current project I needto show an entry field or SingleLine-Edit (SLE) in which the user can enterthe customer code. In case you don’tknow the customer code, it can beselected from the DropDownListBox(DDLB) by looking at the customername and the state combination orany other column combination thatdescribes the customer code. If theuser interface is a combo box (DDLB)that contains all the information for asingle row on the Web page, it wouldoccupy a lot of horizontal space. If theuser interface is a ListBox (LB), itwould occupy a lot of horizontal andvertical space. The smarter user inter-face in this scenario would be to showa DropDownList only on demand.This is possible in PowerBuilder sincewe have a powerful DropDown-DataWindow control. It’s not availablein the HTML world.

DropDownDataWindow in HTMLUsing the current version of HTML

(4.0 and greater) and JavaScript, wecan create the look and feel of a Drop-

DownDataWindow by showing theHTML ListBox form element dynami-cally. First, include the followingJavaScript within the HEAD tag of theHTML page (see Listing 1).

Listing 1 has three major functionsand one important array variablecalled arrayLink, which contains theform element that needs to be dis-played dynamically on demand. InListing 1 it’s the HTML SELECT tagthat creates a ListBox using the SIZEattribute of SELECT tag. It can be anyHTML element, such as TABLE. dis-playMessage function has the HTMLelement as the first argument, thebackground color of the HTML ele-ment as the second argument, andthe x, y coordinates as the third andfourth arguments, respectively, wherethe HTML element has to be shownon the Web page. The data in thearrayLink variable can be generatedusing JSP, ASP, or any other Web serv-er-side scripting language. drop-downOn and dropdownOff functionsactually show or hide the HTML ele-ment, respectively, when the userclicks on the down arrow – a “.gif” fileon the Web page.

Next, add the HTML code in Listing2 to the body section of the HTML page.

In Listing 2 notice how the drop-downOn and dropdownOff JavaScriptfunctions are called by trapping the

onmousedown event of the image(IMG) element of HTML. Care shouldbe taken in defining the dynamicHTML tag – DIV and LAYER for the IEand Netscape browsers, respectively.Notice the ID and NAME attribute“dropdown” as it’s referred to inJavaScript (see Figure 1). In addition,the stylesheet is used in the HTMLcode in Listing 2.

Pros and ConsThe technique shown in this arti-

cle works only in browsers that sup-port JavaScript and HTML 4.0. Both IEversion 4.0 and above and Netscape4.0 and above support it. I have a sam-ple URL to demonstrate how it works,www.intac.com/~kaudata/customer.-htm. This code doesn’t have otheradvanced client-side features of theDataWindow, such as sorting and fil-tering, but you can dynamically gen-erate the data element using server-side scripting. Using this technique,you can save a lot of real estate on aWeb page compared to the SELECTelement of the HTML FORM.

ConclusionWith the growing trend toward

Web-based applications, this kind offeature will be very useful since it’s apopular look and feel in client/serverapplications. It helps to look at multi-ple attributes of a particular data ele-ment. Please contact me if you haveany suggestions on improving theJavaScript code. ▼

FIGURE 1 DDDW look and feel in HTML

[email protected]

DropDownDataWindows Using HTML and JavaScript

A popular look and feel in client/server applications

Page 22: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

27PBDJ volume7 issue10www.PowerBuilderJournal.com

<SCRIPT LANGUAGE="Javascript">var browserName=navigator.appName;var browserVersion=parseInt(navigator.appVersion)if (browserName=="Netscape") boolBrowser=trueelse boolBrowser=falsevar argX=0;var arrayLink=new Array();var toggle=true;function displayMessage(message,backColor,top,left){

this.message=message;this.backColor=backColor;this.top=top;this.left=left;

}function dropdownOn(argX){

toggle=false;if ((browserName=="Netscape" && browserVersion>=4) || (browserName=="Microsoft Internet Explorer" &&

browserVersion>=4)){if (boolBrowser){

with(arrayLink[argX]){document.layers['dropdown'].backColor=back-

Color;

document.layers['dropdown'].document.writeln(message);document.layers['dropdown'].document.close();document.layers['dropdown'].top=top;document.layers['dropdown'].left=left;

}document.layers['dropdown'].visibility="show";

}else {

with(arrayLink[argX]) {dropdown.innerHTML=message;dropdown.style.top=top;dropdown.style.left=left;dropdown.style.background=backColor;

}dropdown.style.visibility="visible";

}}return;

}

function dropdownOff(selectedValue){toggle=true;if (selectedValue!="")

document.dropdownForm.dropdownColumn.value=selected-Value;

if ((browserName=="Netscape" && browserVersion>=4) || ( browserName=="Microsoft Internet Explorer" &&

browserVersion>=4)){if (boolBrowser) document.layers['dropdown'].vis-

ibility="hide";else dropdown.style.visibility="hidden";

}return false;

}arrayLink[0]=new displayMessage('<FORM NAME="selList"><SELECTname="selValue" SIZE=4 onchange="dropdownOff(document.selList.selValue.options[document.selList.selValue.selectedIn-dex].value);"><OPTION style="font-size: 8pt; color: red;"VALUE="">&nbsp;Id&nbsp; | &nbsp;Name&nbsp; |&nbsp; State&nbsp;<OPTION VALUE="P3109"> P3109 | Sonia Das | CA<OPTIONVALUE="D0007"> D0007 | Doyel Datta | NJ<OPTIONVALUE="J1011">J1011 | Bob Silverstone | VA<OPTIONVALUE="S2101"> S2101 | Stephen Smith |MA</SELECT></FORM>','#ffff99',80,70)</SCRIPT>

<DIV ID="dropdown" STYLE="position:absolute;visibility:hid-den;WIDTH=70%"></DIV><LAYER NAME="dropdown" VISIBILITY="hide" WIDTH=70%></LAYER><FORM NAME="dropdownForm"><FONT COLOR=#660033 FACE="Verdana,Arial,Helvetica"SIZE="2">Code :&nbsp;&nbsp;<INPUT TYPE="text" NAME="dropdownColumn" size="5"maxlength="5"><IMG SRC="downarrow.gif" ONMOUSEDOWN="if(toggle==true){ dropdownOn(0);return;} else {dropdownOff('');return;}"></FORM>

Listing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

SYS-CON Media, the world's leading publisher of Internet technology magazines for developers, software architects and e-commerce professionals,becomes the first to serve the rapidly growing wireless application development community!

Look for it on your newsstand and worldwide in December!

ANNOUNCING…Wireless Magazine

w w w . w i r e l e s s m a g a z i n e . c o m

Page 23: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

28 www.PowerBuilderJournal.comPBDJ volume7 issue10

D I S T R I B U T E D T E C H N O L O G I E S

Sanity Checking an EAServer Connection Cache

WRITTEN BYMICHAEL BARLOTTA T

he Jaguar CTS application server provides robust support for a number of different database connec-tion approaches for its connection caches, including JDBC and ODBC, as well as native connectivity toOracle and Sybase Adaptive Server Enterprise.

Avoid getting dropped connections from the database cache

Jaguar CTS uses database connec-tion caches to maintain a pool of pre-allocated database connections thatJaguar components can use to interactwith database servers. Database con-nection caching allows a single con-nection to be shared by several clientsessions on the Jaguar server. This ismade possible by recapturing data-base connections when they’re idlesince most processes requiring accessto a database have long periods whenthey’re not actually using the connec-tion. The Jaguar server manages theconnection cache and connections tothe database (see Figure 1). FIGURE 1 Overview of Jaguar’s database connection caches

ComponentComponent

Component

Kernal

Jaguar CTS

Connection Cache

Connection

Connection

Connection

DBMS

When using database connections, anapplication takes two hits. One is to perfor-mance. Establishing a database connectionis a time-consuming process. The second isto consumption of resources. Maintainingthe database connection takes up resourceson both the client – in our case Jaguar CTS– and the DBMS. In a two-tier client/serverapplication these are not as visible since aclient usually has only one database connec-tion, which typically connects to the data-base once and remains connected.

In a distributed application built withcomponents these hits can add up. Insteadof having to establish and maintain a singledatabase connection, an application serverlike Jaguar CTS needs to handle databaseconnectivity for hundreds or thousands ofconcurrent users. Imagine the resources thatare required to maintain all of these connec-tions on a single machine. Pooling databaseconnections improves the scalability of theJaguar CTS server by reducing the use of serv-er resources, such as CPU cycles and memory.

In addition, Jaguar CTS applications aremade up of components. Each of these smallprograms executes logic in methods and runsin its own thread space. Each component thatrequires data from a database needs its ownconnection. Since a client of the Jaguar serv-

er may have to run business processes thatinvolve several components and databaseinteractions, a single user of the applicationmay actually require more than one connec-tion. Now a Jaguar CTS server that serveshundreds of concurrent users actually needsto maintain thousands of database connec-tions. Pooling these connections improvesthe scalability of both the Jaguar CTS serverand the database server by reducing thenumber of database connections while allow-ing components the access they need bysharing the connections.

To minimize resource usage, Jaguar com-ponents are usually designed to be stateless.This means that after each method call thecomponent instance is removed or deactivat-ed from that client session and pooled for useby another client. Without connection cachingthe performance of the application would begreatly diminished since the componentwould need to physically connect to the data-base at the beginning of every method call anddisconnect after it’s completed. Instead it canask for a connection from the cache alreadyconnected to the database, which is a fasteroperation.

A database connection cache not only pro-vides the advantage of conserving resources onthe Jaguar server and providing a performance

boost to large systems, it also helps compo-nents share transactions. One of the biggestadvantages of using the connection cache inJaguar is its Transaction Manager. TransactionManager manages database transactions onbehalf of the component handling the commitor rollback of database changes. By allowingthe Jaguar CTS server to manage transactions,database changes made across several methodcalls over different components can be groupedinto a single transaction and succeed or fail asa whole. Component methods can take part inJaguar transactions by voting on the outcomerather than committing or rolling back thetransaction itself. A component can performspecialized processing in a single transaction.However, when this component is called byother Jaguar components, each chunk of pro-cessing can be combined to form larger, morecomplex processes that can run in the contextof a single transaction. This allows componentsto be grouped into different transactions in dif-ferent ways to solve business problems, oftenin ways that weren’t originally intended. Trans-action Manager uses the connection cache toallow the Jaguar server to share a databaseconnection and a transaction across multiplecomponents. A component can’t take advan-tage of Transaction Manager if it uses a data-base connection outside the connection cache.

A d v a n t a g e s o f D a t a b a s e C o n n e c t i o n C a c h e s

Page 24: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

29www.PowerBuilderJournal.com PBDJ volume7 issue10

When a Jaguar component requestsa database connection, the Jaguarserver finds a free connection in thecache and assigns it to the compo-nent. Once the connection is assignedto a particular component, it can’t beassigned to any others unless theJaguar Transaction Manager is man-aging a transaction that spans multi-ple components. When the compo-nent releases the connection, it’splaced back in the connection cache.Connection caching works best whencomponents that ask for a connectionto the database give it back whenthey’re finished with it so it’s availablefor use by other components.

As Tim Hatton pointed out in theJuly issue of PBDJ (Vol. 7, Issue 7), con-nection caches can help with the scal-ability of a distributed application. Itdoes this by allowing more “logical”users to access the database than thenumber of physical licenses for theDBMS allows or that the machine thedatabase is running on might be ableto handle. See the sidebar for otherconnection cache advantages.

After database connections are usedby a component, there’s no guaranteethat connection is still valid and ready tobe used by another component whenit’s placed back into the cache. One ofthe options on the database connectioncache is the sanity check (see Figure 2).When this option is enabled, the Jaguarserver checks on the state of the data-base connection before it’s pulled out ofthe cache and given to a client by ping-ing the database that it’s connected to. Ifthe connection is invalid, it’s droppedand a new connection is established.The sanity check ping is performed bysending an SQL statement to the data-base and checking the return code. Thisstatement is specified in the propertycom.sybase.jaguar.conncache.check.The default SQL statement is listedbelow:

SELECT 1

Jaguar checks the SQL codereturned by running the default sani-ty check SQL statement, then dropsthe connection if it returns an error.Table 1 shows the default SQL state-ments for most DBMS engines. To testyour DBMS, try typing the SQL state-ment in a query tool and check theresponse.

If the SQL statement isn’t support-ed by the database used by the con-nection cache, an error will be report-ed and the connection will be droppedand reestablished. If the sanity checkalways fails because the SQL state-ment is invalid, we lose one of the

benefits of the connection cache sincewe reconnect to the database eachtime we request a connection from thecache. To overcome this problem, weneed to change the value of the sanitycheck SQL statement.

The Jaguar properties of a data-base connection cache can’t be setthrough Jaguar Manager becausethere isn’t an All Properties tab on theConnection Cache Properties dialogbox. To modify the properties of adatabase connection cache, a proper-ty file needs to be created manually. In the %JAGUAR%\Repository\Conn-Cache directory, create an ASCII textfile. The file name should match thename of the database connectioncache with the extension “.props”. Forexample, the database connectioncache MyOracleCache would have aproperty file named MyOracle-Cache.props. Keep in mind that theconnection caches are case-sensitive,so name the text file appropriately.Once the file is created, properties forthe cache can be added, modified,and deleted. To change the sanitycheck SQL to a valid statement for theOracle DBMS, add the com.sybase.-jaguar.conncache.check property asfollows:

com.sybase.jaguar.conncache.check=SELE

CT 1 FROM DUAL

ConclusionDatabase connection caches are a

powerful part of the Jaguar CTS appli-cation server. They allow the Jaguarserver to provide a very scalable plat-form upon which distributed applica-tions can be built. In addition, theyprovide powerful transactional capa-bilities, allowing components to sharetransactions even if they’re written indifferent languages. Leveraging themcorrectly in your application can helpmake a difference in the performance,flexibility, and reusability of yourcomponents. ▼

[email protected] 2 Enabling the connection sanity check

TABLE 1 Overview of Jaguar’s database connection caches

DBMS

Adaptive Server Enterprise

Adaptive Server Anywhere

Microsoft SQL server

Oracle

SQL

SELECT 1

SELECT 1

SELECT 1

SELECT 1 FROM DUAL

AUTHOR BIOMichael Barlotta is director of technology atAEGIS Consulting. Mike,a CPD Associate, hasworked with PowerBuildersince version 3.0 and hasa BA in computer sciencefrom SUNY at Albany,New York. He hasauthored several books,including Taming Jaguarand Jaguar Developmentwith PowerBuilder 7(both by Manning Publications). Visit Mike’s Web site atwww.erols.com/m.barlotta.

Database connection

caches are a powerful

part of the Jaguar CTS

application server. They

allow the Jaguar server to

provide a very scalable

platform upon which

distributed applications

can be built

Page 25: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

30 www.PowerBuilderJournal.comPBDJ volume7 issue10

P B & J A V A

…but developers can benefit by uncovering themPB May Hide Its OO Features…

Most PowerBuilder developers are aware of object-orientedconcepts like inheritance, encapsulation, and polymor-phism. A lot has been said about them, and I don’t wantto reinvent the wheel by discussing what they are andhow they’re used in PB applications.

The main purpose of this article isto explain one of the lesser knownconcepts of object-oriented program-ming, namely, upcasting. Later I’llgive an example of method and vari-able overriding in conjunction withupcasting in PowerBuilder and how itdiffers in Java.

I came across upcasting when Iwas preparing for Sun certification forJava. When I learned more about it, Irealized that it’s something commonto PowerBuilder, too. In fact, I hadused it before, but I didn’t know theterm. I then asked a few colleagues ifthey knew about it: these longtimePowerBuilder developer friends hadno idea what was I talking about.That’s when I decided to write an arti-cle about it.

What Is Upcasting ?Some of you may be familiar with

the term casting. In many program-ming languages it means changingthe data type. Casting can be implicitor explicit. For example, consider thiscode in PowerBuilder:

int li_rowcount

li_rowcount = dw_1.RowCount()

The return type of “RowCount()”function is long. However, the aboveassignment is perfectly valid eventhough the variable “li_rowcount” is

declared “int” (of course, there will beproblems in the runtime if the “Row-count( )” returns a value greater thanthe maximum “Int” value). This ispossible because of implicit castingsupported by PowerBuilder

Several low- and mid-level lan-guages support explicit casting. Onceyou understand casting, upcastingshould be obvious if you visualize theinheritance tree below.

In this example the user object (orclass) “n_cst_son” is inherited from theuser object (or class) from “n_cst_father”.

By virtue of inheritance, “n_cst_son”class gets all the functions (in OO termi-nology, called as methods) and proper-ties of the parent class. But that’s not all.Inheritance also defines a “relation”between child class and parent class.This relation is best described by saying:“The child class is of type ‘Parent’ class.”

For example, in the script of yourwindow, the following is perfectly legal:

n_cst_father lnv_father

lnv_father = create n_cst_son

Here the object of child class is cre-ated and assigned to the object of type

parent class. This is possible becauseof upcasting by virtue of inheritance.

Examples of UpcastingAt this point some of you may be

wondering why, how, and where you’duse upcasting in PowerBuilder. Well,you’ve already used it if you everpassed a DataStore or nonvisual userobject through Message object’sPowerObjectParm. As you may recall,it’s a common practice in Power-Builder to pass structures and Data-Stores through a Message object. Sinceall PB objects are inherited from Power-Object, any PB object can be passed.

Upcasting is indispensable ifyou’re writing any framework or evena generic program. Consider thisfunction, which returns the Filterstring for both DataWindows andDataStores:

//parameter a_dw_or_ds PowerObject

string ls_filter

ls_filter = a_dw_or_ds.dynamic &

describe("DataWindow.Table.Filter")

// A Question mark means no filter set.

if ls_filter = '?' then

ls_filter = 'Error or No Filter'

end if

return ls_filter

Listing 1 contains the completecode for the upcasting window.

Overriding Methods andVariables in PB and Java

In the next code we’ll see overrid-ing methods and variables in Power-Builder in conjunction with upcastingand how it’s different in Java.

Parent ClassIII

Child Class

FIGURE 1 Overriding methods and variables

WRITTEN BYATUL KANE

n_cst_fatherIII

n_cst_son

Page 26: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

31PBDJ volume7 issue10

I created two NVOs shown earlier:“n_cst_son” inherited from “n_cst_father”. Each object has a definedone-instance variable for salary andboth have a function with an identicalsignature that returns the age. Inessence, the child class has overrid-den the variable salary as well as thefunction that returns the age.

On the command button of a win-dow I coded the following

n_cst_father lnv_father

lnv_father = create n_cst_son

Now the question is, what wouldbe the value of lnv.father.i_salary? Oflnv_father.uf_getage()?

Will it return the son’s value or thefather’s value?

Note that “lnv_father” is declaredto be of type “n_cst_father” but isassigned the reference to “n_cst_son”.

It turns out that PowerBuildertotally forgets about the declaration of“lnv_father” once we assign “n_cst_-

son” object to it. Thus both valuesreturned are of “n_cst_son” (see Fig-ure 1 and Listing 2).

Similar code in Java reveals thatJava never forgets the type of theobject when looking for instance vari-ables (see Figure 2 and Listing 3).

SummaryTo simplify the job of a program-

mer, PowerBuilder hides many of its

OO features. However, learning thoseconcepts will always benefit the PBdeveloper. Though Java is more object-oriented than PowerBuilder, and ofcourse has more publicity about beingobject-oriented, many people seem toforget that PowerBuilder is object-ori-ented too, and that many of the samefeatures existed in PowerBuilder longbefore Java was born. ▼

//Instance Variabledatastore ids

//Window Open Eventids = CREATE datastoreids.dataobject = "d_upcasting_example"//need any datawindow object here //for this example

//Set Both Filterstring ls_filterls_filter = "col1 = 'Atul'"

dw_1.setfilter(ls_filter)

ls_filter = "col1 <> 'Atul'"ids.setfilter(ls_filter)

//Show DataWindow Filterst_1.text = wf_getfilter(dw_1)

//Show DataStore Filterst_2.text = wf_getfilter(ids)

//Function wf_getfilterstring ls_filter//a_dw_or_ds powerobject

ls_filter = a_dw_or_ds.dynamic &describe("DataWindow.Table.Filter")

// A Question mark means no filter set.if ls_filter = '?' then

ls_filter = 'Error or No Filter'end if

return ls_filter

//n_cst_father

//Instance Variableint i_salary = 5000

//Function uf_getagereturn 40

//n_cst_son

//Instance Variableint i_salary = 2500

//Function uf_getagereturn 20

//Command Button Click on Windown_cst_father lnv_fatherlnv_father = create n_cst_son

if IsValid(lnv_father) thenmle_1.text = "Father variable instantiated with Son~r~n" mle_1.text += "Variable Salary " +

String(lnv_father.i_salary) + "~r~n" mle_1.text += "Method Age " + String(lnv_father.uf_getage())

destroy lnv_fatherend if

//File Example_OO_Method_Variable.java

public class Example_OO_Method_Variable {public static void main(String args[]) {Father father;father = new Son();

System.out.println("Father variable instantiated with Son");

System.out.println("Variable Salary " + father.i_salary); System.out.println("Method Age " + father.func_getage()); }}

class Father {int i_salary = 5000;public int func_getage(){return 40;

}}

class Son extends Father{int i_salary = 2500;public int func_getage(){return 20;

}}

Listing 3

Listing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

www.PowerBuilderJournal.com

FIGURE 2 Overriding in Java

[email protected]

AUTHOR BIOAtul Kane, a consultantbased in San Jose,California, has worked

with PB since version 3and has nine years ofprogramming experience.He is also a Sybase-certifiedPowerBuilder developerassociate and a certifiedSun Java programmerwith a degree in computer science.

Page 27: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

34 www.PowerBuilderJournal.comPBDJ volume7 issue10

P O P U P M E N U S

WRITTEN BYNERMIN TANOVIC

…Easy DW popup menu techniqueAnd Now, Something Completely Different…

How many times have you needed to add an extra menu item ina DataWindow popup menu? If you’ve ever done it, you knowwhat a nightmare it is and how time-consuming it can be.

You’d need to go through the fol-lowing steps (at least):• Create or inherit a new menu for

this purpose and add the new menuitem needed.

• Place code in the new menu item’sClicked Event to dynamically callthe desired DW method.

• Override the DW RbuttonUp Eventand change the reference fromm_dw to a new popup menu.

• Place code in the DW RbuttonUpEvent to create and pop up the newmenu.

• Place code in the DW method – theone that will be called from thepopup menu.

• Place code in the Pfc_PreRmbMenuEvent.

You’re probably getting the picturealready – all this work for just one extrapopup menu item! And this is how it’sdone in most PB frameworks today,PFC-based or not. You need to practi-cally override and redesign the wholepopup menu service. And you need todo it for every DataWindow whosepopup menu needs to be customized.

Creating a ServiceInstead you can create

what I call an Easy PopupMenu DataWindow Service.Once it’s done, you’ll needonly one line of code in yourDataWindow control to cre-ate the extra menu item andone line of code to performan action based on theuser’s choice. Yes, you’rereading this correctly – onlytwo lines of code in aDataWindow control to dis-play an extra popup menuitem and perform an actionwhen the user clicks on anewly created menu item.

This Easy Popup Menu techniquecan be implemented in any PB frame-work, PFC-based or not.

It was originally implemented inthe Hepek PowerBuilder Framework.Since many PB developers aren’tfamiliar with Hepek yet and it’s notPFC-based, I’ll present the Easy PopupMenu Service as a PFC extension, writ-ten using PB7 and PFC7 code exam-ples. We’ll need to add some items andmethods to m_dw, as well as someevents in the u_dw object.

Extending m_dwFirst let’s add three custom events

in m_dw object – m_custom1, m_cus-tom2, and m_custom3 – with threeseparation lines, m_sep1, m_sep2,and m_sep3, between them. Placethem right under the m_table menuitem where all other DW menu itemsare located. Note that the text for eachseparator line needs to be a dash sign(–). You don’t have to limit the numberof custom events to three, of course.So far, we have a m_dw menu, asshown in Figure 1.

Now hide all the menu items (cus-tom menu items and separators) youjust created – set the Visible menuitem property to FALSE. Place one lineof code in the Clicked Event for eachcustom menu item you’ve created.The code will call the DataWindowEvent dynamically:

idw_parent.EventDYNAMIC

ue_custom_event(1)

(Note that the argument to aDataWindow ue_custom_event willbe different for different menu items.For m_custom1 it’ll be 1; for m_cus-tom2, 2; and for m_custom3, 3.)

We also need to create one menufunction, mf_show_custom, that’ll becalled from the parent DataWindow.Based on its arguments, the mf_show_custom function will set the par-

ticular custom menu item text, showthe item, and eventually show the sep-arator line before the menu item. Ittakes three arguments – ai_section,as_item_text, and ab_show_separator.The function declaration and functionbody are shown in Listing 1.

You may think this is “expensive”;showing and hiding menu itemsdynamically isn’t good practice. Well,it’s not true in this case, because thismf_show_custom function will hap-pen after the popup menu is created,but before it becomes visible andpops up. The creation and display of apopup menu using the Easy PopupMenu technique takes no time at allon any machine and it’s not resource-intensive either.

Extending u_dwSo far, we’ve created popup menu

items and methods. The next step is toadd a ue_custom_event user event inthe u_dw object. This event is calledfrom custom menu items created pre-viously and doesn’t have any code inthe u_dw object. All the code will be inthe actual application when using theEasy Popup Menu Service. It’s an emptyuser event that allows you to perform aparticular action based on user choice.

The Event takes one argument andevent declaration as follows:

Event ue_custom_event (integer

ai_section)

The ue_popup_menu event will beused in combination with the DWPfc_PreRmbMenu Event to display theextra menu item and perform a partic-ular action based on the user’s choice.

The Pfc_PreRmbMenu Event is anempty user event that allows you tomodify m_dw contents before display-ing the popup menu. You can optional-ly add logic to this event to selectivelyenable or disable popup menu items.

At this point we’re ready to use theFIGURE 1 The m_dw menu after adding menu items

Page 28: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

35PBDJ volume7 issue10www.PowerBuilderJournal.com

Public subroutine mf_show_custom (integer ai_section, stringas_item_text, boolean ab_show_separator)

// Show a particular custom menu and separator line item whencalled from DataWindow.CHOOSE CASE ai_section

CASE 1This.m_table.m_custom1.Visible = TRUEThis.m_table.m_custom1.Text = as_item_textThis.m_table.m_sep1.Visible = ab_show_separator

CASE 2This.m_table.m_custom2.Visible = TRUEThis.m_table.m_custom2.Text = as_item_textThis.m_table.m_sep2.Visible = ab_show_separator

CASE 3This.m_table.m_custom3.Visible = TRUEThis.m_table.m_custom3.Text = as_item_textThis.m_table.m_sep3.Visible = ab_show_separator

END CHOOSE

String ls_emp_nameInteger li_rowBoolean lb_is_salesrep

li_row = GetRow()

// Get the Employee name

ls_emp_name = GetItemString(li_row, &

'emp_fname') + ' ' + &

GetItemString(li_row, 'emp_lname')

// Show custom Menu item - Employee Details

am_dw.mf_show_custom(1, '&Employee Details: '

+ ls_emp_name,

TRUE)

// Determine if employee is SalesRep

lb_is_salesrep = of_is_salesrep(li_row)

IF lb_is_salesrep THEN

// Disable ‘Delete Row’ option

am_dw.m_table.m_delete.Enabled = FALSE

// Show Custom Menu Item – SalesRep Report

am_dw.mf_show_custom(2, '&SalesRep Report: '

+ ls_emp_name,

FALSE)

END IFListing 2

Listing 1

!edoCehtdaolnwoDThe code listing for this article can also be located at

www.PowerBuilderJournal .com

service in an application. In thisexample, in the Departments DataWindow, we’ll add an extra menu itemin the popup menu. By clicking onthis menu item, users will print theDepartment Report for the depart-ment that currently has focus.

Put this code in the DW pfc_pre-rmbmenu event:

// Display an extra popup menu item

for Department

// Activity Report and show the sepa-

rator line

am_dw.mf_show_custom (1, &

'Department Activity Report', TRUE)

In addition, you need to place thefollowing code in DataWindowue_custom_event the event:

IF ai_section = 1 THEN

MessageBox('Easy Popup Menu Ser-

vice', &

'Department Activity Report')

END IF

The popup menu in this exampleis shown in Figure 2.

Listing 2 is an example of anEmployees’ DataWindow that’s datasensitive and shows or hides popupmenu items based on whether theemployee is a sales rep.

The following code needs to beplaced in the DataWindow Ue_custom_event Event:

CHOOSE CASE ai_section

CASE 1

MessageBox('Easy Popup Menu

Service', &

'Employee Details')

CASE 2

MessageBox('Easy Popup Menu

Service', &

'SalesRep Report')

END CHOOSE

The popup menu is data sensitiveand displays the SalesRep Report itemonly if the person whose row hasfocus is a sales rep rather than anordinary employee. Susan Smith is asales rep while Matthew Cobb isn’t(see Figures 3 and 4).

ConclusionThe Easy Popup Menu technique is

a useful, time-saving feature, fullyimplemented in the Hepek Power-Builder Framework. Hepek goes evenfurther and uses the same popup menu

for DataWindow, ListView, and Tree-View controls. To see the Easy PopupMenu in action, visit www.hepek.comand download code examples. ▼

FIGURE 2 Adding Department Activity Report

FIGURE 3 Adding Employee Details and SalesRep Report

FIGURE 4 Adding Employee Details Report

[email protected]

AUTHOR BIONermin Tanovic, a seniortechnology specialist at Bowne TechnologyEnterprise, a major financial printing company in New York,is the author of theHepek PowerBuilderFramework. His Web site is www.hepek.com.

Page 29: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

PowerBuilder NewsAll things of interest to the PB community BY BRUCE ARMSTRONG

36 www.PowerBuilderJournal.comPBDJ volume7 issue10

e-PortalWorldweb.net8/02

Worldweb.net, Inc.,announced that it’s part of theSybase Enterprise Portal AllianceProgram as well as a member ofthe Sybase Partner Program.With Worldweb.net’s XML-basedExpressroom I/O, users are ableto develop, manage, deploy, anddisseminate e-business assetsresiding in Sybase databases,and deliver information to awide variety of devices. ▼

e-Portal Alliance Reaches 30 Members8/02

Sybase announced it hasreached a major milestone inthe e-Portal Alliance programwith a total of 30 strategicpartners. Among thoseannouncing their commitmentto the Sybase e-Portal Allianceare Sterling Management Consulting, Gauss Interprise,Everypath, Oasis Technology,Ltd., PowerCerv, and EzCommerce. ▼

Taming Jaguar8/01

Manning Publications an-nounced the release of TamingJaguar by Michael Barlotta andJason R. Weiss, a survival guidefor developing and adminis-tering EAServer applications.It’s the first advanced book tothoroughly cover Sybase’snewest Enterprise ApplicationServer technology. ▼

Oasis Technology8/01

Oasis Technologyannounced that it signed anagreement with Sybase,becoming part of the compa-

ny’s e-Portal Alliance Program.This agreement means thatSybase will validate the OasisePayment platform. ▼

Certicom SSL Plus8/01

Certicom announced thatSybase will license Certicom’sSSL Plus as the standard SSLimplementation in many ofSybase’s enterprise softwareproducts. The addition of SSLPlus will provide Sybase cus-tomers with a secure softwareinfrastructure for conductingsafe and reliable electronicbusiness transactions acrossthe Internet and other globalnetworks. ▼

Telecom B2B+I8/01

Sybase announced plansfor the Telecommunications e-Business Support SystemsPortal Plus Intelligence (Telecom B2B+I), a prebuilt,Web-based integration support system applicationdesigned for telecommunica-tions service providers. It willenable telecommunicationsservice providers to rapidlyintegrate customer acquisitionand retention programs at alower cost and with greaterfunctionality. ▼

North 22 Technology Services Group8/01

Sybase and North 22 Tech-nology Services Group (HongKong) Limited announced theformation of a joint venture tocapture Asia’s emerging enter-prise portal market. North 22 isthe parent company of8layer.com, an application ser-vices provider (ASP) that earlierthis year became the first ASP in

Asia to form a strategic alliancewith Sybase to provide applica-tion services utilizing Sybase’sEnterprise Portal solution. ▼

Sybase.com8/01

Sybase announced that ithad reengineered its own Website into a continuously avail-able portal designed to servicecustomers’ needs using theirown e-portal products. Cus-tomers, partners, and prospectscan now access vital businessinformation and services fromSybase through this highly avail-able, integrated Web site. ▼

Intershop7/31

Sybase and Intershop Com-munications announced astrategic alliance to provideleading-edge e-commercesolutions for the EnterprisePortal through the Sybase e-Portal Alliance program. UsingIntershop e-commerce appli-cations within Sybase’s Enter-prise Portal, customers canoffer their goods and servicesover the Internet quickly andalso integrate the e-commercefunction with the rest of thebusiness into a personalized,secure and continuously avail-able enterprise portal. ▼

EAServerCocoBase Enterprise7/31

Thought, Inc., demonstrat-ed CocoBase at TechWave2000. CocoBase allows appli-cation developers to tap intothe disparate types of datacontained in both object andrelational databases. It inte-grates with EAServer and offersthe ability to dynamically map

to all JDBC-compliant rela-tional databases and to auto-matically generate extensibleJava code and entity beans. ▼

Adaptive Server IQCompudigm SeePower 8/01

Sybase announced a part-nership with a New Zealand-based software company,Compudigm, to resell theirSeePower business intelligencesolution, which is embeddedwith Sybase’s high perfor-mance data warehouse –Adaptive Server IQ. The com-panies plan to penetrate thevertical industry marketplacethrough key strategic channelpartnerships. ▼

Product NewsPowerBuilder 8.0/9.08/01

Sybase demonstrated thebeta release of PowerBuilder8.0 at TechWave 2000. The newversion offers increased inte-gration of PowerBuilder withboth Web and applicationservers. Sybase also announcedits plans for developing Power-Builder version 9.0 and hasalready launched a program tosolicit input from the Interna-tional Sybase User Group (ISUG)to develop specification require-ments for that version. ▼

EAServer 3.68/01

Sybase announced the general availability of EAServer3.6. It provides full support ofthe Java 2 Platform, EnterpriseEdition (J2EE) standard toenable developers to achievehighly executable Web applications. ▼

[email protected]

Page 30: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

37www.PowerBuilderJournal.com PBDJ volume7 issue10

ADVERTISER URL PH PG ADVERTISER INDEX

DUTTON SOFTWARE WWW.DUTONSOFTWARE.COM 9

E. CRANE COMPUTING WWW.ECRANE.COM 603-226-4041 39

INTERNET WORLD FALL 2000 WWW.PENTONEVENTS.COM 800-500-1959 13

JAVA DEVELOPER’S JOURNAL WWW.JAVADEVELOPERSJOURNAL.COM 201-802-3020 11

JDJSTORE WWW.JDJSTORE.COM 888-303-JAVA 32-33

NEW MOON WWW.NEWMOON.COM/DESTINY/PDJ 800-ORBIT66 2

NEXUS GROUP WWW.NEXUSGROUP.COM 212-554-4189 37

PRIMAVERA WWW.PRIMAVERA.COM 610-667-8600 37

STARBASE WWW.STARBASE.COM 888-STAR700 7

SYBASE WWW.SYBASE.COM/PBSUCCESS 978-287-1871 40

SYS-CON PUBLICATIONS, INC. WWW.SYS-CON.COM 800-513-7111 37

WIRELESS DEVCON 2000 WWW.WIRELESSDEVCON2000.COM 800-513-7111 19

Page 31: ADVERTISER INDEX Please visit - sys-con.com · ADVERTISER INDEX DUTTON SOFTWARE  9 ... PowerBuilder, they have already taken secondary roles in Sybase’s solution offerings.

38 www.PowerBuilderJournal.comPBDJ volume7 issue10

I M H O

OvercommunicateProbably the most important aspect

of surviving one of these projects is tocommunicate more than you normallywould. For some reason business usersare either insecure or downright para-noid. During the Y2K situation ourcompany had plans for techs to stay inhotels downtown and close to theoffice, so we spent millions of dollars tocreate test labs that would perfectlyemulate our production environments.Many people thought it was going to bea night of terror and problems. Insteadit was really just another good day forchampagne bottlers and pyrotechniccompanies.

We did have software to fix and ifwe hadn’t done so, it would havestopped running and there wouldhave been real problems. But nothingwas as severe as expected. I sent outprogress reports and copies of theupdated project plan on a daily basisduring the remediation project – alongwith a daily teleconference with one ofour offices in Houston and a dailyteam meeting with my developers.This was a lot more than normal – butgave the business users the comfortlevel they desired. This all went on for16 months before New Year’s Eve andthen Leap Year’s Eve – daily, withoutfail. These daily meetings will helpyou keep the lions at bay.

You Spent How Much?Just because budget restraints are

much looser on these types of pro-jects, don’t go crazy. Allow yourself thebest toolset available and spend whatyou need to accomplish the tasks athand. But don’t allow yourself the lux-ury of luxury. This should not be an

opportunity for you to add to yourannual budget or to sneak some extrahardware into the group.

Remember that you get what youpay for. The consultants with the bestreputations in town often have thebroadest skill set and the best com-munication tools. I’ve worked withsome contract programmers whowere wizards at writing code but hadan attitude about communicating.They aren’t as valuable to me as a pro-grammer who is less than a wizard butcommunicates frequently. Contractprogramming is most decidedly notthe area where you want to save a fewbucks. This is the one area where youwant to “Cadillac it.” Sometimes thepresence of a hot consultant is calm-ing in the frenzy.

During the Web architecture projectwe had some interesting frenzy issueswith spending. By definition, architec-ture should be a firm foundation andthe perfect framework. This was notthe time to do it “on the cheap.” We didnot consider price when defining whatthe best servers and IDEs were. We hada bit of levity in our spending. We hireda consulting firm to assist with theproject management and research. Weintentionally ignored pricing consid-erations. In the final analysis many ofthe options we were looking at weresimilar in price – but not in featuressuch as scalability and ease of transi-tion. Cost wasn’t the main concern – itseldom is during a frenzy period.

Standards or Speed – Build or Buy?As programmers, you can find

yourselves being pushed to meet thefrenzied deadlines – and to do so withexcellence. There has been an endlessamount of writing done on Power-

Builder as a RAD tool. The preferenceamong business users is often the buyoption. If they can get their businessneeds met to a certain level, they preferto pay another company to do the job.This is sometimes a result of the frenzy.

There are times when this worksout well, but often the frenzy will leadbusiness users away from a logicalselection. There are considerationssuch as future software changes andreleases, cost escalations, and compa-nies that do not have the same com-mitment to the company that an in-house development team might have.The outside companies do not haveany “skin in the game.” The wisestchoice can often be the developer whois dedicated to the business users’needs, armed with PowerBuilder for arapid solution.

A Little ClosureThere are several ways to help your-

self survive frenzy in your world. Themost important thing to do is commu-nicate extensively with your businessusers. Let them know what’s going on.Tell them what you’re going to do, do it,and then tell them what you did. Thiswill calm the frenzy and help yourusers register confidence in your atti-tude toward their needs. Don’t beafraid to overdocument as well. If abusiness user is making an unreason-able request because of the frenzy,document your response and actionscarefully, erring on the side of cautionwhenever possible. Be responsible withtheir generosity under pressure andmake yourself constantly available tothem, and you may both survive thefrenzy project intact. ▼

AUTHOR BIOMichael Deasy, a staffsystems analyst for theWilliams Companies in

Tulsa, Oklahoma. Heholds an MBA fromSouthern Nazarene

University. He has beenworking with PowerBuilder

since v3 and is president of the Tulsa

PowerBuilder Users Group. [email protected]

Frenzy Projects – How to Survive a Season in the Lion’s Den

I’ve recently been involved with several “frenzy projects” – projects fueled by a sense of desperation.They have a psychotically myopic sense of purpose.These projects are known for large budgets, highprofiles and very severe consequences if they don’t go well.The sentiment among business users is,“We don’t care what it costs, just make it happen.” This happened all over America with Y2K projects,and it’s happening now with companies doing e-business – enabled projects. Next month perhaps it willbe a conversion to microscopic embedded databases. Here are some suggestions to help you avoid thegallows and succeed during a frenzy project.

WRITTEN BYMICHAEL DEASY


Recommended