Jak uzyskać esqueleto, aby wygenerował dla mnie ciąg SQL?

86

Jak uzyskać esqueleto do generowania ciągu SQL z frominstrukcji?

Dokumentacja toRawSqlmówi, że „możesz po prostu włączyć trwałe logowanie zapytań”. Wypróbowałem wszystkie możliwe formy tego MonadLogger, co mogłem zrozumieć, ale nigdy nie wydrukowałem żadnego SQL. Ta sama dokumentacja mówi również, że „ręczne użycie tej funkcji ... jest możliwe, ale żmudne”. Jednak żadne konstruktory tego typu ani żadne funkcje zwracające wartości typu nie QueryTypesą eksportowane. Udało mi się to obejść, zauważając, że QueryTypeto jest newtypei używając unsafeCoerce!

Zostałem również zmuszony do dostarczenia Connection(które otrzymałem przez SQLite), mimo że nie powinno być potrzeby łączenia się z bazą danych w celu wygenerowania SQL.

Oto, co mam. Musi być lepszy sposób.

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
źródło
2
Uważam, że powodem, dla którego musisz dać mu połączenie, jest fakt, że jest on polimorficzny w bazie danych i używa wywnioskowanych SqlPersistinstancji do generowania ciągów SQL specyficznych dla bazy danych.
Thomas
2
Jednak połączenie i typ bazowej bazy danych to różne rzeczy. Powinno być możliwe samo wygenerowanie ciągu SQL.
Tom Ellis

Odpowiedzi:

2

Od czasu opublikowania tego pytania esqueletoprzeszedł szereg ważnych poprawek. Od wersji 2.1.2 i kilku wcześniejszych, QueryType aparametr, który wymagał twojego unsafeCoerce, został usunięty z toRawSql; że duża brodawka nie jest już potrzebna.

Jak obecnie zaimplementowano, Connectionwymagany jest plik . Uważam, że, jak wskazuje nazwa synonimu typu IdentInfo, esqueletoużywa tego do budowania identyfikatorów w zapytaniu. Może na przykład dodać nazwę bazy danych. Tak naprawdę nie odkryłem źródła wystarczająco głęboko. Wystarczy powiedzieć, że przekazywanie fałszywego połączenia (tj. undefined) Nie działa; Nie wiem, czy można by zaimplementować pozorowane połączenie. Twoje rozwiązanie wydaje się wykonalne.

Reszta rozwiązania powinna działać dobrze. Ponieważ toRawSqljest to wyraźnie funkcja wewnętrzna, interfejs API tutaj wydaje się rozsądny. Chociaż inni zauważają, że "powinno" być możliwe wygenerowanie łańcucha neutralnego dla połączenia, który pojawia się poza zakresemtoRawSql .

Wspomniałeś, że nie możesz używać MonadLoggerzgodnie z zaleceniami. Czego próbowałeś i co się stało?

Christian Conkle
źródło
Nie pamiętam, z czym próbowałem MonadLoggerniestety. To było jakiś czas temu.
Tom Ellis
Czy masz teraz pod ręką projekt testowy, aby sprawdzić, czy toRawSqldziała w przypadku użycia tego pytania? Skonfigurowałem esqueletośrodowisko, aby to wypróbować, ale nie miałem czasu, aby wymyślić persistenti wszystkie inne maszyny, aby faktycznie skonstruować i przetworzyć prawdziwe zapytanie.
Christian Conkle
Nie mam żadnego środowiska testowego ani żadnych projektów esqueleto, przepraszam.
Tom Ellis,