Page 1 of 1

Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 12:26 pm
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 view

//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 view

// 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:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 2:31 pm
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...

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 6:48 pm
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?

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 7:08 pm
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 :-)

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 7:15 pm
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" :-)

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Tue Dec 29, 2015 9:18 pm
by xmanuel
Muchas gracias Antonio, lo miro a ver que pasa.

Ya estaba buscando otras alternativas ;-)

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Wed Dec 30, 2015 12:21 pm
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 :!: :!: :!: :!: :!: :!:

Re: Pregunta sobre PHB_ITEM (Para A. Linares)

PostPosted: Wed Dec 30, 2015 3:22 pm
by xmanuel
Esto que es lo que yo quería ya va perfecto:
Code: Select all  Expand view

#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: