Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TIBDataSet.Locate, set current record

245 views
Skip to first unread message

Boris Schlüszler

unread,
Nov 27, 2001, 11:21:35 AM11/27/01
to
Hi!

Is there a way, to set the current record in a TIBDataSet to match a
primary search without using "Locate"?
TIBDataSet.Locate would do it, but I learnt: it doesn't use index, hence
it takes too long.

My goal is as follows:

I have a DBGrid wich displays the dataset (as result of an arbitrary
select statement).
Then I have a non-data-aware component (and it should stay
non-data-aware) to enter values.
If the button is pressed, the dataset should be updated.

Up to now I used TIBDataSet.Locate to scan for the ID, called
TIBDataSet.Edit, refreshed all fields, and called Post on the dataset.
Works fine with small datasets or subsets.

Now, Locate doesn't work for me (no index-search).
What then is the UpdateSQL-property in TIBDataSet for? Is it just for
data-aware entry?
Is the only way to set the current record by visually selecting it in
the grid (besides "locate", "first", "last" and so on)?
Can I call the Update-SQL method in TIBDataSet myself? Or is it
component driven only?

If I used a separate TIBSQL to update values, how do I tell TIBDataSet
to refresh one particular record?
Can I call the Refresh-method myself?

Any comments on this basic problems are veeeeery appreciated.
I fear, I completely misunderstand some things here.

Regards, Boris


P.G. Willemsen

unread,
Nov 27, 2001, 12:09:54 PM11/27/01
to
I'm longing for an answer to this question, too

Regards,

Peter


Craig Stuntz (TeamB)

unread,
Nov 27, 2001, 12:39:58 PM11/27/01
to

Boris Schlüszler wrote:
>
> Is there a way, to set the current record in a TIBDataSet to match a
> primary search without using "Locate"?

Not without incurring as much overhead as Locate would. IBX datasets
don't (presently) use any kind of circular buffering. You always have,
at a minimum, the first record and every record up to the current record
in memory.

This corresponds rather closely with how fetching in InterBase works.
You can't fetch bidirectionally or jump to the middle of a SELECTion.
To "go to the middle" you'd have to write a new query and execute that.

> TIBDataSet.Locate would do it, but I learnt: it doesn't use index, hence
> it takes too long.

In this case, your dataset is too large. In general, I consider it a
bad practice to present the user with more than a couple hundred records
in a list. It's too much to scroll through. When your result sets get
this big, you need to give the user tools to reduce the size of the
result set. For example, instead of showing the user all payroll
records in a week, I give them a screen with tabs for each day of the
week. It makes it much easier to find the record they're searching for.

> What then is the UpdateSQL-property in TIBDataSet for? Is it just for
> data-aware entry?

UpdateSQL is used when you call Post after editing the dataset. In
general, it's most useful for data-aware controls, but it would also be
used if you called Edit and then Post in code.

> Is the only way to set the current record by visually selecting it in
> the grid (besides "locate", "first", "last" and so on)?

I'm not sure I understand your question. The only way to move the
cursor is to move the cursor.

> Can I call the Update-SQL method in TIBDataSet myself?

Don't fool with this. The internal update query is protected for a
reason.

> If I used a separate TIBSQL to update values, how do I tell TIBDataSet
> to refresh one particular record?
> Can I call the Refresh-method myself?

Yes, Refresh will refresh the current record only in IBX.

HTH,

-Craig

--
Craig Stuntz (TeamB) · Vertex Systems Corp. · Columbus, OH
We're hiring: http://www.vertexsoftware.com/careerops.htm#sd
Delphi/InterBase WebLog: http://delphi.weblogs.com

Boris Schlüszler

unread,
Nov 27, 2001, 1:23:07 PM11/27/01
to
"Craig Stuntz (TeamB)" schrieb:

> > TIBDataSet.Locate would do it, but I learnt: it doesn't use index, hence
> > it takes too long.
>
> In this case, your dataset is too large. In general, I consider it a
> bad practice to present the user with more than a couple hundred records
> in a list. It's too much to scroll through.

You're right.
Problem is: I want grant the possibility to the user, to enter an arbitrary
select statement.
Maybe he just won't scroll through it.
Maybe he just ignores it.
But it should be there.


> > Is the only way to set the current record by visually selecting it in
> > the grid (besides "locate", "first", "last" and so on)?
>
> I'm not sure I understand your question. The only way to move the
> cursor is to move the cursor.

OK: I want to move the cursor to the record with ID=56 ("ID" is primary index).
How could I tell TIBDataSet?
If I look at the SQL-Statement in TIBDataSet, it should also be possible, to
"move" the cursor to a record, which isn't even in the dataset.
All the SQL-statements refer to a particular record via a primary index,
independently from what is exposed to the outer world with the initial SELECT.
There should be a way to set the Update/Refresh-parameters via
TIBDataSet-methods.

> > If I used a separate TIBSQL to update values, how do I tell TIBDataSet
> > to refresh one particular record?
> > Can I call the Refresh-method myself?
>
> Yes, Refresh will refresh the current record only in IBX.

How do I refresh the record with ID=56 ("ID" is primary index)?
Problem is: DBGrid is displayed via datasource of TIBDataSet.
TIBSQL updates the data. How to tell TIBDataSet to refresh the updated record?


Craig Stuntz (TeamB)

unread,
Nov 27, 2001, 4:03:14 PM11/27/01
to

