VO Question: dbServer FieldGET issue

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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     
User avatar
TimothyS
Posts: 58
Joined: Thu Dec 15, 2016 3:39 pm
Location: Australia

VO Question: dbServer FieldGET issue

Post 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.
User avatar
Chris
Posts: 4562
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

VO Question: dbServer FieldGET issue

Post 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.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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
User avatar
lumberjack
Posts: 723
Joined: Fri Sep 25, 2015 3:11 pm

VO Question: dbServer FieldGET issue

Post 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?
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am

VO Question: dbServer FieldGET issue

Post 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
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

VO Question: dbServer FieldGET issue

Post 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 277 times
I'll email bBrowser support. Hope Joachim responds.
Post Reply