212 lines
5.9 KiB
ObjectPascal
212 lines
5.9 KiB
ObjectPascal
unit commandcol;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,Contnrs, extTypes, cgiDM;
|
|
type
|
|
{ TCommand }
|
|
|
|
TCommand=class
|
|
protected
|
|
fData,
|
|
fResult: TCommandData;
|
|
fCommandID: string;
|
|
fStatus: integer;
|
|
fcurrentStage: string;
|
|
fProcessor: TNIDBDM;
|
|
fisDone,fisFinished: boolean;
|
|
fIsError: boolean;
|
|
|
|
fSubClass: string;
|
|
fUser: integer;
|
|
fUserName: string;
|
|
fLogger: TLogger;
|
|
fErrors: TStrings;
|
|
function getInt(keyName: string;defaultValue: integer=0): integer;
|
|
function getString(keyName: string): string;
|
|
public
|
|
AccessTime: TDateTime;
|
|
TimeOut: single;
|
|
property Arguments: TCommandData read fData;
|
|
property Results: TCommandData read fResult;
|
|
property CommandID: string read fCommandID;
|
|
property Status: integer read fStatus;
|
|
property isDone: boolean read fIsDone;
|
|
property Error: boolean read fIsError write fIsError;
|
|
property isFinished: boolean read fIsFinished;
|
|
property CurrentStage: string read fCurrentStage;
|
|
property Processor: TNIDBDM read fProcessor;
|
|
property UserID: integer read fUser;
|
|
property UserName: string read fUserName;
|
|
constructor Create(ID: string; aProcessor: TNIDBDM; ASubClass: string; aLogger:TLogger; AUser: string; IDUser: integer); virtual;
|
|
destructor Destroy; override;
|
|
procedure doRun;
|
|
procedure Done;
|
|
function Run: boolean; virtual; abstract;
|
|
class function CommandName: string; virtual; abstract;
|
|
class function CommandSubClass: string; virtual; abstract;
|
|
function CheckArgs(out Errors: TStrings): boolean; virtual; abstract;
|
|
function ParseCommand(ACode: DWORD; iParam: QWORD; ACommand: string; Args: TStrings; intArgs: TParamArray; CmdData: TStream; out Errors: TStrings): boolean;
|
|
function ParseArguments(Args: TStrings; out Errors: TStrings): boolean; virtual; abstract;
|
|
procedure Log(ALevel:TLogLevel; msg: string);
|
|
procedure logError(e:Exception; Command: string);
|
|
function ProcessOptionValues(ParamName: string; out Answer: string; out RetValue: QWORD; out OptionValues: TStrings): boolean; virtual; abstract;
|
|
property Journal: TStrings read fErrors;
|
|
end;
|
|
TCommandClass=class of TCommand;
|
|
|
|
|
|
{ TCommandCollection }
|
|
TCommandCollection=Class;
|
|
TCommandCollection=Class(TClassList)
|
|
private
|
|
class var fCollection: TCommandCollection;
|
|
public
|
|
class procedure Register(ACommand: TCommandClass);
|
|
class function Find(Action,SubClass: string): TCommandClass;
|
|
class procedure Init;
|
|
class procedure Done;
|
|
end;
|
|
|
|
implementation
|
|
{ TCommandCollection }
|
|
|
|
class procedure TCommandCollection.Register(ACommand: TCommandClass);
|
|
begin
|
|
{if not assigned(fCollection) then
|
|
Init;}
|
|
fCollection.Add(ACommand);
|
|
end;
|
|
|
|
class function TCommandCollection.Find(Action, SubClass: string): TCommandClass;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to fCollection.Count-1 do
|
|
if fCollection.Items[i].InheritsFrom(TCommand) and SameText(Action, TCommandClass(fCollection.Items[i]).CommandName) and SameText(SubClass, TCommandClass(fCollection.Items[i]).CommandSubClass) then
|
|
begin
|
|
result := TCommandClass(fCollection.Items[i]) ;
|
|
exit;
|
|
end;
|
|
for i := 0 to fCollection.Count-1 do
|
|
if fCollection.Items[i].InheritsFrom(TCommand) and SameText(Action, TCommandClass(fCollection.Items[i]).CommandName) and SameText('', TCommandClass(fCollection.Items[i]).CommandSubClass) then
|
|
begin
|
|
result := TCommandClass(fCollection.Items[i]) ;
|
|
exit;
|
|
end;
|
|
result := nil;
|
|
end;
|
|
|
|
class procedure TCommandCollection.Init;
|
|
begin
|
|
if not assigned(fCollection) then
|
|
fCollection := TCommandCollection.Create;
|
|
end;
|
|
|
|
class procedure TCommandCollection.Done;
|
|
begin
|
|
fCollection.Free;
|
|
end;
|
|
{ TCommand }
|
|
|
|
function TCommand.getInt(keyName: string; defaultValue: integer): integer;
|
|
begin
|
|
result := StrToIntDef(fData.Keys.Values[keyName],defaultValue);
|
|
end;
|
|
|
|
function TCommand.getString(keyName: string): string;
|
|
begin
|
|
result := fData.Keys.Values[KeyName];
|
|
end;
|
|
|
|
constructor TCommand.Create(ID: string; aProcessor: TNIDBDM; ASubClass: string;
|
|
aLogger: TLogger; AUser: string; IDUser: integer);
|
|
begin
|
|
fProcessor := AProcessor;
|
|
fSubClass := ASubClass;
|
|
fStatus:=StatusWaiting;
|
|
fcurrentStage := 'в очереди';
|
|
fUserName := AUser;
|
|
fUser := IDUser;
|
|
fLogger := ALogger;
|
|
TimeOut:=1/24/4;
|
|
fCommandID:=ID;
|
|
fResult := nil;
|
|
fData := nil;
|
|
fErrors := TSTringList.Create;
|
|
end;
|
|
|
|
destructor TCommand.Destroy;
|
|
begin
|
|
if assigned(fData) then fData.Free;
|
|
if assigned(fResult) then fResult.free;
|
|
fErrors.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCommand.doRun;
|
|
begin
|
|
fStatus:=StatusProcessing;
|
|
fcurrentStage := 'исполняется';
|
|
try
|
|
if Run then
|
|
begin
|
|
fStatus:=StatusComplete;
|
|
fcurrentStage := 'завершена';
|
|
end
|
|
else
|
|
begin
|
|
fStatus := StatusError;
|
|
fcurrentStage := 'завершена c ошибкой';
|
|
end;
|
|
|
|
except on e: Exception do
|
|
begin
|
|
fStatus:=StatusError;
|
|
fcurrentStage := 'error';
|
|
if assigned(Results) then
|
|
Results.Free;
|
|
fResult := TCommandData.Create(ErrorInternal,0,e.ClassName,[e.Message],[],nil);
|
|
Results.Name:=e.Message;
|
|
logError(e,'doRun');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCommand.Done;
|
|
begin
|
|
fisDone:=true;
|
|
end;
|
|
|
|
function TCommand.ParseCommand(ACode: DWORD; iParam: QWORD; ACommand: string;
|
|
Args: TStrings; intArgs: TParamArray; CmdData: TStream; out Errors: TStrings
|
|
): boolean;
|
|
begin
|
|
Errors := nil;
|
|
self.fData := TCommandData.Create(ACode,iParam,ACommand,Args,intArgs,cmdData);
|
|
result := ParseArguments(fData.Keys,Errors);
|
|
end;
|
|
|
|
procedure TCommand.Log(ALevel: TLogLevel; msg: string);
|
|
begin
|
|
fErrors.add(msg);
|
|
if assigned(flogger) then
|
|
fLogger(ALevel,self, self.CommandID+#09+msg)
|
|
end;
|
|
|
|
procedure TCommand.logError(e: Exception; Command: string);
|
|
begin
|
|
log(mtError,format('%s вызвала ошибку %s(%s)',[Command,e.classname,e.Message]));
|
|
end;
|
|
|
|
initialization
|
|
TCommandCollection.Init;
|
|
finalization
|
|
TCommandCollection.Done;
|
|
|
|
end.
|
|
|