Boris Schlüszler wrote:
>
> You're right.
> Problem is: I want grant the possibility to the user, to enter an arbitrary
> select statement.

You're a brave man. Or you *really* trust your users. Or both...

> Maybe he just won't scroll through it.
> Maybe he just ignores it.
> But it should be there.

So don't just worry about large result sets. If you're allowing the
users to enter arbitrary SELECTs, they can easily enter a query which
will essentially lock up their connection. I wouldn't ever allow people
to do this.

If you do allow it, I would re-implement Locate so that it gives up
after a certain amount of searching.



> > > Is the only way to set the current record by visually selecting it in
> > > the grid (besides "locate", "first", "last" and so on)?
> >
> > I'm not sure I understand your question. The only way to move the
> > cursor is to move the cursor.
>
> OK: I want to move the cursor to the record with ID=56 ("ID" is primary index).
> How could I tell TIBDataSet?

Use Locate. There is only one cursor for a dataset.

> If I look at the SQL-Statement in TIBDataSet, it should also be possible, to
> "move" the cursor to a record, which isn't even in the dataset.

It shouldn't be possible. The TIBDataset class is designed to
encapsulate an SQL result set. While you could, with some hacking,
persuade the statements used to query the DB for information not in the
SelectSQL result set, this would be violating the design and intended
purpose of TIBDataset. If you want something outside of the SelectSQL
result set, you need to change the SQL, param values, or use a different
dataset.

> All the SQL-statements refer to a particular record via a primary index,
> independently from what is exposed to the outer world with the initial SELECT.
> There should be a way to set the Update/Refresh-parameters via
> TIBDataSet-methods.

No, there shouldn't, IMHO. Don't think of TIBDataset as a group of
unrelated statements. Rather, think of it as class which includes
properties and methods for operations on a *single* set of records.

> How do I refresh the record with ID=56 ("ID" is primary index)?

You Locate there and call Refresh.

Jason Wharton

unread,
Nov 27, 2001, 5:39:05 PM11/27/01
to
> Is there a way, to set the current record in a TIBDataSet to match a
> primary search without using "Locate"?
> TIBDataSet.Locate would do it, but I learnt: it doesn't use index, hence
> it takes too long.

What part about my earlier post didn't you understand? I thought I gave a
very clear and detailed explanation of this.

Jason Wharton
CPS - Mesa AZ
http://www.ibobjects.com

Jason Wharton

unread,
Nov 27, 2001, 5:47:27 PM11/27/01
to
> > Is there a way, to set the current record in a TIBDataSet to match a
> > primary search without using "Locate"?
>
> Not without incurring as much overhead as Locate would. IBX datasets
> don't (presently) use any kind of circular buffering. You always have,
> at a minimum, the first record and every record up to the current record
> in memory.
>
> This corresponds rather closely with how fetching in InterBase works.
> You can't fetch bidirectionally or jump to the middle of a SELECTion.
> To "go to the middle" you'd have to write a new query and execute that.

This is correct. It requires the dataset implementation to have the smarts
to use parameterized queries internally to virtualize the larger dataset in
an efficient way. One ascending and one descending in just the right way to
efficiently fetch only the needed records and thus benefit from indexes in
the process.

> > TIBDataSet.Locate would do it, but I learnt: it doesn't use index, hence
> > it takes too long.
>
> In this case, your dataset is too large. In general, I consider it a
> bad practice to present the user with more than a couple hundred records
> in a list. It's too much to scroll through. When your result sets get
> this big, you need to give the user tools to reduce the size of the
> result set. For example, instead of showing the user all payroll
> records in a week, I give them a screen with tabs for each day of the
> week. It makes it much easier to find the record they're searching for.

This is nice where there is a limiting context like days, but in many cases
there isn't such a luxury. Take a lookup combo box for example. What if you
could select any name from among 500,000? The answer nowdays is don't use a
lookup combo but with a properly implemented dataset you can use it and the
table size doesn't matter any longer.

FWIW,

Boris Schlüszler

unread,
Nov 28, 2001, 7:44:29 AM11/28/01
to
Hi Jason!

I understood very clearly, what you described to me.
And I do also see the problem that is in the IBX-dataset-implementation.
I' m nearly convinced now to take a closer look at IBOjects.

I had to start somewhere, and I started with IBX which has - IMHO - a good
look and feel.
Do IBObjects and IBX cooperate?

Thank you for your time and patience.

Regards,

Jason Wharton schrieb:

Martijn Tonies

unread,
Nov 28, 2001, 10:01:45 AM11/28/01
to

"Boris Schlüszler" <bo...@ts-autovermietung.de> schreef in bericht
news:3C04DC2D...@ts-autovermietung.de...


> Hi Jason!
>
> I understood very clearly, what you described to me.
> And I do also see the problem that is in the IBX-dataset-implementation.
> I' m nearly convinced now to take a closer look at IBOjects.
>
> I had to start somewhere, and I started with IBX which has - IMHO - a good
> look and feel.
> Do IBObjects and IBX cooperate?

IBObjects and IBX both use their own connection components. IBO does have a
TDataset descendant for compatibility with 3rd party products that depend on
it, just like IBX and is more compatible with the BDE components. Migrating
from the BDE to IBO can be done in minutes, if not seconds!

IBO is more than just connectivity (as Jason already told you) - it also has
a very complete set of data-aware components (not compatible with TDataset)
that give you a lot of power and great features to radically develop an
application with IBO and InterBase. Be sure to give it a try!

