Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
Insertar Un Campo Blob En Gambas.
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Insertar Un Campo Blob En Gambas. 
 
Hola a todos!

He probado de forma efectiva el código para insertar registros con campos blob, funciona bien y rápido.

Solo quisiera saber como conocimiento general como se haría usando una sentencia SQL,  :oops:, es que cuando usaba SQL frecuentemente no existía ese tipo de datos.  

Y aunque el sentido común me dice que debería ser muy, muy sencillo. No consigo información sobre eso para sqlite y no he buscado para mysql o postgres..... e imagino que los 3 gestores tienen funciones añadidas o algo así para resolver el asunto.

Por otra parte, lo de grabar la imagen o documento a disco para luego leerlo en gambas, no es muy de mi agrado, aunque he agregado una instrucción kill para eliminar el archivo que tengo que crear para leerlo, no me parece muy agradable, basta con pensar en una aplicación para manejar música, con carátulas y se convertiría en un quebradero de cabeza.

Sería interesante poder hacer (insert into tabla (campos)  values (campos_forma) ) y que funcionara, a pesar de que los estandares, nunca lo son tanto. Así mismo usar un select SQL y que funcionara bien.

Aquí dejo un codigo para hacer eso solamente, agregar y recuperar un campo blob de una tabla en sqlite3.

Public $Con As Connection
Public $Res As Result


Public Sub Button2_Click()

  Me.Close
  $Con.Close
End

Public Sub Button1_Click()
Dim p As Picture

$Res = $Con.Create("Ttabla1")
$Res["id"] = Null
$Res["nombre"] = TextBox1.Text
$Res["imagen"] = File.Load(PictureBox1.Tag)
$Res.Update
$Res = Null
TextBox1.text = ""
PictureBox1.Picture = p
End



Public Sub Form_Open()

  $Con = Connections["Co1"]
  If Not $Con.Opened Then
    Try $Con.Open

    If Error Then
      Message.Error(Error.Code & " " & Error.Text, "Aceptar")
    Endif
  Endif
  

End

Public Sub PictureBox1_MouseDown()

 Dialog.path = Application.path
 Label2.Text = Dialog.Path
If Not Dialog.OpenFile() Then
  PictureBox1.tag = Dialog.Path
  PictureBox1.Picture = Picture.Load(Dialog.path)
  TextBox1.Text = File.Name(Dialog.Path)
Endif
  

End

Public Sub Button3_Click()
Dim archivo As Blob
  
  $Res = $Con.Exec("select * from Ttabla1 where id=&1", TextBox2.Text)
  TextBox1.text = Str($Res["nombre"])
  archivo = $Res["imagen"]
  File.Save(Application.path &/ "imagen.tmp", archivo.Data)
  PictureBox1.Picture = Picture.Load(Application.path &/ "imagen.tmp")
  Kill Application.path &/ "imagen.tmp"

End
 

 
En este código hay varios detalles, por ejemplo yo uso Application.Path, en lugar de User.Home, porque el primero me deja en el directorio de la aplicación.  Aunque no recuerdo si ya probé mover la aplicación de sitio para ver si seguía funcionando, pero tengo la sensación de que no es así.

También dimensiono una variable p tipo picture, eso no es elegante, pero su valor es null y es para limpiar el campo, si alguien sabe como hacerlo mas elegante, gracias de antemano.

También simplifiqué las conexiones solo por ahorrar tiempo en este caso, pero funciona.

Algo adicional fué el definir la tabla con el primary key, en modo serial, se puede apreciar en el insert, el campo id es null, con lo que se autoincrementa.

Como dije antes, debido a que no quiero tener imagenes en disco, salvo el blob como un archivo de extensión tmp, lo cargo en el picturebox y luego
lo borro.

PD.
  Cualquier remiendo o sugerencia es bienvenida. Es cierto que para solo hacer ver otro ejemplo de inserción y recuperación de campos blob se tocó varias cosas mas, pero me pareció que se vería mas claro para quienes vamos mas despacio.

Saludos!
 



 
ramon_661 - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Insertar Un Campo Blob En Gambas. 
 
Por partes:
Citar:

Solo quisiera saber como conocimiento general como se haría usando una sentencia SQL,  :oops:, es que cuando usaba SQL frecuentemente no existía ese tipo de datos.  

Y aunque el sentido común me dice que debería ser muy, muy sencillo. No consigo información sobre eso para sqlite y no he buscado para mysql o postgres..... e imagino que los 3 gestores tienen funciones añadidas o algo así para resolver el asunto.

En SQLite (Nunca he usado estos campos en MySql) un campo blob es un campo de texto sin límite práctico para su contenido. La diferencia de los campos text es, creo recordar, que no se depura si su contenido es texto, o sea, no página de códigos ni cosas por el estilo. Eso implica que para meter un archivo binario dentro tienes que convertirlo en texto primero. Eso lo hace directamente la función file.load peri siempre tienes que tener en cuenta que estás almacenando una representación en Base64 del fichero. Ignoro si existe una función interna de SQLite, pero... ¿qué falta hace?

