36
www.PowerBuilderJournal.com T HE M ETADATA D ATA W INDOW U.S. $15.00 (CANADA $16.00) Focus: Extreme DataWindows Buck Woolley Create interesting interactive graphical interfaces 6 PBDJ Feature: Real Programmers Joe Slawsky Use BLOBs An effective tool for data manipulation and representation 12 PB Techniques: Boosting Performance Wendell Rios on DataWindow Retrieval in n-Tier Environments Causes of bad performance d 16 Book Excerpt: Dynamic SQL Supporting rBob Hendry SQL inside or outside the DataWindow 18 Messages: The PowerBuilder 9 Berndt Hamboeck IDE Or comment what you write! 24 Wireless Solutions: Mobile vs Scott Heffron Embedded Databases Choosing the right database for your application 28 IMHO: The Hidden Dangers Michael Deasy of Telecommuting ‘Operator, information, get me the CEO on the line…’ 30 Enterprise Application Studio MAY 2003 - Volume: 10 Issue: 5 RETAILERS PLEASE DISPLAY UNTIL JULY 31, 2003 $15.00US $16.00CAN Distributed Applications for Dummies by Bob Hendry pg. 4 From the Co-editors The Future Keeps Getting Brighter! by John D. Olson pg. 3 Industry Announcements by Bruce Armstrong pg. 34 MULTI-PACK ORDER SUBSCRIBE TODAY and get up to 3 FREE CDs! SEE DETAILS ON PAGES 32 & 33 SAVE UP TO $400 (WHILE SUPPLIES LAST)

THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

  • Upload
    lekhanh

  • View
    214

  • Download
    2

Embed Size (px)

Citation preview

Page 1: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

www.PowerBuilderJournal.com

THE METADATA DATAWINDOWU.S. $15.00 (CANADA $16.00)

Focus: Extreme DataWindows Buck WoolleyCreate interesting interactive graphical interfaces 6

PBDJ Feature: Real Programmers Joe Slawsky

Use BLOBs An effective tool for data manipulation and representation 12

PB Techniques: Boosting Performance Wendell Rios

on DataWindow Retrieval in n-TierEnvironments Causes of bad performance d 16

Book Excerpt: Dynamic SQL Supporting rBob HendrySQL inside or outside the DataWindow 18

Messages: The PowerBuilder 9 Berndt Hamboeck

IDE Or comment what you write! 24

Wireless Solutions: Mobile vs Scott Heffron

Embedded Databases Choosing the right database for your application 28

IMHO: The Hidden Dangers Michael Deasy

of Telecommuting ‘Operator,information, get me the CEO on the line…’ 30

Enterprise Application Studio MAY 2003 - Volume: 10 Issue: 5

RETAILERS PLEASE DISPLAY UNTIL JULY 31, 2003

$15.00US $16.00CAN

Distributed Applications for Dummies

by Bob Hendry pg. 4

From the Co-editors The Future Keeps Getting Brighter!

by John D. Olson pg. 3

Industry Announcementsby Bruce Armstrong pg. 34

0 09281 03424 7

0 5

MULTI-PACK ORDER

SUBSCRIBE TODAYand get up to 3 FREE CDs!

SEE DETAILS ON PAGES 32 & 33

SAVE UP TO $400(WHILE SUPPLIES LAST)

Page 2: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

2 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

Amyuni Technologies, Inc.www.amyuni.com

Page 3: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

3www.POWERBUILDERJOURNAL.com PBDJ volume10 issue5

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

COEDITOR-IN-CHIEF: JOHN OLSONCOEDITOR-IN-CHIEF: BOB HENDRYEXECUTIVE EDITOR: NANCY VALENTINEASSOCIATE EDITOR: JAMIE MATUSOW ASSOCIATE EDITOR: GAIL SCHULTZ ASSOCIATE EDITOR: JEAN CASSIDYASSOCIATE EDITOR: JENNIFER VAN WINCKEL

ONLINE EDITOR: LIN GOETZTECHNICAL EDITOR: BERNIE METZGER

NEWS EDITOR: BRUCE ARMSTRONGDATAWINDOWS EDITOR: RICHARD BROOKS

W R I T E R S I N T H I S I S S U EBRUCE ARMSTRONG, MIKE DEASY, BERNDT HAMBOECK, SCOTT HEFFRON,

BOB HENDRY, JOHN D. OLSON, WENDELL RIOS, JOE SLAWSKY,BUCK WOOLLEY

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: 888 303-5282COVER PRICE: $15/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 U.S., $15 ALL OTHERS

PRESIDENT AND CEO: FUAT A. KIRCAALIVICE PRESIDENT, BUSINESS DEVELOPMENT: GRISHA DAVIDA

SENIOR VP, SALES & MARKETING: CARMEN GONZALEZPRODUCTION CONSULTANT: JIM MORGAN

VICE PRESIDENT, SALES & MARKETING: MILES SILVERMANACCOUNTS RECEIVABLE KERRI VON ACHEN

FINANCIAL ANALYST: JOAN LAROSEACCOUNTS PAYABLE: BETTY WHITE

ADVERTISING DIRECTOR: ROBYN FORMADIRECTOR, SALES & MARKETING: MEGAN RING-MUSSA

ADVERTISING SALES MANAGER: ALISA CATALANOASSOCIATE SALES MANAGER: CARRIE GEBERTASSOCIATE SALES MANAGER: KRISTIN KUHNLE

PRESIDENT, EVENTS: GRISHA DAVIDACONFERENCE MANAGER: MICHAEL LYNCH

ART DIRECTOR: ALEX BOTEROASSOCIATE ART DIRECTOR: LOUIS F. CUFFARIASSOCIATE ART DIRECTOR: RICHARD SILVERBERGASSISTANT ART DIRECTOR: TAMI BEATTY

VICE PRESIDENT, INFORMATION SYSTEMS: ROBERT DIAMONDWEB DESIGNER: STEPHEN KILMURRAYWEB DESIGNER: CHRISTOPHER CROCE

SENIOR CUSTOMER CARE/CIRCULATION SPECIALIST: NIKI PANAGOPOULOS CUSTOMER SERVICE REP: SHELIA DICKERSON

JDJ STORE: RACHEL MCGOURAN

E D I T O R I A L O F F I C E SSYS-CON MEDIA

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 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 © 2003 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 Carrie Gebert. SYS-CON Publications, Inc., reserves the right to revise,republish and authorize its readers to use the articles submitted for publication.

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 D. OLSON, EDITOR-IN-CHIEF

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

[email protected] BIO

John D. Olson is principal of Developower, Inc., a consulting company specializing in software solutions using Sybasedevelopment tools. A CPD professional and charter member of TeamSybase, he is a coauthor of SYS-CON’s Secrets

of the PowerBuilder Masters books, and co-editor and author of two upcoming PB9 books.

The Future KeepsGetting Brighter!

A few days ago I attended the PowerBuilder 9.0 Launch Road Show, then spent the next twodays at a TeamSybase meeting. These meetings are always a highlight of my year – we haveabout 12 hours of private, focused technical and marketing discussions with product engi-

neers, managers, visionaries, and marketing and sales directors. Not only do we learn a lot aboutwhat is coming up, we also have the opportunity to influence the technology and marketing.

There are numerous new features already released or planned for upcoming releases, andthere are even new products already in beta or soon to be. Being a technical magazine, PBDJcovers these in detail each month, but we don’t often address Sybase’s vision, trends, or fore-casts for the software development markets. I want to focus on a few important market trendsthat Sybase is basing its future plans on.

During the PB9 Launch Road Show, Dave Fish and John Strano, the PowerBuilder technical evan-gelists, mapped out Sybase’s plan for the next few years for PowerBuilder and related products. Afterthe release of PB8 I had a wait-and-see attitude with regard to PB, specifically whether Sybase wouldcharge ahead with the product or let it wither and die. Now, over a year later, I believe their slogan,“The future keeps getting brighter!” really does reflect their view of PB9, 10, and beyond.

An important market trend they’re basing their plans on is indicated in a report byInternational Data Corporation (www.idc.com) showing that money spent on 4GL productshas declined in recent years in proportion to the money spent on software development tools.Forecasts for 2003 through 2006 show tools dollars increasing from under $6 billion in 2002 toover $7 billion in 2006. The 4GL tools are projected to increase proportionally and continue totake the largest share of the pie. Since PowerBuilder is already a leading 4GL, Sybase wants totake it to the next generation and earn a significant piece of the growing market segment,which is forecasted to reach nearly $3 billion in 2006. A very important point for PowerBuilderis that it crosses the 4GL boundary and also falls into the “Web Professional DevelopmentTools” category, which will account for about $1 billion per year by 2006.

Said Daphne Chung, senior analyst, software, IDC Asia/Pacific, “…the pressure to shortendevelopment time frames and contain costs drives demand for a newer breed of tools frommarkets such as the RAD and 4GL.”

Again, PowerBuilder falls into both of the categories mentioned: RAD and 4GL. Of course,the challenge lies in getting the word out, increasing market presence, and selling to new cus-tomers while holding on to the existing ones. That is a tall order, but one Sybase is taking seri-ously. Their plan is to create a new generation of 4GL they’re calling “4GL+”, which truly rep-resents a unified development environment by including reverse engineering, modeling, andheterogeneous support for Java, J2EE, CORBA, C++, C#, VB.NET, Web services, XML, and more.

Other projections show that in the next few years nearly all organizations will adopt J2EE, .NET, or acombination of both with very little of the market falling outside of these camps. Therefore, Sybase’sfoundational commitment to providing “open” tools means that PowerBuilder will provide full devel-opment capabilities for both J2EE and .NET. Certainly that won’t happen immediately, but they alreadyhave plans for progressively implementing those capabilities in releases in 2003, 2004, and 2005.

The PB9 Launch Road Show is finishing up its U.S. run, but it’s gearing up for at least 19stops in Europe. If you didn’t have the opportunity to attend a Road Show event, ask your localSybase Tools User Group or PB User Group to invite Sybase to bring the Road Show to yourcity. It’s an event you shouldn’t miss! ▼

Page 4: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

4

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

It’s taken a while, but over the past sixmonths a client of mine has finallygotten around to building distributedapplications in PowerBuilder. In

another life I’ve been building distrib-uted applications for over three years;it’s refreshing to do this in PowerBuilder.Perhaps it’s a harbinger of things tocome. With the pending release ofPowerBuilder 9, there will be moreopportunities to develop distributedPowerBuilder applications. This monthI’ll share a few useful design guidelines –actually provided by my two-year-olddaughter Cassie.

You Can’t Build a Crooked Skyscraper

The advantage of writing reusablecomponents is that an organization canenable flexible applications that can beused internally and externally. One dis-advantage of this approach is that sinceso many interconnected objects areused, there are more opportunities forthe applications to fail.

Everyone should remember Legos. Awonderful toy, Legos are made up ofplastic components and connectorswith which any child can build justabout anything, from a spaceship to asubmarine. Cassie loves to play withLegos. I often watch her construct smallbuildings. Not satisfied with her effort,she keeps adding and adding. The build-ing grows higher and higher, eventuallycrashing under its own weight.

The lesson is simple. What works for asmaller scale application will not neces-sarily work for larger ones. When build-ing large distributed applications, makesure there’s a large investment indesigning a supporting infrastructure. Ifyour application collapses under its ownweight, you probably won’t be given anopportunity to rebuild it.

Defining the Point of FailureNot to be dissuaded, my daughter

carefully re-creates her skyscraper. Ateach step she analyzes how her buildingis handling the added stress of addi-tional components. Sometimes, eventhough her skyscraper is growing solidand straight, it still collapses under itsown weight. Clearly it’s time for a con-sultant. The consultant’s name isAndrea, a three-year old with lots ofexperience with both Legos and TinkerToys. She has the knowledge and experi-ence to assist Cassie with her task.

Cassie has learned that a failure pointis hard to find. What appears to be astronger design may not be the caseafter all. Just because a design worked inother models, doesn’t mean it will workin future ones.

Notification of Success (or Failure)

With the team assembled and function-al requirements in hand, Andrea andCassie get to work. After a lengthy designmeeting, they come up with a plan. Ratherthan constructing the skyscraper from theground up, they will build smaller, moremodular portions. Then, by using differentconnectivity methods, determine whichdesigns offer the strength needed to com-plete their task. Some component configu-rations don’t work. Our two young engi-neers note this, and then try other designs.

Both designers have learned that adistributed project must be performedin small, manageable steps. Each stepshould include built-in repeatable stepsin which progress (or lack of) can bemeasured. Even if a few of these stepsresult in failure, the path to failure canbe mapped and documented. After all,it’s much better to fail in small stepsthan for the entire project to fail all atonce. Finally, they learned that their sky-

scraper couldn’t be built all at once; ithad to be built in incremental steps.

Vendor Support Is CrucialWhile our development team fever-

ishly toils away, I notice that someweird-looking Lego pieces are neatlystacked to the side. After a while it’sapparent that our young engineers haveno idea what these pieces do. The factthat they place them all together is a tes-tament that they don’t want to experi-ment with the unknown. It’s time to adda new team member.

Enter “Slick Nick,” an impeccablydressed, articulate, and handsome four-year old. Although Nick possesses zeroexperience building stuff with Legos, hehas extensive Lego product knowledge.He spends most of his time studyingeach of the Lego components, and thenscans the picture on the Lego box to seehow they’re used. Nick has little knowl-edge if the Legos will work in real-worldapplications. But hey, if the directionssay that they will work, then by goshthey will. Nick will work for Sybasesomeday. He is able to explain how themysterious Lego components work.With this knowledge, our young devel-opers have expanded their toolset.

Vendor support is essential. Even themost experienced team won’t mastertheir complete toolset. To maximizeyour team’s chances for success, yourvendor should never be more than aphone call away.

Success!With all the pieces in place, our young

development team wrecks the building– only to build it over again. With theknowledge gained, the team is able tobuild each successive building in lesstime. Now if Nick would stop asking fora support contract, all will be okay. ▼

[email protected]

PBDJ volume10 issue5 www.POWERBUILDERJOURNAL.com

WRITTEN BYBOB HENDRY

AUTHOR BIOBob Hendry is a PowerBuilder instructor for Envision Software Systems and a frequent speaker at national and international PowerBuilder conferences. He specializes in

PFC development and has written two books on the subject, including Programming with the PFC 6.0.

Distributed Applications for Dummies

Page 5: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

5www.POWERBUILDERJOURNAL.com PBDJ volume10 issue5

Sybasewww.sybase.com/powerbuilder

Page 6: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

www.POWERBUILDERJOURNAL.com6 PBDJ volume10 issue5

Today, users are demanding a more dynam-ic user interface in which intuitive display andmanipulation of graphical representation ofdata replaces the simple method of displayingand editing text data. The PowerBuilderDataWindow object is ideal for developing awide variety of graphically rich dynamic userinterfaces. Although the DataWindow is limit-ed in the types of graphics primatives that can

be generated, its tight coupling of data to theproperties of the objects that can be createdmakes manipulation of all visual DataWindowobjects a simple and robust process.

This article covers some of the primary meth-ods used to generate rich graphic user interfaces.The methods covered include drawing simpleshapes, moving images within a DataWindowand from one DataWindow to another, and usingmetadata to control large numbers of graphicobjects on a DataWindow. The techniques dis-cussed cover only the presentation aspects of theDataWindow and are normally used on externalDataWindows. Therefore, there is no discussionregarding database access SQL syntax. Codeexamples come from DataWindow-based ver-sions of the simple video games, “Minesweep”and “Breakout.” You can download these examples from www.dw-extreme.com/down-load8.0.htm.

Drawing Simple ShapesAlthough the DataWindow doesn’t support

the large variety of shapes and graphic primi-tives available on even the simplest CAD pro-gram, it does support enough to provide someinteresting and useful graphics capabilities.These include the line, ellipse, rectangle, andround rectangle objects seen in Figure 1.

One useful functionality that can be appliedto the DataWindow using the rectangle objectis the ability to draw a rectangle with a mouseand capture or select objects within theboundaries of the rectangle. After the objectsare selected, the rectangle is removed. This is

CREATE INTERESTING INTERACTIVE GRAPHICAL INTERFACESCREATE INTERESTING INTERACTIVE GRAPHICAL INTERFACESWRITTEN BY BUCK WOOLLEY

F O C U S

This article is based on PowerBuilder 9Client/Server Development by various authors(ISBN 0672325004) published by Sams Publishing.Also look for PowerBuilder 9 Internet andDistributed Application Development.

