Board index » delphi » Pack and Reindex

Pack and Reindex

I would like to pack and reindex a .dbf file. I know it's possible and i
would like to know how.

Regards,

Micha?l Chrtien
Programmer/Analyst
Bridgestone/ Firestone
1200 Firestone Boulevard
Joliette, Qc
ChretienM...@BFUSA.com

 

Re:Pack and Reindex


On Mon, 19 Apr 1999 10:24:36 -0400, "Michael Chrtien"

Quote
<ChretienM...@Bfusa.com> wrote:
>I would like to pack and reindex a .dbf file. I know it's possible and i
>would like to know how.

There are a number of ways you could approach reindexing a dBASE
table.

One way would be to make a call to the BDE API function
DbiRegenIndexes. This insulates you from having to know what indexes
exist, if any, the BDE handling all the code for you. Error checking
can be handled by examining the return value (type DBIResult) or by
using the Check function (defined in the BDE wrapper unit BDE).

  procedure TForm1.Button4Click(Sender: TObject);
  var
    aExclusive, aActive: Boolean;
  begin
    with Table1 Do Begin
      aActive := Active;
      Close;
      aExclusive := Exclusive;
      Exclusive := True;
      Open;
      Check(DbiRegenIndexes(Table1.Handle));
      Close;
      Exclusive := aExclusive;
      Active := aActive;
      Check(DbiSaveChanges(Table1.Handle));
    end;
  end;

As when calling any BDE API function, the BDE API wrapper unit BDE
(for Delphi 1, the units DbiTypes, DbiErrs, and DbiProcs) must be
referenced in the Uses section of the unit from which the call is to
be made. The BDE API function DbiSaveChanges, used here, forces any
data changes in memory buffer to be written to disk at that point.

Another way to handle this situation -- if you know at design-time all
the indexes that will exist for the table -- would be to iterate
through the items in the TIndexDefs object of the TTable component,
delete each index (DeleteIndex method), and then add all needed
indexes back (AddIndex method).

  procedure TForm1.Button3Click(Sender: TObject);
  var
    aName: String;
    i: Byte;
    aExclusive, aActive: Boolean;
  begin
    with Table1 do begin
      aActive := Active;
      Close;
      aExclusive := Exclusive;
      Exclusive := True;
      IndexDefs.Update;
      i := IndexDefs.Count;
      while i > 0 do begin
        aName := IndexDefs.Items[i - 1].Name;
        DeleteIndex(aName);
        Dec(i);
      end;
      AddIndex('', 'MainField', [ixPrimary]);
      AddIndex('Field1', 'Field1', []);
      AddIndex('Field2', 'Field2', []);
      IndexDefs.Update;
      Exclusive := aExclusive;
      Active := aActive;
      Check(DbiSaveChanges(Table1.Handle));
    end;
  end;

When iterating through the items in the TIndexDefs object, the cycling
must be backwards, from highest to lowest. This is to account for
those table types that have primary indexes. With those table types,
deleting a primary index first causes all secondary indexes to be
unavailable, which interferes with this iterating based on the
TIndexDefs array object contents. This is because a secondary index
cannot exist in some table types (such as Paradox) without an existing
primary index. For the same reason, when recreating the indexes, the
process should start with the primary index and then progress through
all secondary indexes (if any are to be created).

If information about the index definitions is not known at
design-time, this process becomes emminently more complex. The data
from all indexes will need to be saved to memory, the information for
all indexes existing simultaneously in memory. This is because a
primary index would need to be deleted at some point (to later be
rebuilt), destroying references to any secondary indexes (whether
retrieval for the secondary indexes takes place before or after
deletion of the primary index). To accomplish this, some multi-entity
storage structure would need to be created to hold a variable number
of elements, one element per index. Each element would need to be able
to store the four bits of data that comprise an index's definition:
Name (String), Fields (String), Expression (String), and Options
(TIndexOptions). An array or a TList object of Pascal records with
these data fields would suffice for this purpose.

Once the definition information for all indexes are stored to memory,
the succeeding steps are similar to those for the previous method:
Delete each index (DeleteIndex) and then recreate each index based on
the definition information stored in the array or TList (AddIndex).

//////////////////////////////////////////////////////////////////////////
Steve Koterski                  "The income tax has made liars out of more
Technical Publications          Americans than golf."
Borland                                         -- Will Rogers (1879-1964)
http://www.borland.com/delphi

Re:Pack and Reindex


see the following code :

Filename: BSPKTBL.PAS
Description: ObjectPascal file containing improved DELPHI Component
Version:           2.0
Copyright: 1998 Business Software (UK) ebi...@compuserve.com
Status: Freeware
Rev. Date: 12 January 1998
Distribution: Normal Shareware/Freeware Channels
Web Site: http://ourworld.compuserve.com/homepages/ebinfo/

BSPKTBL is a TTABLE replacement with additional functions to
PACK (permanently remove deleted records) and REGENERATE INDEXES
for DBASE and PARADOX tables.

Installation/Usage Notes incorporated in header.

OTHER FREEWARE / SHAREWARE components and applications available from
the above web site.