--
Martijn Tonies
Upscene Productions

InterBase Workbench - The Developer Tool for InterBase
http://www.interbaseworkbench.com

"Experience is what you get when you didn't get what you wanted"

Craig Stuntz (TeamB)

unread,
Nov 28, 2001, 10:20:45 AM11/28/01
to

Boris Schlüszler wrote:
>
> Do IBObjects and IBX cooperate?

It's highly unlikely that you'd want to use both in a single
application.

Craig Stuntz (TeamB)

unread,
Nov 28, 2001, 10:22:47 AM11/28/01
to

Jason Wharton wrote:
>
> This is nice where there is a limiting context like days, but in many cases
> there isn't such a luxury. Take a lookup combo box for example. What if you
> could select any name from among 500,000? The answer nowdays is don't use a
> lookup combo but with a properly implemented dataset you can use it and the
> table size doesn't matter any longer.

I just don't think it's the right control for the job. Why give people
even the *possibility* of scrolling through 500,000 names? It doesn't
make any sense. In one way or another they have to narrow their search,
whether it's through an incremental search or whatever.

Jason Wharton

unread,
Nov 28, 2001, 2:06:14 PM11/28/01
to
> I just don't think it's the right control for the job. Why give people
> even the *possibility* of scrolling through 500,000 names? It doesn't
> make any sense. In one way or another they have to narrow their search,
> whether it's through an incremental search or whatever.

Of course things are narrowed down. That is exactly my point. The difference
between what you are suggesting and what I am suggesting is who does the
work. In your apps, you the programmer muck around and fiddle something
together. Parsing your SQL, plugging in parameter values, opening and
closing datasets, and so on.

What I am suggesting is they give the general SQL for the whole potential
range of records, even if it is quite a large number of them, and then
simply use the ease of stock data aware control, pick lists, etc. and leave
the hard work up to the dataset. One static SQL statement and the dataset
does the rest.

You suggest I think the person is actually going to hit page down through
500,000 records and that is totally absurd. Of course they are going to
limit things. The Locate() method works wonders for helping people find what
they want. There is no reason the dataset cannot be smart about doing their
"narrowing" for them, I know because mine does. And in some circumstances so
did the BDE.

Regards,

Boris Schlüszler

unread,
Nov 28, 2001, 2:31:14 PM11/28/01
to
I agree with you, Jason.
That's exactly my point.

Jason Wharton schrieb:

Craig Stuntz (TeamB)

unread,
Nov 28, 2001, 5:01:42 PM11/28/01
to

Jason Wharton wrote:
>
> Of course things are narrowed down. That is exactly my point. The difference
> between what you are suggesting and what I am suggesting is who does the
> work. In your apps, you the programmer muck around and fiddle something
> together. Parsing your SQL, plugging in parameter values, opening and
> closing datasets, and so on.

There are two differences:

1. Who does the work.
2. How the result is presented to the end user.

I was addressing (2) and not (1). You appear to be referring to (1).

Jason Wharton

unread,
Nov 28, 2001, 7:17:10 PM11/28/01
to
> > Of course things are narrowed down. That is exactly my point. The
difference
> > between what you are suggesting and what I am suggesting is who does the
> > work. In your apps, you the programmer muck around and fiddle something
> > together. Parsing your SQL, plugging in parameter values, opening and
> > closing datasets, and so on.
>
> There are two differences:
>
> 1. Who does the work.
> 2. How the result is presented to the end user.
>
> I was addressing (2) and not (1). You appear to be referring to (1).

I am simply keeping to the point of this thread, as the subject line
indicates.

You once told me you don't help people by suggesting they use an entirely
different piece of technology that they are endeavoring to use. This person
wants to use the Locate() method, not rewrite their entire GUI and use
something like DataSnap and its plethora of added layers and complexity.

An efficient well-designed Locate() is all they need.

Craig Stuntz (TeamB)

unread,
Nov 29, 2001, 9:27:42 AM11/29/01
to

Jason Wharton wrote:
>
> I am simply keeping to the point of this thread, as the subject line
> indicates.

Jason, the point was that I wasn't arguing with you.



> You once told me you don't help people by suggesting they use an entirely
> different piece of technology that they are endeavoring to use. This person
> wants to use the Locate() method, not rewrite their entire GUI and use
> something like DataSnap and its plethora of added layers and complexity.

I see a difference between:

1) Wanting to present the user with an efficient way to find the record
they're looking for, and:
2) Wanting to use the Locate method.

(Where DataSnap came in to this I have no idea.)

1) is a reasonable concern which I was trying to address.

2) puts the cart before the horse, IMHO.

Suggesting the use of a different method/methods of the same component
isn't telling them to "use an entirely different piece of technology."

Jason Wharton

unread,
Nov 29, 2001, 4:40:05 PM11/29/01
to
In short, we are in a circular deadlock.

My observations:

The person has already designed their user interface and how they want
things to work but they are hitting some trouble with IBX. They debugged the
problem and found it has to do with the implementation of the Locate()
method. It is apparent by their diligent persistence on wanting a better
implementation of the Locate() method that they really want to maintain
their current design which relies upon it.

So, I enter the scene and explained in great detail how the Locate() method
can be implemented and why IBX is giving them troubles. I then went on to
explain why other implementations they have seen the Locate() method perform
much better and how it is possible to get even a client/server database such
as InterBase to do likewise.

