Page 2 of 4

PostPosted: Mon Apr 14, 2008 3:08 am
by sysctrl2
quetal adolfo,,

trabajo con xharbour , no uso una lib ole terceros

saludos..

TADOBASE

PostPosted: Mon Apr 14, 2008 6:59 am
by FiveWiDi
Adolfo,

para poder aplicar lo que comento en el mensaje del 13/04/2008 de las 06:29 debes añadir esta función a TADOBase.PRG:

/* ********************************* */
//----------------------------------------------------------------------------//
// IDEA ORIG.: Manuel Exp¢sito Su rez //
// AUTOR.....: CARLOS GELABERT //
// e-Mail....: //
// PRG.......: TADODBServer //
// FECHA MOD.: 14/04/2008 //
// VERSION...: 01.00 //
// PROPOSITO.: Genera una clase particular por TABLA controlando duplicados //
//----------------------------------------------------------------------------//

#include "Obj2Hb.ch"

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

static __ahTADO := {}

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

function ADODBServer( cDatabase, cTabla, Dbclass )

local n := 0
local __nClassH := 0

//#ifdef __HARBOUR__
local __oDb
//#endif

DbClass := upper( if( ValType( DbClass ) != "C", ;
"T" + cDatabase + "_" + cTabla, DbClass ) )

if ( n := DbAt( DbClass ) ) > 0
__nClassH := __ahTADO[ n, 2 ]
++__ahTADO[ n, 3 ]
else
//#ifdef __HARBOUR__
EXTERNAL TADOBASE
_HB_CLASS DbClass
__oDb := HbClass():New( DbClass, __CLS_PARAM ( "TADOBASE" ) )
__oDb:Create()
__nClassH := __oDb:hClass
//#else
/* De momento nada de nada. */
//#endif
AAdd( __ahTADO, { DbClass, __nClassH, 1 } )
endif

//#ifdef __HARBOUR__
return( __clsInst( __nClassH ) )
//#else
/* De momento nada de nada. */
//#endif

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

function DbAt( DbCls )
return( AScan( __ahTADO, { | aClass | aClass[ 1 ] == DbCls } ) )

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

function lDbClass( DbCls ) ; return( DbAt( DbCls ) > 0 )

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

function ADbClass() ; return( __ahTADO )

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

function nInsDbClass( DbCls )

local nAt := DbAt( DbCls )

return( if( nAt > 0, __ahTADO[ nAt, 3 ], 0 ) )

//----------------------------------------------------------------------------//
/* ********************************* */

Además deberás modificar:
#xcommand DEFINE ADOBASE <oDb> ;
[ CONNECTION <oConnect> ] ;
[ TABLE <cTable> ] ;
[ SELECT <cSelect> ] ;
=> ;
<oDb>:= TAdoBase():New( <(oConnect)>, <(cTable)>, <(cSelect)> )

por:
#xcommand DEFINE ADOBASE <oDb> ;
ADODATABASE <cDatabase> ;
[ CONNECTION <oConnect> ] ;
TABLE <cTable> ;
[ SELECT <cSelect> ] ;
=> ;
<oDb>:= ADODBServer( <(cDatabase)>, <(cTable)> ):New( <(oConnect)>, <(cTable)>, <(cSelect)> )

y en el método :NEW()

Antes del 'Return Self' en vez de llamar directamente FieldToData(), condicionarlo así:

if( nInsDbClass( ::ClassName() ) < 2, FieldToData( Self ), )


Saludos
Carlos G.

Re: TADOBASE

PostPosted: Mon Apr 14, 2008 10:54 am
by andresreyes_mzt
Hola Carlos,

Disculpa pero difiero un poco contigo en la forma de utilizar las classes ...

tan solo imaginate una funcion recurrente, digamos cada vez que creas un objeto, entonces deberas crear un clase, seria el mundo de nunca acabar.

Supon tu:

