| ADOExpress Step-by-Step-from-Scratch Tech Note |
Briefcase: UDL and ADTG
Summary: The Briefcase demo program, distributed as part of ADO Express, looks fairly simple, but there are some not-so-obvious steps that are needed to reproduce the program. The Briefcase program establishes an ADO connection using a Data Link File (a UDL file). When the database connection is dropped, data can be accessed locally in an Advanced Data Table Gram (ADTG) file and later written to the database.This Tech Note is based on the Borland ADO Demo program "Briefcase"
in directory
C:\Program Files\Borland\Delphi5\Demos\Ado\Briefcase)
When I first looked at the Briefcase demo program, which was installed as part of ADOExpress, I wanted to see what the properties of the various objects were both visual and non-visual. With Delphi 5 running and the project loaded, I right clicked on the form area to see the option, View as Text, which toggled back to View as Form. With View as Text selected, I could quickly view the properties of the various objects.
A new Delphi 5 form option is also of interest here. When you right click on the form, there is a new Text DFM checkbox. With this checkbox selected, the DFM file can be viewed with an ASCII editor at any time. In earlier versions of Delphi, the DFM form files were in binary and could not be edited or viewed except through Delphi.
After reviewing the form's properties, I didn't have a clue what the UDL file was in the Provider property of the TADOConnection. The file specified as the Provider, C:\Program Files\Common Files\System\OLE DB\Data Links\DBDemos.UDL, wasn't the database since it was only 344 bytes long.
After reviewing the source code in BriefcaseMain.PAS, I didn't know why the briefcase file was saved as an ADTG file. The Employee.ADTG that was created only had 3021 bytes in it. I double-clicked on hit from the Windows Explorer, but there was no default file association. The Briefcase example makes a lot more sense if you know what an ADTG file is.
B. UDL File (Microsoft Data Link)
An ADO database connection is established using a Microsoft Data Link File, which can be saved in a UDL file. Another Step-by-Step-from-Scratch Tech Note explains many details about UDL files and the information they contain. That Tech Note explains how to create the equivalent of the DBDemos.UDL file, which is referenced in the Provider Property of the TADOConnection in the Briefcase demo program.
A UDL file is a lot like a BDE alias. You can edit the properties of a UDL file directly in Windows, and change properties of the database connection, including the filename of the database itself. If all the properties of your database connection are "hard wired," then a UDL file is not necessary since all the information can be specified in an ADOConnection component.
C. ADTG (Advanced Data Table Gram)
This is one of the OLE DB Persistence Providers [with the other provider being the
Extensible Markup Language (XML)]. Even a search of Microsoft's web site reveals little
information about this file format, which appears to be a proprietary Microsoft file
format. An ADTG file will work with appropriate Microsoft products. Two Microsoft
links that give a hint of information about ADTG are:
http://msdn.microsoft.com/library/psdk/dasdk/mdap6chg.htm
http://msdn.microsoft.com/library/psdk/dasdk/mspe7jg2.htm
One final note about the Briefcase demo. Since many new concepts are introduced in such demo programs, I think good programming practices should be demonstrated as part of the example. In particular, the example should have shown how to use a Data Module to "hold" the ADOConnection, ADODataSet, and DataSource, instead of cluttering the user interface in design mode with these "non-visual" components. A Data Module is the "clean" way of sharing such components, especially when more than one form needs to share them in an application. The example below shows how to use a Data Module even though the sample program only has a single form.
In Mastering Delphi 5, this briefcase model is mentioned on p. 579 in "A Snapshot of the Data" and on pp. 999-1000 in "Support the Briefcase Model."
E. Verify Existence of UDL File and Database

Verify that the DBDEMOS.mdb file is specified as the database name as shown above.




