Wie kann ich esqueleto dazu bringen, eine SQL-Zeichenfolge für mich zu generieren?

86

Wie kann ich esqueleto dazu bringen, eine SQL-Zeichenfolge aus einer fromAnweisung zu generieren ?

In der Dokumentation von toRawSqlheißt es, dass "Sie möglicherweise nur die Abfrageprotokollierung von persistent aktivieren". Ich habe alle möglichen Formen ausprobiert MonadLogger, die ich verstehen konnte, aber es wurde nie SQL gedruckt. In derselben Dokumentation heißt es auch "Manuelles Verwenden dieser Funktion ... ist möglich, aber langwierig". Es werden jedoch weder Konstruktoren des Typs noch Funktionen QueryTypeexportiert , die Werte des Typs zurückgeben . Ich habe es geschafft, dies zu umgehen, indem ich bemerkt habe, dass QueryTypees ein ist newtypeund verwendet unsafeCoerce!

Ich war auch gezwungen, eine Connection(die ich über SQLite erhalten habe) bereitzustellen , obwohl es nicht erforderlich sein sollte, eine Verbindung zu einer Datenbank herzustellen, um SQL zu generieren.

Das habe ich. Es muss einen besseren Weg geben.

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
quelle
2
Ich glaube, der Grund, warum Sie ihm eine Verbindung geben müssen, ist, dass es in der Datenbank polymorph ist und abgeleitete SqlPersistInstanzen verwendet, um datenbankspezifische SQL-Zeichenfolgen zu generieren.
Thomas
2
Die Verbindung und der Typ der zugrunde liegenden Datenbank unterscheiden sich jedoch. Es sollte möglich sein, die SQL-Zeichenfolge rein zu generieren.
Tom Ellis

Antworten:

2

In der Zeit seit der Veröffentlichung dieser Frage wurden esqueletoeinige wichtige Änderungen vorgenommen. Ab Version 2.1.2 und mehreren früheren Versionen wurde der QueryType aParameter, für den Sie erforderlich unsafeCoercewaren, entfernt toRawSql. Diese Hauptwarze ist nicht mehr notwendig.

Wie derzeit implementiert, Connectionist a erforderlich. Ich glaube, dass, wie durch den Typensynonymnamen angegeben IdentInfo, dies esqueletoverwendet wird, um Bezeichner in der Abfrage zu erstellen. Es kann beispielsweise den Datenbanknamen hinzufügen. Ich habe die Quelle nicht wirklich gründlich genug untersucht. Es genügt zu sagen, dass das Weitergeben einer gefälschten Verbindung (dh undefined) nicht funktioniert. Ich weiß nicht, ob eine Scheinverbindung implementiert werden könnte. Ihre Lösung scheint praktikabel.

Der Rest Ihrer Lösung sollte gut funktionieren. Da toRawSqles sich explizit um eine interne Funktion handelt, erscheint die API hier sinnvoll. Obwohl andere bemerken, dass es "möglich" sein sollte, eine verbindungsneutrale Zeichenfolge zu generieren, erscheint dies außerhalb des Bereichs von toRawSql.

Sie erwähnen, dass Sie nicht MonadLoggerwie empfohlen verwenden konnten. Was hast du versucht und was ist passiert?

Christian Conkle
quelle
Ich kann mich MonadLoggerleider nicht erinnern, womit ich es versucht habe . Es ist schon einige Zeit her.
Tom Ellis
Haben Sie zufällig ein Testprojekt zur Hand, um zu sehen, ob toRawSqles jetzt für den Anwendungsfall dieser Frage funktioniert? Ich habe eine esqueletoUmgebung eingerichtet, um es auszuprobieren, aber ich hatte keine Zeit, es herauszufinden persistentund all die anderen Maschinen, um tatsächlich eine echte Abfrage zu erstellen und zu konsumieren.
Christian Conkle
Ich habe überhaupt keine Testumgebung oder Projekte, sorry.
Tom Ellis