My goal and intent was to inform this person they can keep their user
interface as designed if they use my implementation of the Locate() method
in IBO. I uphold the way a person wants their end user interface to look and
feel as of utmost importance and I work diligently to allow them as much
flexibility and simplicity there as possible. Obviously this person needs
that.

Then, you enter the scene and start telling them in so many words they need
to redesign their application to have a more efficient way of interacting
with the end-user. You were carefully telling them they need to avoid using
any tool, component or feature of the VCL which makes use of the Locate()
method in their application. In so many words you were insinuating they had
done a poor job designing their user interface.

The irony here is you now claim I am putting the cart before the horse by
dictating what they should do with their user interface design. I am merely
telling this person the design they have is fine if they use tools which are
designed well to support it, which mine are and IBX isn't. Please just
accept and admit that rather than using thinly veiled insinuations that
people are using poor design if IBX doesn't accommodate them.

There are some things IBX does well and it favors people who want
applications a certain way, but there are other people who want their apps
in ways that IBX just doesn't do well for them. I think it is a fundamental
orientation that for many it is hard to change from one way to the other.
That is why I hang out here looking for any strays that wander into the
wrong pastures, such as Boris did.

Don't you agree its better that someone with the IBO orientation of doing
things use IBO with InterBase rather than giving up on InterBase and IBX and
going with MySQL or something like that? Borland makes money on InterBase
licensing, not IBX licensing. Please remember that.

FWIW,

Craig Stuntz (TeamB)

unread,
Nov 29, 2001, 5:55:53 PM11/29/01
to

Jason Wharton wrote:
>
> My goal and intent was to inform this person they can keep their user
> interface as designed if they use my implementation of the Locate() method
> in IBO.

In short, rather than modify their UI -- from something which I don't
think is a good idea irregardless of performance issues -- they should
throw out what they've built the core of their app with? Some choice!
Now I may have to start arguing with you...

> Then, you enter the scene and start telling them in so many words they need
> to redesign their application to have a more efficient way of interacting
> with the end-user. You were carefully telling them they need to avoid using
> any tool, component or feature of the VCL which makes use of the Locate()
> method in their application.

Jason, this is patently false. You are putting words in my mouth to
suit your own line of argument. In fact, I said the *opposite:*

"Craig Stuntz (TeamB)" wrote:


>
> Boris Schlüszler wrote:
> >
> > OK: I want to move the cursor to the record with ID=56 ("ID" is primary index).
> > How could I tell TIBDataSet?
>
> Use Locate.

If you're going to quote me, use your newsreader, eh? I don't know who
you're arguing with here but what you're "responding to" didn't come
from me.

There's nothing wrong with Locate as it stands now provided that the
result sets are a of a reasonable size. You don't need to avoid using
Locate; you need to avoid queries with huge result sets. This is a
basic principle of good C/S application design -- which is exactly what
I suggested to Boris originally:

"Craig Stuntz (TeamB)" wrote:
>
> In this case, your dataset is too large. In general, I consider it a
> bad practice to present the user with more than a couple hundred records
> in a list. It's too much to scroll through.

Jason Wharton wrote:
> In so many words you were insinuating they had
> done a poor job designing their user interface.

I *do* feel that giving a user a list of 500,000 records is not a
useful thing.

> The irony here is you now claim I am putting the cart before the horse by
> dictating what they should do with their user interface design. I am merely
> telling this person the design they have is fine if they use tools which are
> designed well to support it, which mine are and IBX isn't.

What part about what I wrote is not clear to you? You don't have to
agree with me -- it seems you don't, and that's fine -- but I *don't*
think this is a good design, and not just for performance reasons.

Consider the difference in Code Completion between D5 and D6: In D5
you have pretty much what you and Boris are describing: a long list
(though not nearly 500,000 records) of every possible thing which you
could type at the present moment. The performance isn't too bad, but
finding any specific entry in the list is difficult. In D6, you have a
sequential search which progressively refines the list as you type. I
find the D6 interface much easier to use.

Jason Wharton

unread,
Nov 29, 2001, 7:24:15 PM11/29/01
to
Craig,

I suppose I will humor you some more.

> > My goal and intent was to inform this person they can keep their user
> > interface as designed if they use my implementation of the Locate()
method
> > in IBO.
>
> In short, rather than modify their UI -- from something which I don't
> think is a good idea irregardless of performance issues -- they should
> throw out what they've built the core of their app with? Some choice!

Ok Craig, get your storyline consistent here. The first thing you say is
people need to determine how they want their users to interact with the data
and then they chose the technology they want to do it with and now you are
saying they chose their technology first and design their user interface to
suit the technology, which is something you told me was putting the cart
before the horse.

> Now I may have to start arguing with you...

Ok, this could be fun. Bring it on.

This conversation has evolved through levels of understanding. I'm working
at the tip and now you are pulling forward things from the past which are
not harmonious with the current context. That's called SPIN.

> > Then, you enter the scene and start telling them in so many words they
need
> > to redesign their application to have a more efficient way of
interacting
> > with the end-user. You were carefully telling them they need to avoid
using
> > any tool, component or feature of the VCL which makes use of the
Locate()
> > method in their application.
>
> Jason, this is patently false. You are putting words in my mouth to
> suit your own line of argument. In fact, I said the *opposite:*