The PowerBuilder DataWindow object is

one of the main reasons for the success

that PowerBuilder has achieved as a

software development tool. Together,

they have matured and developed. However,

since the beginning the DataWindow has

been used to display and manipulate data in

the form of lists and reports as well as in

various data input and maintenance forms.

Page 7: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

7PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

similar to the ability to select objects on theWindows desktop using the mouse. You canalso use this method to draw rectangles,ellipses, and round rectangles by not doingthe step that removes the rendered object.

Creating and Manipulating a Rectangle

Creating and manipulating the rectanglerequires the creation of three mapped customevents on the DataWindow:• uo_lbd mapped to pbm_lbuttondown• uo_mm mapped to pbm_mousemove• uo_lbu mapped to pbm_lbuttonup

These events will contain all the coderequired to generate, manipulate, and destroythe rectangle along with object selection. Eitherplace the code directly on the DataWindowcontrol or, for a more object-oriented approach,create a custom nonvisual object that containsa reference to the DataWindow. You can thencreate custom events in the nonvisual objectthat map to the DataWindow events.

UO_LBD EVENTIf you’re creating a rectangle to render perma-

nently on the DataWindow, you probably wantto generate a unique name for that object. Ifyou’re creating a rectangle for the purpose ofselecting objects on a DataWindow, use a staticname, in this case, “size_rect” as in Listing 1(code listings for this article are available atwww.sys-con.com/pbdj/sourcec.cfm). The onlyrequired parameters xpos and ypos are providedby pbm_lbuttondown. To make sure a“size_rect” doesn’t already exist, issue a destroystatement before you create the new one. Thismay happen if you do the uo_lbd event, thenmove the mouse off the application and lift yourfinger off the mouse. You will have created a rec-tangle without ever destroying it, so it is a goodidea to destroy it before creating a new one. Youwant to store the original x and y locations ofyour pointer in instance variables il_x and il_y.

UO_MM EVENTThis event controls the rendering of the rec-

tangle on the screen as you move the mouse.First check if the left mouse button is downduring the mouse move, by checking if flags =1. The only trick here is that as long as yourpointer is in an area that is greater than theoriginal x and y locations, you’re simply adjust-ing the width and height of the rectangle. Ifyou move your pointer into an area that’s lessthan the original x or y, you must make adjust-ments to the x, y, width, and height parametersof the rectangle as shown in Listing 2.

UO_LBU EVENTDepending on what you are creating the

rectangle for, you’ll do one of two things in theuo_lbu event. If you’re drawing multiplegraphic objects in the DataWindow, it’s a goodidea to store in the uo_lbu all the data associ-ated with the objects in a properties datastore.

The datastore would contain data such as theobject’s name, x, y, height, width, line types,and color properties. The unique name yougenerated for the object in the uo_lbd eventprovides an easy method for finding objects onthe properties datastore. This will be usefullater in the application because you may needto access the object’s properties; it’s much eas-ier to look them up with the DataWindow findfunction using the object unique name than tosearch for them by looping through the prop-erties using the describe function. This capa-bility is useful when filtering for the existenceof objects within a spatial boundry such as aselection rectangle. As mentioned earlier, youcan use this method to create rectangles,ellipses, and round rectangles. Lines can alsobe created this way except that the line objecthas the x1, y1, x2, and y2 properties instead ofx, y, width, and height to describe its position.

If you’re drawing a selection rectangle youwant to save the x, y, width, and height propertiesof the rectangle into variables. These will be usedlater to find the objects within the boundary ofthe selection rectangle. The last item needed is toissue a idw.modify('destroy size_rect') to removethe selection rectangle from the DataWindow.

Selecting the ObjectsIf you have rendered objects such as images

on the DataWindow it’s a good idea to have adatastore to hold the objects and their proper-ties in storage. The properties of interest arethe object’s x, y, width, and height properties.PowerBuilder provides a powerful tool forselecting the object enclosed by the rectangle,the setfilter() function shown in Listing 3. Inthe uo_lbu event filter the datastore containsrendered objects with this setfilter argument.

This leaves a list of objects that are selected byyour rectangle. The final step is to show the user avisual indicator that the objects have been select-ed. Once again PowerBuilder provides a goodsolution that will work with any image. That solu-tion is the DataWindow’s image object.invertproperty as seen in Listing 4. This will display allselected images in an inverted appearance. Theeasiest method is to loop through the selectedobjects and build a modify string that will invertall selected objects in one modify statement.

Listing 4 also shows that the IDs of theselected objects are stored in an instance arrayto be used later for other processing and toreset the selected objects to a normal appear-ance. This is usually done in a loop in anotherevent after the selected objects have beenprocessed (see Listing 5).

Moving Images Within andBetween DataWindows

Another basic functionality required for aninteractive graphical interface is the ability tomove images, text, or graphic primitives with-in a DataWindow and between DataWindowsusing the mouse. Of course, PowerBuilder pro-vides an easy solution for moving objects with-in the DataWindow, the movable property. Just set the movable property to 1dw_1.object.rect.movable=1 and the objectcan be moved by using the mouse. What yousee is an outline of the object linked to yourmouse. The object actually moves to its newlocation when you release the left mouse but-ton. Sometimes, however, users may want theobject and not just an outline of the object tofollow the path of the mouse as they move it.Although this cannot be accomplished by sim-ply setting a property value, it’s easy to do.

Once again moving objects relies on thethree important custom DataWindow eventsused to respond to mouse actions.

When the user clicks on an object for thepurpose of moving it, several things must bedone. First, you must record the identity of theobject that was clicked on and store it in aninstance variable. Use the getobjectatpointer()function to get the clicked object. You alsowant to store in instance variables the object’sx and y properties. The uo_lbd event containsthe code shown in Listing 6.

To link the object to the movement of themouse, adjust the x and y properties of theobject in the uo_mm event. This is done bysimply applying the difference between theobject’s original location and the current posi-tion of the pointer:

IF flags = 1 THEN

idw.modify(is_object+'.x='+STRING(xpos -

il_x)+' '+is_object+'.y='+STRING(ypos -

il_y))

END IF

Upon releasing the mouse in the oe_lbuevent, reset the is_object instance variable sothe object won’t move the next time you clickthe mouse button:

is_object = ‘’

Moving Images from OneDataWindow to Another

In many applications you might have a situ-ation in which you want to drag objects from apalette of objects to some type of canvas. In

Recta gleRectangle Rou dRoundRectangle

Elli seEllipse Li eLine

FIGURE 1 DataWindow graphics primitives

Page 8: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

8 PBDJ volume10 issue5 www.POWERBUILDERJOURNAL.com

this case, you’ll have a window that might haveone DataWindow that contains a set of stan-dard images that you can select from and copyto another DataWindow in which you buildsomething like a network, pipeline, or work-flow diagram. To make the movement lookseamless between the two DataWindows, use athird independent object that performs theactual move between the objects – in this case,a descendant of the PowerBuilder pictureobject. A descendant is used because you’llcreate instance variables within the pictureobject to store some offset values determinedby the location of the pointer when you select-ed the object to move. You also must set thepicture object to not be visible because you’reusing it as a drag object only.

The action is initiated by the oe_lbd eventon an object in the palette DataWindow. In thisevent, extract the row of the selected imageand the image name. You also want to positionthe picture object precisely over theDataWindow image object and have it assumethe width and height of the object so that itappears as if you are dragging the actual imageobject. This is made more difficult if you haveautosize set on your detail band. In the paletteDataWindow you must create a computed fieldthat contains the cumulative y value of everyrow. This is done with the following computedexpression called row_height:

cumulativeSum( rowheight() for all)

Also take into account that the user mighthave scrolled down and the first row on thepage is not row one. This is resolved by usingthe handy PowerBuilder property First-RowOnPage to determine which row is the firstvisible row. The code in the oe_lbd eventshown in Listing 7 takes care of this.

At this point you should see a box perfectlyoutlining the boundary of the DataWindowimage object. With your mouse you shouldalso be able to move the box around the win-dow. If you drop the dragobject on the canvasDataWindow, you’ll process the dragobjectcalled “source” in the dragdrop event of thecanvas DataWindow. The dragobject isassigned to a variable of type uo_pic, the

source of the dragobject. The il_x and il_y holdoffset values so the object will be created withthe same reference to the mouse pointer as ithad when it was selected. The dimensions ofthe created bitmap come from the dimensionsof the dragobject. Listing 8 shows how to createthe new bitmap on the target DataWindow.

Figure 2 shows the image on the canvasDataWindow at the location of the mouse cur-sor with the same bitmap and properties as theselected image on the palette DataWindow.

Select an image from a palette DataWindow.Note the rectangle around the selected object,which is the picture object with its visibility setto 0 and after the drag(begin!) function isinvoked.

Drag the object from the palette Data-Window to the target DataWindow.

Drop the object onto the target Data-Window and build the DataWindow bitmapobject based on the properties stored in thedraggedobject and the results of the pointerX()and pointerY() functions.

Rich Graphical DataWindows Using Metadata

Although the DataWindow can only do verybasic drawing functions, take advantage of itsrow based architecture to develop veryadvanced interactive graphical user interfaces.Examples of objects that can be developedusing Metadata DataWindows include not onlythe Minesweep and Breakout games but alsointerfaces for business applications such as aproject planner/scheduling object, appoint-ment object, advanced charting, and a hierar-chical chart object for uses such as an organi-zational chart.

What controls the functionality of theseobjects is the use of metadata columns withinthe DataWindow to control the visual proper-ties of individual objects rendered on theDataWindow. Within a row on a DataWindowall object properties have access to all data inall columns. This gives you the ability to storevisual property data for multiple objects with-in a single data column. The advantage of row-based storage of graphical object properties issimple, for instance, to display a 60x40 grid ofrectangles. If you were to explicitly create each

one, you would be generating 2,400 rectangles!Doing this in a DataWindow would create anobject of enormous size. Using the row-basedtechnique, simply create 60 rectangles andinsert 40 rows of data to get the same 60x40grid of 2,400 rectangles. You can increase thisto a grid of 60x60 rectangles without generat-ing any additional rectangle object by simplyadding an additional 20 rows to yourDataWindow. The key is storing each of theobject properties of the 60 rectangles in a col-umn of data. This is where the concept ofDataWindow metadata comes from, withmetadata being defined as simply data aboutdata. In this case the data stored in columns ismetadata that’s parsed into meaningful dataused to control DataWindow object visualproperties. I use the term graphic objects torefer to any visual DataWindow object includ-ing lines, rectangles, ellipses, images, text, andcomputed objects. Visual object parametersinclude x, y, width, height, color, line type, pat-tern, and visibility.

Controlling Visual DataWindow Objects

For illustration purposes let’s say we have aDataWindow (dw_1) with one rectangle (r_1).This rectangle represents two states: on andoff. On is indicated by the presence of a greenrectangle, and off is indicated by no rectangle.The straightforward method for displaying thischange of status is to control the visibility ofthe rectangle by coding:

dw_1.object.r_1.visible = 1 (visible)

or

dw_1.object.r_1.visible = 0 (not visible)

This method works for one rectangle; how-ever, it will change the visibility property for allr_1 objects on all rows because no row proper-ty is used on object properties as is used ondata. This then leads to the alternative method:create a numeric column on the DataWindowcalled r_1_vis. To make this column control thevisibility of the rectangle, set the visible prop-erty expression of r_1 to r_1_vis. To change the

FIGURE 2 Dropping the object on the target DataWindow FIGURE 3 Minefield grid showing the various levels of data

Page 9: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

9PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

Sybase, Incwww.sybase.com/pbextension

Page 10: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

www.POWERBUILDERJOURNAL.comPBDJ volume10 issue510

states of r_1 within PowerScript, set the valuesof r_1_vis[row] = 1 for visible and r_1_vis[row]= 0 for not visible.

The benefit of this method is that you canmake row-specific changes to the state of rec-tangle r_1. Rectangle r_1 can be visible on row 1and invisible on rows 2 and 3, etc., simply bychanging the data in column r_1_vis. You canextend this method by creating columns thatcontrol the x, width, y, pattern, and color prop-erties of the rectangle. In doing this, the singlerectangle r_1 can have a vastly different appear-ance for each row. Remember you can have 100rectangles by creating only one rectangle objecton the DataWindow and adding 100 rows ofdata, and each rectangle can have an appear-ance completely different from its neighbor.

Applying Metadata to the VisualProperties of DataWindow Objects

As you can see, you can control as many visu-al parameters as you want by simply adding acolumn to the DataWindow for each one. Nowconsider adding a second rectangle, r_2, to theDataWindow. You can then set up additionalcolumns for r_2: r_2.vis, r_2_color, r_2_x, and soon, and use the same method for manipulatingthe visual properties of rectangle r_2.

What if you wanted up to 20 rectangles on arow? Or what if you wanted to dynamically addand remove rectangles in each row? Creatingcolumns to define the parameters for eachgraphic object and manipulating them would bedifficult and cumbersome considering the num-ber of columns that would need to be changed.

To manipulate five visual properties on 20rectangles would require 100 columns. If youadd to this 20 lines and 20 ellipses, you can seethat the number of columns and the amountof code needed to manipulate them becomesenormous. At this point the metadata methodof handling all this data makes the task consid-erably easier.

Constructing MetadataA more efficient method of storing the visual

properties of DataWindow objects is to storeeach property for all objects in a stringDataWindow column. Using this method youcan store a property such as visibility for 1 to1,000 objects in one DataWindow column. Thedata is actually referenced in the propertyexpression using the DataWindow’s built-inLONG and MID functions. For example, if youhave 10 rectangles and the task is to control thevisibility of each rectangle, create a string(10)column called r_vis. In the visibility expressionof rectangle 1 (r_1), put the expressionLONG(MID(r_vis,1,1)). This expression places anumeric version of the first character in themetadata column r_vis into the visibility prop-erty of rectangle r_1. You would do the samething for rectangles r_2 through r_10. In the vis-ibility expression of rectangle 2 (r_2), put theexpression LONG(MID(r_vis,2,1)); for rectangle3 (r_3), LONG(MID(r_vis,3,1)). Now, one col-umn, r_vis, controls the visibility for 10 rectan-

gles on one row. The data in one row of columnr_vis would look like “0110111010”. To com-pletely switch the visibility of the rectangles onthis row of data you would simply set r_vis to'1001000101': dw_1.object.r_vis[row_num] =‘1001000101'.

To really understand the power of this method,add 100 rows to dw_1. Now you have 1,000 rec-tangles with visibility properties controlled byone column of data. By using DataWindow meta-data to control the graphical properties of aDataWindow object, you can now do graphicmanipulations of hundreds of objects by simplydoing string manipulations and assignments. Youcan move the data into the DataWindow directly,or use the faster method of loading arrays andusing DataWindow.data expressions to move thedata into the DataWindow. For longer properties,such as color defined in eight characters, changethe parameters of the MID function to accountfor the size of the property. To use metadata tocontrol color, create a string column r_color. Inthe first eight characters, define the color for r_1,in columns 9–16, define the color for r_2, and soon. In the color expression of r_1, put the expres-sion:

LONG(MID(r_color,1,8))

In the color expression of r_2, put theexpression:

LONG(MID(r_color,9,8))

and for r_3:

LONG(MID(r_color,17,8))

Using these expressions to make r_1 white,r_2 black, and r_3 red, the column r_colorwould contain the data “16777215 0 255”.

Normally in a graphical presentation of

data, the number of graphic items required isunknown just as the number of rows in areport is normally unknown at runtime. Thisrequires that you generate the graphic objectson the DataWindow dynamically. In the previ-ous example, you can create 1 to n number ofrectangles at runtime in a loop and generatethe offsets required to place the correct valuesin the property expressions. For instance, inthe creation of the Minesweep DataWindow,three levels of objects are created to set up theminefield grid (see Figure 3). The first level is agrid of ellipses representing the mines. Thesecond level is the grid of computed fieldscontaining numbers that represent the num-ber of adjacent mines. The third level is a gridof computed fields that cover the cells, and theuser can mark a cell by right-clicking.

The visibility of all objects is controlledusing metadata and is set up during the cre-ation of the DataWindow objects. The follow-ing code shows the building of the mine objectlayer – note the visibility expression:

visible="0~tLONG(MID(bomb,'+STRING(cnt)+',1

))"

In Listing 9 the variable “cnt” is the subscriptof the loop and is used to point to the locationin the “bomb” string for the visibility propertyfor a particular ellipse object on a particularrow.

Manipulating MetadataNow that we have created a metadata

