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 (5.11 KiB) Viewed 643 times
I'll email bBrowser support. Hope Joachim responds.