Look, you can two step here and backslide all you want. The fact is the
person's user interface design was done in a way that depends on the Locate
method. They discovered that in IBX the implementation of Locate() is
brain-dead and incapable of delivering satisfactory performance to meet
their needs. At that point you have one option or the other.

1) Drop IBX for something that works at the core level and keep the existing
user interface design.

OR

2) Keep IBX and rewrite their user interface design to suit its
deficiencies.

There is no middle ground and you either promote one or the other.

I'm on the side of these people keeping their perfectly fine UI design and
you are telling them to scrap it and redesign to suit IBX's deficiencies.

> There's nothing wrong with Locate as it stands now provided that the
> result sets are a of a reasonable size. You don't need to avoid using
> Locate; you need to avoid queries with huge result sets. This is a
> basic principle of good C/S application design -- which is exactly what
> I suggested to Boris originally:

No, that is an excuse to avoid making IBX's deficiencies apparent.

If someone has a picklist in a grid to select a customer by name from a
table of hundreds of thousands of names how are you going to manually refine
that query in the application code? That would be a pretty messy job and
prone to a lot of problems. What if your app had a lot of situations like
that? Copy and paste events.. Yuck. That is a lot of messy code to maintain.
How much nicer if the proper refinements for efficiency are all handled for
you automatically inside the dataset. That sounds like a bargain to me.

Why do you find disagreement with this?

> > The irony here is you now claim I am putting the cart before the horse
by
> > dictating what they should do with their user interface design. I am
merely
> > telling this person the design they have is fine if they use tools which
are
> > designed well to support it, which mine are and IBX isn't.
>
> What part about what I wrote is not clear to you? You don't have to
> agree with me -- it seems you don't, and that's fine -- but I *don't*
> think this is a good design, and not just for performance reasons.
>
> Consider the difference in Code Completion between D5 and D6: In D5
> you have pretty much what you and Boris are describing: a long list
> (though not nearly 500,000 records) of every possible thing which you
> could type at the present moment. The performance isn't too bad, but
> finding any specific entry in the list is difficult. In D6, you have a
> sequential search which progressively refines the list as you type. I
> find the D6 interface much easier to use.

Thanks for vividly illustrating my point here.

Delphi 5's implementation is like IBX's implementation of Locate() which
requires everything to be pulled into the client buffer to operate with.

IBO's implementation of Locate() is like the Delphi 6 improvements which
senses what you are locating on and only has to pull in records from a small
refined context. Very fast, sleek and efficient.

We agree on all the principles of good design. The difference is IBX doesn't
implement them so the app developers have to jump through all the hoops in
their application code to obey the principles. IBO does use the wise client
server principles right inside of it so that app developers are free to just
code what they want done and have IBO take care of making it an appropriate
way to use client/server for them.

Craig Stuntz (TeamB)

unread,
Nov 30, 2001, 9:18:41 AM11/30/01
to

Jason Wharton wrote:
>
> I suppose I will humor you some more.

Your tone here (and throughout the rest of the message) is patently
insulting. I'm not going to bring the level of discussion in this
newsgroup down by indulging it. If you want to talk about design
principles, I'm fine with that, but I will not indulge your
condescending sales pitch.

Jason Wharton

unread,
Nov 30, 2001, 7:58:01 PM11/30/01
to
> > I suppose I will humor you some more.

> Your tone here (and throughout the rest of the message) is patently
> insulting. I'm not going to bring the level of discussion in this
> newsgroup down by indulging it. If you want to talk about design
> principles, I'm fine with that, but I will not indulge your
> condescending sales pitch.

I do tend to get carried away at times. I have strongly held convictions
about technical quality and I let that get in the way of being more
friendly. Please accept my apologies.

Regards,

Jason Wharton

unread,
Nov 30, 2001, 8:59:56 PM11/30/01
to
Ok, let me attempt to rephrase my post so that it is void of offensiveness.

<take #2>

Craig,

I hope if nothing else you at least find some humor out of this.

> > My goal and intent was to inform this person they can keep their user
> > interface as designed if they use my implementation of the Locate()
> > method in IBO.
>
> In short, rather than modify their UI -- from something which I don't
> think is a good idea irregardless of performance issues -- they should
> throw out what they've built the core of their app with? Some choice!

At this point in their stage of the game they have one of two choices.
Neither of them are pretty and you can find fault with either one. It's a
balance sheet of pros and cons they are going to have to do for themselves.
We need to get the facts out in the open for them to accomplish this.

> Now I may have to start arguing with you...

Fine with me, you've bested me before and I'll take it again if needed.
Bring it on.

> > Then, you enter the scene and start telling them in so many words they
need
> > to redesign their application to have a more efficient way of
interacting
> > with the end-user. You were carefully telling them they need to avoid
using
> > any tool, component or feature of the VCL which makes use of the
Locate()
> > method in their application.
>
> Jason, this is patently false. You are putting words in my mouth to
> suit your own line of argument. In fact, I said the *opposite:*

This person's user interface design was done in a way that depends on the


Locate method. They discovered that in IBX the implementation of Locate() is

incapable of delivering satisfactory behavior to meet their needs. At that


point you have one option or the other.

1) Drop IBX for something that works as needed to keep the existing user
interface design.

OR

2) Keep IBX and rewrite their user interface design to suit its
deficiencies.

> There's nothing wrong with Locate as it stands now provided that the


