Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread How to capture Warnings???
Sun, Jun 15 2025 7:31 PMPermanent Link

Ian Branch

Avatar

Hi Team,
Get Current Row - Warnings like this are written to the System Log but not made visible to the User.
"The row has been modified since last cached for the table XXXXXXXX"
I suspect the User is unaware that their attempt to do something with the record was unsuccessful.
Is there some way to capture such warnings so they can be flagged to the User??

Regards & TIA,
Ian
Mon, Jun 16 2025 3:11 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian


Looking in the manual there is a specific error for this EDB_ERROR_ROWMODIFIED (1008) so it should be possible to trap for it and do a refresh. The manual also says "Please see the
Updating Rows topic for more information." I'm not sure where or what that is.


I think the behaviour changes depending on wether you are using optimistic or pessimistic locking.

Roy Lambert
Mon, Jun 16 2025 9:43 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian

First have a look in the ElevateDB manual (not the sql one)  - search for "Editing an Existing Row" (its about page 160) it may be useful


Also I had a wade through the newsgroups and with the search terms I used came up with little - but here you are

Path: news.elevatesoft.com
Message-ID: <15B1DB1F-8424-48EB-8863-945D1DADD6A3@news.elevatesoft.com>
Reply-To: "Tim Young [Elevate Software]" <timyoung@elevatesoft.com>
From: "Tim Young [Elevate Software]" <timyoung@elevatesoft.com>
Newsgroups: elevatesoft.public.elevatedb.general
References: <36FED7EB-F55C-47F3-97E1-0FC12170EAC7@news.elevatesoft.com>
Subject: Re: 8708's as was
Date: Tue, 18 Dec 2007 15:38:17 -0500
Lines: 21
Organization: Elevate Software
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198
X-RFC2646: Format=Flowed; Original


Roy,

<< Am I correct in assuming that in EDB, with RecordLockProtocol set to
pessimistic, and RecordChangeDetection set to false we will no longer
receive the error (now 1007/8)?  >>

Correct.

<< If I am correct is the record data being displayed refreshed prior to
editing or what? >>

Yes, the row data is refreshed when the row is edited, so the changes will
be there.  The only difference is that EDB simply won't say "Hey !  The row
changed from what you were just looking at prior to the edit !". Smiley

--
Tim Young
Elevate Software
www.elevatesoft.com



Path: news.elevatesoft.com
Message-ID: <305673A4-A632-4787-A6AA-EEFFD90AAF14@news.elevatesoft.com>
Reply-To: "Tim Young [Elevate Software]" <timyoung@elevatesoft.com>
From: "Tim Young [Elevate Software]" <timyoung@elevatesoft.com>
Newsgroups: elevatesoft.public.elevatedb.general
References: <1C1A62AC-709A-476A-B724-8903E9A49F3A@news.elevatesoft.com> <08D960D1-315D-4B91-908D-7E08C21883EA@news.elevatesoft.com> <E776ADB5-2E58-4FA1-BCC4-FB2A7EAE9E41@news.elevatesoft.com>
In-Reply-To: <E776ADB5-2E58-4FA1-BCC4-FB2A7EAE9E41@news.elevatesoft.com>
Subject: Re: Locking and Concurency question
Date: Fri, 15 Mar 2013 15:30:40 -0400
Lines: 2
Organization: Elevate Software
MIME-Version: 1.0
Content-Type: text/plain;
   format=flowed;
   charset="Windows-1252";
   reply-type=original
Content-Transfer-Encoding: 8bit
X-Priority: 3
X-MSMail-Priority: Normal
Importance: Normal
X-Newsreader: Microsoft Windows Live Mail 14.0.8117.416
X-MimeOLE: Produced By Microsoft MimeOLE V14.0.8117.416


Beni,

