Créer une application Perl autour de MySQL : DBIx::Class (2/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
168
|
Mois de parution
février 2014
|
Domaines


Résumé

Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL. Reste maintenant à utiliser Perl et DBIx::Class pour accéder aux données de cette base.


Body

Introduction

Petit rappel de l'épisode précédent : notre hacker favori a expliqué comment mettre en place dans une base de données MySQL les tables et relations qui assureront la persistance des données de production.

Pour rappel, voici un résumé des tables créées. Le code complet en SQL est disponible sur le GitHub de l'auteur [GITHUBADOD] :

- Table « Packages », avec « id » et « name »,

- Table « Products » avec « id », « name » et « home_page »,

- Table « ProductVersions » avec « id », « version », « product_id », « date », « log », « status »,

- Table « TarballPackages » avec « tarball_id » et « package_id »,

- Table « TarBalls » avec « id », « url » et « product_version_id ».

Chaque colonne finissant en « _id » est une clef étrangère sur la colonne « id » d'une autre table. Par exemple, « product_id » est une clef étrangère sur la colonne « id » de la table « Products ».

1. Accès DB avec Perl

On a maintenant une jolie base de données toute configurée pour recevoir les données de produits et leur myriade de versions. Mais, il s'agit maintenant d'y accéder à partir de notre application.

1.1 Les ORM ou comment ne pas se compliquer la vie ?

Un des premiers réflexes qu'on peut avoir est d'écrire une application générant tout le code SQL nécessaire pour gérer les données. (SQL est le langage de manipulation des bases de données). Au début, ça va suffisamment vite à coder pour rassurer le chef, mais ça finit souvent en un seau de code difficile à maintenir (c'est du vécu), car l'application mélange deux langages avec des paradigmes différents.

Bien des gens brillants se sont penchés sur le problème de relier les données d'un programme avec celles d'une base de données. Les ORM ou Object Relational Mapper, qu'on peut traduire en Passerelle Objet Relationnel (dommage que l'acronyme ne soit pas très vendeur...) permettent de minimiser le code à écrire (aussi bien en Perl qu'en SQL).

Avec un peu de chance, un ORM vous permettra d'écrire votre application sans avoir à écrire une seule ligne de SQL. Mais attention, des connaissances en SQL sont quand même fortement conseillées : les contraintes mises en place sur la base (c'est-à-dire index unique, clef étrangère) vont provoquer des erreurs lors de la mise au point. Ces erreurs sont montrées avec les instructions SQL rejetées par la DB. À vous d'interpréter ces erreurs SQL pour trouver les instructions Perl erronées dans votre programme.

Pour le projet, l'ORM Perl DBIx::Class a été choisi. Il contient toutes les notions requises pour faire de la programmation objet moderne. Le seul problème est qu'il faut lui spécifier la structure de la base de données pour qu'il puisse générer les classes et les méthodes qui feront l'interface avec la base.

Et là, miracle, un codeur fou (celui à qui personne n'a dit que c'était impossible) a créé une application qui interroge la base de données, en extrait le schéma et génère toutes les déclarations qui vont bien pour DBIx::Class : que du bonheur ! Il s'agit de dbicdump fourni avec DBIx::Class::Schema::Loader.

1.2 Installation

Sous Debian, il faudra installer les paquets libdbix-class-perl et libdbix-class-schema-loader-perl (version >= 0.07015).

1.3 Génération des interfaces avec « dbicdump »

Générer l'interface Perl pour votre base de données se résume à cette commande :

dbicdump -o dump_directory=./lib -o use_moose=1 \

-o components='["InflateColumn::DateTime"]' \

Integ::Schema dbi:mysql:Integ root s3cr3t

Voici quelques explications sur les options :

- use_moose=1 : dbicdump peut générer des classes Perl classiques ou des classes Moose (basées sur MooseX:NonMoose) ;

- components='["InflateColumn::DateTime"]' : cette option est fortement recommandée dans la documentation de DBIx::Class::Schema::Loader. Elle permet de gérer toute colonne de type DATE à travers un objet DateTime, ce qui est très pratique.

- Les 3 derniers arguments permettent à dbicdump de se connecter sur la base.

Une fois cette commande finie, on obtient :

$ find . -name *.pm

./lib/Integ/Schema.pm

./lib/Integ/Schema/Result/Package.pm

./lib/Integ/Schema/Result/ProductVersion.pm

./lib/Integ/Schema/Result/TarBall.pm

./lib/Integ/Schema/Result/TarballPackage.pm

./lib/Integ/Schema/Result/Product.pm

Chaque fichier contient la documentation en format Pod et toutes les instructions DBIx::Class pour créer la classe d'accès à votre base de données. Prenons par exemple la classe Integ::Schema::Result::ProductVersion et voyons les parties les plus importantes :

package Integ::Schema::Result::ProductVersion;

use Moose;

use MooseX::NonMoose;

use MooseX::MarkAsMethods autoclean => 1;

extends 'DBIx::Class::Core';

La classe d'interface est bien une classe Moose héritant de la classe DBIx::Class::Core (celle-ci n'est pas une classe Moose).