Tienes una funcion que ejecuta un browse, y cada vez que llamas a esa funcion, esa funcion en lugar de crear una instancia del objeto, crea una clase especifica para ese Objeto ADO. supon tu que llamas a esa funcion durante el dia, algunas 50 veces digamos para una sola tabla (objeto ado) estarias creando 50 classes, y asi seguirias.

Donde quedaria la optimizacion si estarias consumiendo un 500% mas de la memoria necesaria???

a Donde queda el ahorro ??

El tratar o utilizar clases no es algo muy sencillo, no necesariamente las cosas mas rapidas o sencillas son las mejores, hay que analizar muy bien.

Disculpa si a la mejor sueno muy agresivo en mi comentario, cosa que no pretendo que sea asi. Desgraciadamente me tope con muchas cosas desde hace 16 años que trabajaba con clipper, y el trabajar con clases no es algo que se debe de analizar una sola vez.

Sacrificarias una cosa por otra ???

No te parece algo contraproducente ???

Saludos,

Andres Reyes

Re: TADOBASE

PostPosted: Mon Apr 14, 2008 11:42 am
by FiveWiDi
andresreyes_mzt wrote:Disculpa pero difiero un poco contigo en la forma de utilizar las classes ...
...
Sacrificarias una cosa por otra ???

Andres Reyes


Andres,

No te preocupes, si los comentarios no los leo con buena intención más vale que cambie de hobby.

No soy un experto en clases, ni mucho menos. Además el estar acostumbrado a trabajar con DBF y 'programillas' pequeños hacen que tenga vicios que en sistemas basados en tablas sql seguramente seran verdaderas barbaridades.

Ahora bien, por lo que he podido entender del código que he copiado/adaptado de Manuel Expósito, sólo se crean clases nuevas cuando la DATABASE y la TABLA que deseo usar no se ha usado hasta ese momento; momento a partir del cual cada vez que vuelva a usar esa misma tabla usaré una instancia a esa clase creada.

Por tanto si una DATABASE tiene 73 tablas como mucho crearé 73 clases diferentes; y evidentemente si tiene 'X' seran 'X' clases nuevas.

Dónde está el límite? Pues no lo sé. Creo que los sistemas actuales se puden comer perfectamente un número (para mi) muy elevado de clases direfentes.

Espero haber interpretado bien el código y esté haciendo lo que creo que hace; aun así esta tarde provocaré que un programa mío reviente a ver que me deja en el err.log y poder observar cuantas clases y dbf estaban declaradas/en uso.

Saludos y gracias por el comentario.
Carlos G.

PostPosted: Mon Apr 14, 2008 2:02 pm
by Adolfo
Holas a todos.

Carlos revise tus sugerencias y solo opte por lo del "Return self".

Se agregaron nuevas entradas en el metodo Info() y estoy preparando la opcion de conocer los derechos del usuario sobre la tabla o recordset, en unos dias espero tenerlo. ( si el trabajo me deja tiempo )

Descargar lanueva version desde aqui

http://200.72.140.34/privado/adobase.rar

Eso...
Cualquier aporte es bienvenido.

Desde Chile
Adolfo

Re: TADOBASE

PostPosted: Mon Apr 14, 2008 2:19 pm
by FiveWiDi
Andrés,

ya realicé la prueba, y con la solución que adoptó Manuel Expósito en TDBF, las clases sólo se crean la primera vez que se usa la DBF. Por tanto la recursividad no generará un consumo de recursos innecesarios.

En mi caso, tenía 54 usos de 9 DBF diferentes y sólo 9 clases creadas de esos 54 usos.

Visto eso yo si que sacrificaría unos pocos (muy pocos, poquísimos) recursos para ganar velocidad.

Saludos y gracias
Carlos G.

PostPosted: Mon Apr 14, 2008 2:19 pm
by Adolfo
Carlos.

Gracias por tu cooperacion.