<< I just notice something I didn’t see until now! Yes, I’m using sensitive
queries and I handled the situation when 2 applications were trying to edit
the same record (#1005 error code). My problem was related to a record
changed in one application and already loaded in another application. I just
notice that when you go into edit mode the record (in the second
application) is updated (refreshed) silently which is interesting … but is
this the right solution? I will have to explain to my users that what they
see may change when they are trying to change it. Wouldn’t be a better
solution to raise an error when the user tries to change an out of date
record – when the locking is attempted? >>

This is the property that you want (TEDBSession):

http://www.elevatesoft.com/manual?action=viewprop&id=edb2&product=delphi&version=7&comp=TEDBSession&prop=RecordChangeDetection

If you set it to True (default is False), then an Edit will raise a "Row
modified" exception that you can trap in an OnEditError event handler and
use to notify the user.  You can then just retry the operation and it will
continue on as normal.

If you have any other questions, please let me know.

Tim Young
Elevate Software
www.elevatesoft.com






Roy Lambert
Mon, Jun 16 2025 3:40 PMPermanent Link

Ian Branch

Avatar

Tks Roy,
Appreciate the time/effort ou have put in.
I have RecordChangeDetection set to True, and I have ROW_MODIFIED capture/messages routines in OnEditError and OnPostEror but neither of them fire.  Frown
Well, at least the Users tell me they don't get/see any 'Modified record' message when the 'modified' message appears in the System Log.
Both of the routines expect a EDB_ERROR_ROWMODIFIED error code.
As best I can tell from the System log, there is no error code associated with the warning.
Tue, Jun 17 2025 2:59 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian


Can you build a test bed that reproduces the issue? If so I'll happily have a look and see if I can build it into my table/query components

Roy Lambert
Tue, Jun 17 2025 9:28 PMPermanent Link

Ian Branch

Avatar

Hi Team,
This is how I am capturing the Warning:
{code}
/// <summary>
/// Handles database errors during dataset operations, providing informative messages and actions.
/// </summary>
/// <param name="Action">Outputs the action to take after error handling (e.g., daAbort, daRetry, daFail).</param>
/// <param name="E">The database error encountered while saving changes.</param>
/// <param name="DataSet">The dataset being posted when the error occurred.</param>
/// <remarks>
/// - Handles specific ElevateDB errors with user-friendly messages and options.
/// - Logs key error cases for debugging and tracking.
/// - Refreshes the dataset if a record has been modified or deleted.
/// </remarks>
procedure _PostError(out Action: TDataAction; E: EDatabaseError; DataSet: TDataSet);
begin

 var sMessage := 'The record you are trying to save in the "' + DataSet.Name + '" table ';

 Action := daFail; // Default to daFail for safety

 if E is EEDBError then
 begin

   var edbError := EEDBError(E);
   var iCode := edbError.ErrorCode;
   var sError := edbError.ErrorMsg;

   case iCode of

     EDB_ERROR_CONSTRAINT:
       begin
         if sError.Contains('cannot be NULL') then
           StyledTaskMessageDlg('Missing Required Field!', sMessage + Format('''
                                 is missing a required value. See the message below:
                                 %s
                                 ''', [sError]), mtError, [mbOK], 0)

         else if sError.Contains('violates a foreign key') then
           StyledTaskMessageDlg('Invalid Reference!', sMessage + Format('''
                                 contains an invalid foreign key value. See the message below:
                                 %s
                                 ''', [sError]), mtError, [mbOK], 0)

         else if sError.Contains('duplicate') or sError.Contains('already exists') then
           StyledTaskMessageDlg('Duplicate Data Entry!', sMessage + Format('''
                                 is a duplicate. See the message below:
                                 %s
                                 ''', [sError]), mtError, [mbOK], 0)

         else
           StyledTaskMessageDlg('Constraint Violation!', sMessage + Format('''
                                 caused a constraint error. See the message below:
                                 %s
                                 ''', [sError]), mtError, [mbOK], 0);
       end;

     EDB_ERROR_LOCK:
       begin
         if StyledTaskMessageDlg('Locked table!', Format('''
                                 The %s table is currently locked. Try again?
                                 ''', [DataSet.Name]), mtConfirmation, [mbYes, mbNo], 0) = mrYes then
           Action := daRetry;
       end;

     EDB_ERROR_LOCKROW:
       begin
         if StyledTaskMessageDlg('Locked record!', sMessage + '''
                                   is currently locked. Try again?
                                   ''', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
           Action := daRetry;
       end;

     EDB_ERROR_ROWDELETED:
       begin
         StyledTaskMessageDlg('Deleted record!', sMessage + 'has been deleted since it was retrieved.', mtError, [mbOK], 0);
         DataSet.Refresh;
       end;

     EDB_ERROR_ROWMODIFIED:
       begin
         StyledTaskMessageDlg('Error - Record modified!', sMessage + '''
                               has been modified by another user or session
                               since you opened it or began editing it.
                               Please refresh the record and try again.
                               ''', mtError, [mbOK], 0);

         Quicklog('__Post Error - The ' + DataSet.Name + ' record has been modified by another user or session');
         DataSet.Refresh;
         Action := daRetry;
       end;
   end;

   // Also handle specific string error even if code wasn't matched
   if (iCode <> EDB_ERROR_ROWMODIFIED) and ContainsText(sError, 'The row has been modified since last cached') then
   begin
     StyledTaskMessageDlg('Warning - Record modified!', sMessage + '''
                           has been modified by another user or session
                           since you opened it or began editing it.
                           Please refresh the record and try again.
                           ''', mtWarning, [mbOK], 0);

     Quicklog('__Post Warning - The ' + DataSet.Name + ' record has been modified by another user or session');
     DataSet.Refresh;
     Action := daRetry;
   end;

 end;

end;
{code}

Hope this helps somebody else..

Ian
Wed, Jun 18 2025 2:55 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian


Does it work?

Roy Lambert
Wed, Jun 18 2025 2:28 PMPermanent Link

Ian Branch

Avatar

Roy Lambert wrote:
Does it work?

Roy,
I see the Quicklog message written to disk so I presume the User sees the message...  Smile

Ian
Sun, Jun 29 2025 5:49 PMPermanent Link

Ian Branch

Avatar

Hi Team.  I thought I was on a winner here but it ain't so.. Frown
{code}
....


     EDB_ERROR_ROWMODIFIED:
       begin
         StyledTaskMessageDlg('Error - Record modified!', sMessage + '''
                               has been modified by another user or session since you opened it or began editing it.
                               Please refresh the record and try again.
                               ''', mtError, [mbOK], 0);

         if DataSet.Name = 'JobTickets' then
           QuickLog(Format('''
                       __Edit Error - Error Code "%s".. - The "%s".. record for "Job # %s".. has been modified by another user or session!
                       ''', [EDB_ERROR_ROWMODIFIED.ToString, DataSet.Name, DataSet.FieldByName('JobNo').AsString]))
         else
           QuickLog('__Edit Error - Error Code - The ' + DataSet.Name + '.. record has been modified by another user or session!');

         Action := daAbort;
       end;

   end;

   if Action <> daFail then Exit; // Handled above; skip fallback parsing

   // Additional message-based handling for "row modified" warnings (no error code)
   if (iCode <> EDB_ERROR_ROWMODIFIED) and ContainsText(sError, 'The row has been modified since last cached') then
   begin
     StyledTaskMessageDlg('Warning - Record modified!', sMessage + '''
                           has been modified by another user or session since you opened it or began editing it.
                           Please refresh the record and try again.
                           ''', mtWarning, [mbOK], 0);

     if DataSet.Name = 'JobTickets' then
       QuickLog(Format('''
                       __Edit Warning - In Text - The %s record for Job # "%s" has been modified by another user or session!
                       ''', [DataSet.Name, DataSet.FieldByName('JobNo').AsString]))
     else
       QuickLog('__Edit Warning - In Text - The ' + DataSet.Name + ' record has been modified by another user or session!');

     Action := daAbort;
   end;

   // Constraint violation, validation or duplicate key
   if ContainsText(sError, 'must have a value') or ContainsText(sError, 'read-only') or ContainsText(sError, 'duplicate key') or (iCode = EDB_ERROR_CONSTRAINT)
     then
   begin
     StyledTaskMessageDlg('Validation Error', sError, mtError, [mbOK], 0);
     QuickLog(' __Edit Error - Validation failure: ' + sError);
     Action := daAbort;
   end;

 end
 else
   QuickLog(' __Edit Error - Unexpected exception in ' + DataSet.Name + ': ' + E.ClassName + ' - ' + E.Message);

end;
{code}

Turns out Warnings go through the equivalent of this too:
{code}
...

     EDB_ERROR_ROWMODIFIED:
       begin
         StyledTaskMessageDlg('Error - Record modified!', sMessage + '''
                               has been modified by another user or session since you opened it or began editing it.
                               Please refresh the record and try again.
                               ''', mtError, [mbOK], 0);

         if DataSet.Name = 'JobTickets' then
           QuickLog(Format('''
                       __Edit Error - Error Code "%s".. - The "%s".. record for "Job # %s".. has been modified by another user or session!
                       ''', [EDB_ERROR_ROWMODIFIED.ToString, DataSet.Name, DataSet.FieldByName('JobNo').AsString]))
         else
           QuickLog('__Edit Error - Error Code - The ' + DataSet.Name + '.. record has been modified by another user or session!');

         Action := daAbort;
       end;

   end;
{code}

But get logged as a Warning rather then Error, and with no Error code.

Re-evaluating what I do now...
Image