Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Refresh function
Message
From
16/07/2021 17:35:31
 
 
To
16/07/2021 14:32:12
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
01681815
Message ID:
01681822
Views:
37
>Thanks for the ideas re record counter. The backend is still VFP native tables. As for changes, have never really needed to use this before because in this business, only one person works on a "file" at a time (e.g. a collection of records) - like a law firm where the "file" gets passed from lawyer, to assistant, to maybe another person and then back to the lawyer for signing. And so they did not ask to build into their processes (or save routines) the detection of record changes.

User and Timestamp of last change are not as important as a PK, but most C/S databases have them as standard now. If I visualize your connection with stakeholders and guesstimate a project started last century, I'd plot out 3 enhancements to choose from:

  • minimal/basic fields set via application
    minimal/basic fields set via trigger on table level
    minimal/basic fields set via trigger on table level plus generation of an audit table

  • From what I hear about modus operandi performance will not be any problem even if writing an audit table.
    I have used them sometimes, but never really needed them, as I am adamant on bullying customers into external backup ;-)
    OTOH IIRC your processes can reflect high value like real estate values, so getting risk reduction not in ounces but at least in pounds might be reasonable. As I built those apps on a framework having routines for automatic audit trail generation, the added effort for audit trail was minimal, the write process was not taxing the tables (local DBF, road warrior use case) and replication/upserting end of day/end of week was not taxing the backend. John mentions dangers from hackers/crackers/ransomcryptors, those dangers will trend more in the future, why not be proactive ?

    Longevity and value of your product coupled with worth of items is high, even larger enhancements should be mentioned (in writing...). Do not implement yourself, if your fwk does not support it, check those offering source, buy one and rip the source out.

    Discuss GUI after such a decision, in which topics crypto AND client/server should mentioned, even if not necessary due to almost exclusive table usage ;-)


    >But now they have an instance where this is needed so I need to figure out what to do. I am not sure yet as it is still in the discussion phase if they want me to flag the record as having being changed - I was thinking of using dynamic for color to show changed records in red or blue. Or if they want me to block the save or show the user the changed fields etc. I need to discuss more with them what they require. The company is small enough that it would probably work for one person to just call another and ask "hey, you made a change - what was it".
    >
    >Right now, I am just thinking of ideas before I ask them - and try to figure out if Refresh() and CurVal() will help or not.
    >
    >So it seems I would need to do this to the cursor:
    >
    >
    >
    >* scan and refresh each record; when init-ing grid, set the forecolor to something like (let me put some of it in pseudo code for easier reading:
    >
    >THIS.SetAll("DynamicForeColor","IIF(LastSavedField # CURVAL("LastSavedField"),<blue>,<black>,"Column")
    >
    >* save old record number to pop back to
    >* have to use SCAN as it appears REFRESH() does not refresh an entire cursor at once
    >
    >SCAN
    >
    >   * refresh each record
    >   REFRESH(1)
    >
    >   * and then I am done as DynamicForeColor should show the difference
    >
    >ENDSCAN
    >
    >
    >but I don't like moving the record pointer even if I wait for user inactivity; what happens if a user starts doing something in a row when the timer fires to check for activity? That seems to me to be a recipe for disaster.
    >
    >Right now, the only thing I do that is "close" to that is for another screen, which is like a work queue, a timer goes out and checks for the number of records in a work queue and if the RECCOUNT() has changed since they opened the screen, it makes visible a label on the form saying "new records have shown up in your work queue - press Refresh list or Save to see the change" (or something like that). But in that case, I am not looking at individual records.
    >
    >Albert
    >
    >>You did not specify which backend you used and if/how you checked for record alteration before save.
    >>
    >>I never liked vfp leaning inside documentation on unchanged field values and generating single Update SQL statements for PK and oldvalue of fields to update ( WhereType: 3 or DB_KEYANDMODIFIED)in CursorAdapter via TableUpdate() for instance. WhereType 4 (DB_KEYANDTIMESTAMP ) does not need to be a timestamp in the datetime() sense - it can be used with any kind of field.
    >>
    >>My solutions usually include a timestamp of last change (only half trustworthy on servers as server time might be altered by admin, even less on shared dbf, as field only reflects each clients idea of now()) plus a 4 or 8 byte counter for field writes to the record. Such fields are IMO much better to detect update conflicts or a need to update records in a cursor or a view, as you can compare field values. Timestamp trust for need of update less important, if you check on equality, not (later than record.timestampvalue).
    >>
    >>Brutal but effective in avoiding subtle errors stemming from updated fields you selected, did NOT change yourself but used in record validation the change in value by others might kill validation. Crystal clear in showing that a record had been updated in between - if you were rigid in forcing those fields to update.
    >>
    >>regards
    >>thomas
    >>
    >>>Hi all,
    >>>
    >>>I have never really had to use Refresh(). But now I have been asked for one small part of an app where the users have multiple records loaded in a view if "can we know if someone else has just made a change to a record" (I have used optimistic locking up to now).
    >>>
    >>>I looked a Refresh() and CurVal() and have tried to test myself. I have also read Hackers Guide to VFP and it answered some, but not all, my questions:
    >>>
    >>>I am thinking of including a datetime stamp on each record so that I don't have to check all the fields.
    >>>
    >>>Both screens where the editing take place have buffering set to 5 and there are multiple records in each. The users in one screen will typically save their data out after ever record edit. The users in the other "master" screen are seeing records from many users and they want to see the changes others make before potentially making their own changes.
    >>>
    >>>- the notes all say that Refresh() needs to be issued on the current cursor so that the data returned by CurVal() is up to date
    >>>
    >>>- it doesn't seem like Refresh() will refresh an entire view - it seems to be only 1 record at a time; this means I would be moving the record pointer through the master screen for reach record, issuing Refresh(1) and then changing the display to show that a change has been made (probably changing the colour of the row for changed records as a visual clue)
    >>>
    >>>- It seems Refresh() might be kinda kludgy to use - is that the right impression?
    >>>
    >>>Albert
    Previous
    Reply
    Map
    View

    Click here to load this message in the networking platform