Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

(Ebook - Pdf) Kick Ass Delphi Programming

.pdf
Скачиваний:
284
Добавлен:
17.08.2013
Размер:
5.02 Mб
Скачать

lacks. InterBase allows stored procedures, called select procedures, which return any number of rows just as a SQL query would. Its procedure language allows you to iterate over a result set (using a query or another select procedure inside the procedure) and operate on it, as shown in Listing 11.7, which is in the InterBase command language. (The line numbers are significant in the discussion that follows.)

Listing 11.7 InterBase Select Procedures

1.CREATE PROCEDURE GETCHILDREN (STARTING_ITEM_ID SMALLINT,

THISLEVEL SMALLINT)

2.RETURNS(ITEM_ID SMALLINT, DESCRIPTION CHAR(30),

ITEMLEVEL SMALLINT) AS

3.BEGIN

4.FOR

5.SELECT T1.ITEM_ID, T1.DESCRIPTION

6.FROM ITEMS T1

7.WHERE T1.PARENT_ID = :STARTING_ITEM_ID

8.INTO :ITEM_ID, :DESCRIPTION

9.DO BEGIN

10.ITEMLEVEL = THISLEVEL + 1;

11.SUSPEND;

12.FOR

13. SELECT T1.ITEM_ID, T1.DESCRIPTION, T1.ITEMLEVEL

14. FROM GETCHILDREN(:ITEM_ID, :ITEMLEVEL) T1

15. INTO :ITEM_ID, :DESCRIPTION, :ITEMLEVEL

16.DO BEGIN

17. SUSPEND;

18.END

19.END

20.END;

This sort of recursive iteration is exactly what you need to walk up and down the branches of hierarchical data because these stored procedures are recursive: You can call them from within themselves to get children of children, and so on. Instead of getting all the rows in a generation, and then getting the next generation, this strategy gets the first child of the first child, then the first grandchild of the first child, and so on until the last descendant is found.

In the InterBase language, SUSPEND means to return the RETURNS variables as the next row in the result set. The first SUSPEND (line 11) returns the values from the first row of the query on the immediate children of STARTING_ITEM_ID (lines 5 through 8). The next SUSPEND (line 17) returns whatever comes back from a recursive call to the GETCHILDREN select procedure. As long as that second call returns rows (that is, as long as it still has grandchildren and descendants to report), the second SUSPEND will keep passing the return values back to the original caller. When it has no more return values, the calling code continues and uses the first SUSPEND to return the second row of the original query. If you don’t reset the ITEMLEVEL in the outer loop (line 10), it will contain the value from the last iteration of the inner loop (line 15).

Use a TQuery to call InterBase select procedures, not a TStoredProc. The syntax is simple:

with Query1 do begin

