Difference between revisions of "Lazarus Tdbf Tutorial/es"

From Lazarus wiki
m (Reverted edits by Ramonturner (Talk); changed back to last version by Iskraelectrica)
m (Text replace - "delphi>" to "syntaxhighlight>")
Line 39: Line 39:
 
=== Añadir campos===
 
=== Añadir campos===
 
   La creación de campos para su nueva tabla en tiempo de ejecución se realiza como en Delphi. Una vez establecidas las propiedades FilePath, TableLevel, y TableName, hay que utilizar la propiedad FieldDefs para determinar su estructura. Por ejemplo:
 
   La creación de campos para su nueva tabla en tiempo de ejecución se realiza como en Delphi. Una vez establecidas las propiedades FilePath, TableLevel, y TableName, hay que utilizar la propiedad FieldDefs para determinar su estructura. Por ejemplo:
<delphi> MyDbf.FilePathFull := '/ubicacion/para/mis/datos';
+
<syntaxhighlight> MyDbf.FilePathFull := '/ubicacion/para/mis/datos';
 
  MyDbf.TableLevel := 7;
 
  MyDbf.TableLevel := 7;
 
  MyDbf.TableName := 'clientes.dbf'; // nota: ¿es realmente necesario .dbf?
 
  MyDbf.TableName := 'clientes.dbf'; // nota: ¿es realmente necesario .dbf?
Line 45: Line 45:
 
   Add('Id', ftAutoInc, 0, True);
 
   Add('Id', ftAutoInc, 0, True);
 
   Add('Nombre', ftString, 80, True);
 
   Add('Nombre', ftString, 80, True);
  End;</delphi>
+
  End;</syntaxhighlight>
  
 
&nbsp;&nbsp;&nbsp;Los tipos de campo definidos son:
 
&nbsp;&nbsp;&nbsp;Los tipos de campo definidos son:
Line 92: Line 92:
 
===¡Siga adelante y créela!===
 
===¡Siga adelante y créela!===
 
&nbsp;&nbsp;&nbsp;Una vez que ha definido los campos deseará usarlos en su nueva tabla, puede seguir adelante y crearla con:
 
&nbsp;&nbsp;&nbsp;Una vez que ha definido los campos deseará usarlos en su nueva tabla, puede seguir adelante y crearla con:
<delphi> MyDbf.CreateTable;</delphi>
+
<syntaxhighlight> MyDbf.CreateTable;</syntaxhighlight>
  
 
==Añadir índices a una tabla==
 
==Añadir índices a una tabla==
Line 98: Line 98:
 
&nbsp;&nbsp;&nbsp;Si su base de datos es bastante grande, deberá definir índices para hacer búsquedas más rápidas. Para cambiar la estructura de índices de una tabla, deberemos tener acceso exclusivo a la tabla -mientras los creamos.  
 
&nbsp;&nbsp;&nbsp;Si su base de datos es bastante grande, deberá definir índices para hacer búsquedas más rápidas. Para cambiar la estructura de índices de una tabla, deberemos tener acceso exclusivo a la tabla -mientras los creamos.  
  
<delphi> MyDbf.Exclusive := True;
+
<syntaxhighlight> MyDbf.Exclusive := True;
  MyDbf.Open;</delphi>
+
  MyDbf.Open;</syntaxhighlight>
  
 
&nbsp;&nbsp;&nbsp;Justo ahora, tenemos que añadir el índice.
 
&nbsp;&nbsp;&nbsp;Justo ahora, tenemos que añadir el índice.
  
<delphi> MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
+
<syntaxhighlight> MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
 
  MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
 
  MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
  MyDbf.Close;</delphi>
+
  MyDbf.Close;</syntaxhighlight>
  
 
==Lo unimos todo y ... ¡ya está!==
 
==Lo unimos todo y ... ¡ya está!==
Line 111: Line 111:
 
