======================================================================
   USING REFRESH & VERIFY IN MULTI-USER APPLICATIONS
   ======================================================================
   PRODUCT   :  R:BASE                  VERSION      :  3.1 or Higher
   CATEGORY  :  PROGRAMMING             SUBCATEGORY  :  MULTI-USER
   ======================================================================
 
 
   From David Blocker, 65 Morse Street, Sharon, MA 02067. David is an 
   R:BASE author, consultant, and trainer. With Bill Downall, he recently 
   wrote and self-published a book on R:BASE 3.1. The material in this 
   article is adapted from his workbook on networking R:BASE 3.1.
 
   In a network (multi-user) environment, R:BASE uses a system called 
   concurrency control to protect against data conflicts when more than 
   one person edits the same data at the same time.
 
   The different levels of concurrency control are basically the same as 
   those described in Who Locked Me Out? in the July/August 1990 R:BASE 
   EXCHANGE. But in R:BASE 3.1, developers can use a new command SET REFRESH 
   to better control when and how R:BASE tells users about changes made to 
   the same row by other, concurrent users.
 
   Two commands, SET REFRESH and SET VERIFY, affect what you see on the 
   screen when you edit data using either a form or the Browse/edit screen 
   (the screen brought up by choosing Info or Views from the R:BASE Main 
   Menu or by using the EDIT or BROWSE commands from the R> prompt).
 
   The SET VERIFY Command
   ======================
   SET VERIFY ROW and SET VERIFY COLUMN tell R:BASE when to inform you 
   that someone else just changed the data you're currently editing with 
   a form.
 
   <>  When VERIFY is set to COLUMN, R:BASE alerts you when someone else 
       changes the data in the exact column and row you are currently in.
   <>  When VERIFY is set to ROW, R:BASE alerts you when someone else 
       changes any column in the exact row you are currently in.
 
   In both cases, R:BASE alerts you only when you try to save your changes 
   to the row. If you just look at it, R:BASE normally does not notify you 
   that a change was made by someone else unless you use SET REFRESH to 
   cause R:BASE to automatically refresh the display at a given interval.
 
   The VERIFY setting doesn't affect deletions. With either setting, R:BASE 
   tells you if someone else deleted the row while you were editing it but 
   only when you save changes to the row.
 
   In the event of an editing conflict in which two users are changing the 
   same row, the last one out determines the final changes to that row.
 
   For example, Alan and Sue both edit the same row at the same time and 
   Alan saves the row before Sue makes her changes. When Sue completes her 
   changes to the row and tries to save it, R:BASE will give her a message 
   showing Alan's changes. At that point, Sue can either leave the row as 
   is, accepting Alan's changes, or she can edit the row to reinstate her 
   own changes. But she'll have to type them in again (see examples below).
 
 
   The SET REFRESH Command
   =======================
   If you want R:BASE to notify you of all changes, regardless of whether 
   you make a change, you have two options:
 
   <>  Use SET REFRESH in conjunction with SET VERIFY to set up an automatic 
       screen refresh.
   <>  Press [Ctrl-F10] in a form
 
   When REFRESH is set to zero (the default), R:BASE won't automatically 
   refresh form screens. This command sets REFRESH off:
 
   SET REFRESH 0
 
   To set REFRESH on, set it to a number between 10 and 65535 seconds. For 
   example, the following command tells R:BASE to automatically refresh 
   form screens every 12 seconds:
 
   SET REFRESH 12
 
   Now you'll see changes made to the row by others during the last 12 
   seconds whether or not you tried to save changes to the row.
 
   When REFRESH is set to 10 or more, R:BASE automatically refreshes both 
   forms and Browse/edit screens.
 
   R:BASE refreshes a form screen after the REFRESH time period and gives 
   the messages described in the examples below.
 
   <>  R:BASE refreshes a Browse/edit screen more often. R:BASE refreshes 
       the screen as soon as you move the cursor if you haven't moved to 
       a new row in the SET REFRESH time period or if someone changed that 
       table's data since the last time you moved the cursor. R:BASE never 
       refreshes the Browse/edit screen until you move the cursor.
 
 
   Settings Are Station Specific
   =============================
   Each workstation on the network makes its own settings at the R>
   prompt, in the Settings menu, or in application code. For example, 
   one workstation might set VERIFY to ROW while another sets VERIFY to 
   COLUMN. A third workstation might turn auto-refresh off by setting 
   REFRESH to 0 while a fourth has REFRESH set to 10 seconds.
 
 
   Example: VERIFY Set to COLUMN
   =============================
   Alan and Sue are both using forms to edit Wanda Smith's record. Alan 
   changes Wanda's first name to Cindy and saves the row. Assuming that 
   REFRESH is set to zero (the default) and VERIFY is set to COLUMN (the 
   default), here are several scenarios showing how the form will behave 
   for Sue.
 
   If Sue only looks at the row and then moves on to the next row by 
   pressing [F8] or by using the menu, or if she chooses to quit from the 
   form, R:BASE won't tell her that Alan changed the row. 
 
   If, instead, Sue changes Wanda's last name to Smithe but doesn't touch 
   the first name and then she saves the row, R:BASE won't tell her that 
   Alan changed the row. The name on the row will now be Cindy Smithe. 
   You might notice a quick shifting of the screen just before R:BASE 
   leaves the form or brings up the next row. In that split second, R:BASE 
   shows Alan's changes on the screen, but Sue gets no explicit message 
   and no opportunity to make a change. Alan gets no message. Even though 
   the changes were made simultaneously, Sue had not yet saved her change 
   when Alan saved his. Because VERIFY is set to COLUMN and Alan and Sue 
   changed different columns, R:BASE doesn't treat either change as 
   newsworthy for the other user. 
 
   If, however, Sue changes Wanda's first name to Joan and her last name 
   to Smithe (remember that Alan has already changed the first name to 
   Cindy), R:BASE displays the following two messages at the bottom of 
   the form when Sue tries to save the row: Blinking shows another user's 
   conflicting changes. Press Enter to edit the displayed data; press Esc 
   to discard your changes. In addition to the messages, Cindy is 
   highlighted on the form to draw Sue's attention to Alan's change. Now 
   it's Sue's call. She can bow to Alan's change by pressing [Esc]. But 
   then Sue's last name change to Smithe will not be saved. Sue can press 
   [Enter] to have the last word. If she presses [Enter], R:BASE places 
   the cursor in the first name field and display Alan's data: first name 
   Cindy, last name Smith. Sue can now change the first name to Joan and 
   the last to Smithe and save the row to make the final change. Alan gets 
   no retroactive message telling him that someone else has undone his 
   changes. The last one out gets the message and gets to decide. If more 
   than two users change the same row at the same time, the first user to 
   save would get no message and the others would each get a message as 
   they saved the row. The final decision would rest with the last person 
   to save the row.
 
   If you try to save your changes by pressing [Esc] and selecting Exit 
   from the menu, R:BASE first asks whether you want to save your changes. 
   Only if you answer Yes will concurrency control kick in and tell you of 
   the conflict.
 
   Here's a final scenario. If Sue makes no changes to the row but while 
   looking at the row presses [Ctrl-F10] to refresh the screen, R:BASE 
   displays Alan's saved changes and puts these messages at the bottom of 
   the screen: Blinking shows another user's conflicting changes. Press 
   any key to continue.
 
   In the previous instance, Sue wanted to save her changes, and R:BASE let 
   her choose to accept Alan's edits or reinstate her own. But in this case 
   Sue has in effect asked, Has anyone else changed this row in the same 
   columns I've changed? In this case, R:BASE's response depends on the 
   position of the cursor. If it's in the first name field, R:BASE assumes 
   you were about to change that column and responds by highlighting Alan's 
   change to the first name (Cindy), telling you that the highlighted fields 
   have changed. Then R:BASE displays the message Press any key to continue. 
   When Sue presses a key, R:BASE returns the cursor to the conflicting 
   field and displays Alan's change. If the cursor is in a field that Alan 
   didn't change when Sue presses [Ctrl-F10], however, R:BASE just displays 
   Alan's change with no message. Because VERIFY is set to COLUMN, R:BASE 
   is set to inform you only if a change was made to a column you changed. 
   If Sue changes the last name to Smithe and then presses [Ctrl-F10], 
   R:BASE keeps Sue's last name change and also displays Alan's change, so 
   the name now reads Cindy Smithe. Again, Sue gets no message informing 
   her of the conflict because according to the VERIFY setting no conflict 
   exists.
 
 
   Example: VERIFY Set to ROW
   ==========================
   If you want R:BASE to inform you if any change is made to the same row, 
   even if that change does not conflict with your changes, set VERIFY to 
   ROW with this command:
 
   SET VERIFY ROW
 
   Again assuming that REFRESH is still set to 0, here's how the form will 
   behave for Sue once Alan changes the first name to Cindy and saves the 
   row.
 
   If Sue only looks at the row and then moves on by pressing [F8], by 
   choosing Next row under Go to on the menu, or by choosing Exit to leave 
   the form, R:BASE won't tell her that Alan changed the row because no 
   conflicting changes occurred.
 
   If Sue changes Wanda's last name to Smithe without touching the first 
   name, however, R:BASE will show the row as it was when Alan saved it 
   (first name Cindy and last name Smith) when Sue tries to save it. Sue's 
   changes are no longer shown. R:BASE will also show these two messages 
   at the bottom of the form: Another user changed this row. The database 
   contains the displayed information. Press Enter to edit the displayed 
   data; press Esc to move on. But in this case, the changes made by Alan 
   are not highlighted.
 
   Again, it's Sue's call. She can accept Alan's change (Cindy Smith) by 
   pressing [Esc], or she can press [Enter] and have the last word. If she 
   presses [Enter], R:BASE places the cursor in the field where Sue was 
   when she tried to save the row. Now Sue can change the last name to 
   Smithe again and change the first name back to Wanda.
 
   If Sue changes the first name to Joan instead of changing the last name, 
   the form behaves the same when Sue attempts to save it. R:BASE shows 
   Alan's saved row and displays the same message: Another user changed 
   this row. The database contains the displayed information. Press Enter 
   to edit the displayed data; press Esc to move on. Sue can accept Alan's 
   row or press [Enter] to have the last word.
 
   If Sue presses [Ctrl-F10] instead of trying to save the row, R:BASE 
   displays Alan's saved row and shows this message at the bottom of the 
   form: Another user has updated/changed this row. Press any key to 
   continue. 
 
   When Sue presses a key, R:BASE returns her to the spot where where she 
   was when she pressed [Ctrl-F10]. Sue will have lost any changes she made 
   up to that point, so she'll have to rekey them.
 
 
   Deletes
   =======
   When a network user deletes a row, R:BASE handles the deletion the same 
   way no matter what the VERIFY setting. Suppose that Alan and Sue are 
   again both editing Wanda's record. Alan deletes the row.
 
   If Sue makes no changes to the row and moves forward or back to another 
   row, R:BASE doesn't tell her about the deletion. Remember, no conflict 
   exists unless two people try to change the same row at the same time. 
   If she then tries to return to the row Alan deleted, she'll find it's 
   gone.
 
   If Sue makes any change, R:BASE will display this message when she tries 
   to save the row or move to another row: Another user deleted this row. 
   Press Enter to add your row; press Esc to accept deletion. 
 
   If Sue presses [Esc], the row is gone. But if she presses [Enter], the 
   row is placed back in the database with Sue's data. Now, if Alan presses 
   [F8] or [F7] to move back to the row he thought he'd deleted, he'll find 
   the row restored to the database.
 
   Note that R:BASE adds the row back at the end of the table, so it becomes 
   the last row. 
 
   Here's a final scenario. If Sue makes no changes to the row Alan just 
   deleted but presses [Ctrl-F10] for a status check, R:BASE will give her 
   the same screen and message as if she had made a change. Again, she can 
   accept or abort the deletion.
 
 
   Setting REFRESH
   ===============
   If you don't press [Ctrl-F10] to ask for a status check on the row, you 
   won't be alerted to other people's changes unless you try to change 
   something in the row. If you want all concurrent users to see changes 
   even if they aren't making changes, set REFRESH to a value between 10 
   and 65,535 seconds.
 
   For example, if you set REFRESH to 10 seconds, R:BASE refreshes the 
   screen every 10 seconds either showing the same screen or showing a 
   changed screen with a message at the bottom. The message R:BASE displays 
   corresponds to the message R:BASE would have displayed had you pressed 
   [Ctrl-F10].
 
   At first glance, this seems like a better idea because R:BASE advises 
   you of row changes regardless of whether you make a change. But it could 
   be a nuisance unless you remember to set VERIFY appropriately. For 
   example, say Sue and Alan are editing the same employee row. Sue has 
   VERIFY set to ROW and REFRESH set to 10 as she changes address 
   information. Alan is changing salary information. If Alan saves his 
   salary changes and Sue doesn't save her changes within 10 seconds, all 
   her changes up to that point will be undone when R:BASE refreshes the 
   screen. In this case, Sue clearly should have set VERIFY to COLUMN.
 
   When you're going into a form to make wholesale changes, set VERIFY to 
   COLUMN so you're notified only if someone else changes a column. 
 
   When developing a multi-user application, think through each menu action 
   and decide what combination of settings makes the most sense. R:BASE 
   provides you with a flexible set of networking tools that you need to 
   apply appropriately to each situation you encounter. Experiment with 
   different combinations of VERIFY and REFRESH settings to see how the 
   screen behaves in different situations. This will give you a good feel 
   for when to use which settings.