Citar:
Por otra parte, lo de grabar la imagen o documento a disco para luego leerlo en gambas, no es muy de mi agrado, aunque he agregado una instrucción kill para eliminar el archivo que tengo que crear para leerlo, no me parece muy agradable, basta con pensar en una aplicación para manejar música, con carátulas y se convertiría en un quebradero de cabeza.

No puedes ver directamente tu imagen (al menos sin hacer pasos previos). Es una representación encriptada en Base64. Por otra parte no necesitas ningún kill. Símplemente guarda en ambiente temporal y ellos solos se eliminarán del disco al cerrar la sesión. Usa la función tmp() te da un nombre único de fichero en ambiente temporal (/tmp/gambas3/id de usuario/Nº de proceso de tu programa/numero secuencial.tmp) que puedes usar, sabiendo que es único y que puedes "olvidar" después, que el sistema lo eliminará automáticamente.
Citar:

Sería interesante poder hacer (insert into tabla (campos)  values (campos_forma) ) y que funcionara, a pesar de que los estandares, nunca lo son tanto. Así mismo usar un select SQL y que funcionara bien.

No entiendo ¿Qué no funciona bien?
 
Citar:
En este código hay varios detalles, por ejemplo yo uso Application.Path, en lugar de User.Home, porque el primero me deja en el directorio de la aplicación.  Aunque no recuerdo si ya probé mover la aplicación de sitio para ver si seguía funcionando, pero tengo la sensación de que no es así.

Application path te da el path donde está instalado el ejecutable. En tiempo de diseño ese path coincide con la carpeta donde está tu proyecto (al ejecutar gambas crea el ejecutable dentro de la misma carpeta), pero en tiempo de producción, es decir, cuando hayas compilado e instalado tu programa te puedes encontrar con que el ejecutable está en /usr/bin o cosas por el estilo y no te funcionará. Utiliza una carpeta que sepas que existe (Crear /home/usuario/.nombredelproyecto suele ser la solución estándar).

Citar:
También dimensiono una variable p tipo picture, eso no es elegante, pero su valor es null y es para limpiar el campo, si alguien sabe como hacerlo mas elegante, gracias de antemano.

El problema te lo creas tú sólo al utilizar variables públicas, absolutamente innecesarias en este proyecto: Convierte $Res en una variable local y no necesitarás "limpiar" ningún campo porque el result entero será destruído al finalizar el procedimiento Button1_Click.

Citar:
También simplifiqué las conexiones solo por ahorrar tiempo en este caso, pero funciona.

Respecto a $Con ¿qué falta te hace? Si utilizas conexiones almacenadas usa directamentamente Connections["Con1"].Create(etc. etc.) y te ahorras una variable pública.

Citar:
Algo adicional fué el definir la tabla con el primary key, en modo serial, se puede apreciar en el insert, el campo id es null, con lo que se autoincrementa.

Perfecto, no le pongo pegas, pero un secreto te cuento: No hacía falta.
Aunque no lo definas tú, todas las tablas de SQLite tienen un campo llamado rowid que es serial. Si tú defines uno por tu cuenta, ese campo se convierte en un sinónimo del otro. Prueba una cosa. Crea una tabla sin primary key, rellena algunas filas y luego ejecuta "Select rowid from mitabla".

Citar:
Como dije antes, debido a que no quiero tener imagenes en disco, salvo el blob como un archivo de extensión tmp, lo cargo en el picturebox y luego
lo borro.

Si es tu preferencia, adelante, pero supongo que eres consciente de que tienes todos los huevos en la misma cesta. Un error de datos, una corrpción de la BD, un borrado accidental del fichero que soporta la bd y bye bye.
Por otra parte, según el tamaño de las imágenes y la cantidad de registros, la aplicación se te irá enlenteciendo poco a poco y en el peor de los casos puede ser inmanejable.
Yo tengo una aplicación que maneja documentos escaneados y utilizo los ficheros en disco (bueno en un servidor ftp, pero eso es otra historia). En la actualidad tengo más 30.000 documentos y todo funciona igual de rápido que el primer día.

Saludos
 




===================
No podemos regresar
 
shordi - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Insertar Un Campo Blob En Gambas. 
 
Estoy de acuerdo con las sugerencias.

Salvo por una observación, no encontré la forma de limpiar el picturebox, busqué y busqué pero "naaaa" de "naaaa", así que se me ocurrió crear una variable de tipo picture y asignarla al picturebox y se acabó el problema de una pantalla limpia, con la imagen anterior aún presente.

