MCPkit/MySQL: retourner des champs dans un NSArray

narknark Membre
avril 2009 modifié dans API AppKit #1
Bonjour à  vous, je me lance...

J'utilise le framework MCPkit pour la connexion/gestion d'une base de données MySQL. ça va de soi... et jusqu'ici tout va bien.

J'ai une table 'user', très simple:


user_id 
user_login 
user_passwd 
user_level 


1
admin
d64f7d5b0ba1179057ebc27a4e1d31d2
9


1
guest
084e0343a0486ff05530df6c705c8bb6
0



Je souhaite récupérer un NSArray de tout les login (user_ login) de ma table user:
<br />MCPResult *result;<br />NSArray *users;<br />	<br />result = [mySQLConnection queryString:@&quot;SELECT user_login FROM user&quot;]; // J&#39;exécute ma requête<br />users&nbsp; = [result fetchRowAsArray]; // Je retourne le tout dans mon tableau<br />	<br />NSLog(@&quot;%@&quot;, [users description]); // J&#39;affiche dans les logs pour voir le résultat<br />


Le problème survient à  ce moment là , je n'ai qu'un seul champ dans mon tableau:
<br />2009-04-24 02:02:58.301 iGroup[5617:10b] <br />(<br />&nbsp; &nbsp; admin<br />)<br />


Alors qu'il devrait me retourner:
<br />2009-04-24 02:02:58.301 iGroup[5617:10b] <br />(<br />&nbsp; &nbsp; admin,<br />&nbsp; &nbsp; guest<br />)<br />


J'ai aussi essayé avec la méthode -(NSArray*)getQuery:(NSString*)aQuery colWithName:(NSString*)aColName et j'ai le même souci: il ne me retourne que le premier champ.
J'ai aussi essayé d'autres requêtes: pareil.

Quelqu'un utilise t'il ce framework afin de me dire si il y a quelque chose que je n'ai pas compris?
Merci d'avance.

