Ich versuche, einfache Snaplet-Konstruktion zu verstehen. Auch, wann muss ich eigentlich ein Snaplet machen und wenn eine einfache Seitenbibliothek? Und wenn ich brauche, wie mache ich es aus einer Bibliothek?Haskell, Snap: Einfache Snaplet-Konstruktion. Wann verwenden wir Snaplet und wann Bibliothek?
Zum Beispiel habe ich eine Reihe von DB-Funktionen, wo ich meinen SQL-Code wie folgt einpacken.
data Person = Person {personName :: ByteString, personAge :: Int}
connect :: IO Connection
connect = connectSqlite3 "/somepath/db.sqlite3"
savePerson :: Person -> IO()
savePerson p = do
c <- connect
run c "INSERT INTO persons (name, age) \
\VALUES (?, ?)"
[toSql (personName p), toSql (personAge p)]
commit c
disconnect c
Jede Funktion initiiert eine neue Verbindung und schließt die Verbindung nach dem Festschreiben. Ich denke, ein Snaplet ist die Möglichkeit, Verbindung in jeder Funktion zu vermeiden? In meinem Handler würde ich es wie folgt verwenden:
insertPerson :: Handler App App()
insertPerson = do
par <- getPostParams
let p = top par
liftIO $ savePerson p
where
top m =
Person {personName = head (m ! (B.pack "name"))
,personAge = read (B.unpack (head (m ! (B.pack "age")))) :: Int
}
Es bisher funktioniert. Meine Frage (n) ist/sind: Wann muss ich eigentlich eine Bibliothek in einen Snaplet verwandeln? Muss ich meine einfache DB-Bibliothek in einen Snaplet umwandeln, nur um die Verbindung zu initialisieren, anstatt die Verbindung in jeder Funktion herzustellen?
Jetzt, wenn ich die Snaplet ... Auf der Snap-Website gibt es ein winziges Beispiel für eine Top-Level-Sanaplet, aber es gibt keine Spur davon, wie Sie einfach Pluggble Snaplet Ihre eigenen machen.
So habe ich snaplet Initialisierungsfunktion meine DB-Bibliothek
dbInit :: SnapletInit b Connection
dbInit = makeSnaplet "DB" "My DB Snaplet" Nothing $ do
dbc <- liftIO $ connectSqlite3 "/somepath/db.sqlite3"
onUnload $ disconnect dbc
return $ dbc
Ist dies der richtige Weg, es zu tun? Ist das alles, was ich brauche, um es zu einem Pluggble Snaplet zu machen?
Dann stapeln ich diese DB snaplet in die Haupt App
data App = App
{ _heist :: Snaplet (Heist App),
_dbcon :: Snaplet (Connection)
}
makeLens ''App
app :: SnapletInit App App
app = makeSnaplet "app" "My app" Nothing $ do
h <- nestSnaplet "heist" heist $ heistInit "templates"
d <- nestSnaplet "" dbcon dbInit
addRoutes routes
return $ App h d
nun alles, was ich gewinnen die Verbindung zur Verfügung zu meinen Request-Handler ist, nicht wahr? Also mein Handler wird:
insertPerson :: Handler App App()
insertPerson = do
par <- getPostParams
let person = top par
connection <- gets _dbcon
liftIO $ savePerson connection person
where
top m =
Person {personName = head (m ! (B.pack "name"))
,personAge = read (B.unpack (head (m ! (B.pack "age")))) :: Int
}
Dies nicht zu funktionieren scheint. Was mache ich falsch? Ist dies der richtige Weg, um die Verbindung aus dem Snapleet-Handle (dbcon) zu extrahieren? Ist das in der Regel die richtige Richtung, um ein einfaches Snaplet zu konstruieren? Brauche ich in meinem Fall tatsächlich einen Snaplet?
Danke.
Vielen Dank. Ich habe den HDBC Snaplet gesehen und ich habe damit gespielt. Ich möchte es von Grund auf selbst machen, das ist der einzige Weg, um für mich zu lernen. Zuerst habe ich versucht herauszufinden, wie ich eine einfache Bibliothek in meinen Handlern verwenden kann und nun möchte ich lernen, wie man eine Snaplet-Datei daraus erstellt. Ich möchte verstehen, wie ein einfacher Snaplet konstruiert wird, wie sie interagieren und warum/wann ich einen brauche ... –
Kannst du mir sagen, ob das die richtige Richtung ist, um einen Snaplet zu konstruieren? Ist das dbInit alles was ich brauche? –
@ r.sendecky Als ein sehr einfaches Snaplet würde ich sagen, dass es in Ordnung ist. Snapaps werden normalerweise verwendet, um Aktionen von einer Monade auszuführen, die Sie erstellt haben. In Ihrem Fall funktioniert es, weil Sie nur IO-Aktionen verwenden. Ich empfehle die Analyse von mightybytes [AcidState snaplet] (http://hackage.haskell.org/packages/archive/snaplet-acid-state/0.2/doc/html/src/Snap-Snaplet-AcidState.html#Acid). Es ist ein gutes Beispiel dafür, wie/warum man ein Snaplet konstruiert. – qubital