A form to rebuild the structure of Paradox Tables (Views: 28)
Problem/Question/Abstract: How to rebuild the structure of a table with the use of a component. Answer: One of the main problem when we modify programs is when the structure of a table is modified. When we have users distributed along the country the update of the program is almost imposible. I wrote a form that read the structure of every table, compare them with the new strucure and if neccessary rebuild the table. The form is very simply, contains 2 buttons, a BatchMove and a label. One button (BotStart) is for start the procees, other button (BotQuit) to quit the program. Im using RxLib (The function DeleteFiles of the FileUtil Unit) This program contains 3 examples of 3 tables, the program check the structure ov every one. The code of the form is: unit UVerUpd; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Db, DbTables, FileUtil; type TFVerUpd = class(TForm) BotStart: TButton; BotQuit: TButton; StatusBar1: TStatusBar; Bat: TBatchMove; Label1: TLabel; procedure BotStartClick(Sender: TObject); procedure BotQuitClick(Sender: TObject); procedure FillStructure(Sender: TObject; xBase: TTable); procedure Check_a_Table(Sender: TObject; Tabla: string); private { Private declarations } public { Public declarations } xData, xDir: string; // xdata is the alias name // xdir is the directory where xdata is located end; var FVerUpd: TFVerUpd; function GetAliasPath(Base: string): string; implementation {$R *.DFM} procedure TFVerUpd.BotStartClick(Sender: TObject); begin BotStart.Enabled := False; xData := 'Pat41'; // the name of the alias, Pat41 is an example xDir := GetAliasPath(xData); // 3 examples Check_a_Table(Sender, 'Paquete.DB'); Check_a_Table(Sender, 'TabDesc.db'); Check_a_Table(Sender, 'Vehiculo.db'); Close; end; procedure TFVerUpd.Check_a_Table(Sender: TObject; Tabla: string); var TOld, TNew: TTable; xRebuild, xFound, xExiste: Boolean; i, j: Integer; xField: TField; begin StatusBar1.Panels[0].Text := Tabla; StatusBar1.Panels[1].Text := ''; TOld := TTable.Create(Self); TNew := TTable.Create(Self); with TNew do begin DataBaseName := xData; Tablename := Tabla; FillStructure(Sender, TNew) end; xExiste := FileExists(xDir + Tabla); if not xExiste then xRebuild := True else begin with TOld do begin DataBaseName := xData; TableType := ttDefault; Tablename := Tabla; FieldDefs.Update; for i := 0 to FieldDefs.Count - 1 do FieldDefs[i].CreateField(TOld); end; // review the fields xRebuild := False; i := 0; while (i <= TNew.FieldDefs.Count - 1) and (not xRebuild) do begin xField := TOld.FindField(TNew.FieldDefs[i].Name); if xField = nil then xRebuild := True else begin if xField.DataType <> TNew.FieldDefs[i].DataType then xRebuild := True; if xField.Size <> TNew.FieldDefs[i].Size then xRebuild := True; end; inc(i); end; if TNew.FieldDefs.Count <> TOld.FieldDefs.Count then xRebuild := True; // review the keys TOld.IndexDefs.Update; for i := 0 to TNew.IndexDefs.Count - 1 do begin xFound := False; j := 1; while (j <= TOld.Indexdefs.Count) and (not xFound) do begin if UpperCase(TNew.IndexDefs[i].Fields) = UpperCase(TOld.IndexDefs[j - 1].Fields) then if TNew.IndexDefs[i].Name = TOld.IndexDefs[j - 1].Name then xFound := True; inc(j); end; if not xFound then begin xRebuild := True; end; end; if TNew.IndexDefs.Count <> TOld.IndexDefs.Count then xRebuild := True; end; // if the program has to rebuild the table if xRebuild then begin StatusBar1.Panels[1].Text := 'Updating'; if xExiste then begin DeleteFiles(xDir + 'xx.*'); // RxLib TOld.RenameTable('xx'); TNew.CreateTable; Bat.Source := TOld; Bat.Destination := TNew; Bat.Execute; end else TNew.CreateTable; end; TOld.Free; TNew.Free; end; procedure TFVerUpd.FillStructure(Sender: TObject; xBase: TTable); var Tabla: string; begin // this function fills the description of the tables with xBase do begin Tabla := UpperCase(TableName); ///////////////////////////////////////////// if Tabla = 'PAQUETE.DB' then begin with FieldDefs do begin clear; add('Clave_Paq', ftInteger, 0, false); add('Desc_Paq', ftString, 40, false); add('Property_Av', ftBoolean, 0, false); add('Property_Min', ftCurrency, 0, false); add('Property_Max', ftCurrency, 0, false); add('Bodily_Av', ftBoolean, 0, false); end; with IndexDefs do begin clear; add('', 'Clave_Paq', [ixPrimary, ixUnique]); end; end; ///////////////////////////////////////////// if Tabla = 'TABDESC.DB' then begin with FieldDefs do begin clear; add('CLAVE_DTO', ftInteger, 0, false); add('DESC_DTO', ftString, 40, false); add('TIPOL', ftInteger, 0, false); add('TIPO_USO', ftInteger, 0, false); add('POR_DES', ftFloat, 0, false); add('REQMEM', ftBoolean, 0, false); add('MENS_DESC', ftString, 100, false); add('CLAVE_RES', ftInteger, 0, false); end; with IndexDefs do begin clear; add('', 'CLAVE_DTO', [ixPrimary, ixUnique]); end; end; ///////////////////////////////////////////// if Tabla = 'VEHICULO.DB' then begin with FieldDefs do begin clear; add('TIPO_VEH', ftInteger, 0, false); add('DESC_VEH', ftString, 30, false); add('DIASMIN_VE', ftInteger, 0, false); add('PRIMAMIN_V', ftCurrency, 0, false); add('ANTMAX_VEH', ftInteger, 0, false); add('NUMPAS_VEH', ftInteger, 0, false); add('DM_ADMIT', ftBoolean, 0, false); end; with IndexDefs do begin clear; add('', 'TIPO_VEH', [ixPrimary, ixUnique]); end; end; end; end; procedure TFVerUpd.BotQuitClick(Sender: TObject); begin Close; end; function GetAliasPath(Base: string): string; var ParamList: TStringList; begin Result := ''; ParamList := TStringList.Create; try Session.GetAliasParams(Base, ParamList); result := Uppercase(ParamList.Values['PATH']) + '\'; finally ParamList.free; end; end; end. Component Download: http://www.baltsoft.com/files/dkb/attachment/version.zip |