https://foro.gambas-es.org/viewtopic.php?f=3&t=54
-----------------------------------
soplo
Domingo, 20 Septiembre 2009, 15:57

La Clase Connection
-----------------------------------
La clase connection proporciona un interfaz eficiente para el acceso a datos y metadatos de una base de datos. Conocer los recursos de gambas para acceso a base de datos es fundamental a la hora de obtener un código transparente al motor de base de dtos que utilice la aplicación.

El objetivo de este tema es mostrar la forma de realizar accesos a base de datos de forma transparante al motor de búsqueda que estemos utilizando. De esta forma si por alguna razón decidimos cambiar nuestra aplicación de sqlite mysql o viceversa el código serguirá funcionando correctamente con solo cambiar el usuario y tipo de conexion que usemos.

[color=darkgreen][size=14]Crear conexión[/size][/color]
Las propiedades fundamentales para crear una conexión son:
[color=darkred]Name[/color]
Es el nombre de la base de datos que queremos abrir. Si no se especifica se creará una base de datos EN MEMORIA.
En Mysql si deseamos crear usuarios, cambiar privilegios, que afecten al gestor de base de datos deberemos acceder a la base de datos "mysql".

[color=darkred]Host[/color]
Es la ubicación del servidor de base de datos. En muchas ocasiones será "localhost", pero puede ser también un nombre o una dirección IP.
Si NAME es una ruta temporal y localhost es nulo se creará la base de datos en la ubicación temporal proporcionada por TEMP() y que habitualmente es /tmp.

[color=darkred]Login y Password[/color]
Usuario y clave que definan al usuario que intenta crear la base.

[color=darkred]Type[/color]
Indica el tipo de base de datos al que queremos acceder (mysql, sqlite, ..., etc).

[color=darkred]Port[/color]
El puerto por el que accederemos a la base de datos. En el caso de mysql el puerto por defecto es 3306.

[code linenumbers=false]PUBLIC FUNCTION Conectar(Usuario AS String, Clave AS String, BD AS String, OPTIONAL Tipo AS String, OPTIONAL Host AS String, OPTIONAL Puerto AS String) AS Connection
DIM Con AS NEW Connection

Con.host = IIf(Host, Host, "Localhost")
Con.port = IIf(Puerto, Puerto, "3306")
Con.login = Usuario
Con.Password = Clave
Con.type = IIf(Tipo, Tipo, "mysql")
Con.name = BD
Con.Open 
RETURN Con
END [/code]

[color=darkgreen][size=14]Creación de base de datos[/size][/color]
La creación de una base de datos requiere conectarse en Mysql requiere conectarse a la base de datos mysql con un usuario con permiso para crear bases de datos.
Utilizando la rutina anterior sería [code linenumbers=false]
Dim Cn as new connection
Cn=Conectar("Usuario","clave","mysql")[/code]

[color=darkred]Comprobar si la base de datos existe[/color]
Y a partir de la conexión podemos comprobar si la base de datos existe y en caso contrario crearla
[code linenumbers=false]if not Cn.database.exist("Base_de_datos") then
   Cn.database.add("Base_de_datos")
endif[/code]

[color=darkred]La colección Database[/color]
La propiedad database que hemos visto devuelve la colección de bases de datos accesibles por ese usuario que está conectado. Cada item de esa colección es de tipo [b]ConnectionDatabase[/b] y como todas las colecciones tiene las siguientes propiedades y métodos 
COUNT --> Cantidad de items en la colección. En este caso cantidad de bases de datos accesibles para el usuario.
ADD ---> Agregar una nueva base de datos
EXIST ---> Comproar si existe una base de datos
REFRESH ---> Refrescar privilegios, tablas, etc de base de datos
REMOVE ---> Eliminar base de datos.
Como todas las colecciones se puede recorrer en un bucle FOR EACH
[code linenumbers=false]Dim CNB as new ConnectionDatabase
for each CNB in Cn.database
   print CNB.name