DataWindow, the fun starts in manipulating it.In the case of the Minesweep application, themanipulation is a simple adjustment of the vis-ibility property of different objects. When auser clicks on a cell, the first thing to do is tomake the rectangle that covers the cell not visi-ble. This is done by extracting the rectangle’svisibility property Metadata string. This stringis contained in a column called “vis”. Thenames of the rectangle objects start with theletter “t” so you must validate that you clickedon a rectangle object and determine which rec-tangle object on which row you selected. Theobject name consists of “t’” plus the sequenceof the object, for example “t1”, “t20”, “t45”.

The sequence number built into the namedetermines where in the metadata string tolook for that particular rectangle’s visibilityparameter. For rectangle “t20”, look in position20 of column “vis” to determine the rectangle’svisibility. To make the rectangle not visible, justset character 20 in the column “vis” to “0” forthe selected row. As seen in Listing 10, the vari-able “cnt” contains the reference to the loca-tion in the visibility string of the visible prop-erty for “t20”. The visibility expression for “t20”will actually switch the rectangle to not visible.

In some cases you might want to adjustother properties such as color or patterns of anobject. The same technique would be usedexcept you’d adjust the position within the col-umn “color” to correctly locate the color prop-FIGURE 4 Objects spanning multiple rows

Page 11: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

11www.POWERBUILDERJOURNAL.com PBDJ volume10 issue5

erty for the object. In the next example, if youwere changing the color of the object to redinstead of making the object invisible, the fol-lowing lines of code would change in the con-struction of the objects. Note that you mustaccount for the larger size, 8 bytes, of the colorproperty. Again, as shown in Listing 11, use thevariable “cnt” to determine where in the colorstring to find the color property for the partic-ular object.

Also make this change in the oe_lbd event toaccount for the larger size of the color proper-ty within the color column. In this case, if theuser clicks on the object and you want tochange the background color of the object tored, use the following code:

…..//Extract the visibility metadata

ls_color = this.object.color[row]

// Set to not visible and replace the visi-

bility metadata

this.object.color[row] =