> result sets are a of a reasonable size. You don't need to avoid using
> Locate; you need to avoid queries with huge result sets. This is a
> basic principle of good C/S application design -- which is exactly what
> I suggested to Boris originally:

If someone has a picklist in a grid to select a customer by name from a


table of hundreds of thousands of names how are you going to manually refine
that query in the application code? That would be a pretty messy job and
prone to a lot of problems. What if your app had a lot of situations like
that? Copy and paste events.. Yuck. That is a lot of messy code to maintain.
How much nicer if the proper refinements for efficiency are all handled for

you automatically inside the dataset?

If your dataset will do the proper client/server refinements automatically,
what is wrong with a UI design that exploits this is the crux of our
differences...

> What part about what I wrote is not clear to you? You don't have to
> agree with me -- it seems you don't, and that's fine -- but I *don't*
> think this is a good design, and not just for performance reasons.
>
> Consider the difference in Code Completion between D5 and D6: In D5
> you have pretty much what you and Boris are describing: a long list
> (though not nearly 500,000 records) of every possible thing which you
> could type at the present moment. The performance isn't too bad, but
> finding any specific entry in the list is difficult. In D6, you have a
> sequential search which progressively refines the list as you type. I
> find the D6 interface much easier to use.

Thanks for vividly illustrating my point here.

Delphi 5's implementation is like IBX's implementation of Locate() which
requires everything to be pulled into the client buffer to operate with.

IBO's implementation of Locate() is like the Delphi 6 improvements which
senses what you are locating on and only has to pull in records from a small
refined context.

In short, we agree on all the principles of good design but our difference
is where they are implemented and who does the hoop jumping. I believe
having the dataset do it for you adds greatly to what can be done and how
simple it is for application developers to do their job. What's getting
under my skin is you seem to unwaveringly claim this is a "bad" thing
instead of a very cool thing. Which begs the question, why?

I guess I'm just being like an immature little child who is looking for a
few pats on the back from an approving authority figure. Perhaps in the
future Craig you might consider saying, "Wow Jason, that's pretty nifty."
and it will be all over. <g> (here's where I'm genuinely hoping to humor
you)

FWIW,
Jason Wharton
CPS - Mesa AZ
http://www.ibobjects.com

</take #2>

Craig Stuntz (TeamB)

unread,
Dec 3, 2001, 9:56:25 AM12/3/01
to

Jason Wharton wrote:
>
> Ok, let me attempt to rephrase my post so that it is void of offensiveness.

Much better. :)


>
> 1) Drop IBX for something that works as needed to keep the existing user
> interface design.
>
> OR
>
> 2) Keep IBX and rewrite their user interface design to suit its
> deficiencies.

Honestly, I think this conversation would be more constructive if we
stopped talking about IBX and "alternatives" and just talked about user
experiences without discussing implementation at all, because it avoids
"loaded" topics while sticking to the most important issue, which is
making user-friendly software.

What we're really discussing here is a basic problem in C/S
applications: How do you give the end user the ability to select an
item from a list which may be millions of rows long? There are two
potential pitfalls here:

1) Performance. This is an implementation detail (albeit a rather
important one) so I'll set it aside until I've dealt with:

2) End user experience. Since nobody wants to scroll through the list
of millions of records (and my observations of non-computer-saavy people
show that they will try to do just that if given the opportunity), we
need to lead them gently in the direction of a more refined search.

We solve this problem in several different ways in our applications,
because the most appropriate solution varies depending upon several
different factors, including:

o Must the application sever be stateless? (Not a concern in a two
tier app, but our newer apps are not two tier. Any solution which can
scale to three tiers must support stateless servers.)
o Are there convenient ways to subdivide the data (like the days of
week example I gave earlier in the thread)?
o How many records are expected to be in the table?
o Are spelling mistakes an issue?

In the end we have two general UI solutions for this problem:

1) Subdivide the dataset, using tabs, tree views, or other controls.
2) Show no records, then progressively refine the search as the user
types, a la D6.

> If someone has a picklist in a grid to select a customer by name from a
> table of hundreds of thousands of names how are you going to manually refine
> that query in the application code? That would be a pretty messy job and
> prone to a lot of problems.

Parameterized queries aren't that hard. If a simple parameterized
query wouldn't do the job we write a stored proc for it and just change
the parameters we send to that.

> What if your app had a lot of situations like
> that? Copy and paste events.. Yuck.

Copy and paste?!? We have a rule against it (seriously, we do). When
we need to reuse code we write a class or a component.

> That is a lot of messy code to maintain.
> How much nicer if the proper refinements for efficiency are all handled for
> you automatically inside the dataset?

But these "refinements for efficiency" you're describing don't seem to
reduce the length of the result set provided to the end user, which is
my goal here. I don't want to give them a list which even makes it
possible to scroll through a million records. I want to require the end
user to provide enough information to at least come close to the record
they're searching for.

> > Consider the difference in Code Completion between D5 and D6: In D5


> > you have pretty much what you and Boris are describing: a long list
> > (though not nearly 500,000 records) of every possible thing which you
> > could type at the present moment. The performance isn't too bad, but
> > finding any specific entry in the list is difficult. In D6, you have a
> > sequential search which progressively refines the list as you type. I
> > find the D6 interface much easier to use.
>
> Thanks for vividly illustrating my point here.
>
> Delphi 5's implementation is like IBX's implementation of Locate() which
> requires everything to be pulled into the client buffer to operate with.
>
> IBO's implementation of Locate() is like the Delphi 6 improvements which
> senses what you are locating on and only has to pull in records from a small
> refined context.

