home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!destroyer!sol.ctr.columbia.edu!emory!emory!not-for-mail
- From: johnl@obelix.informix.com (Jonathan Leffler)
- Newsgroups: comp.databases.informix
- Subject: Re: Comparing/passing records in 4GL/C
- Date: 11 Nov 1992 02:23:12 -0500
- Organization: Mailing List Gateway
- Lines: 76
- Sender: walt@mathcs.emory.edu
- Distribution: world
- Message-ID: <1dqcd0INNkva@emory.mathcs.emory.edu>
- Reply-To: johnl@obelix.informix.com (Jonathan Leffler)
- NNTP-Posting-Host: emory.mathcs.emory.edu
- X-Informix-List-ID: <list.1584>
-
-
- >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>
-