&nbsp;&nbsp;&nbsp;El siguiente ejemplo crea una tabla "clientes" mediante código. Esto, por supuesto, sólo es necesario hacerlo una vez para cada tabla, y de ahí en adelante, '''abrir la tabla, no crearla ;-)'''
 
&nbsp;&nbsp;&nbsp;El siguiente ejemplo crea una tabla "clientes" mediante código. Esto, por supuesto, sólo es necesario hacerlo una vez para cada tabla, y de ahí en adelante, '''abrir la tabla, no crearla ;-)'''
 
    
 
    
<delphi> {Necesitamos que las siguientes unidades aparezcan en la clásula USES:}
+
<syntaxhighlight> {Necesitamos que las siguientes unidades aparezcan en la clásula USES:}
 
  uses {otras unidades, } Dbf, db, Dbf_Common;
 
  uses {otras unidades, } Dbf, db, Dbf_Common;
 
  { "Dbf" aparecerá, automáticamente, cuando pongamos el componente TDbf en el formulario...  }
 
  { "Dbf" aparecerá, automáticamente, cuando pongamos el componente TDbf en el formulario...  }
Line 138: Line 138:
 
   finally
 
   finally
 
     MyDbf.Free;
 
     MyDbf.Free;
   end;</delphi>
+
   end;</syntaxhighlight>
  
 
==Archivos índice externos==
 
==Archivos índice externos==
Line 144: Line 144:
 
&nbsp;&nbsp;&nbsp;El componente TDBF también soporta índices secundarios que se almacenan en un archivo separado. Esto será útil cuándo la base de datos sea muy grande, al poder separar en varios archivos los distintos índices. Los archivos de índice secundarios se crean de forma muy parecida a los índices normales, pero con la adición de la extensión '.ndx ' en el nombre:
 
&nbsp;&nbsp;&nbsp;El componente TDBF también soporta índices secundarios que se almacenan en un archivo separado. Esto será útil cuándo la base de datos sea muy grande, al poder separar en varios archivos los distintos índices. Los archivos de índice secundarios se crean de forma muy parecida a los índices normales, pero con la adición de la extensión '.ndx ' en el nombre:
  
<delphi> MyDbf.AddIndex('nombrecliente.ndx','Nombre', [ixCaseInsensitive]);</delphi>
+
<syntaxhighlight> MyDbf.AddIndex('nombrecliente.ndx','Nombre', [ixCaseInsensitive]);</syntaxhighlight>
 
&nbsp;&nbsp;&nbsp;Estos índices no se gestionan de forma automática, por ello cada vez que se abre la tabla, se deberán cargar los archivos de índice que deseamos utilizar, usando el método ''OpenIndexFile'', así:
 
&nbsp;&nbsp;&nbsp;Estos índices no se gestionan de forma automática, por ello cada vez que se abre la tabla, se deberán cargar los archivos de índice que deseamos utilizar, usando el método ''OpenIndexFile'', así:
<delphi> MyDbf.OpenIndexFile('nombrecliente.ndx');</delphi>
+
<syntaxhighlight> MyDbf.OpenIndexFile('nombrecliente.ndx');</syntaxhighlight>
 
&nbsp;&nbsp;&nbsp;Por la misma razón los índices se empaquetan por separado, para ello utilizaremos el método ''CompactIndexFile'', de esta forma:
 
&nbsp;&nbsp;&nbsp;Por la misma razón los índices se empaquetan por separado, para ello utilizaremos el método ''CompactIndexFile'', de esta forma:
<delphi> MyDbf.CompactIndexFile('nombrecliente.ndx');</delphi>
+
<syntaxhighlight> MyDbf.CompactIndexFile('nombrecliente.ndx');</syntaxhighlight>
 
&nbsp;&nbsp;&nbsp;Y al dar el valor a la propiedad ''IndexName'', para seleccionar el que estará activo,  debemos incluir el nombre y la extensión:
 
