|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
DataWindows Client/Server-The Haven Of Sensitive Data
Client/Server-The Haven Of Sensitive Data
By: Tom Peters
Jan. 1, 2001 12:00 AM
To this day my mother refuses to make deposits via her bank's ATM. Her reason is a valid one: she doesn't trust a machine with her money. You get no real validation from the ATM, just a receipt stating the amount you said was in your envelope. If the contents of your envelope gets lost or stolen, you don't have any real evidence that you put your money in that ATM. No, Mom wants a human to stamp her pink copy of the deposit slip so she can prove the bank did, in fact, take her money.
Why Client/Server Focus? For these reasons, I'll be discussing application techniques as they apply to client/server. If you don't believe that client/ server is alive and well, go back to your November PBDJ (Vol. 7, issue 11) and read the guest editorial written by Sue Dunnell, Sybase's Project Manager for PowerBuilder. If she doesn't convince you, call Sybase. This article shows you how just a few methods added to your custom DataWindow control can make your small-to-medium-sized applications easier to maintain. They would also make your enterprise-sized applications easier to maintain, but for large applications I highly recommend using the PFC. I know the heart always leans toward using the PFC regardless of the size of the application. But if I'm honest with myself, I know there are times...
When the PFC Is Just Too Much While it's almost always cheaper to use a ready-made class library, there are times when it's most advantageous to build your own. Sometimes all you need is a dozen or so user objects. Trust me, a nice lean library is easier to maintain than a full-blown class library/framework. "Maintain a class library?" you ask. Absolutely! If you've been using the PFC since it was introduced, you're well aware that there are occasions when you have to modify the source. It's kind of like operating on yourself to save your life, but it has to be done. I'm not going to explain how to build a class library. I'm just going to show you 12 methods that I've had in my DataWindow control in my applications (even ones with the PFC) that have saved time and won the praise of my users. The 12 listings appear on the PBDJ Web site.
The Makings of the DataWindow Superhero Each of the following sections will explain a specific type of functionality and the methods that collaborate to accomplish it.
Data Objects and Transaction Objects You'll notice that in Listing 1 the method posts a custom user event called cst_Data ObjectChanged. That's there for your convenience. You may have some special modify method calls to change colors, static text values, and so forth that need to be executed after any data object change. I'm a strong believer that pre- and postmethods should be in place for anything that will impact what the user sees or that manipulates data. For instance, you should have cst_PostConstructor, cst_ PreDestructor, cst_PostUpdate, and so forth throughout your base objects. With these methods in place, you can now set your data object (or build it) dynamically and assign its transaction object by calling one method, of_Set DataObject.
Data Entry for Lazy Users When your user is adding data into a screen that shows multiple rows, appending new rows prior to saving isn't usually an issue because the user knows enough to review the screen before saving his or her data. If the screen displays only one row of data at a time, like in a free-form-style detail DataWindow, it's really a good idea to prompt the user to save the data before it leaves his or her realm of vision. This stops the user from entering duplicate data. The user event cst_AskSaveChanges (see Listing 5) takes care of this. You can also call this from the window's CloseQuery event so the user doesn't lose any work.
Standard Search Abilities First the DataWindow needs a list of its columns and their relative types. This can be loaded into an instance variable DataStore and referenced by the search method. The DataStore is populated via a user method called of_CreateColumnList (see Listing 6). The method populates a DataWindow object in the DataStore with whatever information is pertinent for other methods. For my method, I record column name, type, and tag. I'm only interested in visible columns since the user can't search on data they don't know exists. Even more important, we wouldn't want to highlight a row as a search result because an invisible column had the search criteria in it. That would really aggravate your users. Next we need the event itself, cst_Search (see Listing 7). This method opens a response window (which you'll need to build) that allows the user to enter the text he or she is searching for and specify whether all occurrences are to be highlighted or just the first. Users also need to be able to define match case if they so desire. user criterion is returned via a structure and the search is performed as shown in Listing 7. You'll notice that this method calls a few others. The method of_ LoadDropDowns populates an instance variable DataStore with the data values and display values of a given column so that the search considers both DropDownDataWindow and Drop DownListBox styles. For the sake of space I don't show their code here, but if you understand of_CreateColumnList you can figure out how to code these methods. The method searches all visible columns in the DataWindow for the text entered by the user. If indicated, text case is considered. If the user wants all occurrences highlighted, the method does so. To undo the selection you'll need to code a SelectRow to deselect all rows.
Saving and Restoring Criterion Data The of_GetParentChain method builds a string that represents an exact object in your application. By looping through the parent chain a unique name is created for that specific DataWindow object that can be matched for saving and restoring the user's criterion. The of_SaveCriterion method loops through the visible columns and uses the SetProfileString method to write the data to the ini file. The method accepts two arguments, avs_ini and avs_section. Pass in the result of the of_GetParentChain method as avs_section or specify your own. If you're always going to let the system determine the section name, you can modify of_SaveCriterion and of_Restore Criterion to use the ini specified in your application manager object and of_GetParentChain, and remove the arguments. The of_RestoreCriterion performs the reverse actions of the of_Save Criterion and sets all of the saved data into the DataWindow. You'll need to call the of_Save Criterion and of_RestoreCriterion either at the concrete level or from a custom criterion DataWindow object you inherit from u_dw. Regardless, you never have to code the specific column names and data objects.
Some Obscure Time-Savers IF row > 0 THEN THIS.of_SelectRow( row )You turn this service on at the concrete level via of_SetRowSelect and of_SetRowSelectMulti. This allows standard row selection for the user. of_SelectedCount (see Listing 12) returns the number of selected rows in the DataWindow. You may be familiar with an easier way to do this. According to Sybase documentation you should be able to simply code: Long ll_rowcountUnfortunately, Sybase technical case documentation also states that there's a bug in this functionality and the safe way to code it is to loop through the buffer counting via GetSelectedRow as shown in Listing 12.
Conclusion Reader Feedback: Page 1 of 1
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||