WRITE changes record (OpenInsight 32-Bit)
At 09 JUL 2007 05:48:52PM Karen Oland wrote:
OI 7.2.2
When a WRITE is used on a record, the variable's data is modified after the write is complete (to reflect what was actually saved). In a record that has relational indexes, this means that one or more fields is modified – so in a program that is first writing out the main record, then using the info in it to write out the related records, the list of keys to use is lost (this affects at least one process here, that retrieves archived data for several related records - it puts back first a main resume, for example, then goes to retrieve and restore several related records – but the info about the related records is now gone and no keys are listed in the record.
Although a work-around would be to write out the related records first, this should not be necessary (and violates a number of relational record rules, for anyone using a non-OI datastore, so may not be possible for some formats). It's always been true that the data on disk can be different from what is written (due to the relational indexes), but I don't recall (and can't reproduce) this behavior in AREV.
Example (MYFILE has a related from index on field 1):
Rec=A":@FM:"B"
open "MYFILE" to FVar then
write Rec to FVar, "MY_ID" then*** Rec now equals @FM:"B", not it's original value
endend
At 10 JUL 2007 08:31AM Chris Meyer wrote:
It is my understanding the MFS controlling the related from field prevents you from editing, writing or modifying the related from field. This has been the case in AREV and OI.
BTW I do not use relational index on files that change contantly, they are a pain to rely on. Use Btree instead, may be a bit slower but copying, moving and even reindexing large relational indexed files can be very time consuming.
At 10 JUL 2007 02:27PM Karen Oland wrote:
]
True, but you can put anything you want there (or read the file off disk) and write it out; just that those fields are replaced by what is currently on disk for that ID. What AREV doesn't do is modify the actual variable written out (it passes in by value, not by reference – passing in by reference is considered a pretty poor programming habit, but has become common in C programming and is done for subroutines in AREV and OI – it just didn't apparently used to be done to what was passed into a WRITE command). In most cases, if you read the record from disk, modify it and write it back out, you would never notice that the relational fields were updated (since they mostly won't change). In this instance - the records are all archived into non-indexed tables and are being restored. Which means a copy of the record has to be written out instead, since the list of related keys in other archived tables are being deleted by the WRITE command in OI.
]
No kidding. This is a summary file updated by only processes run weekly and never by users. The relational indexes were used to provide quick access to some related windows (one xlate vs. an index flush and a btree extract - on something done fairly often, this adds up quickly).
I've consulted at places that had huge files with relation indexes (many, many millions of records). And spent many a night sleeping on the floor watching the rebuild process over the weekend – their manager refused to install the NLM and they had dozens of highly active users – during peak periods of processing, they corrupted several indexes a week and their policy was to remove GFE's and keep going, unless they absolutely could not continue, then re-index on the weekend. Made for some nice bonus checks, but not much fun.
At 11 JUL 2007 10:34AM Dave Harmacek wrote:
I've been using relational indexes in every application I've written since 1985, including OI, and have no reservations on their usage.
Do you mean that the WRITE you mention is done by form logic?
If so, it is my understanding that the OI form doesn't write a record, like Arev, but writes many fields. This is the logic used to support forms that update multiple tables and rows.
So, until you READV the relational field after a WRITE it wouldn't have the correct data.
I could point out that since Arev doesn't automatically update all the relational target fields after a WRITE in its @RECORD that it's logic was flawed.
Dave
At 11 JUL 2007 11:53AM John Bouley wrote:
Dave and Karen,
I also noticed this behavior in OI. If I remember correctly it had something to do with doing batch processing. The scenario went like this. An AREV app opened and locked a new batch record. While the record was locked detail records were created that update a relational in the batch. Additionally, we would keep track of the records added by updating @record. In AREV the relational would update immediately and @Record would not be modified by the Write. However, in OI the update to the Relational is queued and as such the relational field would be cleared when the batch record was written.
While this behavior does reflect the contents of the field on disk it can be argued that it is counter-intuitive to have a Write actually read and update a memory variable. So I'm not sure this change from AREV was actually a good thing.
I suppose this would also cause problems if we used AREV32 to run one of these apps.
John
At 12 JUL 2007 10:54AM Karen Oland wrote:
]
No, inside a program. @RECORD is not involved (and is often so wrong, I seldom use it inside forms anyway, but this has nothing to do with forms, @RECORD, @ID or any system variables - only the WRITE statement and how it is processed - presumably by SI.MFS as it passes thru).
]
Since this would be inside a "form", after the write, @RECORD is empty (in OI - it is technically still present for a post-write in AREV that OI lacks, but after the write is truly complete, it is wiped).
At 12 JUL 2007 10:58AM Karen Oland wrote:
Good point - anyone using AREV32 may see some odd behavior in batch processes (which essentially this one is).
If you are rewriting the app anyway, you can work around it (once you discover the problem), but in a converted app, that may be impossible – leaving aside the question of whether you should convert an app with no source – esp as I have worked on large systems were no one could find the current source for what were sometimes critical subroutines (suprise! some other contractor deleted all traces in all versions of the app!); even RTI has suffered from this syndrome in the past.