REPLACE(ls_color,(ll_seq * 8) - 7,8,'

255')

…..

In more sophisticated applications, you’llhave a different number of objects on each rowon the DataWindow, in this case, the object is arectangle. The number of rectangles created isdetermined by which row on the DataWindowrequires the largest number of rectangles. Forinstance, one row might require that 10 rectan-gles be visible while several rows might notrequire any. The first thought is that every rowmust have metadata to control 10 rectangles.However, this is not required, because you onlyneed data for the rectangles actually displayedfor the row. In this case, the row with 10 rectan-gles would have a column controlling visibilitycalled “vis” that contains the following string“1111111111”, with each rectangle’s visibilitybeing controlled by a single character in thestring. On rows with no rectangles visible, youdon’t need to populate the vis column with all0s (“0000000000”); rather you can just have anempty string in column vis. Since the expres-sion could not be evaluated, the default value 0is used in the visible property expression:

(visible="0~tLONG(MID(vis,'+STRING(cnt)+

',1))")

and the rectangle is not shown for that row.This behavior makes it easier to maintain a

DataWindow with a varied number of objectsdrawn on each row. To remove an object from arow, determine its sequence number from thename of the object, and then remove the meta-data for that object. In this case, you’re remov-ing the metadata for the color of rectangle “t2”in the oe_lbd event:

ll_seq = 2

…..

ls_color = ‘ 016777215 255 0’//

black white red black

dw_planner.object.color[row] =

REPLACE(ls_color,(ll_seq * 8) - 7,8,'')

ls_color = ‘ 016777215 0’// black

white black

…..

Do this same substitution for all propertiesused, such as width, height, x, y, pattern, and vis-ibility to remove the reference to properties forobject “t2”. After removing references to theobjects properties, make sure that the number ofobjects rendered equal the number of objectsneeded. This means that if the maximum num-ber of object required of any row is 9 and youhave 10 objects rendered, destroy the highestorder object, in this case rectangle “t10” shouldbe destroyed because it doesn’t reference anymetadata on any row.

To add a new rectangle to a row, simplyappend the new values to the end of the prop-erty value. To add a new green rectangle to arow, do the same extraction of the color valueand append the color value for green.

ll_seq = 2

…..

ls_color = ‘ 016777215 0’// black

white black

dw_planner.object.color[row] = ls_color+’

65280’

ls_color = ‘ 016777215 0 65280’//

black white black green

…..

Do this same appending of data for all prop-erties used, such as width, height, x, y, pattern,and visibility.

If you add properties for an object that does-n’t exist yet, such as in the previous examplewhere there were 10 objects and you add prop-erties for the eleventh, you simply create a newobject, in this case rectangle t11 (see Listing 12).

The new object, t11, will now point to the cor-rect position in the metadata for its x, y, width,

hatch, color, visibility, and background color.

Assigning Negative Values to SomeDataWindow Object Properties

You’re allowed to assign negative numbersto property expressions of DataWindowobjects. At first this doesn’t seem too useful,but when using row-based objects in a graphi-cal format, there might be instances in whichyou only want to display a portion of aDataWindow object in a row or you might wantan object to appear as if it exists between tworows. Figure 4 demonstrates how an object, inthis case the yellow rectangles, can appear toexists on more than one row.

Displaying a Row-Based ObjectAcross Multiple Rows

The concept of row-based objects, alongwith metadata, is used on the appointmentobject seen in Figure 5 in which appointmentsare displayed and a single detail band–basedobject appears to “float” over several rows.

Here the DataWindow object type beingmanipulated is detail band computed objects thatcontain the descriptions of the appointments.What is actually happening is that each objectexists on every row; however, the y property foreach object is different for each row. The y proper-ty is calculated in a computed expression soalthough an object exists on every row, the objectappears to exists only once because an expressionin the object’s y property converts the row-based yproperty of the object into a y property associatedwith the DataWindow, not the row. The primarypurpose of this technique is to display objectsover multiple rows of a DataWindow that arescrollable in the vertical and horizontal directions.

ConclusionI hope that this chapter has broadened your

views about what kind of graphical user inter-faces the DataWindow is capable of. Althoughthe DataWindow was designed to present andinteract with data primarily as a text-based for-mat, many features exist that can be takenadvantage of to create the type of rich graphi-cal interfaces that were presented in this arti-cle. There’s more to the DataWindow than rowsand columns, and by taking advantage of thecapabilities of the DataWindow, you can createsome interesting interactive graphical inter-faces for your programs. Although several busi-ness uses of the metadata DataWindow con-cept were displayed, I hope this article inspiresusers to come up with many more. ▼

AUTHOR BIOBuck Woolley is a software developer and consultant with eight years ofexperience using PowerBuilder in a variety of industries. He is an avidpromoter of PowerBuilder and has written articles for PowerBuilderDeveloper’s Journal. His company, dw-eXtreme, develops and sellsadvanced graphical user interface objects using the PowerBuilderDataWindow.

[email protected]

FIGURE 5 A metadata DataWindow expanded to show metadata

Page 12: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

12 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

BLOBs As a Window intoAlternative Types of Data

It sounds a little like an episode of the“Twilight Zone.” I say that DataWindows can beused to examine alternate types of databecause BLOB manipulation doesn’t limit us tocommon data such as bitmaps or sounds. Wecan use the inherent raw data manipulationcharacteristics of a BLOB to get direct access todata without using external operations such asOCXs and DLLs. It’s possible to build libraries ofuser objects whose sole purpose is to extractand manipulate data from formats not nativelysupported by PowerBuilder. In creating theselibraries, we gain insights into the structure ofthese “data sources” as well as eliminate ourreliance on third-party objects to access them.

When investigating how data is stored in afile, you can check a myriad of sources. Manycompanies share information about their fileformats, and you can directly search the Webor a company’s site to gain access to the fileformatting information. The BLOB data type is

the key between reading in a file as raw dataand translating it to usable data. If you do a lit-tle digging, you can usually come up with apretty reasonable definition for a file structureyou’re interested in. One such example is theinterrogation and exploitation of data from aPalm OS–based PDA. With a little digging onthe Palm Web site, I discovered documentationthat showed the structure of the Palm databasefiles in great detail. Using this information, Iconstructed methods that allowed me toextract Palm data to a DataWindow and backagain.

Identify the Type of File You Wish to Interrogate

This one speaks for itself, but it’s much easi-er when attempting to create a data interroga-tor using BLOBs if you have a known quantityto deal with. For instance, in the Palm example,I created a database with certain identifiablevalues such as obscure column names anddata for each. This way, when I’m interrogatingthe data byte by byte, the values will stand out.This gives me more clues as to the true struc-ture of the file. Even though you might have apublished map of the file structure, you cannever rely 100% on the documents. Sometimesthe documentation is a little behind thereleased product. I know you always keep yoursystems documentation current with all last-minute data changes, right?

Find a Way to Logically Split the Data

Take some time to develop a strategy forbreaking the data down into logical parts.Again referencing the Palm example, break thedata into two logical chunks to start: the data-base header and the database records. From

there, take the simplest component, in thiscase the header data, and split it off of theBLOB using the BLOBMID function, as in:

L_blob_header = blobMid(tot_b,1,79)

This will chunk the entire header to thel_blob_header variable for the first 79 bytes,representing the header space of aPDAToolBox database file. Now, I usually like tosee the data, so create an externalDataWindow to hold the byte number, thebyte, and the character representation of thebyte to get a better understanding of how thedata is stored (see Figure 1).

See how a quick conversion of the datamakes it readable. This is an advisable processwhen you’re writing code to separate a BLOBinto a more usable form. It provides an oppor-tunity to see if there are any undocumentedfeatures or markers stored within the file thatyou may have to deal with. Also note that whendealing with a BLOB directly, you may have anumber of unprintable characters as well asknown items (like numbers) being stored in aform that is not readily identifiable. In the cur-rent example of dealing with data from a Palmdevice, keep in mind that numeric data isstored as “Big Endian” (most significant bytefirst); this is different from how the PC handlesdata, which is “Little Endian” (least significantbyte first). No, I didn’t make this up; it comesfrom Gulliver’s Travels and the dispute overwhich end of a soft-boiled egg to eat from (thebig end or the little end). There have beenmany debates over the merits of each method,but for our purposes, it’s more important torealize that data is not always stored the waywe expect.

Splitting the data comes from a series of

WRITTEN BY JOE SLAWSKY

F E A T U R E

They are as basic as it gets. They are theone way we can look at data withoutrestriction, using our own rules to definetheir existence, their transformation, and

their value; they are the molding clay of data.We call them BLOBs. Once we know thestructure of a file or any data, we can use aBLOB to mimic or manipulate it and, insome cases, create new files from scratch.What are BLOBs? Why should you care? Andwhat can you use them for? Quite simply,BLOBs are how we handle data in a rawform, sometimes without any in-depthknowledge of their structure, just the knowledge that they exist.

Page 13: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

13PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

BLOBMID statements that allow us to surgical-ly extract portions of the BLOB into manage-able pieces of information without changingits structure. Next, for this example, we canconcentrate on the record structure of a PalmPDATOOLBOX database or PDB. For moreinformation on this process, along with adetailed example of transferring BLOB databetween a Palm and a DataWindow, downloadPower PDA (PB Link) from my Web site,www.planetdx.com; it’s free and contains auser object that breaks down the Palm.PDB filesection by section into two DataWindows: onerepresenting the header information and theother representing the record-by-record datafrom the Palm.

Time to Pay the PiperBLOB manipulation, while impressive at a

basic level, comes at a price. For example, tryto read a BLOB from one end to another, onebit at a time using the BLOBMID function.Let’s take the following code snippet thatcomes almost directly out of the PowerBuilderHelp File (the FileRead PowerScriptfunction)with just a couple of modifications:

<Perform FILEREAD here>

Blob tot_b, blob_byte

For ll_byte = 1 to len(tot_b)

blob_byte = BlobMid(tot_b,ll_byte,1)

Next

We are reading in a file named blob1.bmp(but you could use any file that’s not currentlyin use) that comes in at an unimpressive

1.1MB (plus or minus) (see Figure 2). It reads into the local BLOB variable in less than one sec-ond. On my P4 2.4GHz, performing the BLOB-MID to read each byte individually takes over awhopping two hours at about 141.5 bytes/sec-ond to process! Note: The graph on the right inFigure 2 shows bytes/second processed overtime.

I added a checkbox to suspend the progressreport to the screen to lessen the impact of theGUI on the process. Your test times may be dif-ferent based on processor loading and removalof the progress display, but you get the idea.BLOB manipulation in PowerBuilder is notfast. Therein lies our problem. Although theBLOB has many uses, processing the BLOBtakes up enormous amounts of CPU time. Butslow or not, using BLOB manipulation givesyou a way of interrogating data like no othermethod. We can control the amount of CPUtime by carefully examining the data structuresthat we are attempting to extract and usingthat to our advantage. Many times we won’tneed to process the BLOB byte by byte, but wecan extract chunks of data in logical units(records and headers) in order to speed pro-cessing. Also keep in mind that if you know acertain chunk of data contains a string; forexample, your BLOBMID is taking a larger por-tion of the BLOB at a time, and your overallBLOB processing speed will increase.

BLOBs as a DataWindow RepositoryBLOBs not only hold raw data that we might

wish to dissect byte by byte, but can hold largevariable amounts of character-based data thatexceeds the boundaries of some databases’varchar storage. Consider the BLOB as a repos-itory for data that can be rendered at a localworkstation such as DataWindows. While youwouldn’t put all your DataWindows in a BLOBtable, you might consider using the BLOB tablefor storing temporary or volatile reports withinyour system. A good strategy for leveragingBLOBs within your system is to consider anexample of creating a generic reporting systemthat uses data retrieved from BLOBs to create areport on a local user’s PC. The advantage of

using this method is an increase in overall pro-ductivity through a faster turnaround ofreport-based information to your end users.

Many of us have had last-minute requestsfrom users to provide data in a usable form,but the time required to coach a user throughcreating the report using a reporting system(e.g., InfoMaker or other third-party reportingtools) will take longer than just creating aDataWindow yourself. Also take into accountthat this report may need to be run by morethan just the person you are talking to. Howwill you distribute the report? Does a reportjustify a new software release?

Using BLOBs, you can add the report toall/some users without the expense of redis-tributing the core application. Consider thefollowing table’s create statement:

CREATE TABLE "dba"."reports"

("report_id" bigint NOT NULL DEFAULT

autoincrement,

"report_name" char(50) DEFAULT NULL,

"report_blob" long binary DEFAULT NULL ,

PRIMARY KEY ("report_id")) ;

We are creating a table with three columns:a unique report ID, a column for entering areport name, and a BLOB (binary long) col-umn for storing the DataWindow. We create asimple interface for uploading the reports tothe database.

This is a relatively simple DataWindow toBLOB interface (see Figure 3). We start byselecting a .PBL that contains theDataWindow(s) we wish to extract and store asBLOBs. From this .PBL, we extract a list ofDataWindows using the Library Directorycommand:

….

ls_reports = LibraryDirectory (

docname,DirDataWindow! )

dw_datawindows.ImportString(ls_reports )

….

This extracts the DataWindow informationfrom the .PBL and imports the list into the

FIGURE 1 A look at the BLOB data

FIGURE 2 Reading a 1.19 MB file processing a BLOBMID byte by byte

Page 14: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

14 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

external DataWindow for further processing.Coding the double-click event of the firstDataWindow allows us to generate both theDataWindow syntax into a multiline edit and avisual representation (preview) of theDataWindow using:

….

mle_syntax.text =

LibraryExport(st_pbl.text,

this.GetItemString(row,'name'),

ExportDataWindow! )

dw_visual.Create(mle_syntax.text,

error_create)

….

Furthermore, we use this same window tosave the text from the multiline edit to thedatabase as a BLOB using:

lb_report = Blob(mle_syntax.text)

UPDATEBLOB REPORTS SET "REPORT_BLOB" =

:lb_report

WHERE "REPORT_ID" = :ll_REPORT_ID

USING SQLCA;

Commit;

Now you have your DataWindow syntaxsaved to the database intact and as a BLOB. Thenext step is rendering the DataWindow fromthe database BLOB. Again no great feat ofmagic here; you’re just leveraging the resourcesat your disposal in order to give the users whatthey want: a completed report without makingthem wait for a software release. The followingwindow consists of two DataWindows. The firstlists the report IDs and names from the reportsdatabase (see Figure 4).

Upon double-clicking the report name:

l_report_id =

This.GetItemNumber(row,'report_id')

SELECTBLOB "REPORT_BLOB"

INTO :lb_report

FROM "REPORTS"

WHERE "REPORT_id" = :ll_report_id

USING SQLCA;

li_ret =

dw_output.Create(String(lb_report),

ls_error)

dw_output.Settransobject(SQLCA)

dw_output.retrieve()

the code retrieves the DataWindow syntax thatwas saved as a BLOB, and then uses the CRE-ATE statement to render the DataWindow. Inthe last step, the DataWindow is retrieved anddisplayed to the user.

If you were to have a window similar to thisin your application, you could provideenhanced reports with shorter turnaroundtimes, and even be able to refresh the numberof reports available without the user evenneeding to log out and back in to an applica-tion. Also, considering the power of theDataWindow, you could perform more com-plex data gathering by using a stored proce-dure as the data source. It’s also possible tohave a DataWindow with linked retrieval argu-ments stored in your database. The key to pro-ductivity is the ability to store yourDataWindow code as a BLOB and regenerate iton the fly. This method is similar to methodsemployed when using EAServer, more specifi-cally the GetFullState statement; however, weare not transmitting data, only theDataWindow that will be performing theretrieve.

GetFullstate and SetFullState are BLOBmanipulation items of a different perspective.They are used to create and decode BLOBs thatcontain not only the structure of theDataWindow, but the data as well. Primarilyused in distributed applications, these func-tions provide yet another useful BLOB manip-ulation method for solving real-world prob-lems.

Normally, you would find the SetFullStatefunction in an EAServer type of environment,where data retrieval is being performed onEAServer (presumably closer to the databaseserver than the end user is), transformed into a

BLOB by SetFullState, and transmitted back tothe client workstation intact. This BLOB con-tains the DataWindow format, the data, andthe update states contained within. This canbe especially useful when creating a distrib-uted application, where the user may onlyhave access to data via e-mail or some otherdisjointed method.

Picture sending a user a list of customers tocall and update. The user can have a BLOB cre-ated via GetFullState e-mailed to them, andopen the BLOB in their local application usingSetFullState. From this point, they can performlimited editing against the DataWindow, ande-mail the corrected DataWindow back to thesender for processing. The sender will now beopening a DataWindow that shows the remoteusers’ changes, as well as having the statusesassociated with the data contained within.Now PowerBuilder can update this Data-Window against the database. This is a limited-use scenario, because many variables comeinto play when dealing with a “disconnected”user community; however, BLOBs once againprovide an effective alternative in your toolboxof techniques.

ConclusionThe BLOB is an often underutilized but

effective tool for both data manipulation anddata representation. Its unique attribute of notbeing bound by conventional structures allowsthe developer the freedom to use it either as acontainer for large amounts of their data, or apetri dish within which low-level data manipu-lation can occur. ▼

AUTHOR BIOJoseph Slawsky is a technical specialist for United Parcel Service andspecializes in PowerBuilder-based projects. A graduate of the NewJersey Institute of Technology, Joe has been using PowerBuilder sinceversion 3.0a and continues to do so with version 9.0. He has beenworking as a full time programmer since 1989 and has enjoyed positions in some of the largest corporations in America as aPowerBuilder applications developer.

FIGURE 3 Simple DataWindow to BLOB interface FIGURE 4 Example of a simplified end user report interface

[email protected]

Page 15: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

15PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

Sybase, Incwww.sybase.com/powerbuilder

Page 16: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

16 PBDJ volume10 issue5 www.POWERBUILDERJOURNAL.com

WRITTEN BYWENDELL RIOS

P B T E C H N I Q U E S

Boosting Performance on DataWindowRetrieval in n-Tier Environments

Causes of bad performance

When I started using distributed DataWindows, the slow performancefrightened me, usually when the middle server and the client were in separate computers.

At that time I was using a PIII 500desktop computer, and a PIII 800 data-base server over a 10MB network.Although it’s not the top-of-the-linehardware environment, it’s still the bestsome customers can get.

Back then I had resolved to make afew sets of tests, trying to discover thereasons for performance differencesbetween traditional client/server andthe n-tier application, and possibleworkarounds. Despite different headers,control flags, and calling syntaxesbetween n-tier and pure client/servermodels, obviously the main difference isthe amount of data that’s carried fromone point to another.

In a typical client/server environment,the Retrieve DataWindow function getsonly the data. In an n-tier environment,the common primitive for end-to-endDataWindow communication is Get-FullState. Different from Retrieve, Get-FullState doesn’t carry only data. Thewhole DataWindow syntax and statusflags for buffers are transmitted in theBLOB, despite having to also maintainthe DataWindow object in the client. Ofcourse, it’s not a secret as it’s document-ed in the PowerBuilder manual.

But is it always necessary? Are thereother options? I believe so. It’s interest-ing how some things in software devel-opment are so close but we just can’t seethem. PowerBuilder provides a way totransmit data in n-tier environments,and initially I only focused on that way.

Reinventing the WheelWhen I finally figured out that

GetFullState is not a silver bullet, I realizedI should implement my own DataWindowcommunication primitive, as it wouldperform faster in most situations.

It was very easy, since PowerBuilder

provides mechanisms to do this. Say Ihave an object named n_cst_remote_dwin the server that’s a generic interface forretrieving the DataWindow’s data. Allthe DataWindow objects for my applica-tion are distributed with it, and it has ageneric method of_retrieve to do this.

The method declaration is:

n_cst_remote_dw

of_retrieve(string as_connectioninfo,

string as_dataobject, string

as_args[20], string as_types[20], REF

ablb_data, REF al_sqldbcode, REF

as_sqlsyntax, REF as_sqlerrtext)

Listing 1 shows how this method isusually written. The suggested improve-ment is related to the last lines of code.Instead of using GetFullState to fill a BLOBwith data, buffers, and a presentation, weshould just get the data, replacing:

ll_return =

lds.GetFullState(ablb_data)

with

ablb_data = Blob(lds.Describe (

'DataWindow.Syntax.Data' )).

Adjusting the ClientObviously the client must also be pre-

pared for this approach. In this field wehave several choices: • Maintain DataWindow objects in the

client and server libraries, neverreplacing the client version with theserver one. It provides the maximumperformance, but loses some bits ofmaintainability since we had todeploy DataWindow object changesto all desktop clients. However, syn-chronizing and network file serverdeployment could be used to handle

it in most environments.• Maintain DataWindow objects only in

the server and get syntax once, in thewindow Open event. This doesn’t workquickly but it’s the easiest to maintain.The user has to wait longer before thewindow is opened, but subsequentretrievals will be fast, since syntax isn’tcarried again and again. A samplemethod for returning only Data-Window syntax from the server is con-sidered here.

Declaration:

n_cst_remote_dw

string of_getsyntax(string

as_dataobject)

Code:

Datastore lds

lds = CREATE Datastore

lds.DataObject = as_dataobject

as_syntax = lds.Describe (

'Datawindow.Syntax.' )

itrs_Server.SetComplete()

RETURN lds

Returned syntax should be used in theclient to create the DataWindow object:

Declaration:

u_dw /* or another datawindow class

inherited object */

of_getsyntax(string as_dataobject)

The code is shown in Listing 2.

• Maintain DataWindow objects in theserver and the client, and get syntax

Page 17: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

17PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

once in a kind of Postopen event. It’ssimilar to the previous alternative,with a simple difference: the user willbe more comfortable waiting to act inthe window, instead of waiting for it tobe opened. Since the DataWindowobject is in the client, although notnecessarily the latest version, the userwill see something, not just a whiteframe in the window. Regardless of your selection, to use

this performance improvement work-around we must have DataWindowsyntax in the client before applyingthe data retrieved from the server. Acode sample of a method that

remotely retrieves data and fits it in aclient DataWindow control follows:

Declaration:

u_dw /* or another datawindow class

inherited object */

of_retrieve(string as_connectioninfo,

any as_args[20])

The code is shown in Listing 3.

To Do NextAlthough this is a simple and effective

workaround – depending on the syntax sizeand the number of data rows returned, we

could get up to a 90% reduction in theBLOB size – it’s not applicable in every case.GetFullState is a more complex functionthat addresses all DataWindow features.

Therefore, it’s imperative that we havesome “ifs” in both of_retrieve methods(client and server) that should seek par-ticular DataWindow object characteris-tics and still use GetFullState. These fea-tures will work just through GetFullState: • Composite DataWindow • Subreports• Using retrieval arguments in comput-

ed fields or in presentations ▼

AUTHOR BIOWendell Rios is CIO ofTecnoTRENDS, a 10-year-old PowerBuilder-basedsoftware [email protected]

/* Assumed itr_transaction is a previous instance ofTransactionServer object */

Any aa_args[20]Datastore lds

/* connect to database */

SQLCA.DBMS = ‘ODBC’SQLCA.DbParm = as_connectioninfo

CONNECT USING SQLCA;

/* check for errors */

/* convert arguments to any. This function code is notprovide here*/of_converttoany( as_args, as_types, aa_args)

lds = CREATE Datastore lds.Dataobject = as_dataobjectll_return = lds.SetTransObject(SQLCA)

/* check for errors */

/* retrieve data */ll_return = lds.Retrieve ( aa_args[1], aa_args[2],aa_args[3], aa_args[4], &aa_args[5], aa_args[6], aa_args[7], aa_args[8], aa_args[9],aa_args[10], & aa_args[11], aa_args[12], aa_args[13], aa_args[14],

aa_args[15], & aa_args[16], aa_args[17], aa_args[18], aa_args[19],

aa_args[20] )

/* check for errors */ll_return = lds.GetFullState(ablb_data)

/* Complete Transaction*/itr_server.SetComplete()

RETURN

n_cst_remote_dw lnv_remote_dw

/* Assumed icn_connection is a Connection object connectedto a Jaguar Server */ /* It will work in MTS/COM+ also, making appropriatechanges */

n_cst_remote_dw lnv_rdw string ls_syntax

icn_connection.CreateInstance( lnv_rdw,‘myapp/n_cst_remote_dw’)

/* Check for errors */

/* Get syntax from server. Dataobject must be initialized*/ls_syntax = lnv_rdw.of_GetSyntax(THIS.DataObject)

/* Create the dataobject */THIS.Create(ls_syntax)

/* Assumed icn_connection is a Connection object connectedto a Jaguar Server */ /* It will work in MTS/COM+ also, making appropriatechanges */

n_cst_remote_dw lnv_rdwstring ls_args[20]string ls_types[20]string ls_syntax string ls_error

icn_connection.CreateInstance( lnv_rdw,‘myapp/n_cst_remote_dw’)

/* check for errors */

/* convert any arguments to string. This function code isnot provided here*/of_converttostring( aa_args, ls_args, ls_types,)

/* retrieve middleware data ll_return = lnv_rdw.of_retrieve(as_connectioninfo,this.dataobject, ls_a rgs[20], ls_types[20], REF ablb_data, REF al_sqldb-code, REF as_sqlsyntax, REF as_sqlerrtext)

/* check for errors */

/* combine current syntax and retrieved data */ ls_syntax = ids_requestor.Describe ( 'DataWindow.Syntax' )

THIS.Create (ls_syntax + String(ablb_data), ls_error)

/* check for errors */

RETURN

Listing 3:

Listing 2:

Listing 1:

Page 18: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

WRITTEN BYBOB HENDRY

18 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

B O O K E X C E R P T

Dynamic SQLSupporting SQL inside or outside the DataWindow

From the beginning, the DataWindow has been a powerful client/servercontrol. What has set it apart from competing products is its ability tocreate SQL.

In reality, the DataWindow is a SQL-gen-erating machine. By keeping track of rowand column statuses, the DataWindow isable to generate the correct SQL statementto UPDATE, DELETE, or INSERT rows intoa database. In most instances, the develop-er is oblivious to the SQL generation; allthat’s needed to unleash all this functional-ity is to issue a simple update function.However, DataWindows can take SQL onlyso far, as their use of SQL has its limitations,for example:• In certain instances, a SELECT state-

ment, DataWindow result sets, orretrieval arguments can’t be changedeasily.

• A DataWindow cannot issue DDLcommands such as CREATE, DROP,GRANT, and REVOKE.

What many PowerBuilder developersdon’t know is that SQL can be executeddynamically. The level and complexity ofdynamic SQL is determined by what youare trying to accomplish. At any rate, theuse of dynamic SQL falls into four cate-gories and follows a repeatable process.It’s especially helpful when SQL parame-ters or the column set of the statementsare unknown at compile time or mayneed to change within the runtime envi-ronment. Dynamic SQL is broken downinto four formats.• Format 1 or 2 dynamic SQL state-

ments must be used for all forms ofDDL (CREATE, GRANT, etc.).

• Format 3 or 4 dynamic SQL state-ments are handy when the SQL state-ment generates a result set.

Dynamic SQL (Format 1)If you want to issue statements that

don’t require input arguments and don’treturn a result set, use Format 1. It’s agood choice when executing DDL state-ments. Use the DDL syntax for the

Database Management System. Theseexamples will be using DDL syntax forSybase Adaptive Server Anywhere. Thesyntax of Format 1 is as follows:

EXECUTE IMMEDIATE <SQL> USING <TRANS-

ACTION OBJECT>

The SQL statement has to be a validstring, either hard coded or a string vari-able. If a string variable is used, it must bebound with a colon. The Transactionobject is optional and represents thedatabase upon which this action is per-formed. If a Transaction object is notspecified, SQLCA will be assumed. Listing1 drops a table, re-creates it, inserts a row,then grants read permission.

Note that a commit is not being per-formed here. If you leave database com-mits out of your scripts, make sure theautocommit property is set to true in thedatabase profile of the Transaction object.

Dynamic SQL (Format 2)If you need to execute a SQL state-

ment with a finite known number ofinput arguments and no result set, useDynamic SQL Format 2. This format (aswith Formats 3 and 4) uses the Power-Builder DynamicStagingArea. Basically,the DynamicStagingArea provides theinterface between the SQL statementand the Database Management System.

The DynamicStagingArea is a privatePowerBuilder data type used to storeinformation about the SQL statement.Internals of this data type are hiddenfrom the programmer. PowerBuildergave us a default DynamicStagingAreanamed SQLSA. Like the PowerBuilderdefault Transaction object SQLCA, addi-tional DynamicStagingAreas can be cre-ated programmatically. Using Format 2is a two-stage process. First theDynamicStagingArea must be prepared,

then its associated SQL statement canbe executed.

The following code prepares theDynamicStagingArea with one argu-ment, denoted by the question mark.PowerBuilder stores this SQL informa-tion while waiting for it to be executed.The next line of code fires off the stagedstatement after it passes the retrievalargument.

string ls_part = "Scanner"

prepare SQLSA FROM "delete from

inventory where partdesc = ?" USING

SQLCA;

Execute SQLSA USING :ls_part;

Dynamic SQL (Format 3)Dynamic SQL Format 3 is used to exe-

cute a SQL statement that has a resultset and a fixed number of argumentsthat are known at compile time. Thesteps are:• Declare the dynamic cursor for the

DynamicStagingArea.• Prepare the DynamicStagingArea

using the SQL statement to be execut-ed.

• Open the cursor.• Fetch the cursor into a variable list.• Close the cursor.

Listing 2 uses a cursor to read usingthis format and can dynamically fire offa result set into a variable list; althoughnot demonstrated here, stored proce-dures can be used as well. The listingreads a list of employee last names intoa ListBox.

Dynamic SQL (Format 4)This most powerful format is used

when the number of parameters and theresult set are unknown at compile time.Several steps are required to executeFormat 4 Dynamic SQL:

Page 19: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

Millionsof Linux UsersOne Magazine

SAVE 30%OFF!

REGULAR ANNUAL COVER PRICE $71.76

YOU PAY ONLY

$499912 ISSUES/YR

*OFFER SUBJECT TO CHANGE WITHOUT NOTICE

SUBSCRIBETODAY!

WWW.SYS-CON.COMOR CALL

1-888-303-5282

The World’s Leading i-Technology Publisher

Linux Business& Technology

There is no escaping the penetration of Linux into the corporate world. Traditional models are being turned

on their head as the open-for-everyone Linux bandwagon rolls forward.

Linux is an operating system that is traditionally held in the highest esteem by the hardcore or geek

developers of the world. With its roots firmly seeded in the open-source model, Linux is very much born from

the “if it’s broke, then fix it yourself” attitude.

Major corporations including IBM, Oracle, Sun, and Dell have all committed significant resources and

money to ensure their strategy for the future involves Linux. Linux has arrived at the

boardroom.

Yet until now, no title has existed that explicitly addresses this new hunger for information from the

corporate arena. Linux Business & Technology is aimed squarely at providing this group with the knowledge

and background that will allow them to make decisions to utilize the Linux operating system.

Look for all the strategic information required to better inform the community on how powerful an alternative Linux can be. Linux Business & Technology will not

feature low-level code snippets but will focus instead on the higher logistical level, providing advice on hardware, to software, through to the recruiting of trained

personnel required to successfully deploy a Linux-based solution. Each month will see a different focus, allowing a detailed analysis of all the components that

make up the greater Linux landscape.

FOR ADVERTISING INFORMATION:

CALL 201 802.3020 ORVISIT WWW.SYS-CON.COM

ALL BRAND AND PRODUCT NAMES USED ON THIS PAGE ARE TRADE NAMES, SERVICE MARKS, OR TRADEMARKS OF THEIR RESPECTIVE COMPANIES.

Regular features will include:

Advice on Linux Infrastructure Detailed Software Reviews Migration Advice Hardware Advice CEO Guest Editorials Recruiting/Certification Advice Latest News That Matters Case Studies

June 3–5...............LONDONJune 24–26 .........BERLINSeptember ..HONG KONGOctober ..........CALIFORNIA

www.sys-con.comPremieringJune 2003

at

Page 20: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

www.POWERBUILDERJOURNAL.com20 PBDJ volume10 issue5

• Prepare the cursor for the Dyna-micStagingArea.

• Prepare the DynamicStagingAreafrom the SQL statement.

• Describe the DynamicStagingAreainto the DynamicDescriptionArea.

• Open the cursor using the Dyna-micDescriptionArea.

• Execute the cursor.• Fetch the cursor into PowerBuilder

variables.• Close the cursor.

The DynamicDescriptionArea is aPowerBuilder data type. PowerBuilderuses a global variable of this type to holdinformation about the input and outputarguments used in Dynamic SQL(Format 4). When the application starts,PowerBuilder creates a global Dyna-micDescriptionArea named SQLDA.Like the DynamicStagingArea (SQLSA),additional DynamicDescriptionAreascan be created within the code if needed.

PowerBuilder provides a globalDynamicDescriptionArea named SQLDAthat you can use when you need aDynamicDescriptionArea variable. Ifnecessary, you can declare and createadditional object variables of the typeDynamicDescriptionArea. These state-ments declare and create the variable,which must be done before referring to itin a dynamic SQL statement.

If arguments are to be passed to theSQL statement, the SetDynamicParmfunction is used to fill the parameters inthe input parameter descriptor array ofthe SQLDA before executing an OPEN orEXECUTE statement (see Listing 3).

The type and value for each outputparameter in SQLDA is accessed via thefollowing functions:• GetDynamicDate()• GetDynamicDateTime()• GetDynamicNumber()• GetDynamicString()• GetDynamicTime()

Other SQL ConsiderationsThe previous examples illustrated

how SQL is supported outside theDataWindow technology. This next sec-tion will get back to the DataWindowand discuss how SQL can be dynamical-ly changed.

SQLPREVIEW EVENTImmediately before a DataWindow

attempts to execute a SQL statement,the SQLPreview event is fired. This eventis useful in several ways. First and fore-most, it allows programmers to deter-mine which SQL statement theDataWindow is planning to execute. If,

for example, the DataWindow isattempting to execute a SELECT state-ment, we may wish to modify it, perhapsadding a WHERE clause. This may beuseful in the event that our retrievalarguments cannot be defined within theDataWindow painter. For example:• If the user is a “MANAGER”, show all

records in the employee table.• If the user is an “EMPLOYEE”, show

only records where the salary is lessthan $75,000.00.

In our example, because the retrievalargument is contingent on the user, wecan’t define it at design time when we’recreating the DataWindow. Clearly, theWHERE clause must be created dynami-cally. But how? We can use the fourDynamic SQL formats discussed earlier,then “push” the results into aDataWindow. A better bet would be tomodify the DataWindow’s SQL state-ment – adding a WHERE clause justbefore it issues a SELECT statement. TheSQLPreview event is a great place to dothis. Before we add code to the event, wemust first determine what kind of SQLthe DataWindow is planning on execut-ing. This can be determined by using thefollowing enumerated data types. Theirmeanings are intuitive so I won’t elabo-rate on them:• PreviewSelect!• PreviewInsert!• PreviewDelete!• PreviewUpdate!

There are important PowerBuilderarguments that are passed to theSQLPreview Event. They are:• Request: A number identifying the

function that initiated the databaseactivity

• SQLType: A number identifying thetype of SQL statement being sent tothe database

• SQLSyntax: The SQL that is about tobe executed

• DwBuffer: A number signifying whichDataWindow buffer the data is com-ing from

• Row: The row number in theDataWindow that’s being UPDAT-ED/DELETED or INSERTED

SQLSyntax is especially helpful to us.Since it contains the current SQL to beexecuted, we can “intercept” it andchange/append as needed. When we’refinished tweaking it, we call theSetSQLPreview function. This functionpasses our SQL statement to theDataWindow, which then executes it(see Listing 4).

When a new SQL statement is appliedto a DataWindow, it overrides the onethat was defined for it in theDataWindow Painter, including anyretrieval arguments. The SetSQLPreviewfunction should never be called outsidethe SQLPreview event. In addition, itshould be used as close to the end of thescript as possible.

The SQLPreview event also has somehandy return codes:• 0 – Continue processing• 1 – Stop processing• 2 – Skip this request and go on to the

next request

If, for example, certain users were notallowed to update the database, this rulecould be enforced in the SQLPreviewevent with the following code:

If sqltype <> PreviewSelect! Then

If gs_user = "EMPLOYEE" Then

messagebox("Error","You are not

allowed to make changes!")

Return 1

End If

End If

THE TABLE.SELECT PROPERTYAnother way to modify the SQL state-

ment for a DataWindow is to modify theTABLE.SELECT property. As when the SQLis changed via the SQLPreview event,changes made to the DataWindow via theTABLE.SELECT property completely over-ride the SQL that was defined in theDataWindow Painter at design time. Whatmakes the use of TABLE.SELECT differentthan that of the SetSQLPreview function isthat changes made via TABLE.SELECT arepermanent, at least while an instance ofthe DataWindow exists. On the other hand,changes made via SetSQLPreview existonly for that specific database transaction.

Listing 5 uses Describe and Modify tosave/alter a DataWindow SQL statement.

IMPORTANT NOTE ABOUT THE DESCRIBE FUNCTION

The Describe function alwaysattempts to return a SQL SELECT state-ment. If the database is not connectedand the property’s value is a PBSELECTstatement (PBSELECT is the statement ifthe DataWindow was created in graphicmode), the Describe function will con-vert it to a SQL SELECT statement only if

This article is based on PowerBuilder 9Client/Server Development by variousauthors (ISBN 0672325004) published bySams Publishing. Also look forPowerBuilder 9 Internet and DistributedApplication Development.

Page 21: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

1)2)3)

