Title: | RMS asks, 'R U Journaled?' |
Moderator: | STAR::TSPEER UVEL |
Created: | Tue Mar 11 1986 |
Last Modified: | Wed Jun 04 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 3031 |
Total number of notes: | 12302 |
I'm looking for an explanation of why this behavior is happening. Given an indexed file when adding a record using SYS$PUT then executing a SYS$FLUSH, the next record retrieved will be the first record of the file and not the record just added. However, the SYS$FLUSH is not executed, the record retrieved will be the record just added. Here is the C code used to demonstrate the situation: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <rms.h> #include <starlet.h> #include <lib$routines.h> main(int ac, char **av) { static struct FAB idxfab; static struct RAB idxrab; static char *idxname = "TSTIDX.DAT"; static char idxrec[84]; static int st; /* Open file and connect */ idxfab = cc$rms_fab; idxfab.fab$l_fna = idxname; idxfab.fab$b_fns = strlen(idxname); idxfab.fab$b_fac = FAB$M_GET|FAB$M_PUT|FAB$M_DEL|FAB$M_UPD; if (!(1&( st = sys$open(&idxfab) ))) lib$signal(st); idxrab = cc$rms_rab; idxrab.rab$l_fab = &idxfab; idxrab.rab$l_ubf = idxrec; idxrab.rab$w_usz = sizeof(idxrec); idxrab.rab$l_kbf = idxrec; idxrab.rab$b_ksz = 12; if (!(1&( st = sys$connect(&idxrab) ))) lib$signal(st); /* Retrieve and display first record */ idxrab.rab$b_rac = RAB$C_SEQ; if (!(1&( st = sys$get(&idxrab) ))) lib$signal(st); printf("First record of file:\n%.41s\n",idxrab.rab$l_rbf); /* Store a new record */ strcpy(idxrec,"1B1E INITIAL"); idxrab.rab$b_rac = RAB$C_KEY; idxrab.rab$l_rbf = idxrec; idxrab.rab$w_rsz = 84; if (!(1&( st = sys$put(&idxrab) ))) lib$signal(st); /* The application in which this problem originally arose expects the stream's sequential context to point to the record following the one added. This was the intention of the following sys$find. The adverse effect of the sys$flush does not manifest without this sys$find. */ idxrab.rab$l_rop |= RAB$M_KGT; if (!(1&( st = sys$find(&idxrab) ))) lib$signal(st); /* Call sys$flush if any argument is given to the command. */ if (ac > 1) { puts(" calling sys$flush"); if (!(1&( st = sys$flush(&idxrab) ))) lib$signal(st); } /* The following sys$get is supposed to retrieve (by key) and display the record previously added. However, if sys$flush was executed above, it incorrectly retrieves the first record of the file instead. */ idxrab.rab$l_rop &= ~RAB$M_KGT; printf("Key buffer before sys$get:\n%d bytes: %.*s\n", idxrab.rab$b_ksz, idxrab.rab$b_ksz, idxrab.rab$l_kbf); if (!(1&( st = sys$get(&idxrab) ))) lib$signal(st); printf("Record buffer after sys$get:\n%.41s\n",idxrab.rab$l_rbf); } Thanks given to any assistance. Jayna Rabke Digital Customer Support/Colorado
T.R | Title | User | Personal Name | Date | Lines |
---|---|---|---|---|---|
3028.1 | next record context | STAR::EWOODS | Wed May 07 1997 13:37 | 45 | |
First, the user is going through unneeded contortions to accomplish what he wants according to his comments. He hasn't capitalized on his making the keybuffer an overlay of the record buffer. After the $put, there is no need to do a $find before the $flush. Do the $put and then the $flush. After the $flush, the keybuffer (overlaying the record buffer) still contains the key value of the record just $put. o If he wants the same record to be retrieved, there is no need to change the ROP field. RAC is still set to RAB$C_KEY. Simply issue the keyed $GET. The record just put will be returned and the record context reestablished. o If instead he wishes the next record after the record just put to be returned, then he needs to set the KGT option in the rop before the $get (but again only once after the $flush): idxrab.rab$l_rop |= RAB$M_KGT; if (!(1&( st = sys$get(&idxrab) ))) lib$signal(st); After either $get, he can switch rac to RAB$C_SEQ if he wishes to retrieve more records sequentially. As to the $flush resetting the next record context to the first record in the file, this was an artifact of his example. If you change his example to do one more sequential $get at the beginning of the program, then after the $flush, the record retrieved will be the second record in the file. The next record position it is using is the one last associated with the sequential $get. In other words, he has not only the $put but the $gets interacting with the $flush. There is a table in the Guide to File Applications in Chapter 8 (Table 8-3 Record Access Stream Context) that documents the effect of RMS services on the next record context. Well, it at least documents the effect of a number of services -- particularly, gets and puts. Flush isn't documented in this table. I'll make a note to research it and add it for next release. But the response for this customer is that he needs to reset the record context after the $flush; he should assume that it is undefined. And as I indicated above, there are more direct ways to do this than the attempts in his example. -- Elinor | |||||
3028.2 | CSC32::J_RABKE | Wed May 07 1997 15:38 | 7 | ||
Elinor, Thanks for the answer. I'll let customer know. Regards, Jayna |