xsharp.eu • SELECT Command
Page 1 of 1

SELECT Command

Posted: Sat Oct 19, 2019 3:31 pm
by Karl-Heinz
Hi Robert,

I´m struggling with the SELECT command.

Code: Select all

#command SELECT <whatever>  => dbSelectArea( <(whatever)> )
Something like:

SELECT a becomes dbSelectArea ( "a" )
SELECT 9 becomes dbSelectArea ( "9" )
SELECT 10 becomes dbSelectArea ( "10" ) <-- throws an Exception

VO behaves the same, but Foxpro doesn´t show this problem and selects to workareas > 9. in the DB.prg i see what DbSelectArea() does:

Code: Select all

FUNCTION DbSelectArea(uArea) AS LOGIC CLIPPER          -> 
FUNCTION _Select(uWorkArea) AS USUAL CLIPPER           ->
FUNCTION _SelectString(uWorkArea AS STRING) AS DWORD
My idea is to enhance the _SelectString(). See the KHR comment below

Code: Select all

FUNCTION _SelectString(uWorkArea AS STRING) AS DWORD 
	
	LOCAL nSelect := 0 AS DWORD
    uWorkArea := AllTrim(uWorkArea)
    IF SLen(uWorkArea) = 1
        nSelect := Val(uWorkArea)
		VAR nAsc := Asc( Upper(uWorkArea) )
		IF nAsc > 64 .AND. nAsc < 75
			nSelect := nAsc - 64
		ENDIF
		
    ELSE 
    
    	//  ------ added KHR 

   	IF NTrim ( Val( uWorkArea ) ) == uWOrkArea 
   	   nSelect := Val ( uWOrkArea)
   		   
    	ENDIF 

       // -------------------

    		
    ENDIF
        
    IF nSelect > 0 .OR. "0" == uWorkArea
        nSelect := VoDb.SetSelect((INT) nSelect)
    ELSE
        nSelect := (DWORD) VoDb.SymSelect(uWorkArea)
    ENDIF
    RETURN nSelect

Now, if _SelectString() processes e.g. "10", the workarea becomes selected. Calling the func with something like "10A" would still fail.

What do you think ?

regards
Karl-Heinz

SELECT Command

Posted: Sat Oct 19, 2019 4:26 pm
by Jamal
Hi Dev Team!

Maybe unrelated, but since we are talking about the SELECT command, the documentation seems incorrect for the SELECT command. https://www.xsharp.eu/help/command_select.html

Shouldn't the xnWorkArea range be from 0 to 1023 not 0 to 250 ?
VO help has the same doc error. The VO Select() help says it returns a value from 0 to 1023.

Yet, when I scanned X# workareas.prg, I see the:
PUBLIC CONST MaxWorkAreas := 4096 AS DWORD

Workareas.MaxWorkAreas is used in X# CoreDb.prg:

Code: Select all

STATIC METHOD SetSelect(siNew AS INT) AS DWORD
        RETURN CoreDb.Do ({ =>
        IF siNew == -1
            siNew := (INT) RuntimeState.Workareas:FindEmptyArea(FALSE)
        ELSEIF siNEw <= 0
            siNew := (INT) RuntimeState.Workareas:FindEmptyArea(TRUE)
        ENDIF
        IF siNew > Workareas.MaxWorkAreas
            siNew := 0
        ELSEIF siNew == 0 
            RddError.PostArgumentError( __FUNCTION__, EDB_SELECT, nameof(siNew), 1, <OBJECT>{siNew})
        ELSE      
            RuntimeState.CurrentWorkarea := (DWORD) siNew   
        ENDIF
        RETURN (DWORD) siNew
        })

Now this is confusing! Which/What is correct?

Jamal

SELECT Command

Posted: Sat Oct 19, 2019 4:53 pm
by robert
Jamal,

Sabo always used to say (with a fat German accent) "ze truz is in ze source".
So the maximum value is 4096.

Robert

SELECT Command

Posted: Sun Oct 20, 2019 6:10 am
by Karl-Heinz
Hi Jamal,

the first workarea of a dbServer is 4096, the next is 4095, etc.
the workarea of a classic server depends on what you´re doing.

Code: Select all

	RddSetDefault ( "dbfcdx" )
	SetExclusive ( FALSE ) 


	cDbf := "d:testsmall.dbf"	
	
	oDB := DbServer { cDBF }
    	? oDB:WorkArea  // 4096
	? DbGetSelect()  // 4096 
	     
    	?
    
	oDB := DbServer { cDBF } 
    	? oDB:WorkArea  // 4095
	? DbGetSelect()  // 4095 
	    		
	?
	
	DbSelect ( 0 )  // <------------
	use (cDBF) alias "one"
	? DbGetSelect()  // 1
	
	? 

	oDB := DbServer { cDBF } 
    	? oDB:WorkArea  // 4094
	? DbGetSelect()  // 4094 

	?

	DbSelect ( 0 ) // <------------
	use (cDBF) alias "two"
	? DbGetSelect()  // 2 

When you deactivate both DBSelect(0) calls you´ll see how dangerous it is to use a mixture of dbservers and classic servers. The million Dollar question: If both Dbselect(0) calls are deactivated, which servers are finally in the shown workareas ? ;-)

regards
Karl-Heinz

SELECT Command

Posted: Sun Oct 20, 2019 2:37 pm
by Jamal
Hi Karl-Heinz,

Yes, I see how that mix can be a problem.

Jamal

SELECT Command

Posted: Sun Oct 20, 2019 3:15 pm
by robert
Karl-Heinz,

The default behavior if the DbServer class is to not restore the current workarea after an operation.
You can call DbSetRestoreWorkarea(TRUE) to tell the DbServer class to restore the workarea after an operation.
That is "cleaner" but slightly slower, at least that was the case in VO. I am really not sure if this is still the case in X#.
And in stead of DbSelect(0) I would recommend to use the NEW clause for the USE command. This guarantees that the file will be opened in a new workarea.

Robert