如何使用TFDSQLiteValidate在控制台应用程序中验证SQLite DB

时间:2016-08-08 04:56:47

标签: sqlite delphi dll firedac

我们可以在TForm中使用验证,它工作得非常好,但现在我们必须从仅控制台应用程序验证/分析SQLite数据库。请在XE7 +中分享任何有关工作的详细示例。

这是一个执行该功能的功能

  try
      goodsqlitedb:=true;
      //Check if Db is closed and not in use
      if(FDSqliteQuery1.Active) then
      begin
            FDSqliteQuery1.Close;
            updatelog('logfilename.txt', 'Closed Query');
      end
      else
          updatelog('logfilename.txt', 'Query Already Closed');

      FDSqliteConn.Close;
      updatelog('logfilename.txt', 'Connection Closed');

      //FDSqliteConn.Open;
      FDPhysSQLiteDriverLink2:=TFDPhysSQLiteDriverLink.Create(nil);
      FDSQLiteValidate2:=TFDSQLiteValidate.Create(nil);
      FDPhysDriverService:=TFDPhysDriverService.Create(nil);
      FDSQLiteSec2:=TFDSQLiteSecurity.Create(nil);
      FDSQLiteSec2.DriverLink:=FDPhysSQLiteDriverLink2;
      FDSQLiteValidate2.DriverLink:=FDPhysSQLiteDriverLink2;

      //FDSQLiteValidate2.OnProgress(FDPhysDriverService,DBMessage);

      with FDSQLiteValidate2 do
      begin
            updatelog('logfilename.txt', 'To Start the Validation');
            Database := dbfile;
            Analyze;
            updatelog('logfilename.txt', 'Database To be Analyzed');
            if not CheckOnly then
                Result:='1' //Database has problems
            else
                Result:='0'; //Database is good
      end;
  except
  on E: Exception do
      begin
            updatelog('logfilename.txt', 'Database Exception='+E.Message);
            Result:='2';    //Database is Corrupt
            goodsqlitedb := False;
            //raise;
      end;
  end;

  try
      FDPhysSQLiteDriverLink2.Destroy;
      FDSQLiteValidate2.Destroy;
      FDPhysDriverService.Destroy;
      FDSQLiteSec2.Destroy;
  finally
         updatelog('logfilename.txt', 'Drivers destroyed');
  end;

2 个答案:

答案 0 :(得分:4)

以下是一个控制台应用程序,应该按照以下注意事项执行您的操作:

  1. 我无法获得基于您的代码设置的GUI测试平台,而不会在FDSQLiteValidate2.Analyze上引发异常在我的gui版本中,报告的错误是数据库被锁定,而在控制台版本中,错误消息为"数据库异常=类{3E9B315B-F456-4175-A864-B2573C4A2201}的对象工厂丢失。要注册它,您可以将组件[TFDGUIxWaitCursor]放入项目"。

    但是,既然你说'#34;这是一个功能就可以做到这一点",我没有浪费任何时间调试任何一个版本并留给你。

  2. 将数据库函数的结果作为字符串返回不是我做的方式,而是你的选择。

  3. 如果要添加大量日志条目,使用TStringList作为日志并不是很好,但至少它允许使用简单的UpdateLog例程。

  4. 代码:

    program ConsoleValidateDB;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils, System.Classes,
      // following come from a GUI testbed
      FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error,
      FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
      FireDAC.Stan.Async, FireDAC.DApt, FireDAC.UI.Intf,
      FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys,
      FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs,
      FireDAC.VCLUI.Wait, Data.DB,
      FireDAC.Comp.Client, FireDAC.Comp.DataSet;
    
    const
      DBFileName  = 'D:\Delphi\Code\Sqlite\db2.sqlite';
      LogFileName = 'C:\temp\sqlitelog.txt';
    
    var
      Log : TStringList;
    
    procedure UpdateLog(LogFN, Msg : String);
    begin
      if Log = Nil then
        Log := TStringList.Create;
      Log.LoadFromFile(LogFN);
      Log.BeginUpdate;
      try
        Log.Add(Msg);
        Log.SaveToFile(LogFN);
      finally
        Log.EndUpdate
      end;
    end;
    
    function ValidateDB : String;
    var
      goodsqlitedb : Boolean;
      FDPhysSQLiteDriverLink2 : TFDPhysSQLiteDriverLink;
      FDSQLiteValidate2 : TFDSQLiteValidate;
      FDPhysDriverService : TFDPhysDriverService;
      FDSQLiteSec2 : TFDSQLiteSecurity;
    begin
      Result := 'Undefined';
      try
        goodsqlitedb:=true;
    
    (*  These are evidently components in a Gui app.  Ignore them.
        //Check if Db is closed and not in use
        if(FDSqliteQuery1.Active) then
        begin
              FDSqliteQuery1.Close;
              updatelog('logfilename.txt', 'Closed Query');
        end
        else
            updatelog('logfilename.txt', 'Query Already Closed');
    
        FDSqliteConn.Close;
        updatelog('logfilename.txt', 'Connection Closed');
    *)
    
        //FDSqliteConn.Open;
        FDPhysSQLiteDriverLink2:=TFDPhysSQLiteDriverLink.Create(nil);
        FDSQLiteValidate2:=TFDSQLiteValidate.Create(nil);
        FDPhysDriverService:=TFDPhysDriverService.Create(nil);
        FDSQLiteSec2:=TFDSQLiteSecurity.Create(nil);
        FDSQLiteSec2.DriverLink := FDPhysSQLiteDriverLink2;
        FDSQLiteValidate2.DriverLink:=FDPhysSQLiteDriverLink2;
    
        //FDSQLiteValidate2.OnProgress(FDPhysDriverService,DBMessage);
    
       //  "with" is evil, so omit it // with FDSQLiteValidate2 do begin
          updatelog(LogFileName, 'To Start the Validation');
          FDSQLiteValidate2.Database := DBFileName;
          FDSQLiteValidate2.Analyze;
          updatelog(LogFileName, 'Database To be Analyzed');
          if not FDSQLiteValidate2.CheckOnly then
              Result:= '1' //Database has problems
          else
              Result:= '0'; //Database is good
        //end;
      except
        on E: Exception do  begin
                  updatelog(LogFileName, 'Database Exception='+E.Message);
                  Result:= '2';    //Database is Corrupt
                  goodsqlitedb := False;
                  //raise;
            end;
        end;
    
      try
        FDPhysSQLiteDriverLink2.Destroy;
        FDSQLiteValidate2.Destroy;
        FDPhysDriverService.Destroy;
        FDSQLiteSec2.Destroy;
      finally
        updatelog(LogFileName, 'Drivers destroyed');
      end;
    
    end;
    
    begin
      writeln(ValidateDB);
    end.
    

答案 1 :(得分:1)

要将您的工作实现从可视化应用程序移植到非可视应用程序,您至少有两个选项可以从哪里获取组件:

  1. TDataModule 是一个非可视组件,您可以通过IDE的对象检查器放置其他非可视组件并对其进行编辑,就像在TForm或{{1}上一样}}。您可以在Delphi IDE中的 New ... - 向导中找到它。因此,如果您想坚持使用基于GUI的组件,可以将它们放在那里。
  2. 自行创建所需的组件