Delphi Programming

Universal Data Access Components (UniDAC ) as of version 7.5.13 (released 24th of June 2019) have a DBF Specific Option IgnoreMetadataErrors. This option simply helps to ignore table definition errors. One may ask “What is metadata?”

Metadata meaning here is format of table structure. DBF tables has “header” and “data” sections in brief. Header part contains metadata of that table. dBase has evolved in time. For that reason, DBF has a lot of different formats (like dBaseIII, dBaseIV, dBaseV, dBase7, dBase10, dBase for Windows, HiPer-Six, FoxPro 2, Visual FoxPro). Each new format introduced has some new enhancements over previous one.

dBase is still a commercial product as of today (See: http://www.dbase.com/dbasesql/ ) Owner company only made public dBaseVII table structure. UniDAC is capable of using all mentioned formats above and more both over ODBC driver or directly by itself not requiring any driver at all.

Below is a table to understand header format for dBaseIII to dBaseV:

Image1.png


































Source: https://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT

As explained, dBase is a commercial product and versions earlier than dBaseVII header format is not made public. Anything you will find on the internet is a result of a lot of try/fail tests that people or company prepared. As such it is possible that you get a file that you cannot open because of header format is broken.

I have a dBaseIII table. That holds some customer records in it. If you are to use a hex editor, its header looks like as following:

Image3.png

​​​​​










This header is free of metadata errors. It can be opened pretty straight using TUniConnection and below code:
uses
Uni,
UniProvider,
ODBCUniProvider,
DBFUniProvider;

procedure TForm2.FormCreate(Sender: TObject);
begin
UniConnection1.Close();
UniConnection1.Provider := 'DBF';
UniConnection1.Database := 'c:\data';
UniConnection1.Open();
end;

P.S: Above example assuming file is in “c:\data” directory in your drive.

I also have a table with encrypt information in it. That file has a broken header:

Image2.png












It is not clear by first look. In that table there is PATH field of type Char with size of 255 at offset hex 0x70 (marked in red). Please remember that this is a dBaseIII format table and dBaseIII has max character limit of 254.

Image5.png

By design, UniDAC checks all files in TUniConnection.Database directory at the time of connection opening. During that check if you have a file like above with broken header and using a code similar to above sample, that will get you an exception. Message may be different depending on your UniDAC version. It will clearly indicate you have a broken metadata/Field in your database directory. Current latest version (UniDAC v8.1.2) raises exception as following:

Since there is a possibility that there maybe a broken header in dBase files. I myself always turn on DBF specific option IgnoreMetadataErrors. In order to turn it on at run-time, you can use a code like:

uses
Uni,
UniProvider,
ODBCUniProvider,
DBFUniProvider;

procedure TForm2.FormCreate(Sender: TObject);
begin
UniConnection1.Close();
UniConnection1.SpecificOptions.Values['IgnoreMetadataErrors'] := 'True';
UniConnection1.Database := 'c:\data';
UniConnection1.Open();
end;

In order to turn on that option at design time you can double click on UniConnection1 component on your DataModule/Form, switch to Options tab, make sure Provider is set to DBF, find IgnoreMetadataErrors in the list and set its Value to True as in below screenshot

Image4.png













Metadata error example above is a size mismatch. There are other types of metadata errors like number of records are wrong, wrong code page definition. All such type of metadata errors can be easily ignored and table contents can be read without any exception using IgnoreMetadataErrors specific option.

It is important to clarify that this option IgnoreMetadataErrors does not help you if you have a corrupt “data” in your table. This is completely a different type of error and cannot be overcome using that option.