Subject Re: [IBO] Firebird Generated Keys as Master / Slave Links and IBO Controls
Author Helen Borrie
At 02:46 AM 5/12/2006, you wrote:
> > > Our problem concerns generators - specifically, having gone to
> > > primary keys having no logic in the real world but being
>generated by
> > > a Firebird Generator, we now have linking problems.
> > >
> > > From what we understand, for a field to be populated by a
>generator
> > > it must be left out of the IBO query SQL statement.

No, quite wrong.

>If this is so then the query doesn't have it and cannot use it as a linking
>field in a master/slave relationship.

Jason wrote:

> > The surrogate keys (that's what I call them) should still be
> included in all
> > your queries.
> >
> > > Can anyone point us to a document that will enlighten us on
>Master /> Slave relationships using generator populated fields as the key?
> >
>[Jason] Is all you need to do is put a setting in the GeneratorLinks
>property for the surrogate key column and IBO will take care of
>providing values for your keys. Just be sure your triggers do not
>overwrite the values IBO
>retrieves.
> > Check for NULL before applying a value in a trigger.
> >
>[Jason] You can make a setting at the TIB_Connection.GeneratorLinks level
>and it will be applied for all datasets on that connection, or you can
>isolate a setting in your dataset GeneratorLinks property.
> >
> > > The samples are in Delphi and we are using C++ so can't access
>them.

What you can do is inspect them in a text editor, particularly to
look at the DFM file. Some text editors, e.g. CONText (free!!) will
even format the Pascal files with the correct highlighting, to make
it easier to read them.


>Many thanks but what do you mean by 'settings' and should they be in
>the master or slave? (Or if only in the transaction - what settings?).
>
>I tried including the generated field in the query and that produces
>an error message, obviously the control checks the NOT NULL and
>throws an exception before the trigger fires and the generator has a
>chance to populate the field.

You use a SELECT query to retrieve a dataset. You need to have the
primary key in the set.

The query component has built-in methods that internally create
Insert, Update and Delete statements for when you call Insert, Edit
and Delete in your app. Because the primary key is a compulsory field
and, for a master-detail setup, a matching foreign key is compulsory,
you will get an error on calling Insert on *either* set, if IBO
doesn't have a value for the PK of the new master record.

If you want IBO to have access to the new generator value *before* a
new row is constructed, you use the GeneratorLinks property. The
format is the same regardless of whether you're using Delphi or
CPPB. If you want to set it globally for the whole application, set
it in the TIB_connection object (no doubt the IBODatabase in your case):

aTable.PrimaryKeyName=aGenerator

Or you can set it at dataset level, in which case you don't qualify
the fieldname and so it's just

PrimaryKeyName=Generator

>The trigger itself checks for NULL in accordance with the Bible
>(Helen's book).

Then setting GeneratorLinks is all you have to do. IBO does the
rest. As soon as you call the Insert method, and before IBO puts the
dataset into Insert mode, it calls a function called Gen_ID which
returns the new value of the generator and writes it to the PK field
of the (forthcoming) new record. That's it.

Don't include any spaces between PrimaryKeyName and Generator.

>What I suppose I am really after is a user guide so we don't have to
>keep bothering you.

I think GeneratorLinks is covered in the Getting Started
Guide. However, the GSG is *not* a newbie tutorial about SQL,
Firebird/InterBase or Delphi, rather it fills in the gap between your
knowledge of Delphi and the way things are implemented in IBO. So,
for example.-

-- If you're using the TDataset-compatible (TIBO---) components, the
ways of doing Master-Detail are covered in the Delphi help. Same
rules, same limitations.

Supporting generators, viz. GeneratorLinks and the underlying Gen_ID
function, *is* available to "TIBO--" components, being one of a group
of IBO-specific features that is wrapped into these components and
published. It does behove you to understand how generators (more
correctly called "sequences") work, since generators are a
DBMS-specific feature of Firebird and InterBase.

Also, seeing your Subject title makes me want to suggest that you
also try to understand the difference between "components" and
"controls". Controls are components, but they are the visual things
that you use in your user interface - TDBEdit, TDBGrid, and so on.

The data access components are linked to the controls via a
datasource component.

-- With the TIBO-- components you can ONLY use Delphi's TDatasource
for this linking, and you can ONLY use controls that work with (are
compatible with) the TDatasource.

-- With the TIB_-- components you can ONLY use the native IBO
TIB_Datasource and you can ONLY use the TIB_-- controls.

Helen