&nbsp;&nbsp;&nbsp;Y al dar el valor a la propiedad ''IndexName'', para seleccionar el que estará activo,  debemos incluir el nombre y la extensión:
<delphi> MyDbf.IndexName := 'nombrecliente.ndx';</delphi>
+
<syntaxhighlight> MyDbf.IndexName := 'nombrecliente.ndx';</syntaxhighlight>
  
 
==Cómo enlazar TDbf a componentes de datos==
 
==Cómo enlazar TDbf a componentes de datos==
Line 166: Line 166:
 
&nbsp;&nbsp;&nbsp;No olvides establecer las propiedades ''FilePath'' (o ''FilePathFulll''), ''TableLevel'', y ''TableName'' del componente ''TDbf'' a los valores adecuados antes de activarlos mediante
 
&nbsp;&nbsp;&nbsp;No olvides establecer las propiedades ''FilePath'' (o ''FilePathFulll''), ''TableLevel'', y ''TableName'' del componente ''TDbf'' a los valores adecuados antes de activarlos mediante
  
<delphi> TDbf.Active := True;</delphi>
+
<syntaxhighlight> TDbf.Active := True;</syntaxhighlight>
  
 
&nbsp;&nbsp;&nbsp;Se podría decir mucho más sobre programación con bases de datos en Lazarus, y yo recomendaría un buen libro de programación de bases de datos con Delphi porque los conceptos fundamentales son los mismos. Constantemente hago referencia a mi ejemplar de "Liberado Delphi 2" porque los conceptos y el código básico no han cambiado mucho en 8 años.
 
&nbsp;&nbsp;&nbsp;Se podría decir mucho más sobre programación con bases de datos en Lazarus, y yo recomendaría un buen libro de programación de bases de datos con Delphi porque los conceptos fundamentales son los mismos. Constantemente hago referencia a mi ejemplar de "Liberado Delphi 2" porque los conceptos y el código básico no han cambiado mucho en 8 años.
Line 174: Line 174:
 
&nbsp;&nbsp;&nbsp;Cuando se borra un registro, realmente no desaparece físicamente del archivo que guarda la tabla. De vez en cuando debe ''empaquetar'' la tabla para eliminar realmente los registros y así recuperar ese espacio desaprovechado del archivo. Esto hay que hacerlo teniendo la tabla abierta en modo exclusivo.
 
&nbsp;&nbsp;&nbsp;Cuando se borra un registro, realmente no desaparece físicamente del archivo que guarda la tabla. De vez en cuando debe ''empaquetar'' la tabla para eliminar realmente los registros y así recuperar ese espacio desaprovechado del archivo. Esto hay que hacerlo teniendo la tabla abierta en modo exclusivo.
  
<delphi> MyDbf.Exclusive := True;
+
<syntaxhighlight> MyDbf.Exclusive := True;
 
  MyDbf.Open;
 
  MyDbf.Open;
 
  MyDbf.PackTable;
 
  MyDbf.PackTable;
Line 180: Line 180:
 
  MyDbf.RegenerateIndexes;
 
  MyDbf.RegenerateIndexes;
 
  MyDbf.Close;
 
  MyDbf.Close;
  MyDbf.Exclusive := False;</delphi>
+
  MyDbf.Exclusive := False;</syntaxhighlight>
  
 
==Relaciones de tabla principal==
 
==Relaciones de tabla principal==
Line 203: Line 203:
 
&nbsp;&nbsp;&nbsp;En el componente TDbf de facturas seleccione lo siguiente:  
 
&nbsp;&nbsp;&nbsp;En el componente TDbf de facturas seleccione lo siguiente:  
  
