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

Sha*_*tra 0 delphi sqlite dll firedac

我们能够在 TForm 中使用验证,并且工作得非常好,但现在我们必须从仅控制台应用程序验证/分析 SQLite DB。请分享 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;
Run Code Online (Sandbox Code Playgroud)

Mar*_*ynA 5

下面是一个控制台应用程序,它应该可以执行您想要的操作,但需要注意以下事项:

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

    然而,既然你说“这是一个可以做到这一点的函数”,我就没有浪费任何时间调试任一版本并将其留给你。

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

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

代码 :

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.
Run Code Online (Sandbox Code Playgroud)