USES DataDBDemos;
NOTE: Setting this Active property to TRUE, changes the definition of the ConnectionString of the ADOConnection. Instead of being defined via the Use Data Link File Connection String selection (which was specified above in Step 6), the information is now stored in the Use Connection String setting.
Mark Edington's (Borland) comments from UseNet Post:
The [Briefcase] demo is designed in such a way that it will only work correctly if the dataset is closed at design time. This is because it needs to make a determination at runtime of where to get the data.
The ConnectionString getting expanded from the UDL filename to a complete connection string is something that the ADO connection component does. If you close the connection it will revert to the UDL filename. However, if you save the form and reload it while the connection is open, the reference to the UDL filename is lost completely. The VCL needs to preserve the original connection string (with the UDL filename) in this case, but it doesn't currently do that. That's something I plan to fix for the next release.
| procedure
TDataModuleDBDemos.DataModuleCreate(Sender: TObject); begin ADODataSetEmployee.Open end; |
The original Borland example defined the ConnectionString in the FormCreate. That could be also added to the DataModuleCreate method above, but the statement doesn't seem to be necessary.
ADOConnection.ConnectionString :=
'FILE NAME=' +
DataLinkDir + // Gets Data Link Dir from Registry
'\DBDEMOS.UDL';
The DataLinkDir function above (from the ADODB unit) returns the default location of a directory that contains UDL files (usually C:\Program Files\Common Files\Systems\OLE DB\Data Links).
Mark Edington's (Borland) comments from UseNet Post:
The value returned by the DataLinkDir function will be different than the path in the TADOConnection component if Delphi is installed on a machine with a different path to "c:\program files". This is the case on some international versions of Windows.
DataFileName: STRING;
| procedure
TFormBriefcase.FormCreate(Sender: TObject); begin // Save name for private access only DataFileName := ExtractFilePath(Paramstr(0)) + 'EMPLOYEE.ADTG'; // If a persistent datafile exists, assume we exited in
a |

Application.CreateForm(TDataModuleDBDemos, DataModuleDBDemos);
Application.CreateForm(TFormBriefcase, FormBriefcase);
| Private . . . DataFileName: STRING; PROCEDURE SaveData; PROCEDURE UpdateData; . . . USES ADODB, // pfADTG DataDBDemos; // DataModuleDBDemos . . . PROCEDURE TFormBriefCase.SaveData; BEGIN DataModuleDBDemos.ADODataSetEmployee.SaveToFile(DataFileName, pfADTG); END {SaveData}; PROCEDURE TFormBriefCase.UpdateData; |
| procedure
TFormBriefcase.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin IF DataModuleDBDemos.ADODataSetEmployee.Active THEN BEGIN TRY END |
| procedure
TFormBriefcase.CheckBoxConnectedClick(Sender: TObject); begin // Toggle the connection's state IF CheckBoxConnected.Checked THEN BEGIN DataModuleDBDemos.ADOConnection.Open; DataModuleDBDemos.ADODataSetEmployee.Connection := DataModuleDBDemos.ADOConnection END ELSE BEGIN // Note here you must clear the connection property of // the dataset before closing the connection. Otherwise // the dataset will close with the connection. DataModuleDBDemos.ADODataSetEmployee.Connection := NIL; DataModuleDBDemos.ADOConnection.Close END end; |
| procedure
TFormBriefcase.ButtonUpdateServerClick(Sender: TObject); begin UpdateData end; |
| procedure
TFormBriefcase.ButtonRefreshDataClick(Sender: TObject); begin // Close and reopen the dataset to refresh the data. // Note that in this demo there is no checking for // pending updates so they are lost if you click the // refresh data button before clicking the Update // database button. CheckBoxConnected.Checked := True; WITH DataModuleDBDemos.ADODataSetEmployee DO BEGIN Close; CommandType := cmdTable; CommandText := 'Employee'; Open END end; |
| procedure
TFormBriefcase.ButtonSaveToDiskClick(Sender: TObject); begin SaveData end; |


Also see:
The
Briefcase Model: When Your Application Must Travel Well, Delphi Informant,
April 1999
Using
the Briefcase Model for Laptop Databases, Delphi Developer, April 1999
Links Verified 7 Feb 2000
Updated 18 Feb 2002
since 7 Feb 2000