Subject | Re: [IBO] saving atomic data :) |
---|---|
Author | Helen Borrie (TeamIBO) |
Post date | 2002-02-10T23:12:32Z |
At 10:02 PM 10-02-02 +0100, you wrote:
If you have the Mastersource and MasterLinks set up properly, this is done for you. IBO posts the master record first and performs a CommitRetaining on the master table. (If a Cancel occurs later, IBO goes back and deletes this record).
I think your enforcement test should be on the detail dataset which, with MasterSource/MasterLinks defined, will be in dssInsert when you are inserting into the master or when the detail dataset is empty. Write a handler to test the IsEmpty property of the detail dataset, which you can call in its BeforePost event to enforce the obligatory relationship (I suggest BeforePost rather than BeforeInsert, because you will want to enforce the relationship in subsequent delete operations as well).
In the case of an Insert, the new record is already created in the buffer. I think the ib_datasource of the detail does magic of its own (through its DataLinkList property) during AfterInsert to determine whether the user has added data and decide whether the insert should actually be posted.
If you are using TDataset-compatible components, I think there will be a bit more work to do...
regards,
Helen Borrie (TeamIBO Support)
** Please don't email your support questions privately **
Ask on the list and everyone benefits
Don't forget the IB Objects online FAQ - link from any page at www.ibobjects.com
>I want to save an invoice which is made of a header and N detail rows (withThe "database" way to prevent this by using a trigger on the header to disallow a 1:0 relationship - but this can interfere with IBO's handling of master-detail.
>N>=1).
>
>The user inputs invoice data via a normal master/detail form with 2 grids,
>2 navigators, 2 queries and 2 datasources.
>
>I need to prevent:
>
>1. an orphaned header (i.e. that a header is inserted with no detail row)
>2. an orphaned detail row (i.e. that one or more detail rows are insertedThe database way is to enforce the relationship with a foreign key on the detail that points to the primary key on the master. This is recommended for robustness, anyway, in case detail rows are entered via a database tool.
>with no header)
If you have the Mastersource and MasterLinks set up properly, this is done for you. IBO posts the master record first and performs a CommitRetaining on the master table. (If a Cancel occurs later, IBO goes back and deletes this record).
>If I had to test condition 1. only, I would insert the detail rows first,Condition 1 is to enforce 1:1-to-Many, right? Because IBO does a "blind" post first, this test would always cause the blind post to fail.
>then perform the check in the BeforePost event of the header table.
I think your enforcement test should be on the detail dataset which, with MasterSource/MasterLinks defined, will be in dssInsert when you are inserting into the master or when the detail dataset is empty. Write a handler to test the IsEmpty property of the detail dataset, which you can call in its BeforePost event to enforce the obligatory relationship (I suggest BeforePost rather than BeforeInsert, because you will want to enforce the relationship in subsequent delete operations as well).
In the case of an Insert, the new record is already created in the buffer. I think the ib_datasource of the detail does magic of its own (through its DataLinkList property) during AfterInsert to determine whether the user has added data and decide whether the insert should actually be posted.
>If I had to test condition 2. only, I would insert the header first, thenYou might be "double-dipping" here since IBO already handles this by inserting the first detail record automatically. I think your only concern is to ensure that the user has modified the record before the second Post of the master dataset occurs.
>perform the check in the BeforePost event of the detail table.
>
>However, I cannot understand how I can easily test both conditions.
>
>I have deviced a clever method so that the AfterInsert event of the header
>table inserts a new record in the detail table, then the AfterPost event of
>the header table issues a Post of the detail table, etc.
>But I can see tons of subtle problems.You can read the Datasets property of the transaction if you want to attack the problem at the transaction level; but this might be more awkward for the user than using IBO's own devices to intercept an empty detail dataset.
>
>I thought to use the BeforeCommit event of the current transaction, but
>several invoices could have been inserted by the user before he issues a
>commit, and I don't know how to go back to everyone of them.
>On top of it, it would be very unconvenient to have to rollback severalAgreed: it should be done at Post, not at Commit.
>input invoices.
If you are using TDataset-compatible components, I think there will be a bit more work to do...
regards,
Helen Borrie (TeamIBO Support)
** Please don't email your support questions privately **
Ask on the list and everyone benefits
Don't forget the IB Objects online FAQ - link from any page at www.ibobjects.com