Obtention et utilisation des IMessageMetadata
Les instances des objets qui implémentent l’interface IMessageMetadata
pour les variables d’entrée et de sortie peuvent être obtenues à partir de l’interface IRoutineMetadata
. Elles ne sont pas passées directement à une instance de procédure, de fonction ou de trigger. Cela doit être fait explicitement dans la classe du type approprié. Par exemple, dans le cas d’une procédure, d’une fonction ou d’un déclencheur :
// Classe pour l'instanciation de la fonction externe TSumArgsFunction
TSumArgsFunctionFactory = class(IUdrFunctionFactoryImpl)
// Appelé lorsque la classe est détruite
procedure dispose(); override;
{ Exécuté chaque fois qu'une fonction externe est chargée dans le cache de métadonnées.
Permet de modifier le format des messages d'entrée et de sortie.
@param(AStatus vecteur de statut)
@param(AContext Contexte d'exécution de la fonction externe)
@param(AMetadata Métadonnées de la fonction externe)
@param(AInBuilder Constructeur de messages pour les métadonnées d'entrée)
@param(AOutBuilder Constructeur de messages pour les métadonnées de sortie)
}
procedure setup(AStatus: IStatus; AContext: IExternalContext;
AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder;
AOutBuilder: IMetadataBuilder); override;
{ Création d'une nouvelle instance de fonction externe TSumArgsFunction
@param(AStatus vecteur de statut)
@param(AContext Contexte d'exécution de la fonction externe)
@param(AMetadata Métadonnées de la fonction externe)
@returns(Instance de la fonction externe)
}
function newItem(AStatus: IStatus; AContext: IExternalContext;
AMetadata: IRoutineMetadata): IExternalFunction; override;
end;
// Fonction externe TSumArgsFunction.
TSumArgsFunction = class(IExternalFunctionImpl)
// Appelé lorsque l'instance de la fonction est détruite
procedure dispose(); override;
{ Cette méthode est appelée juste avant l'exécution et indique au noyau le jeu de caractères requis
pour échanger des données en interne avec cette méthode. Lors de cet appel, le contexte utilise
le jeu de caractères obtenu par ExternalEngine::getCharSet.
@param(AStatus Vecteur de statut)
@param(AContext Contexte d'exécution de la fonction externe)
@param(AName Nom du jeu de caractères)
@param(ANameSize Longueur du nom du jeu de caractères)
}
procedure getCharSet(AStatus: IStatus; AContext: IExternalContext;
AName: PAnsiChar; ANameSize: Cardinal); override;
{ Exécution d'une fonction externe
@param(AStatus Vecteur de statut)
@param(AContext Contexte d'exécution de la fonction externe)
@param(AInMsg Pointeur vers le message d'entrée)
@param(AOutMsg Pointeur vers le message de sortie)
}
procedure execute(AStatus: IStatus; AContext: IExternalContext;
AInMsg: Pointer; AOutMsg: Pointer); override;
end;
........................
{ TSumArgsFunctionFactory }
procedure TSumArgsFunctionFactory.dispose;
begin
Destroy;
end;
function TSumArgsFunctionFactory.newItem(AStatus: IStatus;
AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction;
begin
Result := TSumArgsFunction.Create();
with Result as TSumArgsFunction do
begin
Metadata := AMetadata;
end;
end;
procedure TSumArgsFunctionFactory.setup(AStatus: IStatus;
AContext: IExternalContext; AMetadata: IRoutineMetadata;
AInBuilder, AOutBuilder: IMetadataBuilder);
begin
end;
Les instances de IMessageMetadata
pour les variables d’entrée et de sortie peuvent être obtenues en utilisant les méthodes getInputMetadata
et getOutputMetadata
de IRoutineMetadata
.Les métadonnées pour les champs de la table sur laquelle le trigger est écrit peuvent être obtenues en utilisant la méthode getTriggerMetadata
.
Important
|
Important
Veuillez noter que le cycle de vie des objets de l’interface |
Pour obtenir la valeur de l’argument d’entrée correspondant, nous devons utiliser sont adresse. Pour ce faire, nous obtenons l’offset de IMessageMetadata
en utilisant la méthode getOffset
et nous l’ajoutons à l’adresse du tampon pour le message d’entrée. Ensuite, nous réduisons le résultat obtenu au pointeur typé correspondant. Il s’agit à peu près du même schéma de travail pour obtenir les indicateurs nuls des arguments, mais la méthode getNullOffset
est utilisée pour obtenir les décalages.
........................
procedure TSumArgsFunction.execute(AStatus: IStatus; AContext: IExternalContext;
AInMsg, AOutMsg: Pointer);
var
n1, n2, n3: Integer;
n1Null, n2Null, n3Null: WordBool;
Result: Integer;
resultNull: WordBool;
xInputMetadata, xOutputMetadata: IMessageMetadata;
begin
xInputMetadata := FMetadata.getInputMetadata(AStatus);
xOutputMetadata := FMetadata.getOutputMetadata(AStatus);
try
// obtenir les valeurs des arguments d'entrée par leurs décalages
n1 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 0))^;
n2 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 1))^;
n3 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 2))^;
// obtenir les valeurs des indicateurs nuls des arguments d'entrée en fonction de leurs décalages
n1Null := PWordBool(PByte(AInMsg) +
xInputMetadata.getNullOffset(AStatus, 0))^;
n2Null := PWordBool(PByte(AInMsg) +
xInputMetadata.getNullOffset(AStatus, 1))^;
n3Null := PWordBool(PByte(AInMsg) +
xInputMetadata.getNullOffset(AStatus, 2))^;
//par défaut, l'argument de sortie est NULL, nous lui attribuons donc la valeur nullFlag
resultNull := True;
Result := 0;
// si l'un des arguments est NULL, le résultat est NULL sinon, on calcule la somme des arguments
if not(n1Null or n2Null or n3Null) then
begin
Result := n1 + n2 + n3;
// une fois qu'il y a un résultat, réinitialiser le drapeau NULL
resultNull := False;
end;
PWordBool(PByte(AInMsg) + xOutputMetadata.getNullOffset(AStatus, 0))^ := resultNull;
PInteger(PByte(AInMsg) + xOutputMetadata.getOffset(AStatus, 0))^ := Result;
finally
xInputMetadata.release;
xOutputMetadata.release;
end;
end;
Note
|
Dans le chapitre Contexte de connexion et de transaction , exemple pour travailler avec différents types SQL en utilisant l’interface |