Utilisation des Services
Pour commencer à utiliser les services, vous devez d’abord vous connecter au gestionnaire de services. Cela se fait à l’aide de la méthode attachServiceManager()
de l’interface IProvider
. Cette méthode renvoie l’interface IService
, qui est ensuite utilisée pour communiquer avec le service. Pour préparer le SPB
à se connecter au Service Manager, vous pouvez utiliser IXpbBuilder
:
IXpbBuilder* spb1 = utl->getXpbBuilder(&status, IXpbBuilder::SPB_ATTACH, NULL, 0);
spb1->insertString(&status, isc_spb_user_name, "sysdba");
spb1->insertString(&status, isc_spb_password, "masterkey");
et connectez-vous :
IService* svc = prov->attachServiceManager(&status, "service_mgr",
spb1->getBufferLength(&status), spb1->getBuffer(&status));
À l’aide de IService
, vous pouvez effectuer des actions disponibles pour les services, telles que l’exécution de services, ainsi que demander diverses informations sur les utilitaires en cours d’exécution et du serveur dans son ensemble. Lors de la demande d’informations, il y a une limitation : le format du bloc de paramètres utilisé par la méthode query()
n’est pas pris en charge par IXpbBuilder
dans Firebird 4. Le support sera probablement ajouté dans les futurs versions, dans Firebird 4 vous devrez créer et analyser ce bloc manuellement. Le format de ce bloc rdt identique à l’ancien format (utilisé dans l’API ISC) un pour un.
Pour démarrer le service, vous devez d’abord créer le SPB approprié :
IXpbBuilder* spb2 = utl->getXpbBuilder(&status, IXpbBuilder::SPB_START, NULL, 0);
et y ajouter les éléments nécessaires. Par exemple, pour imprimer les statistiques de chiffrement de la base de données « employé » dans SPB, vous devez mettre ce qui suit :
spb2->insertTag(&status, isc_action_svc_db_stats);
spb2->insertString(&status, isc_spb_dbname, "employee");
spb2->insertInt(&status, isc_spb_options, isc_spb_sts_encryption);
Après cela, le service peut être démarré à l’aide de la méthode start()
de l’interface IService :
svc->start(&status, spb2->getBufferLength(&status), spb2->getBuffer(&status));
De nombreux services en cours d’exécution (y compris le gstat mentionné ici) renvoient des informations textuelles au moment de l’exécution. Pour l’afficher, vous devez demander ces informations au service en cours d’exécution ligne par ligne. Pour ce faire, appelez la méthode query()
de l’interface IService
avec les blocs de paramètres appropriés pour la réception et l’envoi. Le bloc d’envoi peut contenir diverses informations auxiliaires (par exemple, un délai d’expiration de la demande du service) ou des informations qui doivent être transmises à l’utilitaire stdin, où il peut être vide dans le cas le plus simple. Le bloc d’ingestion doit contenir une liste des balises que vous souhaitez recevoir du service. Pour la plupart des services publics, il s’agit de la seule « isc_info_svc_line » :
const unsigned char receiveItems1[] = {isc_info_svc_line};
De plus, il a besoin d’une mémoire tampon pour demander ces informations :
unsigned char results[1024];
Après ces étapes préliminaires, nous sommes prêts à demander des informations au service dans une boucle (chaque ligne est retournée en un seul appel à query()
) :
do
{
svc->query(&status, 0, NULL,
sizeof(receiveItems1), receiveItems1,
sizeof(results), results);
} while (printInfo(results, sizeof(results)));
Dans cet exemple, nous supposons que la fonction printInfo()
renvoie TRUE tant que le service renvoie un bloc de résultat contenant la ligne de sortie suivante, c’est-à-dire jusqu’à la fin du flux de données du service. Le format du bloc de résultat varie d’un service à l’autre, et certains services, tels que gsec, créent des formats historiques qui ne sont pas triviaux pour l’analyse, mais qui dépassent le cadre de ce chapitre. L’exemple de travail minimal printInfo()
est présent dans l’exemple 09.service.cpp
.
La même méthode de requête est utilisée pour récupérer des informations sur le serveur, mais dans ce cas, la fonction de requête n’est pas appelée dans une boucle, c’est-à-dire que le tampon doit être suffisamment grand pour contenir toutes les informations à la fois. Ce n’est pas trop difficile, car ces appels ne renvoient généralement pas beaucoup de données. Comme dans le cas précédent, vous devez commencer par placer les éléments nécessaires dans le bloc d’accueil — dans notre exemple, il s’agit de isc_info_svc_server_version
:
const unsigned char receiveItems2[] = {isc_info_svc_server_version};
Un tampon de résultat existant d’un appel précédent peut être réutilisé. Dans ce cas, vous n’avez pas besoin d’une boucle :
svc->query(&status, 0, NULL,
sizeof(receiveItems2), receiveItems2,
sizeof(results), results);
printInfo(results, sizeof(results));
Une fois les tâches de service terminées, n’oubliez pas de désactiver le service :
svc->detach(&status);