Le code suivant déclare la table et les composants chargés :

__PACKAGE__->table("ProductVersions");

__PACKAGE__->load_components("InflateColumn::DateTime");

Voici la déclaration des colonnes. add_columns va aussi ajouter les méthodes correspondantes (« accessors ») de façon à pouvoir écrire print $obj->version; ou $obj->version(1.002).

__PACKAGE__->add_columns(

"id",

{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },

"version",

{ data_type => "varchar", is_nullable => 0, size => 32 },

"product_id",

{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },

);

Déclaration de la relation entre Products et ProductVersions :

__PACKAGE__->belongs_to(

"product",

"Integ::Schema::Result::Product",

{ id => "product_id" },

{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },

);

Voici la déclaration de la relation entre Products et TarBalls. Le code généré contient aussi des indications sur les clés étrangères et leur contraintes :

__PACKAGE__->has_many(

"tar_balls",

"Integ::Schema::Result::TarBall",

{ "foreign.product_version_id" => "self.id" },

{ cascade_copy => 0, cascade_delete => 0 },

);

Le commentaire suivant est important, car il définit la zone à partir de laquelle vous pouvez apporter vos propres modifications. Cette zone peut servir à définir de nouveaux attributs ou méthodes pour votre classe d'interface.

# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-02-07 20:31:16

# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/R7o/BCNPW4v3IK8gUkIxQ

Si vous avez à modifier le schéma... Non, je reprends... Quand vous aurez à modifier le schéma de la DB pour suivre les besoins de vos clients, il suffira de relancer la commande dbicdump pour obtenir une nouvelle interface. La zone « libre » ne sera pas touchée. dbicdump ira même jusqu'à vérifier la syntaxe du fichier résultant.

1.4 Extension de la classe d'interface

En général, le premier réflexe est d'ajouter dans cette zone modifiable toutes les méthodes dont on a besoin. Mais c'est un mauvais réflexe. Pour pouvoir gérer correctement votre projet dans le temps et tester la logique métier indépendamment de la DB, il vaut mieux séparer clairement l'interface de la DB de la logique métier.

Le plus simple, quand on utilise Moose, est d'étendre la classe en ajoutant un rôle à la classe générée :

# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-31 15:49:49

# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:NiaYh10AJwYDWMg5lwliVA

# contient mon code à moi pour créer les pages HTML

with 'Integ::HTML::ProductVersion' ;

__PACKAGE__->meta->make_immutable;

1;

Dans le rôle Moose, on peut aussi ajouter des attributs pour enrichir la classe. Ces attributs ne seront pas stockés dans la base de données. Curieusement, les valeurs par défaut spécifiées dans les déclarations des attributs sont ignorées. Il faut utiliser lazy_build => 1 (ou lazy => 1, build => '_build_toto') et spécifier une valeur par défaut avec une fonction du genre sub _build_toto { return "TOTO"; }.

1.5 Connexion à la base

La connexion à la base se fait directement à partir de la classe générée par dbicdump. On prépare d'abord une variable pour spécifier à DBI (le gestionnaire de la connexion à la DB) où se connecter :

my $integ_dsn = 'dbi:mysql:database=Integ;host=localhost;port=3306';

Puis, on se connecte :

my $integ_schema = Integ::Schema->connect(

$integ_dsn, 'integ_mgr', $password,

{ RaiseError => 1 }

);

Pour l'accès en lecture seule, le compte integ_user n'ayant pas de mot de passe, il suffira de passer une chaîne vide en lieu de mot de passe :

my $integ_schema = Integ::Schema->connect(

$integ_dsn, 'integ_user', '',

{ RaiseError => 1, quote_names => 1 }

);

L'option quote_names est nécessaire, car la colonne home page contient un espace.