He visto tus modificaciones sugeridas con respecto al trabajo de Manu, debo recordarte, que la clase maneja un RECORDSET, no una tabla, por lo que pueden haber activas 2 instancias de la clase con una tabla usada en ambos recordset.

Para la comprension de la clase puse un ejemplo mirando a una sola tabla, ahora estoy viendo los ejemplos para navegar por un recordset con llamadas a 2 o mas tablas y ver su comportamiento y si es viable usarla o nop.

La idea de esta clase es hacerla lo suficientemente poderosa para usar recordset "extremos" con join y multiples referencias a otras tablas de manera facil y comprensible para los "antiguos" programadores xBase.

Los nuevos,ja ja ja , ya me vino el viejazo, estaran mas acostumbrados a usar los comandos ADO puros y duros, yo por mi parte trate de encapsular ciertos trabajos repetitivos en una sola clase.

Si hasta migre una aplicacion que usaba 3 dbf en solo 1 dia, ya que hacia uso exclusivo de la tDataBase. por lo menos algo ya me ha servido.

Bueno , esperando sus aportes y comentarios

Desde Chile
Adolfo

PostPosted: Mon Apr 14, 2008 2:22 pm
by FiveWiDi
Adolfo wrote:Holas a todos.

Carlos revise tus sugerencias y solo opte por lo del "Return self".
...
Eso...
Cualquier aporte es bienvenido.

Desde Chile
Adolfo


De acuerdo.

Aun así si puedes pruébalo; yo no tengo nada sobre sql.

Saludos
Carlos G.

PostPosted: Mon Apr 14, 2008 5:57 pm
by metaldrummer
Adolfo wrote:Holas..

Estoy haciendo las modificaciones sugeridas por Carlos, y agregando mas opciones al metodo Info. para mejor informacion al desarrollar.

Segun la documentacion leida no se pueden usar ciertos tipos de bloqueos con ubicaciones y tipos de cursores. Lo ideal es que se pueda informar antes de seguir.

Carlos .. para los nombres de la columnas usa

oRs:Fields( nField ):Name

Puedes Recuperarlas asi.

For n= 1 to ( oRs:Fields:Count )
AADD( oRsNames, oRs:Fields( n-1 ):Name )
Next

Eso...

SysCtrl2
Reviso el Problema con ACCESS, el error me indica que el Recordset no tiene el metodo open asociado.... :?

Eso es muy raro... con que compilador trabajas, Harbour, xHarbour, version, tienes alguna clase propia de OLE o algo asi...?

Sigo en las pruebas y comento.


Adolfo:

Tengo el mismo problema con mysql: Error Adodb.Recordset/6 DISP_E_UNKNOWNNAME: OPEN al acceder a una tabla fuera del mysql que tengo en mi pc...en un servidor con ip pública....
Al acceder al mysql de mi máquina ningún problema por localhost o la ip de mi tarjeta de red....si solo cambio la ip para acceder a un server fuera de mi máquina me arroja ese error al momento de hacer un simple select * from tabla...con un truncate no tengo problemas
Saludos
P.D:te mandé un correo a tu privado hace unos días...

PostPosted: Mon Apr 14, 2008 7:14 pm
by Adolfo
DAVID, SYSCTRL2

He intentado reproducir el error que me indican, pero solo puedo hacerlo cuando el string del cSelect esta con errores o misspelling, vale decir, cuando un nombre de campo, tabla esta mal escrito, mayusculas/minusculas etc.

Prueben recompilando, todo el ejemplo, probando su select en alguna herramienta externa, mmm descartando libs de terceros.

David, no he recibido tu correo, por favor reenvialo.

Eso.

Desde Chile.
Adolfo

PostPosted: Mon Apr 14, 2008 7:50 pm
by sysctrl2
ok. gracias ADOlfo

podras agregarme a tu msg ?

para explicarte algunas cuestiones?

ccc_3_ccc@hotmail.com


saludos ..

