2014-06-03 6 views
8

Próbuję dowiedzieć się, jak napisać następującą kwerendę za pomocą EsqueletoCo to jest poprawny sposób robi COUNT (id) w Esqueleto i jesod

SELECT COUNT("person"."id") 
FROM "person" 
WHERE (("person"."admin" = 't' OR "person"."vip" = 't') // 't' as in True 
     OR "person"."karma" >= 5000 AND "person"."hellbanned" = 'f') 

Oto jak mój model jest zdefiniowany

Person 
    admin Bool 
    vip Bool 
    karma Int 
    hellbanned Bool 

udało mi się dostać niemal wszystko, z wyjątkiem COUNT części

select $ 
    from $ \p -> do 
    where_ 
     ((p ^. PersonAdmin ==. val True) ||. (p ^. PersonVip ==. val True) 
     &&. (p ^. PersonKarma >=. val 5000) &&. (p ^. PersonHellbanned ==. val False)) 
    return $ p ^. PersonId 

I MANAG ed, aby znaleźć funkcję countRows, jednak nie udało mi się znaleźć sposobu na połączenie tych dwóch w sposób, który sprawdza typek.

Nie jestem również pewien, czy potrzebuję wszystkich tych p ^. w każdym oddziale klauzuli where, czy też można je jakoś zwinąć razem?

+1

Czy spróbować użyć [funkcję COUNT] (http: //haddocks.fpcomplete. com/fp/7.4.2/20130829-168/persistent/Database-Persist-Class.html # v: count). –

+0

Istnieje funkcja [countRows] (https://www.stackage.org/haddock/lts-9.6/esqueleto-2.5.3/Database-Esqueleto.html#v:countRows) w 'Database.Eququo'. – mb21

Odpowiedz

3

Oto kilka starych kodów, które mają znaczenie, nie pamiętam wiele o tym, ale mam nadzieję, że to pomaga!

selectCount 
    :: (From SqlQuery SqlExpr SqlBackend a) 
    => (a -> SqlQuery()) -> Persist Int 
selectCount q = do 
    res <- select $ from $ (\x -> q x >> return countRows) 
    return $ fromMaybe 0 $ (\(Value a) -> a) <$> headMay res 

getCount :: RepositoryUri -> Persist Int 
getCount ruri = 
    selectCount $ \(r `InnerJoin` rs) -> do 
    on  $ r ^. R.RepositoryId ==. rs ^. Repo 
    where_ $ r ^. R.Uri ==. val ruri 
1

Znalazłem odpowiedź Adama Bergmark całkiem użyteczne, ale myślę, że powinno być bardziej pouczające:

import Import hiding (Value) 
import Data.Maybe (maybeToList 
        , listToMaybe) 
import Database.Esqueleto 
import Database.Esqueleto.Internal.Language (From) 

selectCount 
    :: (From SqlQuery SqlExpr SqlBackend a) 
    => (a -> SqlQuery()) -> YesodDB App Int 
selectCount q = do 
    res <- select $ from $ (\x -> q x >> return countRows) 
    return $ fromMaybe 0 . listToMaybe . fmap (\(Value v) -> v) $ res 
+0

To działało tak dobrze (po 1-2 godzinach zmarnowane) :) Dlaczego to nie jest po prostu wbudowane? Nie rozumiem... – Alebon

Powiązane problemy