[Perl] Dbix::Class

Philippe Bruhat (BooK) philippe.bruhat at free.fr
Mar 28 Juin 12:14:56 CEST 2016


On Tue, Jun 28, 2016 at 10:54:08AM +0200, Hugues wrote:
> le search ne marche pas
> 

Les messages d'erreur sont là pour t'aider.

> {
>    "error" : "DBIx::Class::ResultSet::search_rs(): Odd number of arguments to search at admin.pm line 314\n",
>    "exception" : "DBIx::Class::Exception"
> }

"Odd number of arguments to search" : si on regarde la doc, le arguments
attendus sont:

https://metacpan.org/pod/DBIx::Class::ResultSet#search

   Arguments: $cond | undef, \%attrs?

La méthode attend un paramètre scalaire (de la forme acceptée par
SQL::Abstract, ou bien undef), suivi d'un paramètre optionel (une
référence à un hash) contenant les attributs de la requête.

> my $mobile   = schema('DB')->resultset('Employe')->search( @where , { rows => 1});
> 

Ici, @where contient deux éléments, donc l'appel revient à

    ->search( $where[0], $where[1], { rows => 1 } );

ce qui est bien impair.

> my $mobile   = schema('DB')->resultset('Employe')->search( \@where , { rows => 1});
> 

Ici, $cond est \@where, une référence à un table. Le second paramètre,
\%attr vaut bien { rows => 1 }. L'appel est sémantiquement correct.

> erreur
> 
> Can't locate object method \"prenom\" via package \"DBIx::Class::ResultSet
> 

Là encore, le message d'erreur est assez informatif : c'est quoi cette méthod
prenom que le code cherche à appeler sur la classe DBIx::Class::ResultSet ?
Il n'y a rien dans le code que tu as montré qui permette de déduire quoi
que ce soit à ce sujet.

> 
> le find marche,  mais ne passe qu'un seul des deux éléments du where

Comme indiqué dans la documentation: https://metacpan.org/pod/DBIx::Class::ResultSet#find

    Finds and returns a single row based on supplied criteria.

Autrement, le fait qu'il renvoie un seul élément est le comportement attendu.

> l'autre solution c'est :
> 
> my $mobile = schema('DB')->resultset('Employe')->find( { TEL_MOBILE =>
> $l->{'caller'}->{'number'} }, { rows => 1});
> my $tel    = schema('DB')->resultset('Employe')->find( { TELEPHONE  =>
> $l->{'caller'}->{'number'} }, { rows => 1});

L'attribut { rows => 1 } dit explicitement à DBIx::Class que tu veux
une seule ligne (c'est l'équivalent de LIMIT 1), search ne renverra donc
jamais plus d'une ligne. Si ça se trouve, ça "marche" depuis le début,
et ton programme te donne la bonne réponse à une mauvaise question...

Pour faciliter le déboggage avec DBIx::Class, et voir un peu la tête
des requêtes exécutées, je te conseille l'emploi de la variable
d'environnement DBIC_TRACE. Quand elle est à 1, DBIC affiche les requête
sur la sortie d'erreur standard. Je pense que le LIMIT 1 t'aurais sauté
aux yeux.

Je vais conclure en citant Klortho le magnifique (cf. Acme::MJD) :

    #11919 No.  You must believe the ERROR MESSAGE.  You MUST believe the error message.

et

    #11920 The error message is the Truth.  The error message is God.

-- 
 Philippe Bruhat (BooK)

 The emptier the brain is of facts, the easier it is to fill with nonsense.
                                    (Moral from Groo The Wanderer #89 (Epic))


Plus d'informations sur la liste de diffusion Perl