Réponses

  • AliGatorAliGator Membre, Modérateur
    06:50 modifié #2
    Hello,

    Je ne connais pas du tout ce framework, mais rien qu'en me basant sur les noms des méthodes, qui semblent explicites, le comportement me parait normal.

    En effet, tu utilises la méthode [tt]fetchRowAsArray[/tt] qui comme son nom doit l'indiquer, te retourne un NSArray représentant... la row (la ligne). Avec une entrée du coup par... champ retourné par ta requête.

    Là  comme ta requête SQL ne demande qu'un champ ([tt]SELECT user_login FROM user[/tt]), le tableau retourné n'a qu'une entrée. Si tu avais demandé [tt]SELECT user_login, user_passwd FROM user[/tt], il t'aurait retourné un tableau non pas juste avec [tt]{ admin }[/tt] dedans, mais avec [tt]{ admin, d64f7d5b0ba1179057ebc27a4e1d31d2 }[/tt] !


    Donc fetchRowAsArray fait bien son boulot... c'est juste ce c'est sans doute pas la méthode adaptée pour ce que toi tu veux.
    Il ne faut pas oublier que rien ne dit que tu n'auras qu'un champ dans ta requête SELECT : donc je doute qu'il existe une méthode dans le framework pour retourner un NSArray directement de user_logins : quand l'auteur a imaginé les méthodes de son framework, il a dû les faire les plus générique possible, donc pour les cas où il y a un nombre quelconque de champs demandés dans la requête SELECT  ;)


    Il ne te reste plus que :
    • soit à  fouiller dans le framework MCPKit voir s'il n'y a pas une méthode qui retourne un NSArray de NSArray (un NSArray de "lignes", chaque ligne étant elle même un NSArray contenant les valeurs de chaque colonne demandée... même si dans le cas de ta requête, chaque NSArray de ce 2e niveau n'aura qu'une entrée)...
    • Ou sinon faire une boucle "for i" sur le nombre de résultats (de rangées) retournés par ta requête, puis demander à  récupérer la valeur du premier (et certes unique) champ de la rangée i pour la mettre dans un NSMutableArray toi-même (et y'a de fortes chances que ce soit, si ce n'est la seule solution, au moins la plus efficace)
  • narknark Membre
    06:50 modifié #3
    Hey,

    En effet, je te remercie beaucoup, c'était bien la méthode qui n'était pas la bonne, ça marche très bien avec la méthode: fetchColWithName:

    Par contre, je te corrige, la requête SQL "SELECT user_login FROM user" ne retourne pas qu'un seul champ, mais bien tout les champs de ma table.

    C'est la méthode fetchRowAsArray: qui interprète mal le jeu de résultat, en ne prenant en compte que le premier champ de la table, ce qui logique après une bonne nuit de sommeil: fetchRowAsArray: où "Row" est au singulier.

    Merci encore pour le coup de main. J'avance bien du coup. ;-)

    NOTA: Ce framework est pas mal du tout, mais il mériterait une bonne documentation (liens d'exemples de code morts sur le site). Cela éviterai ce genre de confusion...

  • AliGatorAliGator Membre, Modérateur
    06:50 modifié #4
    De rien ;)

    Par contre je me sens obligé de te corriger : ta requête retourne bien qu'un champ, (mais plusieurs fiches).
    Mais bon ce n'est qu'une question de vocabulaire.

    Dans le monde des bases de données, on appelle un "champ" une colonne si tu veux. Ainsi, ta table "users" est constituée de 4 champs : user_id, user_login, user_passwd et user_level.
    Dans cette table, au fur et à  mesure que tu la remplis (avec des requêtes INSERT), tu rajoutes des "fiches", ou des "rangées" ou "entrées" (les 3 se disent) à  ta table.
    Par exemple si le 3e user a pour nom "Toto", on dira que le champ "user_login" de la 3e entrée de ta table vaut "Toto".


    Après, certains frameworks (et ça a l'air d'être le cas du tiens, ce qui est pratique surtout dans ton cas) considèrent aussi les colonnes : en fait une colonne c'est juste la valeur d'un champ donné pour chacune des fiches du résultat. C'est à  dire par exemple qu'on appelle la colonne "user_login" l'ensemble formé par la valeur du champ "user_login" sur la fiche 1 + la valeur du champ "user_login" sur la fiche 2 + celle sur la fiche 3... etc.



    Voilà , donc après quand je disais dans mon post plus haut
    donc je doute qu'il existe une méthode dans le framework pour retourner un NSArray directement de user_logins
    j'avais apparemment tort, puisque je ne pensais pas que ton framework proposerait une méthode du genre fetchColWithName, alors qu'apparemment c'est le cas... donc tant mieux :) (Mais c'est pas si fréquent que ça puisque ce n'est pas une manipulation unitaire en SQL, donc j'imagine bien qu'en interne la méthode fetColWithName doit certainement boucler sur les fiches pour récupérer la valeur du champ de chacune et générer ainsi ton tableau)
  • narknark Membre
    06:50 modifié #5
    Ok ok! Merci des précisions!

    J'étais persuader que l'on appelé champs la "ligne" (contenu). En effet, c'est une histoire de vocabulaire! 

    En tout cas, ça marche, et c'est bien pratique.
    Merci AliGator. ;)

    PS: Maintenant je veux stocker des images, ça se complique! B)
  • AliGatorAliGator Membre, Modérateur
    06:50 modifié #6
    Pour t'aider à  rechercher dans ton framework, regarde autour du mot clé "BLOB", utilisé pour stocker des données binaires (genre une image, enfin sa TIFFRepresentation)

    (BLOB = accronyme pour "Binary Large OBject")
  • narknark Membre
    06:50 modifié #7
    Yep, je suis dessus là . :)

    J'arrive à  stocker dans la base:
    NSImage -> NSData -> Blob

    Mais ça marche pas encore dans l'autre sens:
    Blob -> NSData -> NSImage

    Mais ça va venir. ;)
    Merci!
  • AliGatorAliGator Membre, Modérateur
    06:50 modifié #8
    Le conseil du jour, essaye déjà  NSImage -> NSData -> NSImage, voir si tu arrives à  qqch.
    Comme ça si y'a un souci lors du passage au BLOB, style bug avec ton framework par exemple, genre application d'une conversion d'encodage de texte alors qu'il devrait pas sur des données binaires...), je pense vraiment pas que ce soit le cas... mais on est jamais trop prudent :D
  • narknark Membre
    avril 2009 modifié #9
    Héhé, tu as vu juste, c'est bel et bien le cas. Problème de type data.

    Je crois avoir trouvé ici ( http://www.cocoabuilder.com/archive/message/cocoa/2008/5/8/206129 ) ce qu'il me fallait, je met en application là . :)

    Les deux seules méthodes orienté BLOB dans MCPKit sont:
    - (BOOL) isBlobAtIndex:(unsigned int) index;
    - (BOOL) isBlobForKey:(NSString *) key;
    Elles ne me sont pas très utiles pour l'instant. :s
  • AliGatorAliGator Membre, Modérateur
    06:50 modifié #10
    Comme je vois que tu sembles savoir creuser et lire dans la doc, n'hésite pas si tu ne trouves pas l'info et reste bloqué à  contacter l'auteur du framework.
    Je sais que la plupart répondent (selon leur disponibilité bien sûr)... du moment que c'est une question fondée (donc que tu as bien cherché avant et est bloqué, parce que si c'est un truc dont tu peux trouver direct en lisant la doc -- qu'ils ont pris du temps à  faire et tout -- par contre je comprendrais que ça les saoule de redire ce qu'il y est mis :))

    Par exemple j'avoue ne pas avoir regardé/cherché ledit framework, mais si ça se trouve il n'est pas complet sur ces points, genre l'auteur indique qu'il n'a pas encore eu le temps de gérer les champs de type BLOB et que ça viendra à  la prochaine version, ou un truc du genre... je te laisse creuser ;)
  • narknark Membre
    06:50 modifié #11
    Oui, j'ai déjà  eu ce genre de réflexe sur des projets open-sources, et cela m'a toujours été très utile, quand l'auteur est coopérant... :)

    Pour info, j'ai trouvé une solution plus simple que les BLOB, moins performante, mais pour l'instant cela me va très bien et ça marche:

    NSImage -> NSData -> NSString (base64) le tout dans un champ 'TEXT'.
    NSString (base64) -> NSData -> NSImage pour récupérer l'image.
    NOTA: J'utilise CocoaDevAdditions pour le base64.

    Cela fait beaucoup de convertions, mais bon, la programmation ne se résume-t-elle pas à  des convertions de types?  >:D

    Still thanks a lot for tips.
    Google know all. :)
Connectez-vous ou Inscrivez-vous pour répondre.