1.6 Lecture des données

Maintenant qu'on a une connexion toute neuve à la base, on va pouvoir passer aux choses sérieuses.

Avant de continuer, il faut préciser qu'un nom de produit fictif sera utilisé dans cet article. Toute ressemblance avec un produit existant ou ayant existé serait fortuite et involontaire. En effet, par les temps qui courent, il vaut mieux être prudent avec les marques déposées si on ne veut pas se prendre un procès sur la courge. Tiens, ça me donne une idée : notre produit va s'appeler « OpenCourge ». Avec ça, not' rédac-chef favori devrait dormir tranquille ;-)

Pour des raisons pédagogiques, on va d'abord se pencher sur l'extraction de données de la base avant de voir l'écriture. Comme la base est vide, on va ajouter en SQL un produit et une version pour pouvoir tester la lecture avec DBIx::Class. Je vous propose :

$ myqsl -u integ_mgr -p Integ

...

mysql> insert into Products set name="OpenCourge" ;

mysql> insert into ProductVersions set version=1.01, product_id=1, date = "2012-08-20" ;

mysql> insert into ProductVersions set version=1.02, product_id=1, date = "2012-09-27" ;

mysql> quit ;

Première étape pour lire dans la base, il faut trouver le produit OpenCourge. On va d'abord récupérer un objet DBIx::Class::Resultset qui donne accès à la table Products :

my $product_rs = $integ_schema ->resultset('Product');

Notez que le nom de la table est « Products » avec un 's', mais qu'on cherche « Product » (sans 's') dans le schéma. En effet, DBIx::Class::Schema::Loader passe au singulier le nom de la table (qui représente un ensemble de données) pour créer le nom de la classe d'interface (qui représente plutôt un type de données). Pour plus de détails, voir la doc de DBIx::Class::Schema::Loader::Base.

Une fois qu'on a accès à l'ensemble des produits à travers $product_rs, on peut rechercher un produit spécifique :

my $product_row = $product_rs ->find ( { name => 'OpenCourge' } );

La méthode find va renvoyer un objet DBIx::Class::Row référençant la ligne de la table Products ayant pour nom OpenCourge. Comme la colonne Name a un index UNIQUE, on est sûr de référencer la bonne ligne. Le SQL exécuté sera un simple select * from Product where name='OpenCourge' ;.

Surtout, n'oubliez pas les accolades, sinon find chercherait une clé primaire basée sur deux colonnes nommées « name » et « OpenCourge ».

1.7 Utilisation de la relation « 1-vers-n »

On a retrouvé notre produit favori dans la base, il s'agit maintenant de récupérer les versions disponibles. On rappelle que ces versions sont stockées dans leur propre table et liée à la table « Products » avec la colonne « product_id ». La documentation de la classe générée Integ::Schema::Result::Product indique que dbicdump a matérialisé cette relation avec la méthode « product_versions ».

Ainsi, la ligne suivante va renvoyer un objet DBIx::Class::Resultset contenant les versions attachées à notre produit :

my $product_version_rs = $product -> product_versions;

say $product_version_rs->count ; # 2

Dans cet ensemble de versions, on peut chercher une version spécifique :

my $v = $product_version_rs->find({version => '1.02'}) ;

say $v->date->ymd ; # 2012-09-27

Ou chercher des versions selon un critère :

my $v_rs = $product_version_rs->search({date => { like => '2012%' }}) ;

say join(' ', map { $_->version } $v_rs->all) ; # 1.01 1.02

Notez que la méthode find est utilisée si le critère renvoie une seule valeur et renvoie un objet DBIx::Class::Row relié à une ligne dans la table. La méthode search concerne des recherches plus floues et renvoie un objet DBIx::Class::Resultset représentant un ensemble de lignes.

1.8 Écriture des données

Maintenant, il est temps de créer de nouvelles versions du produit dans la base à travers DBIx::Class. Pour éviter les ennuis, les instructions de création de version doivent être idempotentes. Il faut donc vérifier si la version existe déjà avant de la créer. Heureusement, DBIx::Class fournit la méthode qui permet de faire ça d'une manière concise :

say $product_version_rs->count ; # 2

$product_version_rs->find_or_create( { version => '1.04' } );

say $product_version_rs->count ; # 3

$product_version_rs->find_or_create( { version => '1.04' } );

say $product_version_rs->count ; # 3, pas de changement

1.9 Modification des données

