xsharp.eu • VO Question: dbServer FieldGET issue
Page 1 of 2

VO Question: dbServer FieldGET issue

Posted: Tue Jun 11, 2019 7:09 pm
by Jamal
Using VO 2.08 SP4b (2838), I have the following code which sometimes fails to find a field in the dbf file. Thus wPos returns 0.
The same happens in various DBF files in a random fashion and I cannot pinpoint exactly what is causing it. I am passing a SYMBOL for the field name such as oSrv:FieldGet(#MYFIELD). Is IsSymbol() the problem or is it FieldPosSym() ?
Since this is random and I cannot replicate it, I am baffled. Any idea on what is causing this issue or a possible workaround?

Code: Select all

METHOD FIELDGET(uField) CLASS _SpeciallDBServer
	LOCAL uRetVal as USUAL
	LOCAL wPos AS DWORD
	LOCAL dwCurrentWorkArea as DWORD    
	LOCAL oError as USUAL
	
	BEGIN SEQUENCE
		VODBSelect( wWorkArea, @dwCurrentWorkArea )      
		
                IF  IsSymbol( uField )
                       wPos := FieldPosSym( uField) 

		ELSEIF IsString( uField ) 
			wPos := FieldPos( AsString(uField) )
			
		ELSEIF IsNumeric( uField )
			wPos := uField
			IF wPos > wFieldCount
				wPos := 0
			ENDIF		
		ENDIF
		
		IF wPos = 0
			InfoBox{,"Utility", "Invalid field: " + AsString(uField) + " in " + AsString(self:name) + _chr(10) + Psz2String(ProcName(2)) + _chr(10) + AsString(ProcLine(2))}:show()    
		ELSE
			(wWorkArea)->VODBFieldGet( wPos, @uRetVal )
		ENDIF    
		
		__DBSSetSelect( dwCurrentWorkArea )  //SE-060527    
		
	RECOVER USING oError
		oErrorInfo := oError
		__DBSSetSelect( dwCurrentWorkArea )  //SE-060527
		uRetVal := nil
	END SEQUENCE
	
	
	RETURN uRetVal     

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 12:01 am
by TimothyS
Suspect the problem could be in the workarea. You might want to do a few checks to see if you have the right workarea.

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 12:18 am
by Chris
Or maybe sometimes for some reason the wrong symbol is being passed. I would add some debug code after the "IF IsSymbol( uField )" line that prints the symbol, workarea and return value of wPos. And if wPos == 0, maybe I would also print the names of all the fields just after.

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 1:17 am
by Jamal
Hi Timothy & Chris,

The workarea and fieldname are correct based on what is displayed using:

Code: Select all

IF wPos = 0
	InfoBox{,"Utility", "Invalid field: " + AsString(uField) + " in " + AsString(self:name) + _chr(10) + Psz2String(ProcName(2)) + _chr(10) + AsString(ProcLine(2))}:show()    
ELSE
	(wWorkArea)->VODBFieldGet( wPos, @uRetVal )
ENDIF 
The self:name (for the dbf name) and uField are displayed correctly via the InfoBox when wPos is zero.

Jamal

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 5:08 am
by lumberjack
Jamal,
Jamal wrote:Using VO 2.08 SP4b (2838), I have the following code which sometimes fails to find a field in the dbf file. Thus wPos returns 0 for the field name such as oSrv:FieldGet(#MYFIELD). Is IsSymbol() the problem or is it FieldPosSym() ?
Since this is random and I cannot replicate it, I am baffled.

Code: Select all

METHOD FIELDGET(uField) CLASS _SpeciallDBServer
	LOCAL uRetVal as USUAL
	LOCAL wPos AS DWORD
	LOCAL dwCurrentWorkArea as DWORD    
	LOCAL oError as USUAL
	BEGIN SEQUENCE
		VODBSelect( wWorkArea, @dwCurrentWorkArea )      
                IF  IsSymbol( uField )
                       wPos := FieldPosSym( uField) 
		ELSEIF IsString( uField ) 
			wPos := FieldPos( AsString(uField) )
		ELSEIF IsNumeric( uField )
			wPos := uField
			IF wPos > wFieldCount
				wPos := 0
			ENDIF		
		ENDIF
		IF wPos = 0
			InfoBox{,"Utility", "Invalid field: " + AsString(uField) + " in " + AsString(self:name) + _chr(10) + Psz2String(ProcName(2)) + _chr(10) + AsString(ProcLine(2))}:show()    
		ELSE
			(wWorkArea)->VODBFieldGet( wPos, @uRetVal )
		ENDIF    
		__DBSSetSelect( dwCurrentWorkArea )  //SE-060527    
	END SEQUENCE
	RETURN uRetVal     
Is your _SpeciallDbServer class inheriting from DbServer? It just look strange why you would want to select a different workarea (wWorkArea and dwCurrentWorkArea) seeing that DbServer manages its workarea internally?

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 6:02 am
by Jamal
Johan,

I am just "improving" the dbServer and overriding the FIELDGET() which does the same thing; nothing strange about that. Please look at the VO RDD CLASS SDK, FIELDGET() method. Without the

Code: Select all

VODBSelect( self:wWorkArea, @dwCurrentWorkArea ) 
the FIELDGET() will fail.

Jamal

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 7:50 am
by Karl-Heinz
Hi Jamal,

when i switched from 2.5b3 to 2.8 i noticed several strange DBF access problems. The solution was to use DbSetRestoreWorkarea( TRUE ) - the default setting of this global setting is FALSE. As you see, within the __DBSSetSelect() func VODBSetSelect() is only called if __glRestoreWorkarea is set to TRUE.

Code: Select all


FUNCTION __DBSSetSelect(dwNew AS DWORD) AS DWORD PASCAL
   //SE-060527
   IF __glRestoreWorkarea
      RETURN VODBSetSelect(LONGINT(dwNew))
   ENDIF
   RETURN dwNew

STATIC GLOBAL __glRestoreWorkarea := FALSE AS LOGIC //SE-060527

FUNCTION DbSetRestoreWorkarea(lEnable := NIL AS USUAL) AS LOGIC PASCAL
   //SE-060527
   LOCAL lOldValue AS LOGIC

   lOldValue := __glRestoreWorkarea

   IF IsLogic(lEnable)
      __glRestoreWorkarea := lEnable
   ENDIF

   RETURN lOldValue

Don´t know if it helps in your case, but i would give it a try.

BTW. The DBsetRestoreWorkarea() func is documented in the Whatsnew28.rtf

regards
Karl-Heinz

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 4:11 pm
by Jamal
Hi Karl,

Thanks! It is funny I was looking at DbSetRestoreWorkarea() function yesterday and its source in the X# master lib. However, I am not sure if this will help, since I am setting the workarea before accessing the DBF functions and __DBSSetSelect(..) is coming after. On error, I am going to dump the field list into a log file and see what what is returned.

Jamal

VO Question: dbServer FieldGET issue

Posted: Wed Jun 12, 2019 4:38 pm
by Jamal
I modified the code to force an alias to be used via (self:wWorkArea)->

Code: Select all

wPos := (self:wWorkArea)->FieldPos( AsString(uField) 
Will wait to see if any clients have issues or if it solves it.

Jamal

VO Question: dbServer FieldGET issue

Posted: Mon Nov 04, 2019 11:57 pm
by Jamal
I know it has been sometime since posting this topic!

By accident, I think I may have found the real reason for the mystery! It was bBrowser AutoRefresh feature after not touching anything on the bBrowser by sitting idle for about 10 minutes. The use of SetTimer()/KillTimer() combination in bBrowser even with AutoRefreshTime set to 0, caused the DBF workarea to get really screwed up after about 10 minutes of idle time and then FIELDGET() crashed.

I was able to replicate the issue several times. Commenting out the SetTimer()/KillTimer() in the Assign AutoRerfreshTime(...) method code resolved the issue; basically, I just disabled this feature!

I am going to implement my refresh routine and see how it goes by implementing a simple timer function which is not part of the bBrowser's EventHandler().

Edit: so I created my timer to call oBrowser:Refresh() now that always points:
bBrowser:StabilizeServer() line 26 which is: self:oServer:Skip(1). See screenshot:
2019-11-05_0-30-07.png
2019-11-05_0-30-07.png (5.11 KiB) Viewed 643 times
I'll email bBrowser support. Hope Joachim responds.