JobLock&DB2

J’avais publié en avril 2013, sur le site XDocs400.com, un article dans lequel j’expliquais comment récupérer la liste des travaux IBM i verrouillant une table DB2. Suite à la migration de mon blog sur un autre serveur et surtout sur un autre gestionnaire de blog, le lien vers l’article complémentaire suivant était rompu, c’est la raison pour laquelle je le republie aujourd’hui.

La technique – que j’ai présentée dans l’article posté sur le site XDocs400.com – consiste à écrire un programme RPG qui va faire appel à une API IBM, pour générer une liste des verrouillages dans une table DB2 temporaire. Un paramètre optionnel permet d’indiquer au programme RPG si l’on souhaite qu’il nous renvoie les informations sous la forme d’un « result set ».

Mon objectif en écrivant ce programme est de pouvoir mettre la liste des verrouillages à la disposition d’un script PHP, qui va afficher l’information dans une page HTML. A noter que l’affichage dans une page HTML n’est pas le seul usage que l’on pourrait faire de cette solution. On pourrait tout aussi bien écrire un script PHP qui mettrait l’information à disposition sous forme d’un service web, en renvoyant les informations au format XML ou JSON.

Le présent article est donc un complément, dans lequel je vais expliquer comment utiliser en PHP la procédure stockée DB2 (et donc le programme RPG sous-jacent), et comment je vais exploiter les données renvoyées par le « result set » renvoyé par la procédure stockée.

Dans l’exemple que je fournis ci-dessous, j’ai utilisé comme connecteur la classe PDO, couplée au « iSeries Access ODBC Driver », driver qui est fourni en standard avec le logiciel « System i Navigator » d’IBM. Ce script est donc particulièrement adapté pour un usage sur un ZendServer tournant sur plateforme Windows ou Linux.

Si vous souhaitez effectuer la même opération avec un script s’exécutant en environnement IBM i (donc sur un ZendServer pour IBMi), alors vous devrez travailler avec l’extension « ibm_db2 » et avec le jeu de fonctions qui lui sont rattachées (comme db2_connect(), db2_prepare(), etc…). Autre solution, utiliser l’extension « odbc », et le jeu de fonctions correspondant (odbc_connect(), etc…). Mais dans ce cas, vous ne pourrez pas récupérer le result set renvoyé par la procédure stockée, et vous devrez exécuter une requête complémentaire, de type SELECT, sur la table temporaire générée par le programme RPG (comme je l’ai indiqué dans l’article déposé sur XDocs400.com).

/**

* Configuration de la connexion à la base de données

* (dans la pratique, il est recommandé d’externaliser le code de configuration

* dans un script indépendant, appelé via la fonction « require_once »)

*/

$system = ‘xxx.xxx.xxx.xxx’; // nom ou adresse IP de la plateforme IBM i

$database = ‘votre bibliothèque programme’; // nom de la bibliothèque IBM i contenant la procédure stockée DB2

$dsn = « odbc:DRIVER={iSeries Access ODBC Driver};SYSTEM=$system;DBQ=$database« ;

$user = ‘votre profil utilisateur IBM i’; //

$password = ‘mot de passe associé à votre password’;

/**

* Ouverture de la connexion

*/

try {

$db = new PDO($dsn, $user, $password);

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) {

echo ‘Connection en erreur: ‘ . $e->getMessage() . ‘<p/>’;

}

/**

* Paramètres d’appel de la procédure stockée

* (dans la pratique, ces paramètres pourraient

* être transmis via un formulaire)

*/

$objname = ‘le nom de votre table DB2 ici’; // nom court uniquement

$objlib = ‘la bibliothèque de votre table DB2’; // nom court uniquement

$objtype = ‘*FILE’;

$member = ‘*ALL’;

$resultset = ‘YES’; // « YES » pour obtention d’un « result set »

echo ‘<br />Liste des « locks » sur : ‘ . trim($objlib) . ‘/’ . trim($objname) . ‘<br />’;

/**

* Définition des colonnes du tableau HTML

*/

$colnames = array(

‘JOB_NAME’,

‘JOB_USER_NAME’,

‘JOB_NUMBER’,

‘LOCK_STATE’,

‘LOCK_STATUS’,

‘LOCK_TYPE’,

‘MEMBER_NAME’,

‘SHARE’,

‘LOCK_SCOPE’

);

/**

* Affichage de l’entête du tableau HTML

*/

echo ‘<table border= »1″ cellspacing= »0″ cellpadding= »5″ >’ . PHP_EOL;

echo ‘<tr class= »header-row »>’;

echo ‘<td>’;

echo join(‘</td><td>’, $colnames);

echo ‘</td></tr>’ . PHP_EOL;

/**

* Requête d’appel de la procédure stockée

*/

$sql = « CALL APIOBJLCKP (? , ? , ? , ? , ?) »;

try {

/**

* Définition des paramètres d’appel de la procédure et exécution de la requête

*/

$st = $db->prepare($sql);

$st->bindParam(1, $objname);

$st->bindParam(2, $objlib);

$st->bindParam(3, $objtype);

$st->bindParam(4, $member);

$st->bindParam(5, $resultset);

$st->execute();

if ($st) {

/**

* Traitement du « result set » renvoyé par le programme RPG

*/

do {

$rows = $st->fetchall(PDO::FETCH_ASSOC);

foreach ($rows as $row) {

echo ‘<tr>’;

foreach ($row as $col => $value) {

echo ‘<td>’ . trim($value) . ‘</td>’ . PHP_EOL;

}

echo ‘</tr>’ . PHP_EOL;

}

} while ($st->nextRowset()); // passage au « result set » suivant

}

} catch (PDOException $e) {

if ($e->getCode() == 24000) {

echo ‘Aucune donn&eacute;e disponible pour le programme indiqu&eacute;<br/>’;

} else {

echo ‘Erreur grave autre que 24000 :<br/>’;

echo ‘Error : ‘ . $e->getMessage() . ‘<br/>’;

echo ‘Code : ‘ . $e->getCode() . ‘<br/>’;

echo ‘File : ‘ . $e->getFile() . ‘<br/>’;

echo ‘Line : ‘ . $e->getLine() . ‘<br/>’;

echo ‘Trace : ‘ . $e->getTraceAsString() . ‘<br/>’;

}

}

echo ‘</table>’ . PHP_EOL;

La solution proposée dans cet article peut se décliner pour un grand nombre d’API. Vous pouvez par exemple envisager de l’utiliser pour permettre l’affichage en mode « web » – et même la gestion si vous le souhaitez – du planning de travaux IBM i. Mais ce n’est qu’un exemple parmi tant d’autres.

Si vous souhaitez mettre en oeuvre ce type de solution dans votre environnement IBM i, et que vous souhaitez bénéficier d’une formation, ou de sessions de transfert de compétence, je vous invite à prendre contact avec le service commercial de Six-Axe Consultants, soit par téléphone, soit en passant par le formulaire de demande de renseignement. Je prendrai alors contact avec vous pour que nous déterminions ensemble votre besoin, et que je puisse vous proposer la prestation la mieux adaptée.