Mettre à jour les données dans une ligne est très simple avec les méthodes fournies :

my $product_version_row = $product_version_rs -> find( { version => '1.04'} ) ;

$product_version_row -> log( "c'est mûr" );

Mettre en place la date de publication de la version demande un peu plus de précautions si on ne veut pas changer cette date chaque fois que le programme est lancé :

my $d = $product_version_row->date ;

$product_version_row->date( DateTime->now ) unless $d;

Le composant InflateColumn::DateTime va se charger de traduire l'objet DateTime en une chaîne de caractères compréhensible par MySQL.

Et pour déclarer les tarballs générés, on fera :

my $tarball_obj = $product_version_row

-> tarballs

-> find_or_create ( {

url => "http://cucurbitacée.com/repo/OpenCourge-i386.tar"

} ) ;

# http://cucurbitacée.com/repo/OpenCourge-i386.tar

say $product_version_row->tar_balls->single->url ;

Mais les informations écrites sont pour l'instant dans la mémoire du programme. Il faut les transférer dans la base :

$product_version_row -> update;

1.10 Utilisation de la relation « m-vers-n »

Pour pouvoir gérer les paquets et les tarballs, on va aborder le domaine qui rebute souvent les débutants en base de données relationnelles : la relation « plusieurs vers plusieurs », qui implique une table de liaison intermédiaire. En SQL, retrouver ses petits dans cette relation nécessite l'utilisation de jointures.