{============================ BSPKTBL Distribution Notes
==================================}
{DESCRIPTION
-----------
BSPkTbl is a simple improved component for Delphi 1 and 2 {not yet tested on
3, but should be ok)
BSPkTbl includes two additional functions which Borland seem to have
'forgotten' - a simple
and effective way of packing and reindexing Dbase and Paradox tables.
TBSPktbl is a direct
replacement for  TTable in your applications, and may call two extra
functions:

1. PACK (returns 'True:boolean' if successful)
2. REGENINDEXES (returns 'True:boolean' if successful)

{COPYRIGHT NOTICE}
{BSPktbl is distributed as FREEWARE, but remains the COPYRIGHT of
BUSINESS SOFTWARE (UK) (email  ebi...@compuserve.com ). Business Software
grants you the right
to include this compiled component in your DELPHI application, whether
COMMERCIAL, SHAREWARE, or
FREEWARE, BUT YOU MAY NOT DISTRIBUTE THIS SOURCE CODE OR ITS COMPILED .DCU
IN ANY FORM OTHER
THAN AS IT EXISTS HERE; COMPLETE WITH THIS NOTICE AND ALL THE TEXT BELOW.
BSPktbl may be included
in any shareware or freeware libraries or compilation disks, provided no
charge other than the
usual media cost recovery is made.}

{IF YOU HAVE ANY DOUBTS ABOUT WHETHER YOU MAY LEGALLY USE OR DISTRIBUTE THIS
COMPONENT,
CONTACT BUSINESS SOFTWARE BY E-MAIL.}

{VISIT BUSINESS SOFTWARE'S WEB SITE AT
HTTP://OURWORLD.COMPUSERVE.COM/HOMEPAGES/EBINFO/  for
more interesting components and applications}

{WARRANTY / ACCEPTANCE OF LIABILITY / INDEMNITY}
{ABSOLUTELY NONE WHATSOEVER}

{INSTALLATION}
{1.Copy this file into your DELPHI/LIB directory, or wherever your library
files are kept}
{2.Select OPTIONS|INSTALL COMPONENTS|ADD...}
{3.ADD This file; BSPktbl.PAS to the INSTALLED UNITS listbox}
{4.Click OK}

{USING BSPktbl}
{Use just as you would a normal TTable component. Before calling PACK or
REGENINDEXES, you must
make sure that either:

     The TABLETYPE property is correctly set to reflect the tabletype i.e.
ttDbase or ttParadox

     or:

     The TABLENAME property must have the file extension added i.e.
'ANIMALS.DBF' or 'BIOLIFE.DB'

EXCLUSIVE must be set to true!}

unit BSPktbl;

interface
uses dbtables,db,dbiprocs,dbierrs,dbitypes,classes,sysutils;

Type
TBSPktbl=class(TTable)
private
  ftblprops:curprops;
  bopen:boolean;
  ex:string[4];

  procedure fixtabletype;
public
  constructor create(aowner:Tcomponent); override;
  destructor  destroy; override;
  function pack:boolean;
  function regenindexes:boolean;
end;

procedure register;
procedure bdecheck(BDERes: DBIResult);

implementation

procedure register;
begin
registercomponents('BSoft',[TBSPktbl]);
end;

constructor TBSPktbl.create(Aowner:Tcomponent);
begin
inherited create(aowner);
end;

destructor TBSPktbl.destroy;
begin
inherited destroy;
end;

procedure BDECheck(BDERes: DBIResult);
begin
if (BDERes <> DBIERR_NONE) then DBIError(BDERes);
end;

function TBSPktbl.pack:boolean;
var
hDB:                   hDBIdb;
pTblDesc:              pCRTblDesc;

procedure packpdx;
begin
result:=false;
GetMem(pTblDesc,sizeOf(CRTblDesc));
FillChar(pTblDesc^,SizeOf(CRTblDesc),0);
AnsiToNative(DBLocale,TableName,pTblDesc^.szTblName,255);
pTblDesc^.szTblType := FTblProps.szTableType;
pTblDesc^.bPack := True;
hDB := DBHandle;
close;
   try
   BDECheck(DBIDoRestructure(hdb,1,pTblDesc,nil,nil,nil,False));
   result:=true;
   finally
   if pTblDesc <> nil then FreeMem(pTblDesc,sizeOf(CRTblDesc));
   end;
end;

procedure packdbf;
begin
try
open;
BDECheck(DBIPackTable(DBHandle,Handle,nil,nil,TRUE));
result:=true;
except
result:=false;
end;
end;

begin
result:=false;
pTblDesc := nil;
bopen:=active;   {store previous state}
fixtabletype;
if exclusive then
 begin
    try
    open;
    if (tabletype=ttParadox) then  packpdx {paradox}
      else if (tabletype=ttDBASE) then  packdbf {Dbase}
    except
    result:=false;
    end;
 end;
active:=bopen;     {restore previous state}
end;

function TBSPktbl.regenindexes:boolean;
begin
result:=false;
bopen:=active;
fixtabletype;
if exclusive then
  begin
   try
   open;
   BDEcheck(dbiregenindexes(handle));
   result:=true;
   except
   result:=false;
   end;
  end;
active:=bopen;
end;

procedure TBSPktbl.fixtabletype;
begin
if active then close;
ex:=uppercase(extractfileext(tablename));
if (ex='') then
   begin
        if (tabletype=ttparadox) then tablename:=tablename+'.DB' else
           if (tabletype=ttdbase) then tablename:=tablename+'.DBF';
   end
else
  begin
  if (ex='.DBF') then tabletype:=ttDBASE else
   if (ex='.DB') then tabletype:=ttParadox else
      tabletype:=ttDefault;
   end;
end;

end.

--
Olivier Dahan
oda...@{*word*104}cable.fr
Delphi 32b C/S certified engineer
Michael Chrtien <ChretienM...@Bfusa.com> a crit dans le message :
7ffe5j$s...@forums.borland.com...

Quote
> I would like to pack and reindex a .dbf file. I know it's possible and i
> would like to know how.

> Regards,

> Micha?l Chrtien
> Programmer/Analyst
> Bridgestone/ Firestone
> 1200 Firestone Boulevard
> Joliette, Qc
> ChretienM...@BFUSA.com

Other Threads