But it doesn't do what D6 does (or, at least, I'm presuming it doesn't,
because it shouldn't be called Locate if it does). D6 gives you a
progressively smaller selection of choices as you type. It reduces the
size of the list as your search criteria becomes more specific. I find
this *much* easier to use than D5, which simply positioned the cursor
inside of a very long list.

Jason Wharton

unread,
Dec 3, 2001, 1:03:05 PM12/3/01
to
> But these "refinements for efficiency" you're describing don't seem to
> reduce the length of the result set provided to the end user, which is
> my goal here. I don't want to give them a list which even makes it
> possible to scroll through a million records. I want to require the end
> user to provide enough information to at least come close to the record
> they're searching for.

Here is the essence of where we are having problems. The refinements I am
talking about *always* reduce the length of the result set *provided to the
end user* (meaning fetched from the server) when a Locate(), GotoBookmark(),
First, Last, FindFirst, FindLast, etc. are called.

The Locate() method itself provides the "information to at least come close
to the record". The beauty of the Locate() method is, it tells us *exactly*
which record the user is looking for, which is as close as close needs to
get.

The hang-up you seem to have is with the implementation internal to the
dataset the end user could if they wanted to sit there and hit page-down all
afternoon. After a few minutes scrolling the average person would learn it
is much more sensible to just type into the incremental search or locate
criteria (in the picklist or whatever is provided). Which type of refining
control should *always* accompany this kind of scenario.

Which brings me to the point of the many third party controls which use the
Locate() method internally to do their looking up. It is difficult, if not
impossible, to put in hooks and code necessary to inject the refinements
desired. Not to mention inefficient due to having to integrate and prepare
new SQL all the time. By having the dataset capable of doing the refinements
automatically allows you to cleanly make use of whatever 3rd party libs you
want to without the messy helper code/classes or limiting which controls you
can use all together.

You say whatever needs copy-paste should end up in a class somewhere. I
agree entirely. That is why I decided to implement "auto-refinement" inside
the dataset class itself. This abolishes the need to have any helper
code/classes in my applications anywhere and opens the doors to use any 3rd
party controls my customers and I chose to make use of in their user
interface design. Not to mention VCL lookup fields too.

It is VERY fortunate the VCL's TDataset class was designed with the
flexibility to have open ended buffers either direction. It was designed to
accommodate just the kind of automatic refinements I am doing. I know for a
fact I am not doing something taboo as far as TDataset usage is concerned. I
am striving to take it to its utmost richness in capability while remaining
as simple to use as possible.

I hope this clarifies my case. I've spent 5 years striving for it to be
ready for mission critical apps and therefore I am rather passionate about
it. As you know, I tend to take offense when it is played off as a "bad
design". Especially since I know it largely agrees with every principle you
hold dear.

PS. Thanks for putting your foot down to my rudeness. There is and was no
need for it.

Regards,

Craig Stuntz (TeamB)

unread,
Dec 3, 2001, 4:41:06 PM12/3/01
to

Jason Wharton wrote:
>
> Here is the essence of where we are having problems. The refinements I am
> talking about *always* reduce the length of the result set *provided to the
> end user* (meaning fetched from the server) when a Locate(), GotoBookmark(),
> First, Last, FindFirst, FindLast, etc. are called.

I think you would agree that no matter what UI solution number of
records fetched to the IB client needs to be small. A large result set
is simply not an option, because the performance would be unacceptable.
So this conversation can't be perceived as comparing the merits of
fetching lots of records vs. fetching a few, because there are no merits
to fetching lots of records.



> The Locate() method itself provides the "information to at least come close
> to the record". The beauty of the Locate() method is, it tells us *exactly*
> which record the user is looking for, which is as close as close needs to
> get.

I don't agree with this, but I also don't think you meant it the way
I'm reading it. Locate *may* tell you the exact record (if you specify
the primary key, for example) or it might be a partial key value.
Locate is simply a way of moving the client-side cursor, nothing more or
less.



> The hang-up you seem to have is with the implementation internal to the
> dataset the end user could if they wanted to sit there and hit page-down all
> afternoon. After a few minutes scrolling the average person would learn it
> is much more sensible to just type into the incremental search or locate
> criteria (in the picklist or whatever is provided). Which type of refining
> control should *always* accompany this kind of scenario.

You've almost got my "hang-up" -- but it's actually a little more
serious. Most users I've observed in the wilds don't even think to use
the page down key. Instead, they click the mouse on the down arrow,
once per record. Then they try moving the thumb and (if there are, say,
200 records in the list) fly past their desired record in both
directions a few times before giving up and clicking on the arrow
buttons again. It makes me pull my hair out and it's all I can do while
watching them to not sit down and give them a quick seminar on how to
use a scroll bar effectively, but I'm just supposed to be observing, not
training....

But yes, sooner or later they're going to have to type into a search
control or refine the search somehow. And since we know at the outset
they're going to have to do this anyway, I think it's a good UI decision
to force them to do it at the outset. A very important concept in our
application is the workflow -- we try to understand how our users do
their jobs and allow them to configure our application to follow the
same chronological sequence. Users don't have to be trained on how to
accomplish a particular task with the software -- instead the software
trains them how to perform the job, following the way the agency has set
up the process. So whenever possible I try to guide users into a
sequence of interactions which will allow for efficient use of the
server.



