SELECT Command

This forum is meant for questions and discussions about the X# language and tools
Post Reply
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

SELECT Command

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

SELECT Command

Post 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
User avatar
robert
Posts: 4529
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

SELECT Command

Post 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
XSharp Development Team
The Netherlands
robert@xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

SELECT Command

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

SELECT Command

Post by Jamal »

Hi Karl-Heinz,

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

Jamal
User avatar
robert
Posts: 4529
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

SELECT Command

Post 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
XSharp Development Team
The Netherlands
robert@xsharp.eu
Post Reply