SQL.Clear; SQL.Add('SELECT * FROM

GetChildren(' + IntToStr(CurrentItemID) + ',0)');

Open;

end;

The result set will have all the children of the current item and will identify their level.

Products | Contact Us | About Us | Privacy | Ad Info | Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.

All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

To access the contents, click the chapter and section titles.

Kick Ass Delphi Programming

Go!

Keyword

(Publisher: The Coriolis Group)

Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin

ISBN: 1576100448

Publication Date: 09/01/96

Search this book:

Go!

-----------

The TreeData Components

The TreeData components are components I’ve created that allow you to view, navigate, and manage hierarchical data. They will display the rows in a graphical tree form such that each level is indented to show its ownership, show the entire lineage of an item, and give your application a list of all the ancestor or descendent IDs. There are several components in the family, and I’ve summarized them in Table 11.4.

TABLE 11.4 The TreeData Family Of Components

Control

Description

TreeDataComboBox

Displays the items in an

 

indented tree layout on the

 

drop-down list; displays the

 

lineage in the edit control.

 

Allows incremental

 

searching on both the edit

 

and the drop-down.

 

Data-aware to link to

 

chosen IDs to a DataSource.

TreeDataOutline

Displays the entire tree

 

graphically and allows

 

expansion and contraction

 

of various branches.

 

Data-aware to link to

 

chosen IDs to a DataSource.

Use

Get a single choice from the user: get the ID or all the Ancestor or Descendent IDs.

Get a single choice from the user: get the ID or all the Ancestor or of Descendent IDs.

TreeDataList

Combines a

Allows user to pick any

 

TreeDataComboBox with a

number of tree items and

 

data-aware LlstBox.

save them to a table as a

 

 

set or load them as a set.

 

Data-aware to link all

 

 

choseb ID to a DataSource.

 

TreeDataUpdate

Combines a TreeOutline.

Maintains a hierarchical

 

with editing functions to

dataset.

 

edit and update the rows

 

 

that make up the hierarchy.

 

 

Immediate or cached

 

 

updates to DataSource.

 

The TreeData controls crystallize a lot of what I’ve been discussing in this chapter so far. Unfortunately, they represent thousands of lines of source code and cannot be fully reproduced here on the printed page. All the controls are available in source code form, however, on the CD-ROM accompanying this book.

They all require a table name, SQL query text, or a DataSource, as well as the field names with the item’s ID, the item’s parent’s ID, and display values to display in the tree. They load all the available rows and then fill the control’s display with the values in the correct hierarchy.

TreeData Property Management

Certain properties are very important in this operation. All the TreeData controls take the design-time properties: LookupDatabaseName,

LookupTableName, LookupSQL (mutually exclusive with LookupTableName), LookupDisplayField, LookupIDField, LookupParentIDField, and if used with Delphi 2.0, LookupSessionName. (See Figure 11.4.) Using these properties, a TreeData control loads all the data into memory and displays it as a hierarchical tree. The connection to the data table is then closed.

FIGURE 11.4 Properties of the TreeData components.

The TreeData controls also have a LookupSource property that can use an open DataSource to get the data. This lets you filter, range, or query the DataSource.DataSet property to control what items go into the control. The

LookupAutoRefresh property specifies whether or not you want to reload the lookup data if the LookupSource changes.

TreeData Component Internals

All these components share a base code unit TREEUTIL.PAS, which holds the definition of the various internal classes that manage the data. TREEUTIL.PAS defines a class named TTreeDataItem, which holds information about an item, and a class named TTreeDataItems, which is a TList descendent that keeps track of all the TTreeDataItem objects. Each of the controls expose a TTreeDataItems object as the property ItemList. You can call the public methods of this object to load, save, find, move, or delete an item. You can also get all ancestor or descendant IDs for an item, or get the top-level ID in an item’s lineage.

TTreeDataItems actually descends from class TStringList, which holds all the item IDs. The Object property of each TStringList item points to the TTreeDataItem object for that item. The user object pointers are in a separate TList and synchronized by the index into both lists; this index does not change after the data is loaded, so there is no chance of de-synchronization. Sorted TStrngLists will use binary searching within the IndexOf method, so they can easily find IDs. After it loads all the items and sorts the IDs, class TTreeDataItems iterates through all of them and puts the index for the first child and the next sibling in each item’s data structure. This allows easy iteration down and across the hierarchy.

With all that said of the TreeData family as a whole, I’ll briefly discuss each control in the family separately.

TreeDataComboBox

This control is data-aware, so you can use it to save the user’s choices to a table. It stores the single value to LookupIDField. The drop-down portion of the display shows the graphical tree, and the edit box shows the hierarchy of descriptions separated by colons. The edit box also allows incremental type-in that displays the first match to text already entered. When a match is found, typing the colon (or semi-colon) locks that item and moves the search point to text entered after the colon or semicolon. This allows you to continue typing to search that item’s children. This is shown in Figure 11.5.

FIGURE 11.5 TreeDataComboBox.

The TreeDataComboBox component has properties for the description, ID, and Item.FullDescription, which contains the delimited descriptions as displayed in the edit control. It has additional properties that return a string with all the parent or child IDs concatenated together.

Products | Contact Us | About Us | Privacy | Ad Info | Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.

All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

To access the contents, click the chapter and section titles.

Kick Ass Delphi Programming

Go!

Keyword

(Publisher: The Coriolis Group)

Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin

ISBN: 1576100448

Publication Date: 09/01/96

Search this book:

Go!

-----------

TreeDataListBox

This control incorporates both a TTreeDataComboBox at the top and a data-aware TListBox beneath it. (See Figure 11.6.) The TListBox acts on all the rows in its DataSource instead of just the current row. You can use the combo box to pick items and then add them to the list. When you call SaveIDs or exit the control with the SaveOnExit flag set, the control writes all the IDs to the DataSource, one per row. The DataSource can incorporate a range (for example, a MasterSource) or filter so it presents detail rows for only master items in the MasterSource or filter.

FIGURE 11.6 TTreeDataListBox.

TreeDataOutline and TreeDataUpdate

TreeDataOutline displays the hierarchy in a graphical structure resembling the Windows 95 Explorer interface. As with the other controls, you can get the current item’s ID, description, and Item.FullDescription, as well as a string list of all the parent or child IDs.

The TreeDataUpdate control (see Figure 11.7) combines this functionality with some additional behavior to manage a hierarchical data structure from a table.

FIGURE 11.7 TreeDataUpdate.

End Note

Hierarchies use the terminology of family relationships (parents, grandchildren, ancestors, descendants) because families are the most universal example of a gathering of individual entities—here, human beings—relating to other entities in hierarchical ways. Ironically, it is also a reminder that while you may build systems to handle recursive hierarchies generically, each item’s value lies in the information that it contains; its place in the family tree is not valuable in and of itself. Hierarchical structuring is a means of finding the correct item; it’s up to you to ensure that the item is worth finding.

Products | Contact Us | About Us | Privacy | Ad Info | Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.

All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

To access the contents, click the chapter and section titles.

Kick Ass Delphi Programming

Go!

Keyword

(Publisher: The Coriolis Group)

Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin

ISBN: 1576100448

Publication Date: 09/01/96

Search this book:

Go!

-----------

CHAPTER 12

The Oracle Vanishes

DON TAYLOR

Utilities For Linking Memos And Pictures To A Delphi Database

Delphi Drag And Drop

Packing Paradox And DBASE Tables

Keystroke Translation

Playing WAV Files

Ace Breakpoint has returned—but his casebook is missing, and larceny is suspected. Ace begins the hunt for the Mysterious Stranger, who has in turn been hunting for Delphi Wisdom. The plot thickens!

You’re about to embark on a journey that some might call strange. I guess I

would be among the first to agree with them.

It was only a year ago that both Delphi and Ace Breakpoint first came upon the scene. Delphi was, of course, the product of the extremely creative team of developers at Borland International. Ace was—well, the product of necessity.

While learning Delphi, it became obvious that no amount of words could ever describe every aspect of this incredible product. One could never just read about Delphi and learn it—one had to discover it firsthand. My assignment: To write the tutorial map, to lead the expedition and to create a detailed example, using Delphi in a real-world situation. And oh, yes —to hold the readers’ attention for some 200+ pages!

My proposed solution was to write an adventure story that carried the reader through the entire tutorial, featuring one of the most unusual programming consultants of all time. I pitched the idea to Jeff Duntemann, then held my breath. In case you’re not aware, Jeff is just as daring and fun-loving as he is brilliant. He gave me the thumbs-up, and I created Ace Breakpoint, hard-hitting fictional Private Investigator-turned-programmer....

As a boy growing up in Hackensack, Ace dreamed of becoming a P.I., just like his heroes in the classic 1940 movies—Phil Marlowe, Sam Spade, and Ellery Queen. But after years of study and hard work learning investigative techniques and snappy dialog, Ace discovered there was little demand for a 1940’s-style P.I. in today’s world.

Undaunted, Ace decided to make a serious career change. This time, Ace would choose a profession that would be in demand for a lifetime—he would become a Windows programmer. But in addition to becoming today’s professional, he also wanted to become a “person of the 90’s.” So he moved to Poulsbo, Washington, and for two long years he attended night classes in computer programming at the Suquamish School of Art. On graduation day, he was awarded an Associate of Arts in Programming Appropriateness. He promptly rented an office and hung out his shingle.

As with most heroes, Ace has his minor flaws. In spite of all his formal education, he is still a little rough around the edges. Although he does his best to care about the needs of others, there are times when sensitivity hangs on him like a cheap suit. He frequently makes mistakes. But he has a tenacious quality about him, and you’ve got to love him for that. When faced with problems, he will doggedly pursue them until he digs out the answers.

Oh, yes—just one little matter. Although the Breakpoint adventures are fictional, one thing is true. The location—Poulsbo—is a real town, situated about 15 miles (as the crow swims) west of Seattle. At its inception, it was a fishing village, founded by a hardy group of Norwegian immigrants. Today Poulsbo is largely a tourist town, with marinas and a winding street full of quaint shops and restaurants. (You don’t want to move there, though. It’s too crowded already. And it rains nearly all the time. Honest.)

Very little else in the Breakpoint adventures bears any connection to reality. And of course, unless stated otherwise, characters in the stories are purely fictional, and are not meant to represent any person, living or dead.

So don’t touch that dial! Grab your favorite snack, turn down the lights, slide

up close to your screen, and prepare yourself for the adventure I call...

Ace Breakpoint in...

“The Case of the Missing Ink!”