FindOrCreate (CM)
De Wiki1000
Version du 8 mars 2017 à 08:32 par Flfay (discuter | contributions)
function FindOrCreate(const iClassName,iWhere,iOrderBy:string,iDescendants:Boolean; iArgs:Variants; iDelegate:TitObject):TitObject;
Cette fonction recherche un objet d'une classe métier répondant à une condition.
Si l'objet n'est pas trouvé, la fonction exécute la méthode "Execute" de l'objet iDelegate dans une transaction séparée partagée, puis recherche de nouveau l'objet.
Lorsque cette méthode est utilisée dans le cadre d'une exécution parallèle, elle assure que l'objet ne sera créé qu'une fois. Ceci suppose que la transaction séparée va échouer en cas de création de doublon, il faut donc que la classe de l'objet créé comporte une règle unique adéquate.
Result | Un objet de la classe métier |
iWhere | Une expression objet que doit remplir l'objet. |
iOrderBy | Un ordre de tri appliqué dans la requête. |
iDescendants | Inclure les classes dérivées de la hiérarchie de classe. |
iArgs | Arguments de l'expression |
iDelegate | Objet délégation utilisé si l'objet recherché n'est pas trouvé |
Le pseudo-code équivalent à cette fonction est :
function ClassManager.FindOrCreate(const iClassName:string; const iWhereFormat,iOrderBy:string; iDescendants:Boolean; const iArgs:Variant; iDelegate:TitObject):TitObject; var rslt:boolean; new,old:TTranContext; begin // Find the object Result := ClassManager.FindObject(iClassName,iWhereFormat,iOrderBy,iDescendants,iArgs,True); if Assigned(Result) then Exit; // Not found // Call the delegate.Execute method in a separate shared transaction // rslt := false; new := ClassManager.AllocTransContext; old := ClassManager.ActivateContext(new); try ClassManager.BeginTran; try if not _ExecuteDelegation(iDelegate,'Execute') then raise EScript.CreateFmt('(FindOrCreate) Delegate object %s has no Execute method',[iDelegate.Regclass.AClassName]); // rslt := ClassManager.Commit except rslt := false; ClassManager.RollBack; end; finally ClassManager.ActivateContext(old); end; // Result := ClassManager.FindObject(iClassName,iWhereFormat,iOrderBy,iDescendants,iArgs,True); if not Assigned(Result) then begin if not _ExecuteDelegation(iDelegate,'OnExecuteFailed') then raise ERule.CreateFmt(_TP('Impossible de créer un objet de la classe %s'),[RegClass.aClassLabel]); end; end;
Exemple
// delegate class // This class create a ClassB object using unCode as parameter. // MyDelegate = class unCode: string; procedure Execute; end; procedure MyDelegate.Execute; var instB:ClassB; begin instB := ClassB.Create; instB.unCodeB := unCode; end; // Caller class // This method create two objects ClassA and ClassB, ClassB is created using the delagate // procedure MyClass.CreateAandB(const S1,S2:string; iValue:Integer); var instD:Delegate; instA:ClassA; instB:ClassB; begin withP transaction do begin instA := ClassA.Create; instA.unEntierA := iValue; instA.unCodeA := S1; instA.unExtension := S1; // // Create a MyDelegate object instD := MyDelegate.Create; instD.unCode := S2; instB := ClassManager.FindOrCreate('ClassB','unCodeB=%1','',True,[S2],instD); // instA.refB := instB; end; end;
Voir aussi :