This one-day intensive workshop is designed for developers who wish to increase the efficiency and reliability of their code development.

The day will begin by looking at the various hints and tips you can utilize at the code

level to improve the quality and reduce the number of bugs you have to contend with.

The next part will look at Apache’s Ant and how you can use this freely

available tool for your own development, irrespective of your IDE.

Last, and most important, as the old saying goes: “You can never do enough

testing.” This session will look at JUnit and show you how to start building test

harnesses for your code so you can begin your testing strategy.

>PerformanceJava is a powerful language. While it offers a rich array of tools, the fundamentals mustn’t be overlooked. Improving your code at the core layer will result in great improvements in efficiency and produce (hopefully) less bugs. We’ll look at the do’s and don’ts of programming and learn many hints and tips that will accelerate your Java coding.

>Efficiency with AntApache’s Ant is a powerful scripting tool that enables developers to define and execute routine software development tasks using the simplicity and extensibility of XML. Ant provides a comprehensive mechanism formanaging software development projects, including compilation, deployment, testing, and execution. In addition, it is compatible with any IDE or operating system.

> Reliability with JUnitA critical measure of the success of software is whether or not it executes properly. Equally important, however, is whether that software does what it was intended to do. JUnit is an open-source testing frameworkthat provides a simple way for developers to define how their software should work. JUnit then provides test runners that process your intentions and verify that your code performs as intended. The result is software that not only works, but works in the correct way.

April:NEW YORKWASHINGTON, DC

May:BOSTONTORONTO

June:ATLANTARALEIGH

Coming to you...

SaturdaySessionsWe understand the pressures of work and how difficult it can be to get time off. That is why we have designed this workshop to be held in one day and, as a specialbonus, on the weekend, so no days off from work. Your boss will be happy!

W TM T SF S

PRODUCED BY

SPONSORED BY

Alan WilliamsonJDJ Editor-in-Chief

Performance > Efficiency > Reliability

What you will receive...

✓ INTENSIVE ONE-DAY SESSION

DETAILED COURSE NOTES AND ✓ EXCLUSIVE ONLINE RESOURCES

✓ JDJ CD ARCHIVE

ONLY$295 **JDJ subscribers($395 non-subscribers)

———————————————————*GROUP DISCOUNTSAVAILABLE

To Register

www.sys-con.com/education

Call 201 802-3058

ALL BRAND AND PRODUCT NAMES USED ON THIS PAGE ARE TRADE NAMES, SERVICE MARKS, OR TRADEMARKS OF THEIR RESPECTIVE COMPANIES.

PRESENTED BY

Page 22: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

a SetTransObject function has alreadybeen executed for the DataWindowobject. If you’re using describe-lessretrieval (the StaticBind DBParm para-meter is set to 1), the SELECT propertycannot be used.

SETSQLSELECT FUNCTIONThis DataWindow function is used

to change the SQL statement of aDataWindow from within a script.PowerBuilder will validate the SQL if theDataWindow is updateable. When speci-fying a new SQL statement, the new col-umn set’s data types must match the oldones. Also, the Transaction object for theDataWindow needs to be set immediate-ly (via SetTransObject) before SetSQL-Select.

The main limitation of the Set-SQLSelect statement is that it can onlybe used for DataWindows that have aSQL SELECT data source, and there canbe no retrieval arguments defined with-in the DataWindow. A good example ofwhen to use SetSQLSelect is when smallchanges need to made to a WHEREclause. For example, if we needed to lookup all employees who lived in “MA,” and,if none existed, look up all employeeswho live in “CA”:

string ls_cur_sql

string ls_new_sql

ls_cur_sql = "SELECT * FROM employee

WHERE state = 'MA'"

ls_new_sql = "SELECT * FROM employee

WHERE state = 'CA'"

IF dw_1.Retrieve() = 0 THEN

dw_1.SetSQLSelect(ls_new_sql)

dw_1.Retrieve()

END IF

WHY TABLE.SELECT IS PREFERRED OVER SETSQLSELECT

TABLE.SELECT is generally consid-ered to have several advantages over theSetSQLSelect function:

• It’s much faster. PowerBuilder doesnot validate the statement untilretrieval.

• The data source of the DataWindowcan be changed, e.g., from SQLSELECT to stored procedures.

• TABLE.SELECT allows the use of noneor any of the arguments defined forthe DataWindow object in the SQLSelect clause. In SetSQLSelect, argu-ments that were not previouslydefined cannot be used.

In addition to the SELECT property,other important TABLE properties exist.It’s worth it to take a peek.

DYNAMIC DATAWINDOWSIf you need to get “very” dynamic, a

DataWindow can be created based sole-ly on a SQL statement. Although theSQL statement may be hard codedwithin a script, usually the SQL is builtin a more dynamic fashion. A commonusage is when the user is allowed to cre-ate reports, based on dragging anddropping columns – like a customreport generator. If you’re really brave,you can allow the user to type in a SQLstatement, then create a DataWindowbased on it. Dynamic DataWindow canbe one of the following presentationstyles:• (Default) Tabular• Grid• Form (for freeform)• Graph• Group• Label• N-up

Listing 6 will read a SQL statemententered by the user (am I brave). Thecode will then create the DataWindowobject syntax. The DataWindow objectwill then be created and associated to aDataWindow control. Three assump-tions are being made:1. The DataWindow control must exist

at runtime. When we talk about

dynamic DataWindows, we’re talk-ing about the object and not thecontrol.

2. The dynamic DataWindow objectthat we create cannot be saved. Itsscope is limited to the instance of thewindow.

3. The SQL is valid – in this example weare assuming that the user-enteredSQL is well formed and correct.

Listing 6 uses two important functions.The following are the SyntaxFromSQLand Create functions, and the argumentsthey accept.

SyntaxFromSQL• A string representing a valid SQL

statement• The presentation style of the dynamic

DataWindow• A string passed by reference that will

contain any error messages in case thefunction fails

Create• A string containing the syntax of the

dynamic DataWindow• A string passed by reference that will

contain any error messages in case thefunction fails

If all goes well, the DataWindowobject will be created and the user willsee it as the contents on theDataWindow control. At this point youcan use Describe and Modify as youwould on any other DataWindow.

Final ThoughtsThat’s the long and short of it. As you

can see, the SQL that’s generated uponDataWindow creation is just the tip ofthe iceberg. Indeed, to use SQL, a Data-Window need not be used at all. Whenusing the SQL in the DataWindow, youshould now know that this “static” SQL ismore dynamic than you thought. ▼

AUTHOR BIOBob Hendry is a

PowerBuilder instructorfor Envision Software

Systems and a frequentspeaker at national

and internationalPowerBuilder

conferences. He specializes in PFC

development and haswritten two books onthe subject, includingProgramming with

the PFC 6.0. [email protected]

String lsSQL

lsSQL = "drop table inventory;"Execute Immediate :lsSQL Using SQLCA;

lsSQL = "create table inventory(partnumber integer not nullprimary key," + &

"partdesc char(20)," + &"datecount date);"

Execute Immediate :lsSQL Using SQLCA;

lsSQL = "insert into inventory values(100,'Scanner',null);"Execute Immediate :lsSQL Using SQLCA;

lsSQL = "grant select on inventory to public;"Execute Immediate :lsSQL Using SQLCA;

string ls_resultstring ls_state = "MA"string sqlstatementDECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;sqlstatement = "SELECT emp_lname FROM employee WHEREstate = ?"PREPARE SQLSA FROM :sqlstatement ;OPEN DYNAMIC my_cursor using :ls_state;FETCH my_cursor INTO :ls_result;lb_1.AddItem(ls_result)Do While SQLCA.SQLCode = 0 FETCH my_cursor INTO :ls_result;

Listing 2:

Listing 1:

www.POWERBUILDERJOURNAL.com22 PBDJ volume10 issue5

Page 23: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

23www.POWERBUILDERJOURNAL.com PBDJ volume10 issue5

LEARN WEB SERVICES. GET A NEW JOB !

Get Up to Speed with the Fourth Wave in Software Development

Only $69.99 for 1 year (12 issues)*

* Newsstand price $83.88 for 1 yearSubscribe online atwww.wsj2.com or call 888 303-5252*Offer subject to change without notice

SYS-CON Media, the world's leading i-technology publisher ofdeveloper magazines and journals, brings you the most

comprehensive coverage of Web services.

SUBSCRIBE TODAY TO THEWORLD’S LEADINGWEB SERVICES RESOURCE

• Real-World Web Services: XML’s Killer App!

• How to Use SOAP in the Enterprise

• Demystifying ebXML for success

• Authentication, Authorization, and Auditing

• BPM - Business Process Management

• Latest Information on Evolving Standards

• Vital technology insights from the nation’s leading Technologists

• Industry Case Studies and Success Stories

• Making the Most of .NET

• Web Services Security

• How to Develop and Market Your Web Services

• EAI and Application Integration Tips

• The Marketplace: Tools, Engines, and Servers

• Integrating XML in a Web Services Environment

• Wireless: Enable Your WAP Projects and BuildWireless Applications with Web Services!

• Real-World UDDI

• Swing-Compliant Web Services

• and much, much more!

The Best.NETCoverage Guaranteed!

lb_1.AddItem(ls_result)Loop

string ls_varstring ls_sqlint li_var

ls_sql = "SELECT emp_lname FROM employee"

PREPARE sqlsa FROM :ls_sql ;DESCRIBE sqlsa INTO sqlda ;DECLARE my_cursor DYNAMIC CURSOR FOR sqlsa ;OPEN DYNAMIC my_cursor USING DESCRIPTOR sqlda ;FETCH my_cursor USING DESCRIPTOR sqlda ;

