Dirty flag for changed data in ORM class

232 views
Skip to first unread message

Alex Strickland

unread,
Oct 12, 2023, 6:28:50 AM10/12/23
to Harbour Users
Hi

I've written an ORM to abstract away workareas, allowing local object
variables to contain a workarea. In the ORM I declare data variables in
the class which correspond to each field in the database. So code like
"PLU->pluno" becomes "oPLU:nPLUNo".

One problem is that the data variables are only written to the
underlying workarea when they are deliberately written - ::WriteAll().
Workareas are a little different in that updating the field immediately
changes the value in the file. I assume that there is some "dirty" flag
in the workarea which ensures this data is written away when moving off
the current record, seeking, etc.

I would like to have an equivalent "dirty" flag set whenever the object
data variables are updated. If I had such a thing I could avoid some
subtle bugs and optimise other code. I cannot think of any way to do
this, does anyone have any ideas?

--

Regards

Alex


poopall

unread,
Oct 12, 2023, 5:18:05 PM10/12/23
to Harbour Users
I assumed that data is only written to the workarea on a commit being issued.

Francesco Perillo

unread,
Oct 12, 2023, 5:50:42 PM10/12/23
to harbou...@googlegroups.com
Look for SETGET methods.

I suppose they work in this way:
METHOD rows( nValue ) SETGET

So if you do a
object:rows = 5 
harbour calls the methos rows( 5 )
If you do a
? object:rows
it calls object:rows()

Since you call a method you need to have a shadow data member to store the value and in this method, if the value is different from the one already stored, set the flag

There are several examples in Harbour source code:
METHOD HbQtBrowse:posBlock( bBlock )
   IF bBlock != NIL
      ::bPosBlock := __eInstVar53( Self, "POSBLOCK", bBlock, "B", 1001 )   <---- see below, checks that parameter is a codeblock otherwise raise an error
   ENDIF
   RETURN ::bPosBlock

Here is a bit different:
METHOD HbQtEditor:updateRequestBlock( bBlock )
   LOCAL bOldBlock := ::bUpdateRequestBlock
   IF HB_ISBLOCK( bBlock )
      ::bUpdateRequestBlock := bBlock  <--- no call to __eInstVar53...
      ::qEdit:connect( "updateRequest(QRect,int)", {|oRect,nYScrolled| Eval( ::bUpdateRequestBlock, oRect, nYScrolled ) } )
   ENDIF
   RETURN bOldBlock

From changelog:
 + harbour/source/rtl/einstvar.prg
    + added undocumented CA-Cl*pper function _eInstVar() used to validate  <--- later renamed to __eInstVar53
      variable type in assign messages.

/* NOTE: In CA-Cl*pper 5.2/5.3 the cMethod argument seems to be ignored. */

FUNCTION __eInstVar53( oVar, cMethod, xValue, cType, nSubCode, bValid )

   LOCAL oError

   IF ! ValType( xValue ) == cType .OR. ;
      ( bValid != NIL .AND. ! Eval( bValid, oVar, xValue ) )
      oError := ErrorNew()
      oError:description := hb_langErrMsg( EG_ARG )
      oError:gencode := EG_ARG
      oError:severity := ES_ERROR
      oError:cansubstitute := .T.
      oError:subsystem := oVar:className
#ifdef HB_CLP_STRICT
      HB_SYMBOL_UNUSED( cMethod )
#else
      oError:operation := cMethod
#endif
      oError:subcode := nSubCode
      oError:args := { xValue }
      xValue := Eval( ErrorBlock(), oError )
      IF ! ValType( xValue ) == cType
         __errInHandler()
      ENDIF
   ENDIF

   RETURN xValue




--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/005bef8e-17b3-c1a2-5fa3-5a169bbad7f9%40mweb.co.za.

Victor Casajuana Mas

unread,
Oct 13, 2023, 2:55:59 AM10/13/23
to Harbour Users
Hello.
I created an ORM for use in my applications, documented it and created some videos, in case it serves as a reference.

Alex Strickland

unread,
Oct 17, 2023, 12:20:01 PM10/17/23
to harbou...@googlegroups.com

Hi Francesco

I did not mention that I am building the data variables from a data dictionary with many 1000's of different fields in a few 100 tables. Still your idea looks interesting, I would need to adapt tclass.prg to create SETGET methods but I think that is doable.

I fixed one of my "subtle" bugs and now at least the ORM seems reliable, but the efficiency can definitely be vastly improved with a flag, and I would need to do something like the above.

Thank you for the ideas.

--

Regards

Alex

Alex Strickland

unread,
Oct 17, 2023, 12:21:36 PM10/17/23
to harbou...@googlegroups.com

Hi Victor

Thank you for the link, that is a very thorough implementation. I have done something quite a bit simpler, but if I need to extend it I know where to look.

Thank you.

--

Regards

Alex

CV

unread,
Oct 17, 2023, 6:43:56 PM10/17/23
to Harbour Users
Alex

There is a function named 

dbrecordinfo( 9 )) 

that returns all the data in the record (as plain text) one field after the other, including memos.
The number (9) comes from dbfinfo.ch:
...
#define DBRI_RAWRECORD        7  /* Harbour extension */
#define DBRI_RAWMEMOS         8  /* Harbour extension */
#define DBRI_RAWDATA              9  /* Harbour extension */
...

Maybe this gives you an approach to what you want.

My 2cents.

Regards
--
Claudio Voskian
Buenos Aires - Argentina

Alex Strickland

unread,
Oct 18, 2023, 8:58:19 AM10/18/23
to harbou...@googlegroups.com

Hi

I don't think that is the case. A commit ensures that the workarea is flushed to the disk (or at least instructs the OS to do so, I think I read that the OS does not have to obey).

When you write workarea->field := 1 I don't think you can do anything to revoke the change.

I would be interested to hear if I am wrong.

--

Regards

Alex

--
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.

joselu...@gmail.com

unread,
Oct 18, 2023, 1:53:17 PM10/18/23
to Harbour Users
Hi Alex,
Is your ORM available for download and test.
Regards,
José Luis

Alex Strickland

unread,
Oct 19, 2023, 3:24:47 AM10/19/23
to harbou...@googlegroups.com

Hi José

Unfortunately it is not really built to be a standalone library. I will see if we can remove external dependencies but we are kind of under the whip and I can't promise anything.

--

Regards

Alex

Reply all
Reply to author
Forward
0 new messages