René Flores López 03.may.2002
Xbase es el nombre que se le da genéricamente a todos aquellos lenguajes de programación
cuyo conjunto de instrucciones y funciones son un derivado de los de dBase
III+, y que manejan archivos de datos que tienen la estructura conocida
como DBF (DataBase File).
Cuando desarrollamos un sistema, la mayoría de las veces nos preocupamos por los campos
que deben contener las estructuras de los archivos de datos, sus relaciones,
sus índices y sobre todo, como los tiene que utilizar nuestro
programa para lograr los resultados que nos han solicitado, pero… ¿
te has puesto a pensar alguna vez como ocure el amacenamiento y búsqueda
de datos internamente dentro de Clipper ?, seguramente no, simplemente
sabemos que lo hcae, pero pocas veces reparamos en COMO lo hace.
Este pequeño articulo te enseñara como es por dentro ese
viejo desconocido nuestro que es el archivo DBF.
El formato nativo de archivos de datos de Clipper es la estructura conocida como DBF, que
fue mostrada por primera vez en el dBase III+, si bien muchos programadores
"modernos" la consideran vieja, obsoleta y decadente, el archivo DBF tiene
la sencillez de un clasico, visto desde el punto de vista romántico,
un DBF es como las Piramides de Egipto, un ejemplo vivo de una cultura
antigua pero que ha durado por siglos, por mucho, más tiempo que
obras maestras de la arquitecutra moderna como Las Torres Gemelas de NY,
porque fue creado para durar.
Un archivo DBF puede almacenar los siguientes tipos de datos
| Caracter |
(Character) Cadenas de caracteres
de longitud variable de hasta 64 kbytes de longitud |
| Numérico |
(Numeric) Hasta 19 dígitos
de longitud, contando el punto decimal en campos no enteros |
| Fecha |
(Date) Longitud fija de 8 bytes |
| Lógica |
(Logic) Valores booleanos (.T. y
.F.) de 1 byte de longitud |
| Memo |
Cadenas de caracteres de longitud
variable los cuales se almacenan en un archivo con la extensión
.DBT para el NTX y FPT para el CDX.
Nota: El valor mínimo
para un campo memo es de 512 bytes cuando se utiliza el RDD NTX y va aumentando
en la misma proporción, es decir, si tenemos un texto de 514 bytes,
se utilizarán 2 bloques de 512 bytes para guardarlo, aunque solo
se utilicen 2 bytes del segundo bloque, un DBT no "recicla" el espacio
una vez borrado el registro con campo memo, lo que significa que el espacio
ocupado por el memo del registro borrado permanecerá desperdiciado
hasta que se realice una operación de PACK sobre la base de datos.
En el caso de los campos memo para
CDX, el valor mínimo para un campo memo es de 1 byte, aunque por
omisión se maneje un valor de 15 bytes, estos memos ofrecen la ventaja
de que su tamaño mínimo puede ser establecido por el usuario
desde programa. |
|
El archivo DBF está dividido
en 2 partes: el Area
de Encabezado (Header Area) y el Area de Datos (Data
Area).
El Area de Encabezado almacena información sumamente importante,
a su vez está dividida en 2 partes: Informacion del archivo
(file information) y Descripción de campos (Field
description).
Inmediatamente
después de terminar el Area de Encabezado comienza el Area
de Datos, donde se almacena la información como tal de la base
de datos, lo datos son almacenados en bloques x+1 bytes donde x
es la longitud total de todos los campos descritos y el byte adicional
(+1) es la bandera de borrado. Este byte de borrado tiene un valor de 20h
(espacio) cuando el registro está activo y un 2Ah (asterisco *)
cuando el registro ha sido marcado para borrar, esto en el caso de los
drivers NTX y CDX, si se esta utilizando Advantage Database Server este
byte se utiliza para controlar los procesos de transacciones cuando estas
se manejan en entornos Cliente / Servidor.
Es necesario recordar que DOS no elimina nada cuando se graba un archivo en el disco; cuando un DBF es creado en un área de disco donde previamente se ha escrito
y borrado información, existe la posiblidad de que los espacios
que permanecen vacios en el header (ver siguiente tabla) se llenen de caracteres
de basura, sin embargo, esto no tiene consecuencias en la estructura de
la base de datos.
Todos los datos en el Area
de encabezado están escritos en formato hexadecimal.
El formato del encabezado en su sección
Información de Archivo es como sigue:
| Byte |
Información almacenada |
| 0 |
Este byte indica si se ha especificado
la existencia de campos memo. Si no hay memos, el valor es 03h, si los
campos memo existen para este archivo el valor es un 83h.
| Tip: Todos los programas
que puedan leer archivos DBFs, como Excel o Access, utilizan este byte
para identificar al archivo como un DBF, asi que una buena técnica
de protección consiste en cambiar estos valores por cualquier otro,
asi ninguna otra herramienta tendra acceso a nuestros datos. En futuros
artículos explicaré con mayores detalles esta técnica. |
|
| 1 |
Almacena el año de la última
actualización, por ejemplo si el archivo fue modificado en 1999
contendrá un valor de 63h, si el año fue el 2000 tendrá
un valor de 00h (NUL) y así sucesivamente, si te das cuenta sólo
se almacenan los dos últimos dígitos del año. |
| 2 |
Almacena el mes de la última
actualización, Enero (01h), Febrero (02h), Marzo (03h), Abril (04h),
Mayo (05h), Junio (06h), Julio (07h), Agosto (08h), Septiembre (09h), Octubre
(0Ah), Noviembre (0Bh) y Diciembre (0Ch) |
| 3 |
Almacena el día de la última
actualización, también en formato hexadecimal, su valor mínimo
es 1 (01h) y el máximo es 31 (1Fh) |
| 4 al 7 |
Estos 4 bytes almacenan el número
de registros dentro de la base de datos. De aquí se obtiene el valor
de la función LastRec().
| Mito: ¿ Cuantos registros le caben a un DBF ?, ¿ es cierto que
su tamaño es infinito ?, ¿estan realmente limitados?, de
una forma u otra, un DBF SI ESTA LIMITADO en el número de registros
que puede tener, el valor de estos 4 bytes nos puede dar una buena idea
de cuantos registros le caben a un dbf si pensamos que su valor máximo
es de FFFFFFFFh, asi que en teoría, el número máximo
de registros que le caben a un DBF es de 4,294,967,295 (si,
leiste bien, de acuerdo al valor máximo de esta parte de la estructura,
a un DBF le caben CUATRO MIL DOSCIENTOS NOVENTA Y CUATRO MILLONES, NOVECIENTOS
SESENTA Y SIETE MIL DOSCIENTOS NOVENTA Y CINCO registros). |
|
| 8 y 9 |
Declaran la longitud del encabezado
(ver mas adelante la sección de Descripcion de campos) |
| 10 y 11 |
Indican la longitud total del registro,
incluyendo la bandera de borrado
| Mito: Se ha hablado
mucho del número de campos que puede contener la estructura de un
DBF, unos dicen que 100, unos que mas, otros que menos, lo cierto es que
el número de campos que puede contener un DBF, va en razón
directa de su longitud, entre menor sea la longitud mas campos podemos
tener, la pregunta es ¿ existe un límite real para el número
de campos ?, la respuesta es : SI, el número de campos esta
precisamente establecido por estos 2 bytes, cuyo máximo valor es
FFFFh (65535), mientras la longitud de todos los campos de la base de datos
no exceda este valor, podremos tener tantos campos como necesitemos. |
|
| 12 al 31 |
No se usan. |
Descripción de campos: Después
del los primeros 31 bytes de la sección de Información
de archivo, viene la sección de Descripción
de campos, que comienza en el byte 32 (20h). Cada campo dentro
de la estructura del DBF, sin importar su tipo ni su longitud, genera 32
bytes dentro de esta sección, de tal forma que si nuestra base de
datos tiene 10 campos, esta sección medirá 320 bytes, si
tiene 100 medirá 3200 bytes y as sucesivamente, como es fácil
adivinar esta sección no tiene una longitud fija, ya que está
en función del número de campos que tenga nuestro DBF.
En general, cada campo proporciona la siguiente información a la sección de
descripción de campo:
| Byte |
Información almacenada |
| 0 al 10 |
Estos 11 bytes almacenan el nombre
del campo. Los nombres de los campos pueden tener de 1 a 10 caracteres
de longitud. El caracter que se utiliza para indicar la terminación
del nombre de campo es un 00h, lo que signfica que si el nombre es seguido
por 00h y tiene menos de los 10 bytes reservados para el nombre del campo,
los bytes sobrantes se desperdician. |
| 11 |
Especifica el tipo de campo
| Caracter |
43h (C) |
| Numérico |
4Eh (N) |
| Fecha |
44h (D) |
| Lógico |
4Ch (L) |
| Memo |
4Dh (M) |
|
| 12 al 15 |
Cuatro bytes que especifican el
espacio que ocupará en la memoria el campo. |
| 16 |
Especifica la longitud del campo |
| 17 |
Especifica la longitud decimal del
campo, si se trata de un campo numérico no entero |
| 18 al 31 |
No se usan. |
Después de la última descripción de campo, se escribe el caracter
que indica la terminación, que es un 0Dh. A partir de este punto,
y hasta el final del archivo se extiende el Area de datos,
que estudaremos mas adelante.
Como podrás
observar, la longitud del encabezado depende del número de campos
especificados. Cada campo agrega 32 bytes a la longitud total del área
de encabezado; lo que quiere decir que si tu base de datos tiene dos campos,
su Area de Encabezado tendrá una longitud de 96 bytes
(32 bytes de información de archivo, mas 64 bytes de descripción
de campos, 32 por cada campo).
El Area de datos y el almacenamiento de la información:
El área que sigue inmediatamente después del Area de Encabezado
es el Area de Datos (Data Area). Cada registro dentro de
nuestro DBF tiene una longitud fija, como la descripción de campos.
Los datos son recuperados siempre por su posición en relación
al principio del registro; no se utiliza ninguna señal de delimitación
para separar los campos, el motor de base de datos utiliza la información
de la sección Información de Archivo bytes
10 y 11 para calcular en donde comienza y donde termina cada registro y
recuperarlos de manera óptima, porque en esta sección todo
se almacena en formato ASCII, en otras palabras el Area de datos
es un simple archivo de texto.
La forma de almacenamiento es como sigue:
- Las cadenas de caracteres se almacenan en formato ASCII
- Los valores numéricos se almacenan
en formato decimal usando el punto (.) como un separador entre la parte
entera del número y la parte decimal. Un signo de menos (-) puede
preceder a los valores numéricos.
- Los campos lógicos contienen
un signo de interrogación (?) hasta que se modifique el campo, los
valores válidos son Y,N,T,F,y,n,t,f
- Los campos de fecha contienen 4 bytes.
Los primeros dos bytes almacenan la porción correspondiente al año
(incluyendo el siglo), el tercer byte contiene el mes y el cuarto contiene
el día (los separadores de día, mes y año NO SON PARTE
DEL CAMPO FECHA, como muchos programadores piensan).
- Finalmente los campos memo contienen
una referencia de 10 bytes al bloque correspondiente dentro del archivo
.DBT, cuando se utiliza el RDD NTX, cuando se utiliza el CDX, estos mismos
10 bytes contienen adicionalmente un apuntador de doble liga al archivo
FPT correspondiente, lo cual garantiza una comunicación de 2 vias
entre DBF y FPT, reduciendo el riesgo de generar corrupción de datos
en uno u otro archivo.
El algoritmo de recuperación de datos es bastante sencillo de imaginar, si yo
ejecuto desde mi programa una instrucción DBGOTO(5), internamente
el motor de datos obtendra la longitud de todo el registro a partir de
la informacion contenida en los bytes 10 y 11 de la sección
Información de archivo, una vez calculada la longitud
total del registro, esta se multiplica por 5, y el motor de base de datos
sabe el número de bytes que deberá desplazarse a partir del
comienzo del area de datos hasta el comienzo del registro 5, una vez que
ha llegado al principio del registro que queremos recuperar, nuevamente
se utiliza la longitud del registro para saber cuantos bytes tiene que
leer y acomodarlos en sus respectivas variables de nombre de campo. Como
podrás apreciar, la estructura DBF provee de una solucion sencilla
y elegante para la manipulación de datos, aunque muchos la consideren
vieja y obsoleta.
Dedicado con todo cariño a Dorien Mast,
Esperamos verte recuperada pronto de tu Rizotomia Dorsal Selectiva
¿ Quieres conocer a Dorien ? Visita http://www.dorienmast.be