2

私は haskell に不慣れで、正直苦労しています。しかし、それは私の考えを拡大するので、ここに行きます。Postgres DB にクエリを実行し、結果を JSON として返す必要がある、非常に単純な Web サーバーを実行しようとしています。

クエリは非常に単純です: "Select id,data from MYTABLE where id = 1"

しかし、haskell の型システムが今私を殺しており、私のアクションの最終的な型が一致しません。SpockPostgreSQL-Simpleをコンボとして使用しています。

ほとんどのチュートリアルは、私がやりたいことに対して単純なものか、難しいものです。私はその中間にいて、多くのHaskellの理解を欠いています.以前の問題の多くは、単純なコピーと貼り付けですでに解決しており、単純なバージョンが機能しています.

しかし、ルート変数を渡そうとするとすぐに失敗します。これが私の作業バージョンです。私のデータベーステーブルはここでは「封筒」と呼ばれています.重要な呼び出しはそれが言う場所get "json"です:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}

module Main where

import Web.Spock
import Web.Spock.Config
import Database.PostgreSQL.Simple
import Data.Pool
import Data.Aeson (ToJSON(toJSON), object, (.=),Value)
import  Database.PostgreSQL.Simple.FromRow

type AppAction a = SpockActionCtx () Connection AppSession AppState a

data AppState = EmptyState
data AppSession = EmptySession

data Envelope = Envelope { envId :: Int, envData :: Value } deriving Show

instance FromRow Envelope where
  fromRow = Envelope <$> field <*> field

instance ToJSON Envelope where
   toJSON (Envelope envA envB) = object [ "id" .= envA, "data" .= envB ]

main :: IO ()
main =
  do pool<-createPool (connect (ConnectInfo "localhost" 5432 "" "" "envelopes") ) close 1 10 10
     spockCfg <- defaultSpockCfg EmptySession (PCPool pool) EmptyState
     runSpock 8080 (spock spockCfg app)

app :: SpockM Connection AppSession AppState ()
app = do 
    get root $
      text "Hello World!"
    get "json" $ do
      xs<-runQuery $ \conn -> 
        query_ conn  "select id,data from envelope where id = 1"
      json (xs::[Envelope])

次に、ラムダ関数を使用してエンベロープ ID を渡そうとします。そのためには、PostgreSQL-Simplequery_query次のように変更する必要もあります。

    get ( "json" <//> var  ) $ \eid -> do
      xs<-runQuery $ \conn -> 
        query conn  "select id,data from envelope where id = ?" (eid :: Int)
      json (xs::[Envelope])

私が得るエラーは言う:

 No instance for (ToRow Int) arising from a use of ‘query’
   In the expression:
      query conn "select id,data from envelope where id = ?" (eid :: Int)
    In the second argument of ‘($)’, namely
      ‘\ conn
         -> query
              conn "select id,data from envelope where id = ?" (eid :: Int)’
    In a stmt of a 'do' block:
      xs <- runQuery
            $ \ conn
                -> query
                     conn "select id,data from envelope where id = ?" (eid :: Int)

ラムダ関数がなくても、クエリから最初のアイテムだけを返すという問題もあります。

完全なソースはbitbucketにあります

誰かが私をここで助けてくれることを願っています。すでにお読みいただきありがとうございます。

4

2 に答える 2