<delphi> InvDbf.IndexName := 'idxclienteid'; // campo que se emparejará con el campo ID de la tabla clientes                                     
+
<syntaxhighlight> InvDbf.IndexName := 'idxclienteid'; // campo que se emparejará con el campo ID de la tabla clientes                                     
 
  InvDbf.MasterSource := dsClientes;  // fuente de datos que se enlaza al componente TDbf de clientes
 
  InvDbf.MasterSource := dsClientes;  // fuente de datos que se enlaza al componente TDbf de clientes
  InvDbf.MasterFields := 'Id';        // campo en la tabla clientes que emparejamos con nuestro índice</delphi>
+
  InvDbf.MasterFields := 'Id';        // campo en la tabla clientes que emparejamos con nuestro índice</syntaxhighlight>
  
 
==Programa de ejemplo - navegador DB==
 
==Programa de ejemplo - navegador DB==

Revision as of 15:41, 24 March 2012

Deutsch (de) English (en) español (es) français (fr) português (pt) русский (ru) 中文(中国大陆)‎ (zh_CN)


Resumen

   Esta tutoría trata sobre el desarrollo elemental de bases de datos usando el componente TDbf (de Micha Nelissen) con Lazarus. Hay disponible documentación adicional para TDbf. Esta página fue creada por Tony Maro, pero ¡se agradecen otras colaboraciones!

Lo que necesitarás

   El componente TDbf viene con FPC y por tanto con Lazarus.    También necesitarás instalar el paquete DbfLaz que trae Lazarus. Está situado en la carpeta lazarus/components/tdbf/.

¿Qué se puede hacer con TDbf?

   El componente TDbf proporciona a Lazarus (y otros entornos) acceso a tablas dBase y FoxPro. Permite la lectura, escritura y creación de tablas dBase III+, dBase IV, Visual dBase VII y FoxPro. Y sin necesitar librerías o gestores de bases de datos adicionales. Simplemente ponga el componente TDbf en su formulario y tendrá acceso inmediato a un entorno de bases de datos de para múltiples plataformas. TDbf funciona tanto en Windows como en Linux usando Lazarus.

Cómo crear una nueva tabla

   Como no hay todavía una aplicación "Database Desktop" para Lazarus, debemos crear las tablas de la base de datos mediante código, o utilizando herramientas externas.

Puedes probar esta aplicación (windows - funciona con wine): http://www.dirfile.com/cdbf_explorer.htm

Establecer la ruta de acceso

   Es recomendable crear una carpeta para sus aplicaciones de bases de datos. Esto simplifica la realización de copias de seguridad de los datos. Hay dos maneras de establecer la ruta de acceso. Puede fijar la ruta completa usando la propiedad FilePathFull, o puede establecer una ruta relativa a la ruta del programa con FilePath. Por ejemplo, estableciendo "FilePath" en tiempo de ejecución a "datos/" utilizaría una subcarpeta de datos dentro de la carpeta del archivo ejecutable. Fijar la propiedad "FilePathFull" a "/var/datos/" colocaría todo en esa carpeta, no teniendo en cuenta la ubicación del programa.

Elegir un tipo de tabla con TableLevel

   Por omisión, TDbf creará tablas dBase IV. Aunque son muy compatibles, hay características que puede desear usar que no están disponibles. Para poder utilizar campos autoincrementales, debe usar algo más nuevo. Los tipos de tabla posibles son:

Tipos de tablaTableLevel
dBase III+3
dBase IV4
Visual dBase VII7
FoxPro25


   Para elegir un tipo de tabla de el valor adecuado a la propiedad TableLevel.

