 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mark Reichert Guest
|
Posted: Sat Jan 20, 2007 3:42 am Post subject: Filling Lists |
|
|
Thanks to help from TeamB members I came up with this for filling a Listbox.
The names have been changed to generics, because I'm uncomfortable posting
our actual code in a public forum.
Where Items is an ObjectList created in the DataModule OnCreate and freed in
the OnDestroy.
procedure TdmB.GetList(TheStrings: TStrings);
var Item : TItem;
begin
TheStrings.Clear;
With ibsql1 do
begin
With Transaction do
If Not InTransaction Then
StartTransaction;
Try
ParamByName('ID').AsInteger := dmA.ID;
ExecQuery;
While not Eof do
begin
Item := TItem.Create(FieldByName('irID').AsTrimString);
Items.Add(Item);
TheStrings.AddObject(FieldByName('NAME').AsTrimString, Item);
Next;
end;
Close;
Finally
With Transaction do
If InTransaction Then
Commit;
End;
end;
end;
Only then did it occur to me that I was tying my GUI to my DataModule, which
is what I've been working to avoid in single record code.
The first step is to maintain a separate list in the object layer. I could
even use the above, if it is alright for the data modules to see classes in
the object layer.
Are there any good examples anywhere showing connecting up datamodules to an
object layer with the populating of lists. |
|
| Back to top |
|
 |
Marc Rohloff [TeamB] Guest
|
Posted: Sat Jan 20, 2007 8:01 am Post subject: Re: Filling Lists |
|
|
On Fri, 19 Jan 2007 15:42:28 -0600, Mark Reichert wrote:
| Quote: | Where Items is an ObjectList created in the DataModule OnCreate and freed in
the OnDestroy.
You keep on adding items to this list but you never remove them or |
reuse them?
| Quote: | If Not InTransaction Then
StartTransaction;
...
If InTransaction Then
Commit;
End;
|
The commit will always execute since you will always be in a
transaction at this point. You need to do something like:
TransactionNeeded := not InTransaction;
if TransactionNeeded then
StartTransaction;
....
if TransactionNeeded then
Commit;
| Quote: | Only then did it occur to me that I was tying my GUI to my DataModule, which
is what I've been working to avoid in single record code.
I don't really see how this ties the GUI to the Datamodule |
implementation however you can always add an extra layer if you think
it will improve the separation.
| Quote: | The first step is to maintain a separate list in the object layer. I could
even use the above, if it is alright for the data modules to see classes in
the object layer.
Yes |
--
Marc Rohloff [TeamB]
marc rohloff -at- myrealbox -dot- com |
|
| Back to top |
|
 |
Mark Reichert Guest
|
Posted: Mon Jan 22, 2007 8:20 pm Post subject: Re: Filling Lists |
|
|
"Marc Rohloff [TeamB]" <"on request"> wrote in message
news:tcyznymgj3cd$.dlg (AT) dlg (DOT) marcrohloff.com...
| Quote: | On Fri, 19 Jan 2007 15:42:28 -0600, Mark Reichert wrote:
Where Items is an ObjectList created in the DataModule OnCreate and freed
in
the OnDestroy.
You keep on adding items to this list but you never remove them or
reuse them?
|
Ah, sorry, I left out an ObjectList clear with the Strings clear. The
Objectlist is just intended to be a memory manager.
| Quote: | If Not InTransaction Then
StartTransaction;
...
If InTransaction Then
Commit;
End;
The commit will always execute since you will always be in a
transaction at this point. You need to do something like:
TransactionNeeded := not InTransaction;
if TransactionNeeded then
StartTransaction;
...
if TransactionNeeded then
Commit;
|
I'm not sure how the two differ other than not having to call InTranaction
again.
| Quote: | Only then did it occur to me that I was tying my GUI to my DataModule,
which
is what I've been working to avoid in single record code.
I don't really see how this ties the GUI to the Datamodule
implementation however you can always add an extra layer if you think
it will improve the separation.
|
Well, the GUI layer was making a direct call of a data module method. I
grant that's already a big improvement over letting the GUI have any access
to the database components, or worse, the data module knowing anything about
the GUI, but it still is a direct call.
| Quote: | The first step is to maintain a separate list in the object layer. I
could
even use the above, if it is alright for the data modules to see classes
in
the object layer.
Yes
|
Thanks. I'm just trying to do this project a lot better from an object
oriented design perspective, in the hopes of really easing maintenance. |
|
| Back to top |
|
 |
Mark Reichert Guest
|
Posted: Mon Jan 22, 2007 10:09 pm Post subject: Re: Filling Lists |
|
|
"Mark Reichert" <mark (AT) messagelink (DOT) com> wrote in message
news:45b4c75b$1 (AT) newsgroups (DOT) borland.com...
| Quote: | If Not InTransaction Then
StartTransaction;
...
If InTransaction Then
Commit;
End;
The commit will always execute since you will always be in a
transaction at this point. You need to do something like:
TransactionNeeded := not InTransaction;
if TransactionNeeded then
StartTransaction;
...
if TransactionNeeded then
Commit;
I'm not sure how the two differ other than not having to call InTranaction
again.
|
I've figured it out. We only want to do the commit in this scope if the
transaction was started in this scope. |
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Mon Jan 22, 2007 11:42 pm Post subject: Re: Filling Lists |
|
|
"Mark Reichert" wrote
| Quote: | I've figured it out. We only want to do the commit in this scope
if the transaction was started in this scope.
|
Right--that's the general idea..
However, this looks like you're just doing a single SELECT statement. If
that's true, you don't really need an explicit transaction at all.
bobD |
|
| Back to top |
|
 |
