| |
| Listing TDatabase Components and BDE Aliases |
 |
May 6th
Oleg Gopaniouk
There are many cases in which you are required to get an information about BDE
aliases, drivers, etc. This article contains information that explains how to get the list
of all TDataBase components, in addition to all aliases. You can use this knowledge for
your application and your custom components.
Pay attention to the DataBase property in TTable or TQuery components. How do these
components get a full list of all BDE's aliases? If your project contains TDataBase
components then the list contains the DatabaseName properties of all these components too.
Do you know how to obtain this information? As a starting point, I suggest you look at the
source of the DBTables unit. This unit contains the TSession implementation which is
useful in understanding this process. TSession has many methods which return information
that is necessary. For example, there is a GetAliasNames method which returns a TStrings
object with all BDE's aliases. Let us take look at the implementation of this method.
procedure TSession.GetAliasNames(List: TStrings);
var
Cursor: HDBICur;
Desc: DBDesc;
begin
List.BeginUpdate;
try
List.Clear;
LockSession;
try
Check(DbiOpenDatabaseList(Cursor));
finally
UnlockSession;
end;
try
while DbiGetNextRecord(Cursor, dbiNOLOCK, @Desc, nil) = 0 do
begin
OemToChar(Desc.szName, Desc.szName);
List.Add(Desc.szName);
end;
finally
DbiCloseCursor(Cursor);
end;
finally
List.EndUpdate;
end;
end;
end;
The List parameter is a TStrings object that contains the list of all BDE's aliases when
the method's execution is over. This method contains two local variables: Cursor and Desc.
These variables are needed for a direct call to BDE. The BDE has an DbiOpenDatabaseList
function which returns a cursor on a list of accessible databases (and all aliases) that
are in the configuration file. Before calling this function, a call to the LockSession
method is needed.
This method is private and is used to prevent collisions related with threads. After
calling the DbiOpenDatabaseList function, a call to the UnlockSession method must follow.
This method is private too.
I call your attention to the Check function, whose argument is the result of the
DbiOpenDatabaseList function. The Check function determines whether a value returned from
the Borland Database Engine (BDE) represents an error condition. After the data is
retrieved you can add it to the output list.
You can get the remaining databases and aliases using the DbiGetNextRecord function. This
function returns zero value if no errors occur when data is retrieved. It's first
parameter is the cursor and the second is the constant which specifies the lock request
type. There are three values from this parameter: dbiNOLOCK, dbiREADLOCK, dbiWRITELOCK.
The next parameter is the pointer of the client buffer that receives the record data. If
it's NULL, no data is returned. The last parameter is the client-allocated RECProps
structure. This is used with dBASE, FoxPro, and Paradox drivers only. If NULL, the record
properties aren't returned. See Delphi's help for more details.
After all data is retrieved you have to call the DbiCloseCursor function. You can use this
method from your applications or components. However, you can create your own method that
uses these ideas. The next step is getting the list of all TDatabase components of your
project. The TSession class has special method for this purpose. It's name is GetDatabaseNames.
Take a look at it's implementation:
procedure TSession.GetDatabaseNames(List: TStrings);
var
I: Integer;
Names: TStringList;
begin
Names := TStringList.Create;
try
Names.Sorted := True;
GetAliasNames(Names);
for I := 0 to FDatabases.Count - 1 do
with TDatabase(FDatabases[I]) do
if not IsDirectory(DatabaseName) then Names.Add(DatabaseName);
List.Assign(Names);
finally
Names.Free;
end;
end;
This method returns the list of all BDE's aliases and all databases. This method creates a
TStringList object and fills it in. It's next step is calling GetAliasNames method, that
has already been explained. The list of all aliases is transferred to the Names object
whose type is TStringList.
I call your attention to the FDataBases property. It's type is TList, which presents a
list of pointers to objects. Using TList object you can add, delete, insert object
pointers. The Count property indicates the number of objects which are kept in the TList
object. The TSession component uses this TList object for storing all pointers to the
accessible TDataBase components.
If the DataBaseName value is not a Directory name then it is added to the Names list. If
an exception occurs, the Names list is freed.
You will, probably, wish to ask me how to transfer the information about all accessible
TDataBase components to the DataBase property. You will have to look at the TDataBase
constructor. See it's source bellow.
constructor TDatabase.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if FSession = nil then
if AOwner is TSession then
FSession := TSession(AOwner)
else
FSession := DefaultSession;
SessionName := FSession.SessionName;
FSession.AddDatabase(Self);
FDataSets := TList.Create;
FParams := TStringList.Create;
TStringList(FParams).OnChanging := ParamsChanging;
FLoginPrompt := True;
FKeepConnection := True;
FLocale := FSession.Locale;
FTransIsolation := tiReadCommitted;
end;
The constructor adds the TDataBase object to the Session's DataBases list. Therefore, when you drop TDataBase component on form or data module,
a pointer to this TDataBase component is added to the databases list of current Session.
In conclusion, I want to call to your attention that this information is most useful for creating your own data-aware components.
|
|
| Hits/month |
2,500,000+ |
Downloads (Since May 2000) |
7,393,709 |
| Total Files |
6,023 |
| Forum msgs |
7,670 |
| Articles/FAQs |
70+/900+ |
Top Selling Software at Amazon
|