Pregunta sobre PHB_ITEM (Para A. Linares)

Post Reply
xmanuel
Posts: 768
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Been thanked: 5 times
Contact:

Pregunta sobre PHB_ITEM (Para A. Linares)

Post by xmanuel »

Realmente para Antonio, Carlos o quien lo pueda saber o darme ideas.

Para implementar el método bindParam y bindColumn de una clase que estoy haciendo necesito saber si hay alguna manera de guardar una referencia a un item que se crea como una variable a nivel PRG.
Y que luego voy a necesitar modificar su valor desde C o tomar su valor sin volver a pasarlo como parámetro de una función.

Tal vez con un ejemplo se ilustre un poco mejor:

Code: Select all | Expand


//A nivel de PRG:
local miVariable1
local miVariable2

oStmt:bindParam( 1, @miVariable1 )
oStmt:bindParam( 2, @miVariable2 )

// Ahora quiero que cuando asigne un valor a miVariable1 o miVariable2 ese valor se visible en C sin tener que pasar nuevamente la variable:

miVariable1 := "Valor 1"
miVariable2 := 23

oStmt:execute() // Esto llama a una función hecha en c que necesita de las variable asociadas con el método bindParam

miVariable1 := "Valor 2"
miVariable2 := 32

oStmt:execute()

 


Code: Select all | Expand


// A nivel de C
static HB_ERRCODE bindParam( pHDOSTMT stmt, PHB_ITEM pParam, PHB_ITEM pVariable )
{
    pHDO_BIND pParameter = (pHDO_BIND) hb_xgrab( sizeof( HDO_BIND ) ); // Esto es una estructura con un miembro que es el puntero a la variable del PRG

    if( pParameter )
    {

        pParameter->pParam = pParam;
        pParameter->pVariable = pVariable;

 


No sé si me he explicado bien :-)

PD: Feliz año :arrow: nuevo :lol:
______________________________________________________________________________
Sevilla - Andalucía
Carlos Mora
Posts: 989
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by Carlos Mora »

Manu,

Hasta donde me acuerdo, HB_ItemParam() te devuelve una referencia al parámetro, incrementando el contador de referencias. Por eso se requería hacer luego un HB_ItemFree(), que decrementa el contador de referencias de la variable.

No se como está eso en Harbour, pero era la forma. Supongo que, modernizado, deben ser parecidas.

Respecto de la implementación del bind... sería interesante que se pudiera poner un codeblock, para poder referenciar cualquier expresión, incluyendo métodos de objetos y cosas así. Por ejemplo en el trabajo tenemos una TRecBuffer para dbfs y un TModel para SQL que mapean virtualmente las datas con nombre de campo a los valores de las columnas. Eso es VIRTUAL, es decir, no existen realmente y no sería posible usar valores de esas datas en el BIND. Con un codeblock se solucionaria el problema: te independiza de tener que gestionar cuestiones extrañas y te permite usar cualquier tipo de expresion como parámetro.

My 2 cents...
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
xmanuel
Posts: 768
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Been thanked: 5 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by xmanuel »

Hola Carlos. No me vale hb_itemParam() ni hb_param() que es más directa...
Si tengo entendido lo que se hace es meter una copia de la variable (ITEM) en la pila y no un puntero a ese ITEM que es lo que yo quiero.
Yo creo qu debe existir algo que haga que se esté tratando transparentemente una variable en PRG y el ITEM que la representa en C.
Si puedes Carlos postealo en la lista de Harbour a ver si alguien como Przemyslaw Czerpak o Viktor contestan, mi inglés es pésimo rozando el nulo :( :mrgreen:

En una segunda fase se podría implementar el codeblock como comentas, pero primero quiero quitarme esto de encima.

Saludos

PD: Antonio tu sabes cómo hacerlo?
______________________________________________________________________________
Sevilla - Andalucía
User avatar
Antonio Linares
Site Admin
Posts: 42548
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 78 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by Antonio Linares »

Manu,

Tienes que usar:

extern PHB_ITEM hb_gcGripGet( PHB_ITEM pItem );
extern void hb_gcGripDrop( PHB_ITEM pItem );

Fijate que pertenecen a la categoria "gc" (garbage collector), ya que de lo que se trata es de indicarle al recolector de basuras que no destruya ese item.

Mi duda es si se puede mantener "viva" una variable local una vez se salga de una función. Habría que hacer unas pruebas.

Busca por esos nombres de funciones en el código fuente de Harbour y seguramente encontraras ejemplos de uso :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42548
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 78 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by Antonio Linares »

En el código fuente de Harbour no se usa a excepción de el ItemAPI.

Si buscas en Google verás que yo las usé en "FivePhone" :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
xmanuel
Posts: 768
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Been thanked: 5 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by xmanuel »

Muchas gracias Antonio, lo miro a ver que pasa.

Ya estaba buscando otras alternativas ;-)
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
Posts: 768
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Been thanked: 5 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by xmanuel »

Fallo mío...
Con hb_param() va perfecto, el problema es que no le ponía @ detenle de la variable, aunque en ejemplo que puse si lo ponía.

Así que resuelto el problema.
A seguir con el tema.
A ver si para Reyes pongo la LIB y ejemplos para que probeis mi HDO (Harbour Data Object) :twisted: :shock: :roll: :wink: :oops: :mrgreen:

Muchas gracias Carlos y Antonio.

FELIZ AÑO A TODOS :!: :!: :!: :!: :!: :!:
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
Posts: 768
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Been thanked: 5 times
Contact:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

Post by xmanuel »

Esto que es lo que yo quería ya va perfecto:

Code: Select all | Expand


#include "hdo.ch"

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

procedure main()

    local oDb, oStmt, aRes, e
    local cDb := "agenda.db"
    local cTabla := "socios"
    local socio, direccion, telefono, miblob, categoria // Variables para los BINDS
    local cSql := "INSERT INTO " + cTabla + ;
                       " ( socio, direccion, telefono, miblob, categoria ) " + ;
                       "VALUES ( ?, ?, ?, :miblob, ? );"

    oDb := THDO():new( "sqlite" )

    if oDb:connect( cDb )

       TRY
            oStmt := oDb:prepare( cSql ) // Prepara la sentencia

            // Cracion de binds con variables de harbour
            oStmt:bindParam( 1, @socio )
            oStmt:bindParam( 2, @direccion )
            oStmt:bindParam( 3, @telefono )
            oStmt:bindParam( ':miblob', @miblob )
            oStmt:bindParam( 5, @categoria )

            oDb:beginTransaction()

                // Uso de binds
                socio     := "socio.........1"
                direccion := "direccion.....1"
                telefono  := 1111111111
                miblob    := "blob..........1"
                categoria := "categoria.....1"

                oStmt:execute()
               
                socio     := "socio....................2"
                direccion := "direccion................2"
                telefono  := 222222222
                miblob    := "blob.....................2"
                categoria := "categoria................2"

                oStmt:execute()
               
                socio     := "socio........3"
                direccion := "direccion....3"
                telefono  := 333333333
                miblob    := "blob.........3"
                categoria := "categoria....3"

                oStmt:execute()

            oDb:commit()

        CATCH e
            muestra( oDb:errorInfo(), "Error desde rdl:errorInfo()" )
            Eval( ErrorBlock(), e )
            oDb:rollBack()
        FINALLY
            oStmt:free()
        END
    endif

    oDb:disconnect()

return
 

:wink:
______________________________________________________________________________
Sevilla - Andalucía
Post Reply