En el caso de Application.Path, yo estaba equivocado en mis suposiciones, donde pongas el ejecutable ahí te lleva application.path, es decir, si crear una carpeta para tu proyecto en /bin, digamos "ventas", ajustas permisos, y si tienes todos los recursos que necesita tu aplicación para funcionar dentro de esa carpeta, conseguirá todo. No sé si me explico correctamente. Pero lo cierto es que el caso que propusiste funciona con Application.Path, mientras que para el caso de User.Home, para que funcione bien todos los recursos de tu aplicación deben estar debajo de /home/(usuario). Haz la prueba, yo al igual que tú pensaba que se trataba de una ruta fija al lugar donde se creo la aplicación y no es así. Claro, que si siempre vas a instalar las aplicaciones en el usuario de alguien, User.Home, funciona de maravilla, así que no hay drama. Es por detalles como este de Application.Path, que funciona mejor de lo que imaginabamos. Que me lleva a pensar en esto.  El procedimiento que usamos el caso blob, funciona y no hay dudas al respecto, pero como se haría con por ejemplo; hcon.Exec("insert into TABLA ( CAMPO1, CAMPO2, CAMPOBLOB ) values (......)",.....), si gustas llamalo la curiosidad de eva, estuve buscando infructuosamente toda la noche información al respecto y no conseguí una función intrínseca que hiciera tal cosa, no he probado con algo como convertir un archivo en base64, guardarlo en una variable de tipo blob o algo así y tratar de almacenarlo con el insert.  Como dije es solo curiosidad, el procedimiento que he aplicado mi aplicación es el que usé en el ejemplo.

Con todo lo demás estoy totalmente de acuerdo contigo, he debido evitar el uso de variables publicas en algo tan corto, y la razón de no usar Connections[Con1].Create, debo admitirlo flojera de escribir, pero no volverá a ocurrir.

Lo que si no está bien y me doy cuenta ahora que lo veo con calma es que no está documentado.....
En algún momento revisaré lo de usar base64 para quitarme la espinita.
 



 
ramon_661 - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Insertar Un Campo Blob En Gambas. 
 
Todos presumimos que gambas es bueno, excelente quizás, pero hay que reconocer que es mejor aún....

Y la verdad, quiero hacer un reconocimiento a todos los que dedican su tiempo o el que les queda, para compartir sus conocimientos con el resto de nosotros.


Saludos y muchas gracias.
 



 
ramon_661 - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Insertar Un Campo Blob En Gambas. 
 
Citar:
En el caso de Application.Path, yo estaba equivocado en mis suposiciones, donde pongas el ejecutable ahí te lleva application.path, es decir, si crear una carpeta para tu proyecto en /bin, digamos "ventas", ajustas permisos, y si tienes todos los recursos que necesita tu aplicación para funcionar dentro de esa carpeta, conseguirá todo. No sé si me explico correctamente


Application.Path te da el camino donde está el ejecutable. No deberías basarte en él para nada más. La ubicación de ficheros... mejor abro otro hilo, que el tema puede ser interesante para alguien más: https://foro.gambas-es.org/viewtopic.php?f=1&p=34018
 




===================
No podemos regresar
 
shordi - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Insertar Un Campo Blob En Gambas. 
 
Citar:
Salvo por una observación, no encontré la forma de limpiar el picturebox, busqué y busqué pero "naaaa" de "naaaa", así que se me ocurrió crear una variable de tipo picture y asignarla al picturebox y se acabó el problema de una pantalla limpia, con la imagen anterior aún presente.

Es una manera, pero no le veo sentido. ¿Has probado con mipicturebox.visible=false?

Citar:
El procedimiento que usamos el caso blob, funciona y no hay dudas al respecto, pero como se haría con por ejemplo; hcon.Exec("insert into TABLA ( CAMPO1, CAMPO2, CAMPOBLOB ) values (......)",.....), si gustas llamalo la curiosidad de eva, estuve buscando infructuosamente toda la noche información al respecto y no conseguí una función intrínseca que hiciera tal cosa, no he probado con algo como convertir un archivo en base64, guardarlo en una variable de tipo blob o algo así y tratar de almacenarlo con el insert.  Como dije es solo curiosidad, el procedimiento que he aplicado mi aplicación es el que usé en el ejemplo.


gambas te ofrece una función que te hace el trabajo. Algo así:
miconexion.Exec("Insert into TABLA ( CAMPO1, CAMPO2, CAMPOBLOB ) values (&1,&2,&3)",mivar1,mivar2,base64(file.load(mipathfichero)))


Citar:
Con todo lo demás estoy totalmente de acuerdo contigo, he debido evitar el uso de variables publicas en algo tan corto.

Huye de las variables públicas independientemente de lo largo o corto que sea tu programa. Cada variable ha de tener muy bien definido su ámbito de visibilidad según su naturaleza dentro de la aplicación. El saco de las Public (le doy public y ya lo tiengo siempre, jejeje) es una trampa que se llega a pagar muy cara.
 




===================
No podemos regresar
 
shordi - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Insertar Imagenes Campo "Blob" M... chen_08 Bases de Datos 26 Miercoles, 12 Enero 2011, 22:51 Ver último mensaje
estrella_de_galicia
No hay nuevos mensajes Como Insertar Audio En Gambas Jetxax General 7 Lunes, 12 Agosto 2013, 20:34 Ver último mensaje
jguardon
No hay nuevos mensajes Guardar Blob Desde DB En Fs (no Es Una Ima... mckaygerhard Bases de Datos 4 Viernes, 16 Agosto 2013, 15:01 Ver último mensaje
mckaygerhard
No hay nuevos mensajes Como Guardar Una Imagen En Sqlite En Un Ca... v3ctor Bases de Datos 9 Viernes, 01 Enero 2016, 14:55 Ver último mensaje
shordi
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron