Веб-форма Haskell Yesod для Sqlite3 - PullRequest
1 голос
/ 01 октября 2019

Ищите способ получить информацию, собранную из веб-формы:

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  defaultLayout [whamlet|<p>#{show person}|]

в Sqlite3:

sqliteInsertEntry :: String -> Integer -> IO () 
sqliteInsertEntry name age = do 
  conn <- connectSqlite3 "sqlite.db"
  run conn "INSERT INTO persons (Person,Age) VALUES (?, ?) "
    [ toSql ("Name" :: String)
    , toSql (35 :: Integer)
    ]
  commit conn
  disconnect conn

, но я не могу отделаться от Handler Html

Полный код:

{-# LANGUAGE EmptyDataDecls                 #-}
{-# LANGUAGE FlexibleContexts              #-}
{-# LANGUAGE GADTs                          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving    #-}
{-# LANGUAGE MultiParamTypeClasses         #-}
{-# LANGUAGE OverloadedStrings             #-}
{-# LANGUAGE QuasiQuotes                   #-}
{-# LANGUAGE TemplateHaskell               #-}
{-# LANGUAGE TypeFamilies                  #-}

module Main where
import Yesod 
import Data.Text (Text) 
import Control.Applicative 
import Database.SQLite.Simple 
import Database.HDBC.Sqlite3
import Database.HDBC
import System.IO
import Data.List

data App = App

mkYesod "App" [parseRoutes|
  /       HomeR   GET 
  /input  InputR  GET
|]

instance Yesod App 

instance RenderMessage App FormMessage where 
  renderMessage _ _ = defaultFormMessage 

data Person = Person { 
    personName :: Text 
  , personAge  :: Int 
} deriving Show 

getHomeR :: Handler Html 
getHomeR = defaultLayout 
  [whamlet| 
    <form action=@{InputR}>
      <p>My name is 
      <input type=text name=name>
      and I am 
      <input type=text name=age>
      <input type=submit value="Introduce myself"> 
  |]

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  defaultLayout [whamlet|<p>#{show person}|]

sqliteInsertEntry :: String -> Integer -> IO () 
sqliteInsertEntry name age = do 
  conn <- connectSqlite3 "sqlite.db"
  run conn "INSERT INTO persons (Person,Age) VALUES (?, ?) "
    [ toSql ("Name" :: String)
    , toSql (35 :: Integer)
    ]
  commit conn
  disconnect conn

fromPerson whois = print $ whois 

runWarp :: IO () 
runWarp = warp 666 App 

main :: IO ()
main = runWarp

Примечание: все еще учусь, но хотел бы начать использовать Haskell по-настоящему.

1 Ответ

0 голосов
/ 01 октября 2019

Если вы посмотрите на определение Handler, вы увидите, что у него есть экземпляр MonadIO, поэтому, если вы хотите выполнить действие IO, вы простонадо liftIO это:

getInputR :: Handler Html
getInputR = do 
  person <- runInputGet $ Person 
            <$>ireq textField "name"
            <*>ireq intField "age" 
  liftIO $ sqliteInsertEntry (personName person) (personAge person)
  defaultLayout [whamlet|<p>Saved!|]
...