Añadir campos

   La creación de campos para su nueva tabla en tiempo de ejecución se realiza como en Delphi. Una vez establecidas las propiedades FilePath, TableLevel, y TableName, hay que utilizar la propiedad FieldDefs para determinar su estructura. Por ejemplo:

 MyDbf.FilePathFull := '/ubicacion/para/mis/datos';
 MyDbf.TableLevel := 7;
 MyDbf.TableName := 'clientes.dbf'; // nota: ¿es realmente necesario .dbf?
 With MyDbf.FieldDefs do begin
   Add('Id', ftAutoInc, 0, True);
   Add('Nombre', ftString, 80, True);
 End;

   Los tipos de campo definidos son:

  • ftUnknown
  • ftString
  • ftSmallInt
  • ftInteger
  • ftWord
  • ftBoolean
  • ftFloat
  • ftCurrency (TableLevel 25)
  • ftBCD (TableLevel 25)
  • ftDate
  • ftTime
  • ftDateTime
  • ftBytes (TableLevel 25)
  • ftVarBytes
  • ftAutoInc (TableLevel 7 or 25)
  • ftBlob
  • ftMemo
  • ftGraphic
  • ftFmtMemo
  • ftParadoxOle
  • ftDBaseOle
  • ftTypedBinary
  • ftCursor
  • ftFixedChar
  • ftWideString
  • ftLargeInt
  • ftADT
  • ftArray
  • ftReference
  • ftDataSet
  • ftOraBlob
  • ftOraClob
  • ftVariant
  • ftInterface
  • ftIDispatch
  • ftGuid
  • ftTimeStamp
  • ftFMTBcd

   Los tipos que aparecen en negrita son los soportados en la actualidad.

¡Siga adelante y créela!

   Una vez que ha definido los campos deseará usarlos en su nueva tabla, puede seguir adelante y crearla con:

 MyDbf.CreateTable;

Añadir índices a una tabla

   Si su base de datos es bastante grande, deberá definir índices para hacer búsquedas más rápidas. Para cambiar la estructura de índices de una tabla, deberemos tener acceso exclusivo a la tabla -mientras los creamos.

 MyDbf.Exclusive := True;
 MyDbf.Open;

   Justo ahora, tenemos que añadir el índice.

 MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
 MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
 MyDbf.Close;