CHOOSE CASE sqlda.OutParmType[1]

CASE TypeString!ls_var = GetDynamicString(sqlda, 1)

CASE TypeInteger!li_var = GetDynamicNumber(sqlda, 1)

END CHOOSE

CLOSE my_cursor ;

//gs_user is a global variablestring ls_current_sqlstring ls_where

If sqltype = PreviewSelect! Thenls_current_sql = sqlsyntaxIf gs_user = "EMPLOYEE" Thenls_where = " WHERE salary < 75000"ls_current_sql = ls_current_sql + ls_whereThis.SetSQLPreview(ls_current_sql)

End If End If

string ls_orig_sqlstring ls_new_sqlstring ls_rcstring ls_mod_string

ls_orig_sql = dw_1.Describe("datawindow.table.select")ls_new_sql = "select * from employee where state = 'CA'"ls_mod_string = "datawindow.table.select = '" +ls_new_sql + "'"ls_rc = dw_1.Modify(ls_mod_string)dw_1.SetTRansObject(SQLCA)dw_1.Retrieve()

string ls_errorsstring ls_sqlstring ls_presentation_strstring ls_dwsyntax_str

ls_sql = mle_1.Textls_presentation_str= "style(type=grid)"

ls_dwsyntax_str = SQLCA.SyntaxFromSQL(ls_sql,ls_presenta-tion_str,ls_errors)IF Len(ls_errors) > 0 THEN

MessageBox("Warning","Could not create DW syntax " +ls_errors)HALT CLOSE

END IF

dw_1.Create(ls_dwsyntax_str,ls_errors)

IF Len(ls_errors) > 0 THENMessageBox("Warning","Could not create DW" +

ls_errors)HALT CLOSE

END IF

Listing 6:

Listing 5:

Listing 4:

Listing 3:

Page 24: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

WRITTEN BYBERNDT HAMBOECK

M E S S A G E S

The PowerBuilder 9 IDEOr comment what you write!

Okay, I know you’re already familiar with the PowerBuilder IDE.Yes, you’reone of those people who knows where to find the system tree and how toturn it off.

And you already know what the clipwindow is for (if you don’t, look at it, it’s apretty cool feature – we used it in our 7-year-old application to document whomade changes or bug fixes). No, that’s notwhat I’ll be talking about today. I want todiscuss the internals of the IDE, as it hasimproved a lot since PowerBuilder 7.

The IdeaWhy should we take a closer look at the

IDE? It works great, we like it, so every-thing’s okay. I agree, but I miss having anautocomment tool, a tool that pastes aheader like the following sample:

// Object : axisclient

// Method : open (event)

// Author : B. Hamboeck

// Date : 3/31/2003

//

// Argument(s): string commandline

// Returns: (none)

//

//

//***********************************

*************************

// Modification history:

// Date Version Author

Comment

This header displays a lot of informa-tion that we could get directly from theIDE; Figure 1 displays the script painter.

There are three dropdownlistboxes.1. The first one is used to select objects,

functions, or declares. In Figure 1 it dis-plays the object name (axisclient). InFigure 2 it’s within a function [we knowit’s within an event if we see the objectname and not the string “(Functions)”].

2. The second one displays either theevent name (see Figure 1) or the func-tion name (see Figure 2), and the argu-

ments with the correspondingdatatype; don’t forget the return value.

3. The third one displays the name ofthe parent, if the object is inherited.

There’s a lot of information thatshould be described within an objectheader. We’ll have to do a lot of typing ifwe don’t have a tool like the commenter.The commenter would read all thesevalues and place a header (the defaultvalues should be stored within an inifile) that contains all the informationwithin our script.

Windows, Messages, and Handles

To get information, we need to read thevalues from the dropdownlistboxes, buthow? As PowerBuilder developers wealready know that the Windows operatingsystem is based heavily on messages. Forexample, when a user closes a window,the operating system sends the window aWM_CLOSE message. When the usertypes a key, the window with the focusreceives a WM_CHAR message, and so on.

Messages can also be sent to a windowor a control to affect its appearance orbehavior or to retrieve the information itcontains. For example, you can send theWM_SETTEXT message to most windowsand controls to assign a string to theircontents, and you can send theWM_GETTEXT message to read their cur-rent contents. Keep in mind that throughthese messages we can set or read thecaption of a top-level window or set or

read the text property of an edit control ordropdownlistboxes. This is exactly howwe would like to get the information that’sneeded by commenter.

We know that PowerBuilder greatlysimplifies the programming of Windowsapplications because it automaticallytranslates most of these messages intoproperties, methods, and events. Insteadof using WM_SETTEXT and WM_GET-TEXT messages, we as PowerBuilderdevelopers can reason in terms of titleand text properties. We don’t have toworry about trapping WM_CLOSE mes-sages sent to a window, because thePowerBuilder runtime automaticallytranslates them into the desired closeevent. More generally, control messagesmap to properties and methods, where-as notification messages map to events.

PowerBuilder helps us a lot here, butsometimes we don’t have an eventmapped to the object. For example, theWM_MOUSEMOVE messages don’t fireper default on any PowerBuilder object.So what now? Well, try to create anevent, give it the name ue_mousemove,and map the pbm_mousemove event toit. If it’s not there by default, it doesn’tmean we can’t do it in PowerBuilder.

To sum it up, we can say that windowssend messages to objects and theobjects react to messages. This raisestwo questions: How do we send mes-sages and where should we send them?

The main API function that we can useto send a message to a form or a control isSendMessage, whose declare statement is:

www.POWERBUILDERJOURNAL.comPBDJ volume10 issue524

FIGURE 1 The script painter

Page 25: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

www.POWERBUILDERJOURNAL.com 25PBDJ volume10 issue5

Function Long SendMessageA(Long hwnd,

Long wMsg, Long wParam, Ref String

lParam) Library "user32"

The hWnd argument is the handle ofthe window to which you’re sending themessage, wMsg is the message number(usually expressed as a symbolic con-stant that you can find in the header filestored on your hard disc in the folder%Sybase%\Shared\PowerBuilder\cgen\h\nt\winuser.h), and the meanings ofthe wParam and lParam values dependon the particular message we’re sending.

This should answer our two questions.Well, not really. We know how to send amessage, but we still don’t know where,or to which object and hWnd to send amessage. Fortunately, there’s a relativelysimple way to determine what’s going onwith a program. We need spyxx.exe (alsoknown as Spy++). In my opinion (a devel-oper’s point of view), the Spy++ tool isone of the most useful programs ever cre-ated for the Windows platform. It comeswith Visual C++ and the Platform SDK,but you might also find it on the Web. Theinformation it provides is invaluable forpeeking into how an application is imple-mented.

I fired up Spy++ and started to look atseveral applications. Let’s fire it up andlook at PowerBuilder (use the spyglassand put it onto the PowerBuilder IDE byusing drag-and-drop). Figure 3 providesa snapshot – you see the CPS_Comboobject selected, and below are the threedropdownlistboxes displaying the infor-mation we would like to read. On the leftside of every object is the handle for theobject. This handle will look different onyour snapshot; it’s unambiguous on yoursystem, but will change every time yourprogram runs.

Let’s Implement CommenterWe won’t implement the complete

application now; I’ll just provide the neces-sary steps and show the way. You candownload the commenter source codefrom www.sys-con.com/pbdj/sourcec.cfm or the author’s Web site. I found com-menter a long time ago on the Web andenhanced it for PowerBuilder 8 and now forPowerBuilder 9. There were some reallygood PowerBuilder gurus involved in writ-ing it; you’ll find their names in the headersof the different functions they wrote.

First we have to find the PowerBuilder9 IDE. You can see in Listing 1 that we usetwo different of_findwindow functions.The first one is pretty short: returnFindWindowA(as_classname, as_win-downame).

The API FindWindow function

retrieves the handle of the top-level win-dow whose class name and windowname match the specified strings. If itfinds a top-level window of typePBFRAME90, we have our first handle.

The second of_findwindow call is a bitmore complex. We call it when there’s nowindow of type PBFRAME90 open. Weuse the GetDesktopWindow function,which returns the handle of the Windowsdesktop window. From there we’re look-ing for a window of the type PBFRAME90by walking through all open windows. Ifwe don’t find it by the type, we try it withpart of the title. We look for “-PowerBuilder”. This makes it possible tofind and let commenter work forPowerBuilder 8 (the main IDE window isof type PBFRAME80) and, who knows,maybe for PowerBuilder 10. For the com-plete code see Listing 2.

The next step is to get the currentsheet. This would be the object with thehandle 001c02ae and the captionaxisclient (axisclient) (C:\d_drive\Arti-cles\Axis\axisclient.pbl) inherited fromapplication – Application. To comparethe hex values displayed from Spyxx withthe long values returned by the API func-tions, either write a function that con-verts long values to hex values, or youcould use the calculator application thatcomes with Windows (change the view toscientific and you’re able to switch fromdecimal to hex mode and vice versa).

IF of_getcurrentSheet(l_parenthandle,

l_handle, ls_caption) > 0 THEN

//OK

//MessageBox(ls_oops, "c,

CurrentSheet: " + String(l_handle))

ELSE

MessageBox(ls_oops, "Unable to get

CurrentSheet...")

return

END IF

We need the client window within thecurrent sheet (see Listing 3). This is theone with the class name of pbworkXX(XX could be any number chosen by theIDE).

Again we need the child below theobject’s handle that we already have.When I talk about a child, I mean a win-dow that has the WS_CHILD style (look atthe properties/styles in Spyxx) and isconfined to the client area of its parentwindow. An application typically useschild windows to divide the client area ofa parent window into functional areas. Toget the object we want, the class typeshould be “CVS_Tiled” or “CPBWS_View”,depending on which painter we are in.

l_handle = inv_extcalls.of_getwin-

dow(l_handle, 5) //Child

ls_classn = Space(150)

inv_extcalls.of_getclassname(l_handle,

ls_classn, 150)

DO WHILE ls_classn <> "CVS_Tiled" AND

ls_classn <> "CPBWS_View" AND

l_handle > 0

l_handle =

inv_extcalls.of_getwindow(l_handle, 2)

//Next

ls_classn = Space(150)

inv_extcalls.of_getclassname(l_handle,

ls_classn, 150)

LOOP

This was straightforward. We onlyneeded to walk through the tree, but nowwe could have different objects of thetype “CVS_Tabbed”, as you can see byusing Spyxx. Only one is right; the otheris the property view of our PowerBuilderobject. The right object handle has achild of type wedit; the wrong one hasanother one (to be exact it’s of type“PB_PropertyListClass90”). If we havethe correct handle, we’d like to read the

FIGURE 2 Script painter and complex function

Page 26: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

AUTHOR BIOBerndt Hamboeck is a

senior consultant forBHITCON. He’s a CSI,SCAPC8, EASAC, andSCJP2 and started hisSybase development

using PB5.

www.POWERBUILDERJOURNAL.comPBDJ volume10 issue526

values from the dropdownlistbox. To dothis, we send a message, as discussedearlier. In fact, we have to send two ofthem: CB_GETCURSEL (decimal 327)and CB_GETLBTEXT (decimal 328). Thefirst one retrieves the index of the cur-rently selected item; the second returnsthe text of the dropdownlistbox.

ll_index = SendMessage(hwnd,

CB_GETCURSEL, 0, 0)

String lparam = SPACE(255)

as_objname = Space(255)

SendMessage(hwnd, CB_GETLBTEXT,

ll_index, as_combos[1])

Another interesting object is the weditcontrol (handle 002E02CC). This is wherewe write the header and where we’ll workwith the WM_CHAR message. We sendthis message for every character wewould like to see within the scriptpainter. The syntax of the message isSend(a_hndl, WM_CHAR, code, 0),where a_hndl is the handle to the con-trol, WM_CHAR is the code of the mes-sage (WM_CHAR = 258), and code is theASCII value of the character to send (lookat the Asc function in PowerBuilder).

Listing 4 shows a function that writesa complete string into the script painter.

ConclusionWe see that the PowerBuilder 9 devel-

opment environment is “not more” thana standard windows application. It lis-tens and responds to what’s common inthe Windows world: messages. With the

information provided in this article,we’re now able to send messages toother applications. You might applywhat you have learned here to buildapplications that remotely control otherapplications. I wish you a happy(Windows) messaging! ▼

[email protected]

FIGURE 3 Spyxx output for PowerBuilder

// Get the handle using the classnamel_parenthandle = inv_extcalls.of_findwindow(ls_class,

ls_name)

// Get the handle using part of the nameIF l_parenthandle = 0 AND lb_32bit THENl_parenthandle = inv_extcalls.of_findwindow('-

PowerBuilder')END IF

IF inv_extcalls.of_gettext(l_parenthandle, ls_caption, 150) > 0 THEN

// OKELSEreturn

END IF

int li_charcount = 255ulong hMainWindow, lu_desktopstring ls_windowtitle

lu_desktop = GetDesktopWindow()

// Get a handle to the first child of the desktop (1st main window)

hMainWindow = GetWindow(lu_desktop, 5)IF IsNull(hMainWindow) THEN RETURN 0

// Loop through Top Level windows until we find the windowwe want DO UNTIL Upper(left(ls_windowtitle, len(as_name))) =Upper(as_name) &OR Upper(right(ls_windowtitle, len(as_name))) =

Upper(as_name) &

OR hmainwindow = 0// Get a handle to the sibling windowhmainwindow = GetWindow(hmainwindow, 2)IF hmainwindow > 0 THENls_windowtitle = Space(li_charcount)IF GetWindowTextA(hmainwindow, ls_windowtitle, li_charcount)

< 0 THEN RETURN 0END IF

LOOP

IF hmainwindow > 0 THEN

RETURN hmainwindowELSEreturn -1END IF

String ls_classnl_handle = inv_extcalls.of_getwindow(l_handle, 5) //Childls_classn = Space(150)// This is the right sheet (pbworkXX)inv_extcalls.of_getclassname(l_handle, ls_classn, 150)

//MessageBox(ls_oops, "d, Current class: " + ls_classn)IF Lower(Left(ls_classn, 6)) <> "pbwork" THENMessageBox("Error", "No WORKSHEET (pbworkXX) found " +

ls_classn)return

END IF

int code, &pos = 0, &len, &i, &start = 60

char lc_charpointer oldpointer

oldpointer = SetPointer(HourGlass!)len = len(a_string)Send(a_hndl, WM_KEYDOWN, code, 0)DO WHILE pos <= lenpos ++lc_char = Mid(a_string, pos)code = Asc(lc_char)IF code = 13 THENSend(a_hndl, WM_KEYDOWN, code, 0)Send(a_hndl, WM_CHAR, code, 0)Send(a_hndl, WM_KEYUP, code, 0)continue

END IFSend(a_hndl, WM_CHAR, code, 0)LOOPSend(a_hndl, WM_KEYUP, code, 0)

SetPointer(oldpointer)

Listing 4:

Listing 3:

Listing 2:

Listing 1:

Page 27: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

27PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

W W W . J D J S T O R E . C O M

GUARANTEED LOWEST PRICES!

▲▲

▲▲

▲▲

▲▲

▲▲▲▲▲▲▲

▲▲

▲▲

▲▲

Web

Services journal

Readers’CHOICE AWARD

WSJWorld class

AWARD

SIMPLICITYSimplicity˙ Enterprise Lite

SYBASEPowerBuilder Enterprise v.8

Introducing PowerBuilder 8! The award-winning, indus-try-leading application development environment justgot better. Release 8 of PowerBuilder adds exciting newfeatures and capabilities that will make your develop-ment of Web, client/server, and distributed applications easier, faster, andmore cost-effective. New features focusing on improved productivity,tighter integration with EAServer, and Web application developmentmake this release indispensable to your development efforts.

ACCELTREEFULCRUM Professional Edition 1.1 - A Java

Code Assembler

“FULCRUM” is a Java development tool that uses a propri-etary concept of code templates that can be used as"building blocks" to construct efficient Java objects andapplications. Unlike code generators that impose their cod-ing techniques and run-time environments on the users, FUL-CRUM allow users to build their own coding standards in the templates andalso lets users switch to manual coding at any point in time.

$2,558.99

OFFER SUBJECT TO CHANGE WITHOUT NOTICE

Simplicity Enterprise Lite provides the ability tobuild server-side, enterprise class Web applica-tions. Using a palette of graphical modules, the developer links togethertheir desired functionality and interactively tests their application in oneseamless development environment. Application targets include Web sites,WAP-enabled mobile devices, n-tier application services, and enterpriseServlets.

