Comment puis-je obtenir esqueleto pour générer une chaîne SQL pour moi?

86

Comment puis-je obtenir esqueleto pour générer une chaîne SQL à partir d'une frominstruction?

La documentation de toRawSqldit que "vous pouvez simplement activer la journalisation des requêtes de persistant". J'ai essayé toutes les formes possibles MonadLoggerque je pouvais comprendre, mais cela n'a jamais imprimé de SQL. La même documentation dit également que "l'utilisation manuelle de cette fonction ... est possible mais fastidieuse". Cependant, aucun constructeur du type, ni aucune fonction renvoyant des valeurs du type, ne QueryTypesont exportés. J'ai réussi à contourner cela en remarquant que QueryTypec'est un newtypeet en utilisant unsafeCoerce!

J'ai également été obligé de fournir un Connection(que j'ai obtenu via SQLite) même s'il ne devrait pas être nécessaire de me connecter à une base de données pour générer le SQL.

Voilà ce que j'ai. Il doit y avoir un meilleur moyen.

withSqliteConn ":memory:" $
    \conn -> return $ toRawSql SELECT
                               (unsafeCoerce ((const mempty)
                                  :: a -> Text.Lazy.Builder.Builder))
                               (conn, initialIdentState) myFromStatement)

http://hackage.haskell.org/package/esqueleto-1.3.4.2/docs/Database-Esqueleto-Internal-Sql.html

Tom Ellis
la source
2
Je pense que la raison pour laquelle vous devez lui donner une connexion est qu'elle est polymorphe sur la base de données et utilise des SqlPersistinstances inférées pour générer des chaînes SQL spécifiques à la base de données .
Thomas
2
La connexion et le type de base de données sous-jacente sont cependant des choses différentes. Il devrait être possible de générer purement la chaîne SQL.
Tom Ellis

Réponses:

2

Depuis que cette question a été publiée, esqueletoa subi un certain nombre de révisions majeures. Depuis la version 2.1.2 , et plusieurs versions antérieures, le QueryType aparamètre qui nécessitait votre unsafeCoercea été supprimé de toRawSql; cette verrue majeure n'est plus nécessaire.

Tel qu'actuellement mis en œuvre, un Connectionest requis. Je crois que, comme indiqué par le nom de synonyme de type IdentInfo, esqueletoutilise ceci pour créer des identificateurs dans la requête. Il peut, par exemple, ajouter le nom de la base de données. Je n'ai pas vraiment exploré la source suffisamment en profondeur. Qu'il suffise de dire que passer une fausse connexion (c'est-à-dire undefined) ne fonctionne pas; Je ne sais pas si une connexion simulée pourrait être mise en œuvre. Votre solution semble réalisable.

Le reste de votre solution devrait fonctionner correctement. Puisqu'il toRawSqls'agit explicitement d'une fonction interne, l'API semble ici raisonnable. Bien que d'autres notent qu'il "devrait" être possible de générer une chaîne indépendante de la connexion, cela apparaît en dehors de la portée de toRawSql.

Vous mentionnez que vous ne pouvez pas utiliser MonadLoggercomme recommandé. Qu'avez-vous essayé et que s'est-il passé?

Christian Conkle
la source
Je ne me souviens pas de ce que j'ai essayé MonadLoggermalheureusement. C'était il y a assez longtemps.
Tom Ellis
Avez-vous un projet de test à portée de main pour voir s'il toRawSqlfonctionne maintenant pour le cas d'utilisation de cette question? J'ai mis en place un esqueletoenvironnement pour l'essayer, mais je n'ai pas eu le temps de comprendre persistentet toutes les autres machines pour réellement construire et consommer une vraie requête.
Christian Conkle
Je n'ai aucune sorte d'environnement de test ou de projet esqueleto du tout, désolé.
Tom Ellis