Como posso fazer o esqueleto gerar uma string SQL para mim?

86

Como posso fazer o esqueleto gerar uma string SQL a partir de uma frominstrução?

A documentação do toRawSqldiz que "você pode simplesmente ativar o log de consultas de persistente". Tentei todas as formas possíveis MonadLoggerque pude entender, mas nunca imprimi nenhum SQL. A mesma documentação também diz "manualmente usar esta função ... é possível, mas tedioso". No entanto, nenhum construtor do tipo, nem nenhuma função que retorne valores do tipo, QueryTypeé exportado. Consegui contornar isso observando que QueryTypeé um newtypee usando unsafeCoerce!

Também fui forçado a fornecer um Connection(que obtive via SQLite), embora não deva haver necessidade de conectar-se a um banco de dados para gerar o SQL.

Isso é o que eu tenho. Deve haver uma maneira melhor.

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
fonte
2
Acredito que o motivo pelo qual você precisa fornecer uma conexão é porque ele é polimórfico no banco de dados e usa SqlPersistinstâncias inferidas para gerar strings SQL específicas do banco de dados .
Thomas
2
A conexão e o tipo de banco de dados subjacente são coisas diferentes. Deve ser possível gerar a string SQL puramente.
Tom Ellis

Respostas:

2

Desde que esta questão foi postada, esqueletoela passou por uma série de revisões importantes. A partir da versão 2.1.2 e de várias versões anteriores, o QueryType aparâmetro que precisava de seu unsafeCoercefoi removido toRawSql; aquela grande verruga não é mais necessária.

Conforme implementado atualmente, um Connectioné necessário. Eu acredito que, como indica o nome sinônimo tipo IdentInfo, esqueletousa isso para identificadores de compilação na consulta. Pode, por exemplo, adicionar o nome do banco de dados. Eu realmente não investiguei a fonte com profundidade suficiente. Basta dizer que passar uma conexão falsa (ou seja undefined) não funciona; Não sei se uma conexão simulada poderia ser implementada. Sua solução parece viável.

O resto da solução deve funcionar bem. Como toRawSqlé explicitamente uma função interna, a API aqui parece razoável. Embora outros observem que "deveria" ser possível gerar uma string de conexão neutra, isso aparece fora do escopo de toRawSql.

Você mencionou que não poderia usar MonadLoggerconforme recomendado. O que você tentou e o que aconteceu?

Christian Conkle
fonte
Não consigo me lembrar com o que tentei, MonadLoggerinfelizmente. Já faz algum tempo.
Tom Ellis
Você tem um projeto de teste à mão para ver se toRawSqlfunciona para o caso de uso desta pergunta agora? Eu configurei um esqueletoambiente para testá-lo, mas não tive tempo para descobrir persistente todas as outras máquinas para realmente construir e consumir uma consulta real.
Christian Conkle
Não tenho nenhum tipo de ambiente de teste ou nenhum projeto de esqueleto, desculpe.
Tom Ellis