$3,999.00$469.99

POINTBASEPointBase Embedded 4.4 - Windows Installer

PointBase® Embedded is a 100% Pure Java˙RDBMS ideal for embedding in your Java appli-cations, within the J2EE˙ and J2SE˙ platforms. PointBase Embedded utilizesa multi-threaded architecture allowing multiple connections from within thesame JVM. PointBase Embedded features also include small footprint archi-tecture, extensibility, referential integrity, near-zero administration, and a lowcost of ownership.

$353.00/N SOFTWARE

IP*Works! SSL Scripting Edition (1 cpu)

IP*Works! SSL adds SSL and Digital Certificate capabilitiesto the IP*Works! Internet Toolkit providing Secure WebBrowsing, Secure Client, Secure Server, Secure Mail,Digital Certificate Management Capabilities, and a lotmore. The current release consists of 15 components forsecure Internet connectivity.

$295.00

BORLANDJBuilder 7 SE NEW-USER 98/W2K/NT/LINUX/SOL

JBuilder˙ is the leading cross-platform environment forlearning Java˙ programming and personal applicationdevelopment. JBuilder 6 Personal includes an integratededitor, debugger, compiler, visual designers, wizards,and tutorials.

$389.99

SHOP ONLINE AT JDJSTORE.COM FOR BEST PRICES OR CALL YOUR ORDER IN AT 1-888-303-JAVA

Attention Java Vendors:To include your product in JDJStore.com, please contact [email protected]

GUARANTEED LOWEST PRICES!

Helping you enable intercompany collaboration on a global scale• Product Reviews• Case Studies• Tips, Tricks

and more!

Now in More

than 5,000

Bookstores Worldwide –

Subscribe NOW!

Go Online & SubscribeToday!*Only $149 for 1 year (12 issues) – regular price $180.

WebLogicDevelopersJournal.comSYS-CON Media, the world’s leading publisher of i-technology magazines for developers,software architects, and e-commerce professionals, brings you the most comprehensive coverage of WebLogic.

SPECIALOFFER!SAVE $31*OFFER SUBJECT TOCHANGE WITHOUT NOTICE

THE WORLD’S LEADING INDEPENDENT WEBLOGIC

DEVELOPER RESOURCE

Page 28: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

28 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

WRITTEN BYSCOTT HEFFRON

W I R E L E S S S O L U T I O N S

Mobile vs Embedded DatabasesChoosing the right database for your application

Irecently participated in a development meeting in which handheld and database

deployment was the main topic. Some participants became confused about the difference between a mobile and an embedded database as a result of this discussion.

I thought it would be a good idea toclarify and describe the features of eachdatabase. They both perform the sameactions, but in a different manner. FirstI’ll define each database and then moveto the following areas: database schema,SQL statements, declarative referentialintegrity, stored procedures, triggers,and synchronization.

DefinitionsIn the dictionary, mobile is defined as

“capable of moving or of being moved read-ily from place to place.” This means placingthe database on a device, which could be alaptop or handheld. A mobile database canhave more than one application connect-ing or trying to gain access to it, so someonehas to install the database and applicationon the device. A database connection, nor-mally ODBC, must be configured from theapplication to the mobile database. In theend, you have to install at least two separateapplications and one database connection.One of the advantages of a mobile databaseis that the vendors try to make it self-con-tained, which tells us that it is low mainte-nance. The upgrade process could becomechallenging depending on the IT infra-structure and policies.

The embedded database is placedinside the application, which means itshares memory space with the businessand/or UI code. This enables the user toinstall just one application, removingthe need for any specific database con-figuration. This is one reason embeddeddatabase applications are targeted forvending machines, handheld devices, orplatforms that have memory constraints– very little or no database maintenanceis needed. A characteristic of embeddeddatabases is the ability to run entirelywithout administration. This is the type

of environment that the UltraLitedeployment option was designed towork within.

Database SchemaOne of the initial steps when creating

a software application is to know whichdata your application will need to use.This data needs to be available to theuser when he or she is executing theapplication, otherwise the applicationwill be useless. When designing a data-base schema, developers try to captureall the necessary data.

Mobile databases were created to tar-get small groups, usually ranging from 1to 10 people. These days most laptopsare equipped with a significant amountof storage capabilities. My laptop has astandard 30G drive. Normally this isplenty of room for a workgroup data-base. Another area of concern that weshould be considering is the RAM space.Databases use as much RAM as they canfind. They need it to store recentlyretrieved queries and SQL access paths.

The embedded database was designedto target not the amount of people, but atype of device. One type of device couldbe a vending machine, which is unat-tended and left for people to use. In thiscase the embedded database would onlybe used if someone bought an item fromthe machine. The database could initiatethe synchronization process when a cer-tain product’s stock went below a certainlevel.

Another type of device is a handheldcomputer, which has limited storagespace and is small in size. When design-ing its use, you need to restrict the datacolumns and records to just what isneeded. There are no luxury featureswith this engine. If it’s not used, we keep

it off. With this type of database, ourmain focus is getting the job done withfew or no frills.

SQL StatementsAs a reminder, a SQL statement is

used by the user to gather or modify dataon a database.

When using a mobile database, anapplication screen may allow the user toenter in one or more pieces of informa-tion to search for a certain record. Thisability requires the database engine toallow SQL statements to be modifiedduring runtime. In other words, the“where” clause can be changed at anytime. This enables the application to bemore helpful to the user in many cir-cumstances, but does require more cod-ing on the developer’s side.

Now, let’s look at the opposite engine– the embedded database. The applica-tion that uses this type of database isfocused specifically on distinguishablebusiness logic. This implies that notmuch analysis or ad hoc work is per-formed with these applications. The rea-son for this is that the SQL statementsare translated into specific code. I’vecreated Palm OS applications with theembedded database. My embedded SQLstatements are processed through anUltraLite generator called “ulgen” andtranslated into “C” code. This code isthen placed into the source files used tocreate the handheld application.

The following is an example of the orig-inal and the translated SQL statement:

Original:

EXEC SQL SELECT COUNT(*)

INTO :dblCustCount

FROM Customer;

Page 29: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

29PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

Translated:

{

{

struct { SQLDA_VARIABLE sql-

var[1]; } __SQLV_db_custo_18;

((SQLDA *)&__SQLV_db_custo_18)-

>sqlvar[0].sqldata = (void *)

(&(dblCustCount));

((SQLDA *)&__SQLV_db_custo_18)-

>sqlvar[0].sqlind = (short int

*)((SQLNULL));

ulpp_execute_db_customer_10(

(&sqlca), (SQLDA _fd_ *)0, ((SQLDA

*)&__SQLV_db_custo_18) );

if( (&sqlca)->sqlcode < 0 ) goto

Error;

}

}

Declarative ReferentialIntegrity

Since this methodology is set up togovern data consistency within a database, specifically relationshipsbetween primary and foreign keys, thisprocess is practiced between many orall of the different vendors. The prac-tice of primary and/or foreign keysdoes not change with the differenttypes of databases. The only thingsthat could change are the columnsand record sets, depending on the userand his or her business requirements.

Embedded databases are designedto pull over needed columns. Thetable’s primary keys, foreign keys, andnot null fields are normally neededon both systems, so the migrationprocess of creating the embeddedobjects will check the SQL statementsbeing used in the static SQL and cre-ate the needed database object.

Stored ProceduresMobile databases can implement

these objects. However, the embeddeddatabase engine does not allow thesetypes of objects to be implemented,because vendors try to implement thesmallest engine possible for theembedded database. They have toremove certain features that wouldmake the engine and storage bigger.Another reason is that only static SQLis allowed. Developers can check theSQL access paths to help them writeeffective statements. This processtakes away the need for stored proce-dures. Stored procedures were alsocreated for black box programming,which means you just call the proce-dure with the accompanying parame-ters and it does the rest of the work.This happens with embedded SQL.

TriggersThere are no triggers implemented

in the embedded-type database.Again we’re looking at features thevendors thought would be best leftout. The programmer will have toimplement programmatic referentialintegrity at the coding level or declar-ative referential integrity. Triggers areexecuted on the central databaseduring synchronization.

SynchronizationThis is a process of moving data

back and forth from a “central” data-base to a “remote” one. Whetheryou’re using a mobile or embeddeddatabase, the synchronizationprocess does not change. What willchange is the number of records andcolumns in the remote database.

A mobile database will usuallycontain all the columns and tablesfrom the central database. It may not,however, contain all the records; thisdepends on the size availability. It’ssomething the designers will have toevaluate in the analysis section.

Embedded database synchroniza-tion takes on a different design pat-tern. When working with this type ofdatabase, you need to restrict thecolumns, tables, and records anddesign your scripts to be very criticalof all areas. Not every column isneeded for the specific task that’sbeing placed on the application.

SummaryEach database engine has its own

set of features that are available forthe developer to use. It’s the develop-er’s responsibility to link the applica-tion requirements with these fea-tures.

This overview discussed the differ-ences between these two models. Besure to review your application’sbusiness requirements. This will helpyou decide on which engine andwhich steps are needed to make theapplication perform to the best ofyour business needs.

Mobile hardware vendors offer awide range of devices that are suitedfor different uses. These include lap-tops, PDAs, bar code scanners, point-of-sale devices, wearable computers,and smart phones. Targeting the spe-cific business need along with thedatabase requirements and capabili-ties is a step toward creating an effec-tive mobile application. ▼

AUTHOR BIOScott Heffron is an application developmentmanager for corporatestrategies at NutraceuticalCorp. in Park City, UT. Hespecializes in mobile andWeb development. Scottis currently working withhandheld device [email protected]

Calling Sleek Geeks Everywhere!

Make sure you have your finger on the pulse of i-Technology...bookmark http://developer.sys-con.com today.

i-Technology

Newsi-Technology

Viewsi-Technology

Commenti-Technology

Debate

STEP UPto the mike

and be...

STEP UPto the mike

and be...

ATTN: Developers

HEARD!HEARD!

Go to http://developer.sys-con.com

©C

OP

YR

IGH

T 2

002,

SY

S-C

ON

ME

DIA

W

WW

.SY

S-C

ON

.CO

M

Page 30: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

30 PBDJ volume10 issue5 www.POWERBUILDERJOURNAL.com

WRITTEN BY MICHAEL DEASY

The Hidden Dangers of Telecommuting‘Operator, information, get me the CEO on the line…’

Telecommuters are becoming more than aclever ’90s buzzword. Businesses are inclinedto allow trusted employees to connect in andwork from home. They save money 10 differ-ent ways and quite often give the workers abetter quality of life.

The essence of telecommuting is to avoidthe drive, which in Seattle is a breathtakingprospect. There are no short drives here, anda large part of that is the infrastructure.Seattle has experienced explosive growth inthe last 40 years, and that is exactly how longthe discussions have been taking place as tohow to connect the city together with someeasy form of transportation. Puget Sounddivides cities, as does Lake Washington – con-nected by bridges and the flowing caramel ofcars winding across the ironically namedfreeways.

There are more than a few people out therewho want to avoid working in tall office build-ings these stormy days. Certainly we all haveimages of fallen buildings cauterized onto thedeep recesses of our thinking, and it’s easy tosigh relief at the thought of not working intheir expanses. Working from the comfort ofour homes seems an easy way to keep safe.

Times are calling for solutions to the gaswars, not to mention the fact that with gasprices spilling over the $2 a gallon mark – it’sno little financial bonus to leave theBlackwood in the garage and log on from theliving room.

‘Women and Children into theBoats First!!’

There are some dangers involved in cablingor networking in from home, not the least ofwhich is that you must be an extremely disci-plined person to pull it off. Having gained thetrust of your company or contract holder, it’simportant that you fulfill everything you havepromised. The project still has to be done ontime and under budget – and it won’t be if you

fall victim to any or all of these errant behav-iors.

1. Napping at your work station: One of thebig dangers of the telecommute is fallingasleep at your desk, especially if your desk isequipped with a pillow and quilt. Those ofyou working on your Serta Perfect Sleeperdesks must shake yourself awake and get backto the task at hand. Don’t fall victim to takingnaps, sleeping late, and missing deadlines.While the temptation is always there becauseyou can work at almost any time, it’s a slip-pery slope or, as Dr. Phil might call it, “a softplace to land.”

2. Running errands: Another danger of thetelecommute is the “honey-do” list that canget left for you on a semi-regular basis. It’smuch easier to pick up the cleaning, get a fewgroceries, and drop off the electric bill ifyou’re doing it from home instead of theoffice. This is another trap. While it is a matterof some convenience to take care of some ofthe daily grind during the daily grind, you canfind yourself sitting in the exact same trafficjams you were trying to avoid by stayinghome and working. Time passes with blind-ing consistency when you are driving aroundlistening to your local sports talk show. Youcan also achieve a false sense of accomplish-ment if you take care of important businesswhen you should be working.

3. Your favorite TV series on A&E: It seemsthey only show reruns of “Magnum PI” andthe “Rockford Files” during the middle of themorning or after the “Tonight Show.” Eitherway, don’t get caught up on the episodes thatyou missed. Taking a break to stretch, workout, or walk can be necessary and important –but making sure you don’t miss an episode of“All My Children” is another fissure to avoid.

4. Personal hygiene: Who among us has notenjoyed the quality time of programming intheir skivvies, a glass of frosty lemonade atyour side, and a two-day beard (leg hairgrowth for the ladies) at hand? It’s easy to

avoid the shower when you don’t have to sit inconference rooms and in meetings with yourpeers or business users, but it doesn’t bodewell. One of the keys to success in workingfrom home is getting up, shaving, showering,and getting dressed. It may seem elemental,even silly to say it, but those of you with thefour-day shadow and the unused Sport Stickknow who you are.

5. Being your own child-care professional:For some this is arguably one of the biggestadvantages of working from home. If you havesmall children and can pull it off, it’s a godsend– as the only thing getting more expensive thangas is good child care. It’s tough to do, however;you need to have some boundaries for yourselfand magnificent time management skills. Ifyou have a toddler, then the work schedule willvery likely be dictated by naps and movies –and that can threaten deadlines. Don’t read anysexism into this last, as there are as many menstaying home with the kids as women.

6. Writing for computer magazines: Yes, if youhave found yourself researching and outliningarticle ideas when you should be enhancing aDataWindow, then you are another victim ofJohn Olson and Bob Hendry and their evil plotto publish an interesting, informative, andprovocative magazine. Be careful of this time-consuming and therapeutic preoccupation.

While this is a tongue-in-cheek look at afew of the problematic angles and curvesinvolved in the telecommute, it is only that.Telecommuting is a part of our daily lives, andfor some it’s a part of their daily work life. Itcan be richly rewarding, or deceitfully unpro-ductive – it’s all up to you. ▼

AUTHOR BIOMichael Deasy works in the Seattle area as a project manager,Webdesigner, and freelance writer. He has been working withPowerBuilder since version 3. Mike holds an MBA from SouthernNazarene University.

[email protected]

I M H O

And if not the CEO, how about some tech

support, order takers, a programmer,

some direct marketers, and maybe even a

couple of scheduling analysts?

Page 31: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

31PBDJ volume10 issue5www.POWERBUILDERJOURNAL.com

800 513-7111

www.sys-con.com

The world’s leading i-technogy publisher

SUBSCRIBE NOWTO THEFINESTTECHNICALJOURNALSIN THE INDUSTRY!

PBDJ ADVERTISER INDEXADVERTISER URL PHONE PAGE

Advertiser is fully responsible for all financial liability and terms of the contract executed by theiragents or agencies who are acting on behalf of the advertiser. This index is provided as an addi-tional service to our readers. The publisher does not assume any liability for errors or omissions.

Amyuni Technologies, Inc. www.amyuni.com 866-926-9864 2

E.Crane Computing www.ecrane.com 35

JDJ Store www.jdjstore.com 888-303-JAVA 27

JDJ Workshop www.sys-con.com/education 201-802-3058 21

Linux Business & Technology www.sys-con.com 888-303-5282 19

PowerObjects www.powerobjects.com 612-339-3355 36

Sybase www.sybase.com/powerbuilder 5

Sybase, Inc www.sybase.com/pbextension 9

Sybase, Inc www.sybase.com/powerbuilder 15

SYS-CON Media http://developer.sys-con.com 888-303-5282 29

SYS-CON Reprints www.sys-con.com 201-802-3026 27

SYS-CON Subscription Offer www.sys-con.com/suboffer.cfm 888-303-5282 32, 33

Web Logic Developer's Journal www.weblogicdevelopersjournal.com 888-303-5282 27

