Re: Postgress PGexecparam
Pablo Botella

Hi Sander,
First sorry for the late response (was leave so many things unatended this
days).
I will try to explain the issues step by step
First issue to solve is how to pass an array of integers.
In pure Xbase++ probably you can do something like this
cSizes := ""
aEval( aValues , {|e,n| cSizes += L2Bin( Len( e ) ) } )
and pass cSizes to the called function
With ot4xb you can get some advantadges using nFpCall() instead of
DllCall() or DllExecuteCall(). One of this advantadges is that you can
provide an Xbase++ array of numeric values and nFpCall() will pass it
as an array of integers and, if is provided by reference, update the array
elements after the call.
aSizes := Array( Len( aValues) )
aEval( aValues , {|e,n| aSizes[n] := Len( e ) } )
result := nFpCall( fpPQexecParams, ....some_params.., aSizes, ...more_params...)
The second issue is how to pass an array of strings. If you see the Phil post
you can see how do it with bap or bap2.
In ot4xb as you can provide an array of numerics to nFpCall() can store the pointers into an Xbase+ array and just pass it
apValues := Array( Len( aValues) )
aSizes := Array( Len( aValues) )
aEval( aValues , {|e,n,nSize| apValues[n] := _xgrab(e,@nSize) , aSizes[n] := nSize } )
result := nFpCall( fpPQexecParams, ....someParams.., apValues,aSizes, ...moreParams... )
aEval( apValues , {|e,n|_xfree(e)} )
apValues := NIL
..... ummmh works, but still there are another way ....... specially if you are not confortable dealing with pointers
// ---------------------------------------------------------------------------
function Array2ppMarshall( aItems , aSizes)
local nItems,nSize,pMem,nShift
if( ValType( aItems ) != "A" ) ; return 0 ; end
nItems := Len( aItems )
if( nItems < 1 ) ; return 0 ; end
aSizes := Array(nItems)
nSize := (5 * nItems) + 1
aEval( aItems , {|_e,_n| nSize += (aSizes[_n] := iif(_e == NIL,0,Len(_e)))})
pMem := _xgrab(nSize)
nShift := 4 * nItems
PokeDWord( pMem , @nShift , aSizes )
aEval( aItems , {|_e,_n| PokeDWord(pMem,4*(_n-1),pMem+nShift),;
PokeStr(pMem,@nShift,iif( _e == NIL,"",_e)),;
nShift++ } )
return pMem
// ---------------------------------------------------------------------------
I will include a C version of the Array2ppMarshall() function in next
release of ot4xb that probably will be a litle faster but you can use this in Xbase++ in the
meantime.
Syntax:
Array2ppMarshall( aItems , [ aSizes ] ) -> (LPSTR * ) pItems
The strings pointed from the pItems elements are contained inside the same
memory block so , you just need to release 1 pointer with _xfree(pItems) when no longer
needed.
aSizes := NIL
ppValues := Array2ppMarshall( aValues,@aSizes)
result := nFpCall( fpPQexecParams, ....someParams.., ppValues,aSizes, ...moreParams... )
_xfree( ppValues )
ppValues := NIL
Hope this can help you a bit, the rest of the implementation is specifically related to Postgress
Regards,
Pablo Botella