next[/code]

[color=darkred]La clase Users[/color]
No basta con crear la base de datos. También habrá que crear al menos un usuario capaz de acceder a esos datos. En nuestro caso vamos a crear dos. Uno con permiso para acceder a datos y otro con permisos de administración en su base de datos.
La clase que permite acceder a usuarios es la clase [b]users[/b]  que devuelve una colección de usuarios con permisos en la base de datos activa.

Este tema no lo tengo del todo resuelto por lo que pongo aquí lo que conozco en este punto.
La propiedad USERS que vemos devuelve la colección de usuarios con permiso para acceder a la base de datos activa. Cada item de esa colección es de tipo [b]ConnectionUsers[/b] y como todas las colecciones tiene las siguientes propiedades y métodos [code linenumbers=false]
COUNT --> Cantidad de items en la colección. En este caso cantidad de usuarios con permiso para esa base de datos
ADD ---> Agregar un nuevo usuario
EXIST ---> Comprobar si existe un usuario
REFRESH ---> Refrescar datos y privilegios del usuario
REMOVE ---> Eliminar usuario[/code]
[code linenumbers=false]Dim CNB as new ConnectionUsers
for each CNU in Cn.Users
   print CNU.name
next[/code]
El método add agrega un valor boleano para especificar si el usuario será o no administrador. Ojo con esto porque si la base de datos activa es mysql y creamos un usuario administrador estamos creando otro usuario root.
[code linenumbers=false]Cn.Uses.Add(usuario,TRUE/FALSE)[/code]

He tenido algunos problemas con esto y no siempre lo he resuelto correctamente. A veces me ha funcionado y no se bien porque razón por la cual agrego la forma de crear y asignar permisos según el motor de mysql (desaconsejado).
[code linenumbers=false]'Usuario con permiso de administración
Conexion.Users.Add(UsuarioAdm, ClaveAdm, FALSE) 'creo el usuario SIN permiso de administración

'Le asigno todos los privilegios en esa base de datos exclusivamente.
TRY Conexion.Exec("grant all on " & NombreBd & ".* to " & UsuarioAdm & "@localhost identified by '" & ClaveAdm & "'")
[/code]
¡OJO! estoy explicando crear usuarios pero hay que ser conscientes que esas claves no están encriptadas. Conviene pensarlo antes de pastear textos directamente a un código. Debeis conocer la librería CRYPT.

[code linenumbers=false]'Usuario sin permiso de administración
Conexion.Users.Add(Usuario, Clave, FALSE) 'creo el usuario SIN permiso de administración

'Le asigno todos privilegio de select, insert, delete y update en esa base de datos exclusivamente.
TRY Conexion.Exec("grant select,insert,delete,update on " & NombreBd & ".* to " & UsuarioRW & "@localhost identified by '" & Clave & "'")
[/code]

[color=darkgreen][size=14]Creación de tablas[/size][/color]
No basta con crear una base de datos vacía. Habrá que crear las tablas que correspondan.
La propiedad Tables permite acceder a la colección de tablas de la base de datos activa. Por esta razón primero conectaremos a nuestra base de datos activa y creamos una tabla.

Utilizando la rutina anterior sería [code linenumbers=false]
Dim Cn as new connection
Cn=Conectar("Usuario","clave","BaseDatos")[/code]
Y ahora utilizar la propiedad tables para acceder a la colección de tablas.
La propiedad TABLES que vemos devuelve la colección de tablas en la base de datos activa a las que el usuario tener permiso de acceso. Cada item de esa colección es de tipo [b]ConnectionTables[/b] y como todas las colecciones tiene las siguientes propiedades y métodos [code linenumbers=false]
COUNT --> Cantidad de items en la colección. En este caso cantidad de tablas de esa base de datos a las que podemos acceder.
ADD ---> Agregar un nueva tabla
EXIST ---> Comprobar si existe una tabla
REFRESH ---> Refrescar datos y privilegios de la tabla
REMOVE ---> Eliminar tabla[/code]
[code linenumbers=false]Dim CNT as new ConnectionTables
for each CNT in Cn.tables
   print CNB.name
