Re: Comparing/passing records in 4GL/C
Posted in 1992
>From: uunet!magnus.acs.ohio-state.edu!kbrummel (Karl P Brummel) >Subject: Comparing/passing records in 4GL/C >Date: 5 Nov 92 15:24:59 GMT >X-Informix-List-Id: <news.2067> >I'm interested in comparing two entire records at runtime, so I can tell if >one (which started out a copy of the first) is still the same as the first: >i.e., I want to detect if the record has been updated. I can't do something >like >if ( rec1 = rec2 ) then... >or >if (rec1.* = rec2.*) then... >in 4GL, and I don't seem to be able to find a way to pass a pointer to a >record to a C function. That's not very surprising -- there are no pointers anywhere in I4GL. >I can pass all the fields with >call myfunc(rec1.*,rec2.*), >but then I have to pop all the fields off the stack, which means I have to >know all the fields in the record. What I want to do is get a pointer to >the first, a pointer to the second, find the size somehow (at run time) >and do a >memcmp(rec1,rec2,sizeof(rec)); >or something similar. No chance. >The library function field_touched() almost does what >I want, so there must be a way to know this information at runtime. Any >ideas how I write field_changed()? I doubt if it does. What it does is tell you if the user typed anything in any of the fields in the input record. It may be that the user typed an 'A' over an existing 'A' -- that makes field_touched think something happened. And it only tells you if the record was modified during input. >Poking through the headers for 4GL didn't give me any great ideas. Bad luck -- it wouldn't have helped me either. Roughly speaking, what you have to do is, for each field in the record, is: LET is_changed = FALSE IF is_changed = FALSE THEN CASE WHEN rec1.columnA IS NULL AND rec2.columnA IS NULL LET is_changed = FALSE WHEN rec1.columnA IS NULL OR rec2.columnA IS NULL LET is_changed = TRUE WHEN rec1.columnA != rec2.columnA LET is_changed = TRUE --OTHERWISE --LET is_changed = FALSE END CASE END IF IF is_changed = FALSE THEN CASE WHEN rec1.columnB IS NULL AND rec2.columnB IS NULL ... END CASE END IF Obviously, for each field which cannot contain nulls, you only need the last test -- a darned sight easier. This algorithm can end up testing is_changed a few times, but it avoids poblems with the tests being indented off the RHS of the screen. This is non-trivial, especially on tables with 50-odd columns -- I normally use a shell script to generate the code, and I leave the shell script in the program as a set of comments, so if (when?) the table is changed, I can recreate the test automatically. Yours, Jonathan Leffler (johnl@obelix.informix.com) #include <disclaimer.h>