
Product:        VCL Component (TDbCheck)
Author:         Markelov Vladimir & Momot Alexander
E-Mail:         v_matroskin@aport2000.ru
Status:         FreeWare
Delphi:         Delphi 5

  Function of component is to check and correct structure
of local data bases (DBase, Paradox) without any data loss.
Component require Borland Database Engine(BDE).        
Now you can distribute your application without new structure
of data files. Your program converts files of old format to
new withut any data waste. Even you can distribute to new
clients only one EXE-file without any databases.
Application will create all tables that it need.


{------------------------------------------------------------}
       What component can do if it find the difference
           between current and original structure:
{------------------------------------------------------------}

1.  Change size of field.
2.  Change field type.
3.  Add field.
4.  Remove field.
5.  Change order of fields.
6.  Add index.
6.  Modify index.
7.  Remove index.
8.  Can correct error "Index out of date".
9.  Can correct header in case the counter of Autoinc field is
    damaged and this component change value of counter to 
    right value.

{------------------------------------------------------------}
        How to make component work:
{------------------------------------------------------------}

1. Drop it on main form.
2. Set property ReadPath to the path where lays your 
   standard data files. Instead path you can select alias
   from list. This property (ReadPath) is needed only
   for design time.
3. You need fill property ReadFiles  with all table names that
   you want to check after starting your application. Name of
   table you have to write with an extension and in one line
   of list must be only one table name. You can describe all of
   tables. It is useful in case you want to show description of
   checking table when it is checking. Example of list of files
   ReadFiles=
        JOURNAL.DB=Documents journal
        MAIN.DB=Main file
        City.DB=City reference
   ATTENTIN! In case the property ReadFiles is empty the 
   component will check all of tables in directory that is
   indicated by property ReadPath.
4. Property CorrectPath have to indicate the path or alias where
   your checking tables is located. (It is preferred to use alias
   but you can assign that property in event OnCreate of main form,
   before checking tables)
5. When you are in design-time click with right button on component
   and select the item 'Read database structure...'. After that
   structure of your standard data files will be stored in property
   Descriptor. You shouldn`t correct this property by yourself
   but you can. This property is used to compare with structure of
   checking files. That is why that after every changing structure 
   of your data files you should againg do 'Read database structure...'
6. Checking of tables is preferred to do in OnCreate event of 
   main form. For example:

    procedure TMainForm.FormCreate(Sender: TObject);
    begin
     { You can change property CorrectPath
     DbCheck1.CorrectPath := ExtractFilePath(Application.ExeName);
     }
     DbCheck1.CheckDatabase;
    end;

   Then you have to write event OnFoundDiff that is called when 
   component has found a difference between standard and checking
   tables, like that:
   
    procedure TForm1.DbCheck1FoundDiff(Sender: TObject;
      ChkMessage: TChkMessage; TblName: String; var Correct: Boolean);
    begin
      case( ChkMessage )of
      CHK_TABLECREATE:
       Correct := MessageBox(Handle, PChar(Format('Table "%s" not found. Create?',
                             [TblName])), 'Warning', MB_YESNOCANCEL or MB_ICONWARNING) = ID_YES;
      CHK_TABLEMODIFY:
       Correct := MessageBox(Handle, PChar(Format('Table "%s" has a different structure from
                             standard. Modify structure?',
                             [TblName])), 'Warning', MB_YESNOCANCEL or MB_ICONWARNING) = ID_YES;
      end;{ CASE }
    end;

  ChkMessage has to types
    CHK_TABLECREATE - table is not found and you have to create new empty
                      one with original structure;
    CHK_TABLEMODIFY - table is found but the structure of fields or indexes
                      differs from standard that described in Descriptor.

   TblName - is the name of file or description of table that you
             wrote after '=' in property ReadFiles. If you wrote
             no description TblName is the name of file.

   Correct - setting this variable to True indicates that the component
             have to correct structure. 

   This event (OnFoundDiff) you can show additional information on
   form like that:

    procedure TMainForm.DbCheck1FoundDiff(Sender: TObject;
      ChkMessage: TChkMessage; TblName: String; var Correct: Boolean);
    var
     RetCode: Longint;
    begin
      case( ChkMessage )of
      CHK_TABLECREATE:
       Correct := MessageBox(Handle, PChar(Format('Table "%s" not found. Create?',
                             [TblName])), 'Warning', MB_YESNOCANCEL or MB_ICONWARNING) = ID_YES;
      CHK_TABLEMODIFY:
       Correct := MessageBox(Handle, PChar(Format('Table "%s" has a different structure from
                             standard. Modify structure?',
                             [TblName])), 'Warning', MB_YESNOCANCEL or MB_ICONWARNING) = ID_YES;
      end;{ CASE }
       Correct := (RetCode = ID_YES);

      if( Correct )then
        with( ABForm )do begin
        //ABForm is a splash screen that is shown while application launching
          case( ChkMessage )of
            CHK_TABLECREATE: LABEL_PROC.Caption := Format('Creating table %s...',[TblName]);
            CHK_TABLEMODIFY: LABEL_PROC.Caption := Format('Modifying table %s...',[TblName]);
          end;{ CASE }
          LABEL_PROC.Refresh;
        end;
    end;

   To show to user what process is launching you have to use 
   OnBeforeCheck event:

    procedure TMainForm.DbCheck1BeforeCheck(Sender: TObject;
      ChkMessage: TChkMessage; TblName: String);
    begin
      case( ChkMessage )of
        CHK_NONE: ABForm.LABEL_PROC.Caption := Format('Checking table %s...',[TblName]);
        CHK_AUTOINCREPAIR: ABForm.LABEL_PROC.Caption := Format('Correcting autoincrement error %s...',[TblName]);
      end;{ case }
      ABForm.LABEL_PROC.Refresh;
    end;

   To show error message you have to write OnError event:

    procedure TMainForm.DbCheck1Error(Sender: TObject; Message: EDBEngineError);
    begin
     MessageBox(Handle, PChar(Format('[Error] %s', [Message.Message])), 'ERROR', MB_OK or MB_ICONERROR);
    end;


   To know what fields in table were added or modified there are two events:

        OnAddField  OnModifyField

    procedure TMainForm.DbCheck1OnAddField(Sender: TObject; TblName, FldName: String);
    begin
     MessageBox(Handle, PChar(Format('Field %s added to table %s', [FldName, TblName])), 'Warning', MB_OK or MB_ICONWARNING);
    end;
   Using  OnModifyField is the same

   After successful creating table OnCreateTable event is raised:

    procedure TMainForm.DbCheck1OnCreateTable(Sender: TObject; TblName: String);
    begin
     MessageBox(Handle, PChar(Format('Table %s has been created', [TblName])), 'Information', MB_OK or MB_INFORMATION);
    end;

   After successful modifying table OnModifyTable event is raised:

    procedure TMainForm.DbCheck1OnModifyTable(Sender: TObject; TblName: String);
    begin
     MessageBox(Handle, PChar(Format('Table %s has been modifying', [TblName])), 'Warning', MB_OK or MB_ICONINFORMATION);
    end;


7. ATTENTION! 
   For normal functioning of component is needed that all checking
   tables weren`t busy.

   Component needs unit DsgnIntf;
   If you don`t have it I include its from Delphi 5 with unit Masks;

Any offers, remarks, comments etc send to v_matroskin@aport2000.ru

This component is freeware but if you change it`s source,
please send me a letter with your changes.
    
   Vladimir Markelov.