Lo unimos todo y ... ¡ya está!

   El siguiente ejemplo crea una tabla "clientes" mediante código. Esto, por supuesto, sólo es necesario hacerlo una vez para cada tabla, y de ahí en adelante, abrir la tabla, no crearla ;-)

 {Necesitamos que las siguientes unidades aparezcan en la clásula USES:}
 uses {otras unidades, } Dbf, db, Dbf_Common;
 { "Dbf" aparecerá, automáticamente, cuando pongamos el componente TDbf en el formulario...   }
 { pero necesitamos la unidad "db" para el objeto DataSet
 { y la unidad "Dbf_Common" para las definiciones de tipos de campo, por ejemplo        }
 var
   MyDbf: TDbf;
 begin
   MyDbf := TDbf.Create(nil);
   try
     
     MyDbf.FilePath := 'datos/';    // usamos una ruta de acceso relativa para la carpeta "datos"
     MyDbf.TableLevel := 7;         // utilizaremos tablas de tipo "Visual dBase VII"
     MyDbf.Exclusive := True;       // imprescindible para poder modificar la estructura añadiendo campos
     MyDbf.TableName := 'clientes.dbf';
     With MyDbf.FieldDefs do begin
       Add('Id', ftAutoInc, 0, True);
       Add('Nombre', ftString, 80, True);
     End;
     MyDbf.CreateTable;
     MyDbf.Open;
     MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
     { añadimos un índice secundario }
     MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
     MyDbf.Close;
   finally
     MyDbf.Free;
   end;

Archivos índice externos

   El componente TDBF también soporta índices secundarios que se almacenan en un archivo separado. Esto será útil cuándo la base de datos sea muy grande, al poder separar en varios archivos los distintos índices. Los archivos de índice secundarios se crean de forma muy parecida a los índices normales, pero con la adición de la extensión '.ndx ' en el nombre:

 MyDbf.AddIndex('nombrecliente.ndx','Nombre', [ixCaseInsensitive]);

   Estos índices no se gestionan de forma automática, por ello cada vez que se abre la tabla, se deberán cargar los archivos de índice que deseamos utilizar, usando el método OpenIndexFile, así:

 MyDbf.OpenIndexFile('nombrecliente.ndx');

   Por la misma razón los índices se empaquetan por separado, para ello utilizaremos el método CompactIndexFile, de esta forma:

 MyDbf.CompactIndexFile('nombrecliente.ndx');

   Y al dar el valor a la propiedad IndexName, para seleccionar el que estará activo, debemos incluir el nombre y la extensión:

 MyDbf.IndexName := 'nombrecliente.ndx';

Cómo enlazar TDbf a componentes de datos

   Los ejemplos anteriores muestran como crear una nueva tabla de base de datos mediante código. Usar la tabla es aún más simple.

   Los componentes de acceso a datos en Lazarus (como TDBEdit y TDbNavigator por ejemplo) se vinculan a un componente TDataSource mediante las propiedades DataSource y DataField. El componente TDataSource controla la comunicación entre el gestor de bases de datos y los componentes de acceso a datos. Un TDataSource se vincula al componente TDbf mediante su propiedad DataSet. La conexión sería así:

 TDbEdit------\
              |
 TDbEdit------|-->TDataSource-->TDbf
              |
 TDbNavigator-/

   No olvides establecer las propiedades FilePath (o FilePathFulll), TableLevel, y TableName del componente TDbf a los valores adecuados antes de activarlos mediante

 TDbf.Active := True;

   Se podría decir mucho más sobre programación con bases de datos en Lazarus, y yo recomendaría un buen libro de programación de bases de datos con Delphi porque los conceptos fundamentales son los mismos. Constantemente hago referencia a mi ejemplar de "Liberado Delphi 2" porque los conceptos y el código básico no han cambiado mucho en 8 años.

Empaquetar y reconstruir índices

   Cuando se borra un registro, realmente no desaparece físicamente del archivo que guarda la tabla. De vez en cuando debe empaquetar la tabla para eliminar realmente los registros y así recuperar ese espacio desaprovechado del archivo. Esto hay que hacerlo teniendo la tabla abierta en modo exclusivo.

 MyDbf.Exclusive := True;
 MyDbf.Open;
 MyDbf.PackTable;
 // reconstruimos todos los índices
 MyDbf.RegenerateIndexes;
 MyDbf.Close;
 MyDbf.Exclusive := False;

Relaciones de tabla principal

   La verdadera potencia de la programación de bases de datos comienza cuando tenemos múltiples tablas que se hacen referencia mutuamente. Mientras que TDbf aún no soporta la integridad referencial, si soporta una relación del tipo maestro/detalle entre componentes TDbf.

   Cuando hay dos tablas relacionadas, por ejemplo:

 [clientes]
 Id       <----\
 Nombre        |
 Telefono      |
 Direccion     |
               |  ClienteID en facturas hace referencia a un campo primario de clientes
 [facturas]    |
 Id            |
 Importe       |
 ClienteID   --\---|  * Campo indexado como "idxclienteid"

   Si desea mostrar todas las facturas para un cliente determinado, la tabla detalle (facturas) puede sincronizarse con la tabla principal (clientes) automáticamente.

   En el componente TDbf de facturas seleccione lo siguiente:

 InvDbf.IndexName := 'idxclienteid'; // campo que se emparejará con el campo ID de la tabla clientes                                     
 InvDbf.MasterSource := dsClientes;  // fuente de datos que se enlaza al componente TDbf de clientes
 InvDbf.MasterFields := 'Id';        // campo en la tabla clientes que emparejamos con nuestro índice

Programa de ejemplo - navegador DB

   He escrito un programa sencillo que utiliza el componente TDbf para abrir y mostrar tablas de bases de datos mediante el control dbGrid. El ejecutable Linux, junto con las fuentes del proyecto, que debería compilarse bien en Windows, está disponible en

 tony.maro.net

A tener en cuenta

   Actualmente no se soporta la integridad referencial, ni los archivos .db encriptados internamente.