Web Services Journal www.sys-con.com 888-303-5282 23

the annual newsstand rateSAVE$31Off*

SAVE$31Off*

Receive 12 issues of PBDJ for only $149.00. That’s a savings of $31 off the annual newsstand rate.

Visit our site at www.powerbuilderjournal.com or call 1-888-303-5282 and subscribe today!

ANNUAL COVER PRICE

$180.00ANNUAL NEWSSTAND RATE

$149.00

$31

YOU PAY

YOU SAVEOff the AnnualNewsstand Rate

• New PowerBuilder Features • Tips, Tricks and Techniques in

Server-Side Programming • DB Programming Techniques • Tips on Creating Live PowerBuilder Sites • Product Reviews • Display Ads of the Best Add-on Products • PowerBuilder User Group Info

Here’s whatyou’ll find in every

issue of PBDJ

Here’s whatyou’ll find in every

issue of PBDJ• New PowerBuilder Features • Tips, Tricks and Techniques in

Server-Side Programming • DB Programming Techniques • Tips on Creating Live PowerBuilder Sites • Product Reviews • Display Ads of the Best Add-on Products • PowerBuilder User Group Info

*Offer subject to change without notice

Page 32: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

and receive yourFREE CD Gift Package VIAPriority MailEach CD is an invaluable developerresource packed with important articles and useful source code!

The largest and most complete library of exclu-sive XML-Journal articles compiled on one CD!Edited by well-known Editors-in-Chief Ajit Sagarand John Evdemon, these articles are organizedinto more than 30 chapters containing morethan 1,150 articles on Java & XML, XML &XSLT, <e-BizML>, data transition... and more!

LIST PRICE $198

The most up-to-date collection of exclusiveWSDJ articles! More than 200 articles offerinsights into all areas of WebSphere, includ-ing Portal, components, integration, tools,hardware, management, sites, wireless pro-gramming, best practices, migration...

LIST PRICE $198

The most complete library of exclusive CFDJarticles on one CD! This CD, edited by CFDJEditor-in-Chief Robert Diamond, is organizedinto more than 30 chapters with more than 400exclusive articles on CF applications, customtags, database, e-commerce, Spectra, enter-prise CF, error handling, WDDX... and more!

LIST PRICE $198

More than 1,400 Web services and Java articleson one CD! Edited by well-known editors-in-chief Sean Rhody and Alan Williamson, thesearticles are organized into more than 50 chap-ters on UDDI, distributed computing, e-busi-ness, applets, SOAP, and many other topics.Plus, editorials, interviews, tips and techniques!

LIST PRICE $198

The most complete library of exclusive JDJarticles compiled on one CD! Assembled byJDJ Editor-in-Chief Alan Williamson, morethan 1,400 exclusive articles are organizedinto over 50 chapters, including fundamen-tals, applets, advanced Java topics, Swing,security, wireless Java,... and much more!

LIST PRICE $198

An up-to-the-minute collection of exclusive LinuxBusiness & Technology articles plus MaureenO'Gara's weekly LinuxGram, which keeps a finger onthe pulse of the Linux business community. Editedby LBT's Editor-in-Chief Alan Williamson, these arti-cles cover migration, hardware, certification, and thelatest Linux-related products. Available June 2003!

LIST PRICE $198

The most complete library of exclusive WLDJarticles ever assembled! More than 200 arti-cles provide invaluable information on “every-thing WebLogic”, including WebLogic Server,WebLogic Portal, WebLogic Platform,WebLogic Workshop, Web services, security,migration, integration, performance, training...

LIST PRICE $198

Pick the CDsto go with yourMulti-Pack orderPick one CD withyour 3-Pack orderPick two CDs withyour 6-Pack orderPick three CDs withyour 9-Pack order

Your order will beprocessed the same day!

■ Web Services Resource CD■ Java Resource CD■ WebLogic Resource CD■ ColdFusion Resource CD■ XML Resource CD■ WebSphere Resource CD■ Linux Resource CD

Subscribe Online Today

A LIMITED TIME SAVINGS

Go To www.sys-con.com/suboffer.cfmSUBSCRIBE TODAY TO MULTI

Page 33: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

3-PackPick any 3 of our magazines and saveup to $27500

Pay only $175 for a 1 year subscriptionplus a FREE CD• 2 Year – $299.00• Canada/Mexico – $245.00• International – $315.00

6-PackPick any 6 of our magazines and saveup to $35000

Pay only $395 for a 1 year subscriptionplus 2 FREE CDs• 2 Year – $669.00• Canada/Mexico – $555.00• International – $710.00

9-PackPick 9 of our magazines and saveup to $40000

Pay only $495 for a 1 year subscriptionplus 3 FREE CDs• 2 Year – $839.00• Canada/Mexico – $695.00• International – $890.00

RECEIVEYOUR DIGITAL

EDITIONACCESS CODEINSTANTLY

WITH YOUR PAID SUBSCRIPTIONS

www.sys-con.com/2001/sub.cfm

■ Web Services JournalU.S.- Two Years (24) Cover: $168 You Pay: $99.99 / Save: $68 + FREE $198 CDU.S. - One Year (12) Cover: $84 You Pay: $69.99 / Save: $14Can/Mex - Two Years (24) $192 You Pay: $129 / Save: $63 + FREE $198 CDCan/Mex - One Year (12) $96 You Pay: $89.99 / Save: $6Int’l - Two Years (24) $216 You Pay: $170 / Save: $46 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ Java Developer’s JournalU.S. - Two Years (24) Cover: $144 You Pay: $89 / Save: $55 + FREE $198 CDU.S. - One Year (12) Cover: $72 You Pay: $49.99 / Save: $22Can/Mex - Two Years (24) $168 You Pay: $119.99 / Save: $48 + FREE $198 CDCan/Mex - One Year (12) $84 You Pay: $79.99 / Save: $4Int’l - Two Years (24) $216 You Pay: $176 / Save: $40 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ Linux Business & TechnologyU.S. - Two Years (24) Cover: $143 You Pay: $79.99 / Save: $63 + FREE $198 CDU.S. - One Year (12) Cover: $72 You Pay: $39.99 / Save: $32Can/Mex - Two Years (24) $168 You Pay: $119.99 / Save: $48 + FREE $198 CDCan/Mex - One Year (12) $84 You Pay: $79.99 / Save: $4Int’l - Two Years (24) $216 You Pay: $176 / Save: $40 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ .NET Developer’s JournalU.S. - Two Years (24) Cover: $168 You Pay: $99.99 / Save: $68 + FREE $198 CDU.S. - One Year (12) Cover: $84 You Pay: $69.99 / Save: $14Can/Mex - Two Years (24) $192 You Pay: $129 / Save: $63 + FREE $198 CDCan/Mex - One Year (12) $96 You Pay: $89.99 / Save: $6Int’l - Two Years (24) $216 You Pay: $170 / Save: $46 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ XML-JournalU.S. - Two Years (24) Cover: $168 You Pay: $99.99 / Save: $68 + FREE $198 CDU.S. - One Year (12) Cover: $84 You Pay: $69.99 / Save: $14Can/Mex - Two Years (24) $192 You Pay: $129 / Save: $63 + FREE $198 CDCan/Mex - One Year (12) $96 You Pay: $89.99 / Save: $6Int’l - Two Years (24) $216 You Pay: $170 / Save: $46 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ ColdFusion Developer’s JournalU.S. - Two Years (24) Cover: $216 You Pay: $129 / Save: $87 + FREE $198 CDU.S. - One Year (12) Cover: $108 You Pay: $89.99 / Save: $18Can/Mex - Two Years (24) $240 You Pay: $159.99 / Save: $80 + FREE $198 CDCan/Mex - One Year (12) $120 You Pay: $99.99 / Save: $20Int’l - Two Years (24) $264 You Pay: $189 / Save: $75 + FREE $198 CDInt’l - One Year (12) $132 You Pay: $129.99 / Save: $2

■ WebLogic Developer’s JournalU.S. - Two Years (24) Cover: $360 You Pay: $169.99 / Save: $190 + FREE $198 CDU.S. - One Year (12) Cover: $180 You Pay: $149 / Save: $31Can/Mex - Two Years (24) $360 You Pay: $179.99 / Save: $180 + FREE $198 CDCan/Mex - One Year (12) $180 You Pay: $169 / Save: $11Int’l - Two Years (24) $360 You Pay: $189.99 / Save: $170 + FREE $198 CDInt’l - One Year (12) $180 You Pay: $179 / Save: $1

■ Wireless Business & TechnologyU.S. - Two Years (24) Cover: $144 You Pay: $89 / Save: $55 + FREE $198 CDU.S. - One Year (12) Cover: $72 You Pay: $49.99 / Save: $22Can/Mex - Two Years (24) $192 You Pay: $139 / Save: $53 + FREE $198 CDCan/Mex - One Year (12) $96 You Pay: $79.99 / Save: $16Int’l - Two Years (24) $216 You Pay: $170 / Save: $46 + FREE $198 CDInt’l - One Year (12) $108 You Pay: $99.99 / Save: $8

■ PowerBuilder Developer’s JournalU.S. - Two Years (24) Cover: $360 You Pay: $169.99 / Save: $190 + FREE $198 CDU.S. - One Year (12) Cover: $180 You Pay: $149 / Save: $31Can/Mex - Two Years (24) $360 You Pay: $179.99 / Save: $180 + FREE $198 CDCan/Mex - One Year (12) $180 You Pay: $169 / Save: $11Int’l - Two Years (24) $360 You Pay: $189.99 / Save: $170 + FREE $198 CDInt’l - One Year (12) $180 You Pay: $179 / Save: $1

■ WebSphere Developer’s JournalU.S. - Two Years (24) Cover: $360 You Pay: $169.99 / Save: $190 + FREE $198 CDU.S. - One Year (12) Cover: $180 You Pay: $149 / Save: $31Can/Mex - Two Years (24) $360 You Pay: $179.99 / Save: $180 + FREE $198 CDCan/Mex - One Year (12) $180 You Pay: $169 / Save: $11Int’l - Two Years (24) $360 You Pay: $189.99 / Save: $170 + FREE $198 CDInt’l - One Year (12) $180 You Pay: $179 / Save: $1

■ 3-Pack ■ 1YR ■ 2YR ■ U.S. ■ Can/Mex ■ Intl.

■ 6-Pack ■ 1YR ■ 2YR ■ U.S. ■ Can/Mex ■ Intl.

■ 9-Pack ■ 1YR ■ 2YR ■ U.S. ■ Can/Mex ■ Intl.

•Choose the Multi-Pack you want to order by checkingnext to it below. •Check the number of years you want toorder. •Indicate your location by checking either U.S.,Canada/Mexico or International. •Then choose which magazines you want to include with your Multi-Pack order.

TOORDER

Pick a 3-Pack, a 6-Pack or a 9-Pack

OFFER FROM SYS-CON Media

OFFER SUBJECT TO CHANGE WITHOUT NOTICE

PLE MAGAZINES ONLINEAND SAVE UP TO $400 ANDRECEIVE UP TO 3 FREE CDs!

Page 34: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

34 www.POWERBUILDERJOURNAL.comPBDJ volume10 issue5

POWERBUILDERPowerBuilder 9.03/24 – Sybase has releasedPowerBuilder 9.0, the industry-leading rapid application devel-opment tool. PowerBuilder 9.0enables developers to build richclient applications to meet theirmission-critical business require-ments, and features new capabil-ities for J2EE and Microsoft .NETenvironments. This release alsolays the foundation for “4GLplus”, an initiative under whichsubsequent versions of Power-Builder will bring an even higherlevel of developer productivitythrough tight integration ofdesign, modeling, development,deployment, and management.

THIRD PARTYuNokSoftGroup3/27 – Added “Dynamic Script inRuntime” sample.www.mycgiserver.com/~unoksoftgroup

PBL Peeper3/26 – Initial 9.0 release of PBLPeeper. www.techno-kitten.com/PBL_Peeper/What_s_New/what_s_new.html

PowerBuilder Developers Resource3/23 – Added “Transparent API”sample. www.pbdr.com/software/comp/examples.htm

PBSearch3/21 – TopWiz Softwareannounced an allnew version ofPBSearch. It fea-tures a System Treesimilar to PB ver-sion 8, for easier searching ofmultiple applications. It alsosupports PB version 9. www.topwizprogramming.com

Real’s How-To3/01 – Added “Get the PBLName” sample. www.rgagnon.com/howto.html

SmartPaste 2.32/27 – The new version addssupport for PB9.www.romu.com/smartpaste

Lifeboat Distribution Services3/24 – Lifeboat DistributionServices, a leading independentmarketer of software tools fortechnology professionals,announced that it has enteredinto an agreement with Sybaseto distribute both SybasePowerDesigner, the intuitivemodeling and design tool thatsupportsmultipleleadingmodeling techniques within onegraphically rich environment,and Sybase EAServer, the SPECbenchmark record-breakingEnterprise Application Server.www.lifeboatdistribution.com

CORPORATEJapan3/10 – Sybase announced theappointment of Masaki Sawabeas president and general manag-er of Sybase’s subsidiary inJapan, Sybase K.K. Sawabe suc-ceeds David Warren, who servedas acting president for over ayear and who will become vicepresident of business operationsin Sawabe’s new organization.

China3/12 – Sybase announced that itwas selected as the “MostSuccessful Database SoftwareCompany in China for 2002” bythe China Center forInformation IndustryDevelopment Consulting Co.Ltd. (CCID Consulting) at the2003 China IT Market AnnualConference. In addition, CCIDConsulting’s “Annual SoftwareMarket Report 2002–2003” con-firmed that Sybase is the secondlargest database company inChina.

Europe, Middle East, and Africa3/19 – Sybase announced theappointment of Steve Shine assenior vice president and gener-al manager for Europe, MiddleEast, and Africa (EMEA). In thisrole, Shine will be responsiblefor overseeing sales, humanresources, financial, and opera-tional activities in the region,and will report directly toMichael Bealmear, president ofWorldwide Field Operations forSybase.

IANYWHEREIntel3/12 – iAnywhere Solutions, asubsidiary of Sybase, and IntelCorporation announced a strate-gic relationship to fuel the devel-opment of always availablemobile enterprise applicationsthat extend enterprise informa-tion to mobile workers regard-less of network avail-ability. As part of thisrelationship,iAnywhere Solutionsis completing exten-sive product testing to optimizeSQL Anywhere Studio fordeployment on Intel Centrinomobile technology–powerednotebook computers.www.intel.com/products/mobiletechnology/index.htm?iid=sr+centrino&

ProspectSoft3/12 – iAnywhere Solutions, asubsidiary of Sybase, andProspectSoft demonstrated oneof the first wireless enterpriseapplica-tions opti-mized forthe newIntel Centrino mobile technolo-gy. The ProspectSoft CRM solu-tion is powered by SQLAnywhere Studio fromiAnywhere Solutions andextends critical enterprise capa-bilities. www.prospectsoft.com

.NET Provider Demo3/19 – iAnywhere Solutions, asubsidiary of Sybase, demon-strated an innovative applicationthat leverages the .NET dataprovider for SQL AnywhereStudio and the Microsoft .NETCompact Framework at theMicrosoft Mobility DeveloperConference. The mobile insur-ance claims processing applica-tion enables remote workers toview and enter information,import and annotate photos,and synchronize data to a back-end enterprise database using aPocket PC device.

ADAPTIVE SERVERENTERPRISESun Cluster 3.003/19 – Sybase announcedSybase Adaptive ServerEnterprise (ASE) 12.5.0.3 nowsupports the Sun Cluster 3.0software active-passive agent,expanding theoffering to include active-pas-sive support in addition toactive-active support. Customersnow have the option to selectthe most optimal solution tomeet their individual high-avail-ability needs. www.sun.com/software/cluster

INDUSTRIAL WAREHOUSESTUDIOTrackMax3/24 – Sybase announced thatIndustry Warehouse Studio(IWS) will act as the analyticalinfrastructure for TRACKMAX,Distributor ResourceManagement’s premier earned-income tracking software for thefood serviceindustry. IWS isan enterprise ana-lytic infrastructure that “jump-starts” the design, development,and implementation of focusedenterprise analytic applications. www.trackmax.com

[email protected]

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

Page 35: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed

E.Crane Computingwww.ecrane.com

Page 36: THE METADATA DATAWINDOW - SYS-CON · PDF file4 FROM THE CO-EDITOR I t’s taken a while, but over the past six months a client of mine has finally gotten around to building distributed