Subject | Re: [IBO] Master-Detail dillemas with TIBO* |
---|---|
Author | Eyal |
Post date | 2005-03-10T01:00:46Z |
Helen,
Thanks a lot for the very educative reply (as usual!)
docs that explains this?
I'll read IBO help again, but I'll appreciate a simple example.
only commit once all the data is coherent. I don't understand how a
BeforePost can help me do validation that needs to check rows that the
user hasn't input yet.
have an alternative. I can't do all this server-side, becuause I need
to do validation and data fixing that depends on application parameters.
I don't want to waste too much of your time with detailed
explanations, but just some examples: I need to calculate a special
date field that depends on user input and a non-trivial logic, and
store the result in the detail row. Then I have to verify that all
those calculated dates in all detail rows fall within a certain range.
I need to calculate (and store) a tax amount field which depends on
many application variables and uses a very twisted logic (tax laws...)
columns in the table. As I explained above, I need to calculate them
client-side becuase the calculation isn't trivial. So during user
input those fields/columns don't have any values, because I fill them
only AFTER the user signals that input is done. However the user can't
input anything because the dataset complains on the missing values.
I may have found a solution. It seems that the dataset sets the
"Required" property for the TFields that correspond to each of those
columns. So I need to set "Required=FALSE" to prevent the dataset from
validating until posting time, at which point I'll take care of
stuffing the fields with the proper values.
editing and before posting all the data, I can do eg.:
...
TotalCheck:=0;
VerifyOk:=VerifyMasterRow;
DetailQuery.First;
WHILE Ok AND (NOT DetailQuery.EOF) DO
BEGIN
Ok:=VerifyDetailRow;
CalcDetailFields;
TotalCheck:=TotalCheck+DetailQuery['amount'];
{ Etc. }
DetailQuery.Next;
END;
IF VerifyOk THEN
ApplyUpdates
ELSE
MessageDlg('Houston we have a problem');
...
above, ie. for each row do the validation and update the calculated
fields, and keep counters for set-level data.
At the end of the iteration I'll test the set-level counters, and
either proceed to post or warn the user to fix the input.
to move the current row, etc. Let's suppose I have the GUI in place -
how can I move a row in a (cached) dataset? I can't find any method
to change the order of rows, or to move a row from one "place" in the
dataset to another.
Helen - thanks again for the great help. I hope you still have some
more patience for me, as I now know that there's more I should know...
Eyal.
Thanks a lot for the very educative reply (as usual!)
> >So if I need to use a JOIN in theI'm a bit lost here. Can you point me to an example, or a place in the
> >future, then I should use TIBOQuery and lose the Master-Detail
> features.
>
> Why? TIBOQuery inherits the TQuery implementation of master-detail.
> Thus, like TQuery, it doesn't expose explicit MasterFields linking.
> This means that the linking columns in the two output sets must be
> of exactly the same type and have the same field names in the
> database; and the Details set must be designed so that the
> column[s] that link[s] to the Deal set's KeyLinks (for the
> masterlinking) are parameters.
docs that explains this?
> Or perhaps you were unaware that you link your Details set to yourIndeed...
> Deal set through the Datasource property of the Details set?
I'll read IBO help again, but I'll appreciate a simple example.
> >2. Should I use cached updates? Before posting a deal to the DB II understand that I need to take control of the transaction, so that I
> must check that the data is valid, eg. that the balance of all
>
> That sounds like an occasion when cached updates could be
> used.....However, since all posting is done at the level of the
> current row, you can always intervene in the BeforePost event of
> either (or both) dataset[s] to do this kind validation. The key
> thing here, where you have inter-row dependencies, is NOT to use
> an AutoCommit transaction.
only commit once all the data is coherent. I don't understand how a
BeforePost can help me do validation that needs to check rows that the
user hasn't input yet.
> IMO, relying on client code to do this is not a good designI understand and even anticipated this shortcoming. But I don't really
> practice, since it totally binds the integrity of your data to the
> application....and, if you have another application (maybe even in
> another language, which can't share your classes) you have to
> repeat the same validation.
have an alternative. I can't do all this server-side, becuause I need
to do validation and data fixing that depends on application parameters.
I don't want to waste too much of your time with detailed
explanations, but just some examples: I need to calculate a special
date field that depends on user input and a non-trivial logic, and
store the result in the detail row. Then I have to verify that all
those calculated dates in all detail rows fall within a certain range.
I need to calculate (and store) a tax amount field which depends on
many application variables and uses a very twisted logic (tax laws...)
> >4. When I try to input a new detail row I get an error box thatOk, I think I'm starting to figure it out.
> >compains "missing value for MASTER_ID". I guess this is because
>
> You don't have the linking set up.
> ...
> The hidden implicit linking will take care of writing the
> master_id to the detail set when you call Insert on the detail set.
> >5. There are additional "missing value" messages for other fields.Those calculated fields that I mention are all "real" fields, ie.
> >Those are calculated fields, which can be calculated only after the
> >user inputs all data (ie. user click OK). How can I tell
> >TIBODataset to "be patient" with those fields until I actually
> >try to post?
>
> This needs to be explained more clearly. A calculated field on the
> client side doesn't exist in the database. It sounds as though you
> need some help constructing the detail query so you can get your
> head around the binding between the output set and the underlying
> table.
columns in the table. As I explained above, I need to calculate them
client-side becuase the calculation isn't trivial. So during user
input those fields/columns don't have any values, because I fill them
only AFTER the user signals that input is done. However the user can't
input anything because the dataset complains on the missing values.
I may have found a solution. It seems that the dataset sets the
"Required" property for the TFields that correspond to each of those
columns. So I need to set "Required=FALSE" to prevent the dataset from
validating until posting time, at which point I'll take care of
stuffing the fields with the proper values.
> The methods that have to check the whole set will be pretty ugly,Can't I just iterate the rows in the dataset? Once the user is done
> because they will have to iterate through the rows of the detail
> set....maintain a structure (TStrings usually) to hold the linkages
> between the detail set's Keylinks and the sequence number.
editing and before posting all the data, I can do eg.:
...
TotalCheck:=0;
VerifyOk:=VerifyMasterRow;
DetailQuery.First;
WHILE Ok AND (NOT DetailQuery.EOF) DO
BEGIN
Ok:=VerifyDetailRow;
CalcDetailFields;
TotalCheck:=TotalCheck+DetailQuery['amount'];
{ Etc. }
DetailQuery.Next;
END;
IF VerifyOk THEN
ApplyUpdates
ELSE
MessageDlg('Houston we have a problem');
...
> If the logic permits, call the set-level methods after theI think I can do them both at the same time as shown in the example
> row-level validations are done.
above, ie. for each row do the validation and update the calculated
fields, and keep counters for set-level data.
At the end of the iteration I'll test the set-level counters, and
either proceed to post or warn the user to fix the input.
> >7. I want to let the user move detail rows relative to each other.I'm not concerned about the UI part. I can add up/down arrow buttons
>
> Then you certainly want to cache the detail set. I think you will
> have to search for a third-party grid or tree control to get the
> UI you want, since the VCL's TDBGrid doesn't have the capability
> you want, AFAIR.
to move the current row, etc. Let's suppose I have the GUI in place -
how can I move a row in a (cached) dataset? I can't find any method
to change the order of rows, or to move a row from one "place" in the
dataset to another.
Helen - thanks again for the great help. I hope you still have some
more patience for me, as I now know that there's more I should know...
Eyal.