Heureusement, la classe DBIx::Class::Relationship (héritée par DBIx::Class::Core) gère ces relations et permet de masquer au programmeur les détails de la jointure (sauf en cas d'erreur) avec la fonction many_to_many.

Pour que dbicdump déclare cette liaison many_to_many, il faut une table de liaison avec :

- deux colonnes configurées en clé étrangère,

- une clé primaire faite avec ces 2 colonnes.

Attention : la génération de la relation many_to_many ne fonctionne qu'à partir de la version 0.07015 de DBIx::Class::Schema::Loader.

À défaut, vous pouvez ajouter vous-même cette relation dans la zone « libre » de la classe générée par dbicdump. Voir [MANYTOMANY] pour les détails.

Revenons-en au programme Perl. Il faut maintenant associer le tarball avec ses paquets dans la base de données. Plusieurs cas de figure peuvent se présenter :

- Vous êtes certain que le paquet n'existe pas dans la base. Dans ce cas, l'ajout est très simple :

$tarball->add_to_packages({ name => 'concombre-1.1.el5.i386.rpm'} ) ;

L'inconvénient de cette commande est qu'elle va chercher à créer une nouvelle ligne dans la table « Packages ». Si ce paquet est déjà connu, la base refusera l'insertion, car la colonne « name » a un index unique.

- Le paquet existe dans la base, mais la relation entre le tarball et le paquet n'existe pas. La méthode find_or_create_related est capable de gérer ce package qui existe peut-être :

$tarball_obj->find_or_create_related('tarball_packages',

{ package => { name => 'courgette-1.2.el5.i386.rpm' }}) ;

- Le paquet et la relation peuvent exister dans la base. C'est le cas à considérer si vous voulez obtenir un script idempotent. Dans ce cas, il faut toujours vérifier l'existence de la relation et utiliser la méthode find_or_create_related comme avant :

my $pkg_name2 = 'courgette-1.2.el5.i386.rpm' ;

if (not $tarball_obj->packages->search({name => $pkg_name2})->count) { ;

$tarball_obj->find_or_create_related('tarball_packages',

{ package => { name => $pkg_name2 }}) ;

}

Le premier cas de figure est le plus facile à traiter, mais le moins souple. À vous de choisir ce qui conviendra le mieux à votre application.

1.11 Et les jointures ?

Supposons que mon chef me demande maintenant de pourvoir lister les versions de produits qui contiennent des corrections de sécurité. Il paraît que c'est facile, les logs du paquet contiennent la mention du CVE corrigé. Il faudra, pour chaque version de produit, aller chercher le tarball associé, ses packages et chercher CVE dans le log.

Il faut donc :

- Modifier le schéma de la table « Packages » pour ajouter une colonne « log »,

- Régénérer les classes d'interface vers la base,

- Scanner les paquets pour récupérer leur log et le stocker dans la base,

- Enfin, construire une requête avec une jointure pour extraire l'information de la base.

Les trois premières étapes ne posant pas de problème particulier, on va se concentrer sur la dernière. Il faut utiliser une jointure basée sur les relations mises en place par DBIx::Class :

my $cve_rs = $integ_schema->resultset('ProductVersion')->search(

{

'package.log' => { like => '%CVE%'}

},

{

join => { tar_balls => { tarball_packages => 'package' }}

}

);

L'appel à search prend deux paramètres sous forme de « hash ref ». La jointure est spécifiée dans le deuxième « hash » : la première difficulté est que la jointure passe au travers d'une relation « many-to-many » (entre les tarballs et les paquets). DBIx::Class ne sait pas gérer la jointure en utilisant directement la relation « many-to-many » entre « TarBalls » et « Packages » (matérialisée par la méthode packages de la classe Integ::Schema::Result::Tarball).

La jointure est donc spécifiée avec les relations plus simples « has_many » et « belongs_to ». Chaque relation à traverser est représentée par un « hash ref » : il faut spécifier la jointure à partir de la table « ProductVersions » (join => {), trouver les tarballs associés (tar_balls => {), utiliser la relation tarball_packages vers la table de liaison et enfin, spécifier la dernière relation vers la table « Packages », (tarball_packages => 'package').

Le premier paramètre du search contient juste le critère de recherche. Comme l'attribut log ne fait pas partie de la table « ProductVersions », mais de la table « Packages », il faut spécifier le nom de la relation utilisée dans la jointure et le nom de la colonne (package.log). Comme on recherche un log qui contient « CVE », un simple critère comme package.log = 'CVE' > ne suffit pas, car ce critère spécifie une égalité stricte. Il faut utiliser un hash ref pour spécifier un critère assez proche du SQL : like = '%CVE%'>. En SQL, le « % » signifie « n'importe quoi ». On recherche donc une chaîne quelconque contenant « CVE » quelque part.

D'autres formes de jointure sont possibles en jouant sur la structure de données passée au join. La doc DBIx::Class::Manual::Joining contient beaucoup d'autres possibilités.

2. « Show me the code ! »

Vous trouverez sur [GITHUBADOD] un petit script pour générer le schéma (gen-schema.sh) et un petit programme de test qui reprend tout le code de cet article (test-db.pl).

3. Oui, mais qu'est-ce que je montre à mon chef ?

Résumons : on a une base de données, de quoi y accéder en Perl sans trop se fatiguer. Avec ça, on peut écrire des programmes qui tournent dans un bon vieux terminal. Pour un hacker, c'est parfait. Mais ce n'est pas bien alléchant pour mon chef. Il faudrait lui montrer un truc à la mode, genre une application web qui permette de voir et manipuler les versions de produit.

Pour remédier à ça, je vous propose de découvrir dans un prochain article comment exploiter DBIx::Class dans une application web.

Remerciements

Les Mongueurs de Perl pour leur accueil et la relecture de cet article.

Liens

[DBICLASS] Class::DBI, un ORM pour Perl : Application à la gestion de DNS, GNU/Linux Magazine n°96 (http://articles.mongueurs.net/magazines/linuxmag96.html)

[MANYTOMANY] http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Relationship.pm#many_to_many

[GITHUBADOD] https://github.com/dod38fr/glmf-article-dbix-class-web

 

Sur le même sujet

Exporter une application Godot dans différents formats

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Vous avez terminé votre application et vous souhaitez maintenant la distribuer ? Il faut donc que vous convertissiez - ou exportiez - votre programme, pour qu'il puisse être exécuté sur les plateformes cibles. Nous verrons dans cet article les exports vers le Web, Windows et Android.

L’exponentielle : sa vie, son œuvre

Magazine
Marque
GNU/Linux Magazine
Numéro
239
|
Mois de parution
juillet 2020
|
Domaines
Résumé

L’exponentielle est au cœur de nombreuses méthodes dans le domaine de la data science, et nous avons connu ces derniers mois ses effets très directement à travers la propagation du SARS-Cov-2.

Interactions dans un environnement 3D

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Pour interagir avec des éléments 3D, il va falloir créer un environnement 3D et connecter les objets à du code GDScript pour effectuer diverses actions. La partie la plus importante sera la modélisation 3D en utilisant l'IDE fourni par Godot.

Utilisez GitLab pour la gestion globale de vos projets en équipe

Magazine
Marque
Linux Pratique
Numéro
120
|
Mois de parution
juillet 2020
|
Domaines
Résumé

D’après Wikipédia, GitLab est un « logiciel libre de forge basé sur Git [1] proposant les fonctionnalités de wiki, un système de suivi des bugs, l’intégration continue et la livraison continue » [6]. Il est développé par la société GitLab Inc. et est très utilisé par les entreprises informatiques, mais aussi les centres de recherche et les équipes produisant des logiciels libres. Sa première version date d’octobre 2011 et il n’a pas cessé d’évoluer depuis. GitLab est donc une plateforme permettant d’héberger et de gérer des projets dans leur ensemble. Elle offre la possibilité de gérer ses dépôts Git et permet une gestion de tout le processus de développement de l’idée à la production. Elle propose ainsi une collaboration simple et efficace entre les différents participants d’un même projet.

Machine Learning sur des objets connectés avec TensorFlow Lite pour l’agriculture verticale

Magazine
Marque
GNU/Linux Magazine
Numéro
239
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Tout au long de cet article, nous verrons comment déployer des algorithmes de Deep Learning sur des objets connectés grâce à TensorFlow Lite. Nous verrons comment l’utiliser pour concevoir une « ferme verticale » capable de prédire et optimiser la production de légumes, aussi bien chez soi que dans des pays en voie de développement où la connexion internet est intermittente.

À la découverte de Godot

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé
  • Godot ? D'habitude on l'attend, on ne le découvre pas, comme dans la pièce de théâtre de Samuel Beckett...
  • Je parle du moteur 3D.
  • Un moteur 3D ? Non, je connais Unity, Unreal Engine, mais pas celui-là.
  • Alors, découvrons dans cet article Godot, « The game engine you waited for ».

Par le même auteur

Créer une application Perl autour de MySQL : Intégration avec Mojolicious, HTML::Tiny et HTML::FormHandler (3/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
169
|
Mois de parution
mars 2014
|
Domaines
Résumé
Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL, un ORM (DBIx:Class). Reste maintenant à fournir un serveur web pour exploiter les données de cette base.

Créer une application Perl autour de MySQL : DBIx::Class (2/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
168
|
Mois de parution
février 2014
|
Domaines
Résumé

Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL. Reste maintenant à utiliser Perl et DBIx::Class pour accéder aux données de cette base.

P... de proxy, le retour

Magazine
Marque
GNU/Linux Magazine
Numéro
152
|
Mois de parution
septembre 2012
|
Domaines
Résumé
L'article « P... de proxy» a expliqué comment utiliser tinyproxy pour se simplifier la vie sur un ordinateur nomade. Cette suite (c'est la mode au cinéma) va expliquer comment étendre la solution proposée pour gérer d'autres proxys (genre proxy-cache pour serveur de paquets) et surtout faire une commutation automatique de proxy pour atteindre le Saint-Graal des hackers : la machine s'occupe de tout et moi de rien :-)

Config::Model - Créer un éditeur graphique de configuration avec Perl (2e partie)

Magazine
Marque
GNU/Linux Magazine
Numéro
120
|
Mois de parution
octobre 2009
|
Résumé
Dans un article précédant [GLMF], nous avons vu comment créer la partie graphique d'un éditeur de configuration en précisant la structure et les contraintes des données du fichier /etc/ssh/sshd_config. Config::Model va utiliser cette structure (le modèle de la configuration de sshd_config) pour générer l'interface graphique. Mais il reste à pouvoir charger les données du fichier et les ré-écrire. Nous allons voir dans cette deuxième partie comment utiliser l'API de Config::Model pour lire et écrire les données de sshd_config.

Config::Model – Créer un éditeur graphique de configuration avec Perl (1ère partie)

Magazine
Marque
GNU/Linux Magazine
Numéro
117
|
Mois de parution
juin 2009
|
Résumé
La configuration d'une application est très souvent le premier obstacle que doit franchir un utilisateur avant de pouvoir utiliser une application. Le plus souvent, l'utilisateur est dirigé vers un fichier qu'il doit éditer avec « son éditeur favori ». Peu d'applications proposent une interface plus conviviale. Pour combler cette lacune, cet article décrit comment créer un éditeur de configuration d'une manière simple et maintenable. Dans la première partie de cet article, nous allons spécifier le modèle de sshd_config, c'est-à-dire sa structure et ses contraintes. Ce modèle permettra à Config::Model de générer l'interface graphique. Nous verrons dans une seconde partie comment lire et écrire les données de sshd_config pour les charger dans l'interface.