PostPosted: Mon Apr 21, 2008 11:11 pm
by Adolfo
www.xdata.cl/ADOBASE.rar

English ON --------------------------------------------------

Hi everybody.

This is the latest version of ADOBASE.

You have a complete example of use, I have an small MYSQL db on my server.
Speed is no so good at all, but at least you will be able to test it from your home country, the server is in Chile, with a 1MB dedicated line :(

I'll have this test DB up for at least 3 days, so you will be able to test it.

I'm preparing documentation on the class and some precautions to use RECORDSETS in general.

So stay TUNED....

Spanish ON --------------------------------------------------

Hola a todos.

Esta es la ultima version de ADOBASE.

Tienen un ejemplo completo de uso, levante una peuqeña DB Mysql en mi server.
La velocidad no es muy buena, pero a lo menos podran probarlo desde su pais, el servidor tiene linea internacional de 1MB :(

Estara disponible por 3 dias, asi podran probarlo.

Estoy preparando la documentacion sobre la clase y algunas cosas sobre los recordsets

Esten atentos


FROM CHILE
Adolfo

PostPosted: Tue Apr 22, 2008 8:57 am
by Carlos Mora
Hola Carlos,

FiveWiDi wrote:Me dejé una cosa importantísima que hace TDBF, y es crear una 'nueva' clase para cada DBF diferente que va a utilizar. Supongo que teniendo en cuenta ese 'pequeño' detalle deja de ser una mala práctica.

Adolfo, por lo tanto, lo que he sugerido no vale sin esa asignación previa.

En fin, si puedo seguiré mirando como hacerlo.
Carlos G.


Adhiero a la opinión de Andrés, y te hago notar otro detalle: en SQL cada consulta es diferente, no es como con dbfs que abres la tabla y luego tu seleccionas los datos. Con SQL los selects son diferentes y pueden provenir de varias tablas, por ejemplo uno no abre toda la tabla de cuentas corrientes de clientes, sino que hace un select de los registros que pertenecen al cliente que te interese en ese momento, y para el periodo que buscas, y puede que no seimpre te traigas los mismos campos de la misma tabla, por lo que hacer una clase por cada consulta no me parece la mejor solución.

Un saludo,

Carlos.

PostPosted: Tue Apr 22, 2008 1:00 pm
by FiveWiDi
Carlos Mora wrote:Hola Carlos,

FiveWiDi wrote:Me dejé una cosa importantísima que hace TDBF, y es crear una 'nueva' clase para cada DBF diferente que va a utilizar. Supongo que teniendo en cuenta ese 'pequeño' detalle deja de ser una mala práctica.

Adolfo, por lo tanto, lo que he sugerido no vale sin esa asignación previa.

En fin, si puedo seguiré mirando como hacerlo.
Carlos G.


Adhiero a la opinión de Andrés, y te hago notar otro detalle: en SQL cada consulta es diferente, no es como con dbfs que abres la tabla y luego tu seleccionas los datos. Con SQL los selects son diferentes y pueden provenir de varias tablas, por ejemplo uno no abre toda la tabla de cuentas corrientes de clientes, sino que hace un select de los registros que pertenecen al cliente que te interese en ese momento, y para el periodo que buscas, y puede que no seimpre te traigas los mismos campos de la misma tabla, por lo que hacer una clase por cada consulta no me parece la mejor solución.

Un saludo,

Carlos.


No es que cree una clase para cada consulta sino que crea una clase para cada tabla.
Ahora bien como cada consulta puede tener 'campos' (columnas) diferentes entre consultas, seguramente trabajando un poco el tema se puede aprovechar una misma clase para todas las consultas de una misma tabla.

Saludos
Carlos G.

PostPosted: Tue Apr 22, 2008 2:35 pm
by Adolfo
...Alguien ha hecho pruebas de acceso con la nueva version y el demo que les he dejado ?

Algun comentario, error, sugerencia...

eso..

Desde Chile
Adolfo