Mark Reichert Guest
|
Posted: Tue Jan 23, 2007 12:34 am Post subject: Re: Filling Lists |
|
|
"Bob Dawson" <bdawson (AT) idtdna (DOT) com> wrote in message
news:45b4f76e$1 (AT) newsgroups (DOT) borland.com...
| Quote: | "Mark Reichert" wrote
I've figured it out. We only want to do the commit in this scope
if the transaction was started in this scope.
Right--that's the general idea..
However, this looks like you're just doing a single SELECT statement. If
that's true, you don't really need an explicit transaction at all.
|
I somehow had gotten the idea that it was good form to do so, particularly
when dealing with Interbase components. |
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Tue Jan 23, 2007 4:21 am Post subject: Re: Filling Lists |
|
|
"Mark Reichert" wrote
| Quote: |
I somehow had gotten the idea that it was good form to do so,
particularly when dealing with Interbase components.
|
In general, the semantics of a transaction is that either all database
changes commit, or no changes commit (rollback). Since a select statement
doesn't (normally) change a database, there's nothing to commit.
If there's some specific reason to transaction wrap a select statement in
Interbase, that would be a definite peculiarity--but I'll admit I'm not an
Interbase user. You might want to ask about that on the sqlservers forum.
bobD |
|
| Back to top |
|
 |
Mark Reichert Guest
|
Posted: Tue Jan 23, 2007 9:02 pm Post subject: Re: Filling Lists |
|
|
"Bob Dawson" <bdawson (AT) idtdna (DOT) com> wrote in message
news:45b538e1 (AT) newsgroups (DOT) borland.com...
| Quote: | "Mark Reichert" wrote
I somehow had gotten the idea that it was good form to do so,
particularly when dealing with Interbase components.
In general, the semantics of a transaction is that either all database
changes commit, or no changes commit (rollback). Since a select statement
doesn't (normally) change a database, there's nothing to commit.
If there's some specific reason to transaction wrap a select statement in
Interbase, that would be a definite peculiarity--but I'll admit I'm not an
Interbase user. You might want to ask about that on the sqlservers forum.
|
********
One thing you have to get used to when you start working with InterBase is
that everything happens within a transaction. Even a simple SELECT to fetch
some rows must take place within a transaction. If you do not explicitly
start and commit or rollback a transaction InterBase Express will
automatically wrap each SELECT and each row insert, update or delete in its
own transaction. While this may be acceptable in many situations,
particularly SELECT queryies, you will want to explicitly start and end
transactions in any case where the transaction must include more than one
change to one row in one table.
********
So, my doing it for a single SELECT is unnecessary, but would be advisable
for all other cases.
But I didn't come to oodesign to talk about Interbase. It's merely the
database from which I'm fetching information to put in my list. I still
haven't seen a good example of how to both have loose coupling and have the
database stuff a container with objects of the appropriate type based
information in the database. |
|
| Back to top |
|
 |
Bob Dawson Guest
|
Posted: Wed Jan 24, 2007 2:13 am Post subject: Re: Filling Lists |
|
|
"Mark Reichert" wrote
| Quote: | I still
haven't seen a good example of how to both have loose
coupling and have the database stuff a container with objects
of the appropriate type based information in the database.
|
Fair enough.
In my system I've got a TLookupList item that functions as a sort of
dictionary class. The persistence layer manager maintains these as a list of
lists.
Lookups are structured as ID, Name, and Description. They have no save
method.
PL management is mostly a matter of persistence latency: Lookups are lazy
loaded, and maintained in memory for X minutes after the last access. Since
all calls route through a lookup manager, it can track that (it maintains
LastTouch(dateTime) on each lookup list) and clean itself up as necessary.
PL access calls include
FrameServices.ListFillStrings(const LookupName : string; aStrList :
TStrings);
FrameServices.ListIdOfItem(const LookupName : string; const Item : string) :
TBObjectId;
FrameServices.ListItemOfID(const LookupName : string; const aId :
TBObjectId) : string;
FrameServices.ListDescriptionOfItem(const LookupName : string; const Item :
string) : string;
FrameServices.ListDescriptionOfID(const LookupName : string; const aId :
TBObjectId) : string;
The GUI can fill a listbox etc using the ListFillStrings method.
Getting something like CustID from CustName or ProductName from ProductID is
handled by the next two calls.
This allows selection boxes etc on the GUI, reading the form's current
selection, etc., without direct db knowledge.
Unlike a normal BO class, a lookup list item cannot depend directly on SQL
autogen, since a lookuplist item might come from anywhere. How you negotiate
that issue depends entirely on the OPF framework design and capabilities.
bobD |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|