> Which brings me to the point of the many third party controls which use the
> Locate() method internally to do their looking up. It is difficult, if not
> impossible, to put in hooks and code necessary to inject the refinements
> desired. Not to mention inefficient due to having to integrate and prepare
> new SQL all the time. By having the dataset capable of doing the refinements
> automatically allows you to cleanly make use of whatever 3rd party libs you
> want to without the messy helper code/classes or limiting which controls you
> can use all together.

Locate is not an evil method to be feared! Locate is a way of moving
the cursor on the client. What we're really trying to avoid is large
amounts of fetching, and I don't equate that with Locate -- even with
IBX. :)

If I had to contrast our approaches, I'd say that I avoid large result
sets altogether while you attempt to turn them into many smaller ones.
There's not a right or wrong here from a performance standpoint (at
least in a two tier app) -- it's two different styles. From a UI
standpoint, I prefer my solution (no surprise there, I guess).

IMHO,

Jason Wharton

unread,
Dec 3, 2001, 5:52:00 PM12/3/01
to
>> The Locate() method itself provides the "information to at
>> least come close to the record". The beauty of the Locate()
>> method is, it tells us *exactly* which record the user is looking
>> for, which is as close as close needs to get.
>
> I don't agree with this, but I also don't think you meant it the way
> I'm reading it. Locate *may* tell you the exact record (if you specify
> the primary key, for example) or it might be a partial key value.
> Locate is simply a way of moving the client-side cursor, nothing more or
> less.

You entirely missed the point. The information the Locate() method provides
is sufficient to also determine the most efficient way (refinement context)
to locate the record. It's just up to the dataset implementation to take
advantage of the inherent refinement context or not.

The TDataset class has been architected to accommodate the virtualization of
huge datasets, which is what a proper Locate() implementation should do. I
challenge you to take this up with the VCL data access architects and see
what they have to say about it.

> If I had to contrast our approaches, I'd say that I avoid large result
> sets altogether while you attempt to turn them into many smaller ones.
> There's not a right or wrong here from a performance standpoint (at
> least in a two tier app) -- it's two different styles. From a UI
> standpoint, I prefer my solution (no surprise there, I guess).

The luxury you *as an individual* have is you are largely in control of your
application design requirements. You have found a way to comfortably jump
through all the hoops in your apps to follow the rules. You have selected
the controls you like to work with, and so on.

In my position, I not only have to fulfill my own apps requirements but
thousands of customers and their requirements. I need to make a data access
architecture which will accommodate efficient usage for however people like
to design their applications. Which I still maintain comes first in
importance where feasible.

I take pride in allowing people to present data to their users in as easy
and flexible manner as possible. Good design is what is easy to code,
maintain and works well, with snappy performance. I like to open the range
of possibilities rather than tell people what they shouldn't do.

Do you see the value in what I have done for the general developer in this
"opening up" of the range of application possibilities?

Jason Wharton

unread,
Dec 3, 2001, 6:10:43 PM12/3/01
to
> You've almost got my "hang-up" -- but it's actually a little more
> serious. Most users I've observed in the wilds don't even think to use
> the page down key. Instead, they click the mouse on the down arrow,
> once per record. Then they try moving the thumb and (if there are, say,
> 200 records in the list) fly past their desired record in both
> directions a few times before giving up and clicking on the arrow
> buttons again. It makes me pull my hair out and it's all I can do while
> watching them to not sit down and give them a quick seminar on how to
> use a scroll bar effectively, but I'm just supposed to be observing, not
> training....
>
> But yes, sooner or later they're going to have to type into a search
> control or refine the search somehow. And since we know at the outset
> they're going to have to do this anyway, I think it's a good UI decision
> to force them to do it at the outset. A very important concept in our
> application is the workflow -- we try to understand how our users do
> their jobs and allow them to configure our application to follow the
> same chronological sequence. Users don't have to be trained on how to
> accomplish a particular task with the software -- instead the software
> trains them how to perform the job, following the way the agency has set
> up the process. So whenever possible I try to guide users into a
> sequence of interactions which will allow for efficient use of the
> server.

I think all of the above said is totally beside the point of our discussion
whether Locate efficiency is implemented inside the dataset or by external
application constraint. Never the less, it does raise a few thoughts.

Not all software is written for brain-dead idiots. Software catering too
much to those people keeps them in their brain-dead state. That isn't a win
situation for a company wanting to invest in the intelligence factor of
their employees.

In my apps I utilize a lot of color contexts and conventions so that they
can sit down in front of any interface and go right to work. Learning the
conventions is really very easy when you appeal to the human mind in the
right way. If a program needs to have accompanying documentation (other than
reference) then I feel the designer has done something wrong.

I do use narrowed stuff where appropriate but I tend to think it is counter
productive in most situations where there could be complex interactions,
which isn't an uncommon situation. Not to mention this style of application
becomes exponentially complex and cumbersome to maintain as the requirements
increase. Once a user gets to where they know the ropes with a good
interface their productivity doubles or more and apps to suit them are far
easier to write and maintain.

How would you feel if Delphi itself was written in the same manner and mode
as you promote applications being written? I think you would feel highly
insulted and that your creative intelligence was being restrained. I know
that is how I would feel.

Just food for thought...

0 new messages