next[/code]
El método ADD crea una nueva tabla y devuelve un objeto de clase TABLE. Tiene el siguiente formato:
[code linenumbers=false]
Dim T as new table
Table=Cn.tables.add(tabla,tipo)[/code]
Donde el tipo es uno de los siguientes
[quote]Innodb
BDB
Heap
Isam
Merge
MyIsam[/quote]
Y de ellas solo INNODB y BDB soportan el uso de TRANSACCIONES.

[color=darkred]La clase TABLE[/color]
La clase table define objetos de clase tabla y tiene únicamente el método UPDATE para grabar los cambios en una tabla.
La clase table tiene las siguientes propiedades
Name ---> Nombre de la tabla
Fields ---> devuelve una colección de campos de la tabla
Indexes ---> devuelve una coleción de índices de la tabla
Primary key ---> devuelve la clave primaria de la tabla
System ---> Devuelve si la tabla es o no es del sistema
Type ---> El tipo de la tabla (especificado anteriormente.

[color=darkred]La clase FIELDS[/color]
La propiedad FIELDS que vemos devuelve la colección de campos en la tabla a las que el usuario tener permiso de acceso. Cada item de esa colección es de tipo [b]TableFields[/b] y como todas las colecciones tiene las siguientes propiedades y métodos [code linenumbers=false]
COUNT --> Cantidad de items en la colección. En este caso cantidad de tablas de esa base de datos a las que podemos acceder.
ADD ---> Agregar un nueva tabla
EXIST ---> Comprobar si existe una tabla
REFRESH ---> Refrescar datos y privilegios de la tabla
[/code]
[code linenumbers=false]Dim CNF as new tablefields
for each CNT in Cn.table.fields
   print CNF.name
next[/code]
El formato del método ADD para agregar un campo nuevo es el siguiente:
[code linenumbers=false]table.fields(nombre,tipo,longitud,defecto)[/code]
Nombre ---> nombre del campo
tipo ---> Los tipos de campo válidos son gb.integer, gb.float,gb.boolean,gb.string,gb.date
Longitud ---> Se usa únicamente en campos de tipo gb.string
defecto ---> Especificar un valor por defecto. Si no se especifica el valor será NULL:

[color=darkred]La clase INDEXES[/color]
La propiedad indexes del objeto tables devuelve una colección de índices en la tabla
La propiedad INDEXES del objeto TABLE devuelve la colección de índices en la tabla. Cada item de esa colección es de tipo [b]TableIndexes[/b] y como todas las colecciones tiene las siguientes propiedades y métodos
 [code linenumbers=false]
COUNT --> Cantidad de items en la colección. En este caso cantidad de índices que tiene esa tabla..
ADD ---> Agregar un nuevo índice
EXIST ---> Comprobar si existe un índice
REFRESH ---> Refrescar datos del índice
REMOVE ---> Borrar índice
[/code]
[code linenumbers=false]Dim CNI as new tableIndexes
for each CNI in Cn.table.Indexes
   print CNI.name
next[/code]
El formato del método ADD es el siguiente
[code linenumbers=false]table.indexes.add(nombre,campos,unico)[/code]
nombre ---> nombre del índice
campos ---> los campos que incluye el índice. Si son varios separados por coma
unico ---> es opcional. Si vale true significa que solo admite valores únicos. Por defecto es FALSE.

[color=darkgreen][size=14]Ejemplos[/size][/color]
Recorrer todas las bases de datos accesibles por una conexión llamada CN y mostrar sus tablas y campos
[code linenumbers=false]
Dim Bases as new ConnectionDatabase, Tabla as new ConnectionTables, Campo as new TableFields, Indice as new TableIndexes

'Bucle que recorre todas las bases a las que tiene acceso el usuario
for each Bases in CN.databases
   print Bases.Name
   ' Bucle para recorrer todas las tablas de esa base
   for each Tabla in CN.tables
      print Tabla.Name
      'Bucle para recorrer todos los campos
      for each Campo in Tabla
         print Campo.Name
      next
      'bucle para recorrer los índices 
      for each Indice in Tabla
         print Index.Name
      next
   next
next[/code]

Ejemplo de creación de una base de datos con tablas y campos sobre una conexión Cn 
[code linenumbers=false]
Dim tabla as table, CN as connection
Cn=Conectar(Usuario,clave,"mysql")
CN.database.add("Base")
CN.close

CN=Conectar(Usuario,clave,"Base")

Tabla=Cn.table.add("tabla","Innodb")
With Tabla
   .fields.add("nombre",db.string,20)
   .fields.add("numero",dbinteger)
   .fields.add("decimales",db.float)
   .fields.add("fecha",db.date)
   .fields.add("boleano",db.boolean)

   .primarykey=["nombre"]
   .update
end with
[/code]


-----------------------------------
soplo
Domingo, 20 Septiembre 2009, 17:59

Re: La Clase Connection
-----------------------------------
[color=darkgreen][size=14]Transacciones[/size][/color]
Una transacción en términos simples es un conjunto de operaciones que se realizan en diversas tablas de una base de datos y que deben ejecutarse todas o ninguna.

Puede haber transacciones anidadas en Mysql. Esto depende de motor de base de datos. Postgre no lo admite por ejemplo.

Por ejemplo una transacción puede darse a la hora de meter una nueva factura en una aplicación de facturación.  Meter una nueva factura puede suponer insertar datos en tabla de facturas, tablas de totales, tablas de resumen, tablas de clientes, tablas de inventario, ..., etc. Se deben hacer todas o no hacer nada pues no quedaría la información consistente y la factura estaría mal registrada.

Solo se pueden hacer transacciones en tablas que sean de tipo INNODB o BDB.

[color=darkred]Begin[/color]
Método para iniciar una transacción

[color=darkred]Commit [/color]
Método para grabar una transacción

[color=darkred]Rollback[/color]
Método para cancelar una transacción

[color=darkgreen][size=14]Ejemplo[/size][/color]
[code linenumbers=false]Dim CN as new Connection
CN=conectar(usuario,clave,base)

CN.begin ---> iniciar la transacción

'
' realizar actualización en tabla 1. Utilizar TRY en los cambios para detectar caso de error
'

'
' realizar actualización en tabla 2. Utilizar TRY en los cambios para detectar caso de error
'

'
' realizar actualización en tabla 3. Utilizar TRY en los cambios para detectar caso de error
'
CN.commit ----> grabar los datos físicamente en las tablas

finally
CN.close ---> terminar conexión

catch 
CN.rollback[/code]

En vez de utilizar en el código anterior CN (la conexión) pude haber utilizado un objeto de la clase DB que siempre representa la conexión actual.


-----------------------------------
soplo
Domingo, 20 Septiembre 2009, 18:27

Re: La Clase Connection
-----------------------------------
[color=darkgreen][size=14]Edición de datos[/size][/color]
Todos tenemos la tentación de obtener un recordset mediante uns claúsula select del tipo
[code linenumbers=false]select * from tabla where condicion order by campos group by campo[/code]

[color=darkred]El método EXEC[/color]
Esto se puede realizar mediante el método EXEC pero plantea el problema de que esa selección depende del motor de base de datos porque este método lo que hace es enviar el string al motor de base de datos y obtener un resultado si procede.
Dim Cn as new connection, Rs as new Result
Cn=Conectar(Uuario,clave,base)
Rs=Cn.exec("select * from tabla where condicion order by campos group by campo")

Yo suelo creaar un string que haga directamente lo que quiero hacer, pero es posible crear un string genérico de la forma
[code linenumbers=false]select * from %1 where %2=%3 order by %4 group by %5[/code]
Donde Los diversos % serán sustituídos por argumentos que se pasan al método exec
[code linenumbers=false]Rs=Cn.exec("select * from %1 where %2=%3 order by %4 group by %5","tabla","campo",7,Campo2,Campo3)[/code]
Para lo que se ejecuta lo siguiente tras la traslación de parámetros
[code linenumbers=false]select * from TABLA where CAMPO=7 order by CAMPO2 group by CAMPO3[/code]

[color=darkred]El método EDIT[/color]
El método edit permite actualizar datos sin necesidad de utilizar clausulas SQL lo que permite un método transparente independiente del motor de base de datos que estemos usando
Edit (tabla,condicion,argumentos)
tabla ---> tabla que se quiere actualizar
condicion ---> lo que estaría en una claúsula WHERE de una orden select con los parámetros a trasladar como vimos antes
argumentos ---> valores que se van a trasladar
[code linenumbers=false]Dim Rs as new result
Rs=Cn.edit(tabla,""%1=%2","Campo",7))
Rs!nombre="Perico"
Rs.update
[/code]

[color=darkgreen][size=14]Inserción de datos[/size][/color]
Por la misma razón que antes podemos usar una sql insert que inserte datos en un recordset mediante el método Exec visto anteriormente.
Gambas proporciona la alternativa del método CREATE que genera un recordset a rellenar
[code linenumbers=false]Dim Rs as new result
Rs=Cn.create(tabla)
Rs!nombre="perico"
Rs!apeliido="de los palotes"
Rs.update[/code]

[color=darkgreen][size=14]Eliminación de datos[/size][/color]
Por la misma razón que antes podemos usar una sql delete que elimine datos en un recordset mediante el método Exec visto anteriormente.
Gambas proporciona la alternativa del método DELETE que elimina registros
Delete(Tabla,condicion,argumentos)
tabla ---> tabla donde se quiere borrar
condicion ---> lo que estaría en una claúsula WHERE de una orden select con los parámetros a trasladar como vimos antes
argumentos ---> valores que se van a trasladar
[code linenumbers=false]Rs=Cn.delete(tabla,""%1=%2","Campo",7))[/code]

[color=darkgreen][size=14]Búsqueda de datos[/size][/color]
Gambas proporciona el método FIND que busque registro en un recordset y que es una alternativa a una claúsula SELECT.
Find(Tabla,condicion,argumentos)
tabla ---> tabla donde se quiere borrar
condicion ---> lo que estaría en una claúsula WHERE de una orden select con los parámetros a trasladar como vimos antes
argumentos ---> valores que se van a trasladar
[code linenumbers=false]Rs=Cn.Find(tabla,""%1=%2","Campo",7))[/code]
El Recordset resultante es de solo lectura


-----------------------------------
soplo
Martes, 22 Septiembre 2009, 19:55

Re: La Clase Connection
-----------------------------------
[color=darkgreen][size=14]Triggers[/size][/color]
Los triggers son bloques de código que se ejecutan al realizar un determinado evento en un campo de una tabla.
En sybase, sql server y oracle están desde que yo tengo conocimiento, pero en mysql están disponibles desde la versión 5.0. No se si existen en postgre y lo dudo en sqlite.
Los usuarios que los crean deben tener el permiso SUPER.
[code linenumbers=false]GRANT CREATE TRIGGER ON nombreTabla TO Usuario[/code]

[color=darkred]Los eventos disparadores[/color]
Un evento dispador puede ser  insert, delete o update. El código se ejecutará ANTES o DESPUES de que ocurra
Osea que yo puedo hacer un trigguer cuando se vaya a ejecutar una sentencia INSERT inmediatamente antes de que se produzca la inserción o inmediatamente despues. Para ello disponemos de las palabras clave AFTER (despues) y BEFORE (antes)
[code linenumbers=false]
Create trigger nombre_trigger AFTER INSERT ...
Create trigger nombre_trigger BEFORE IINSERT ...
Create trigger nombre_trigger AFTER DELETE ...
Create trigger nombre_trigger BEFORE DELETE...
Create trigger nombre_trigger AFTER UPDATE ...
Create trigger nombre_trigger BEFORE UPDATE...[/code]

[color=darkred]bloque de código[/color]
Cuando se produce un evento que tiene asociado un trigger se ejecuta un bloque de código que puede ser cualquier cosa imaginable excepto utilizar procedimientos almacenados.
En ese bloque de código disponemos de OLD.nombre_campo para especificar el valor anterior de un campo y NEW.nombre_campo para especificar el nuevo valor del campo.
De esta forma podemos ejecutar un bloque de código que antes de hacer un delete o un update haga un insert en otra tabla donde se guarden los datos antiguos por ejempo.

[color=darkred]Ejemplos de triggers[/color]
Crear un trigger que despues de hacer un update en la tabla de clientes inserte un registro en una tabla auditoria_clientes en la cual guardaremos el dato viejo, el nuevo, el usuario que hizo el cambio y cuando
[code linenumbers=false]CREATE TRIGGER trigger_auditoria_clientes AFTER UPDATE ON clientes 
   FOR EACH ROW
   BEGIN
   INSERT INTO auditoria_clientes(nombre, anterior_ejecutivo_cuenta, usuario, cambiado)
   VALUES (OLD.nombre, OLD.ejecutivo_cuenta, CURRENT_USER(), NOW() );
   END;
[/code]
La función mysql CURRENT_USER() devuelve el nombre del usuario que está ejecutando y la función NOW() devuelve la fecha del sistema.

Los triggers son tan útiles que acaba habiendo muchos de manera que es conveniente ponerles nombres claros que ayuden a enfocar problemas. Yo tengo la costumbre de poner DOS LETRAS que identifiquen lo que hacen IN -> INSERT, DE -> DELETE, UP-> UPDATE luego un guion y el nombre de la tabla donde escriben.

En el caso anterior
[code linenumbers=false]CREATE TRIGGER UP_auditoria_clientes AFTER UPDATE ON clientes 
   FOR EACH ROW
   BEGIN
   INSERT INTO auditoria_clientes(nombre, anterior_ejecutivo_cuenta, usuario, cambiado)
   VALUES (OLD.nombre, OLD.ejecutivo_cuenta, CURRENT_USER(), NOW() );
   END;
[/code]
En mysql podemos ver los triggers actuales mediante la orden
[code linenumbers=false]show triggers[/code]

De manera que al final en gambas podemos ejecutar (un usuario con permisos de administración en la base) la siguiente instrucción[code linenumbers=false]
Dim Sql as string
sql="CREATE TRIGGER UP_auditoria_clientes AFTER UPDATE ON clientes " _
   & "FOR EACH ROW " _
   & "BEGIN " _
   & "INSERT INTO auditoria_clientes(nombre, anterior_ejecutivo_cuenta, usuario, cambiado) " _
   & " VALUES (OLD.nombre, OLD.ejecutivo_cuenta, CURRENT_USER(), NOW() ) " _
   & "END"
Conexion.exec(sql)[/code]

A mi no me gusta crear tablas de log porque acabas almacenando un montón de información inuti por cada insert, delete y update que se haga en una tabla y quizá lo haces en muchas tablas así que prefiero utilizar dos campos adicionales en cada tabla importante donde dejo únicamente la fecha en que el registro cambió y el usuario que lo hizo

Este trigger antes de un update cambia el campo FechaW en la tabla para grabar la hora actual y el campo UsuarioW para grabar el usuario actual
[code linenumbers=false][code linenumbers=false]Dim Sql as string
sql="CREATE TRIGGER UP_auditoria_clientes BEFORE UPDATE ON clientes " _
   & "FOR EACH ROW " _
   & "BEGIN " _
   & "INSERT INTO clientes(NEW.FECHAW, NEW.USUARIOW) " _
   & " VALUES (NOW(), CURRENT_USER) " _
   & "END"
Conexion.exec(sql)[/code]


Este trigger antes de un insert cambia el campo FechaW en la tabla para grabar la hora actual y el campo UsuarioW para grabar el usuario actual
[code linenumbers=false][code linenumbers=false]Dim Sql as string
sql="CREATE TRIGGER UP_auditoria_clientes BEFORE INSERT ON clientes " _
   & "FOR EACH ROW " _
   & "SET NEW.FECHAW=NOW(), NEW.USUARIOW=CURRENT_USER() " _
Conexion.exec(sql)[/code]


-----------------------------------
powerdgo
Viernes, 25 Diciembre 2009, 21:23

Re: La Clase Connection
-----------------------------------
creo que es mejor poner en esta sentencia la palabra Databases:

if not Cn.exist("Base_de_datos") then    -----------------  IF NOT Cn.Databases.Exist("Base_de_datos") then 
   Cn.database.add("Base_de_datos")
endif

:)


-----------------------------------
soplo
Viernes, 25 Diciembre 2009, 21:30

Re: La Clase Connection
-----------------------------------
Cierto cierto, muchas gracias por la corrección.

Es dificil no cometer al escribir en un foro errores de bulto como ese, pero cuando salen hay que corregirlos para evitar que alguien pastee el código y se encuentre con errores tontos. 

Ahora mismo lo corrijo.

Agradecido
 :lol:


-----------------------------------
jsoto61
Lunes, 03 May 2010, 07:08

Re: La Clase Connection
-----------------------------------
Estoy intentando desarrollar una función que me permita ver las bases de datos que tengo en mi servidor de mysql y el código:

[code linenumbers=false syntax=gambas]
Dim CNB as new ConnectionDatabase
for each CNB in Cn.database
   print CNB.name
next
[/code]

desencadena el siguiente error:

Unknown identifier: ConnectionDatabase en línea tal del formulario cual

Llevo todo el fin de semana intentando resolver este tema pero no doy con ello. ¿a alguien se le ocurre alguna idea?.

Gracias de antemano.


-----------------------------------
jguardon
Lunes, 03 May 2010, 08:47

Re: La Clase Connection
-----------------------------------
[quote user="jsoto61" post="3427"]

[quote]
Dim CNB as new Connection[strike]Database[/strike]
for each CNB in Cn.database
   print CNB.name
next
[/quote]

Unknown identifier: ConnectionDatabase en línea tal del formulario cual

[/quote]


Es lógico. No existe ningún objeto llamado "ConnectionDatabase", sino sólo "Connection". A menos que tú hayas creado una clase con ese nombre...
Lo que sí existe es una propiedad del objeto Connection que es "Databases" (con la s al final):

http://gambasdoc.org/help/comp/gb.db/.connectiondatabases

De todos modos no creo que puedas iterar en un objeto Connection, ya que no es un array ni colección. Esto otro debería funcionar:

[code linenumbers=false syntax=gambas]DIM cdb AS  Database
FOR EACH cdb IN Cn.Databases
    PRINT cdb.Name
NEXT[/code]

Lógicamente "Cn" es una nueva conexión que debería estar abierta antes.


El mejor consejo que puedo darte es que revises el código fuente de Gambas, la parte relativa al Database Manager (Gestor de Base de Datos), del cual aprenderás mucho.

Saludos


-----------------------------------
jsoto61
Martes, 04 May 2010, 07:41

Re: La Clase Connection
-----------------------------------
Muchísimas gracias, efectivamente he aplicado lo que me has indicado y funciona correctamente.

En cuanto a Lo de analizar el código de gambas me parece que aún me queda mucho que aprender para ello, de hecho, tras tu comentario he intentado hacerlo y no se ni por donde empezar, me he puesto a navegar entre el "mogollón" de archivos y directorios y al final lo he dejado por iimposible,.... ¡ya me gustaría...!


