Subject Re: [IBO] Re: general question concerning database and delphi
Author Helen Borrie
At 10:11 AM 16-12-01 +0000, Marco Menardi wrote:
>I was a big fan of datamodule, and when I started my last big project with IBO I followed that approach.
>But it's the wrong one with IBO for the following reasons:
>- IBO is strictly chained with the visual controls, so if you have same table but two forms using it, and one of the two needs special setting of fields, you need a IB_Query for that form.

I disagree with this assertion. I like and use datamodules always, for my native datasets. I make it a strict rule to make public functions or procedures available in the dtm unit, to which the form code passes parameters. This is made * more * streamlined for me by the tight binding of controls to datasets, not less so. For example, when the user makes a selection from a listbox or combobox, the only parameter I have to send is a Boolean which indicates that the form is ready for the dtm to "do its stuff". Even non-data-aware controls on forms interact with the dtm units this way.

I'm not saying that one shouldn't ever use data components on a form. However, I wouldn't. If I have a modal form, I create and destroy its datamodule along with the form. In some cases, I can re-use the same dtm with different forms. Each form declares its own variable for this dtm.

Generally, I have one dtm for the whole application, which is the first thing created by the application and is used by everything. This dtm has the ib_connection(s) and ib_sessionprops. If forms are being created and destroyed in the application, they will have their own datamodules which also use the main dtm. For ISAPI modules, though, instead, an ib_connection and an ib_session go onto a dtm which gets created and destroyed for each instance of the module.

>- IBO surfaces a lot of properties but, above all, events that lets you fine tune your visual behaviour. So if the query is on the datamodule, you have to chain datamodule code to forms components, messing up your datamodule with code related to n forms, and without any benefit

This assertion assumes that an application can have only one datamodule. Moreover, it assumes that datamodules contain code that manipulates or reads forms. They shouldn't. If forms are collecting data in non-data-aware controls, they should "use" the dtm and write their values to structures in the datamodule by passing parameters to procedures in the dtm itself. Most often, IBO forms are just a UI for the datasets, and the data module can get those data for itself without reference to the form.

>- Transaction: it's a good idea having a transaction component per form, so you are pretty sure that is often committed (almost when you close the form)

The idea is good (although I would prefer to have the form's own transaction in its own datamodule) but I don't regard it as a good idea to rely on the form's Close method to commit uncommitted work. If you are using explicit transaction control, you should take good care of any open transactions * before * the form closes.


>For your problem of the relation master/detail with a lot of details chained to one of few masters, it's not very much clear to me.

I think he was possibly talking about a "drill-down" type of application, where the master, e.g. a Customer list, is selected on the main form and the user might select an "Account" button, an "Address" button or a "Latest Invoice" button to start a drill-down sequence. In each case the master is the same but each buttonclick displays a form that shows a different detail set.

If most of the calling code is similar for these forms, then create a base form with a base dtm which the base form creates. Have the base form's descendants override the datamodule code as required.

In the case of an accounting app such as you described, where you were forcing "fiscal year" to be the masterlink, I don't think that would ordinarily be a good thing. I would want to pass fiscal year as a parameter, not as a key. But perhaps I misunderstood where you were going with this. I would certainly want to keep away from setting WHERE criteria in global variables; if I want things to be accessible across unit boundaries, I make them properties and have the private code validate them before submitting them to SQLWhereItems.