Better documentation of Sql's internals.

This commit is contained in:
Felipe Lessa 2012-09-06 10:00:23 -03:00
parent 17a2cb65a9
commit 3b995ba46f

View File

@ -21,6 +21,8 @@ module Database.Esqueleto.Internal.Sql
, update
, toRawSql
, Mode(..)
, Escape
, SqlSelect
) where
import Control.Applicative (Applicative(..), (<$>))
@ -199,6 +201,7 @@ parensM Parens = parens
data OrderByType = ASC | DESC
-- | (Internal) Backend-specific function that escapes a 'DBName'.
type Escape = DBName -> TLB.Builder
@ -451,7 +454,12 @@ update = rawExecute UPDATE . from
----------------------------------------------------------------------
-- | Pretty prints a 'SqlQuery' into a SQL query.
-- | (Internal) Pretty prints a 'SqlQuery' into a SQL query.
--
-- Note: if you're curious about the SQL query being generated by
-- @esqueleto@, instead of manually using this function (which is
-- possible but tedious), you may just turn on query logging of
-- @persistent@.
toRawSql :: SqlSelect a r => Mode -> Escape -> SqlQuery a -> (TLB.Builder, [PersistValue])
toRawSql mode esc query =
let (ret, SideData fromClauses setClauses whereClauses orderByClauses) =
@ -466,6 +474,7 @@ toRawSql mode esc query =
, makeOrderBy esc orderByClauses
]
-- | (Internal) Mode of query being converted by 'toRawSql'.
data Mode = SELECT | SELECT_DISTINCT | DELETE | UPDATE
@ -552,8 +561,11 @@ parens :: TLB.Builder -> TLB.Builder
parens b = "(" <> (b <> ")")
-- | Class for mapping results coming from 'SqlQuery' into actual
-- results.
----------------------------------------------------------------------
-- | (Internal) Class for mapping results coming from 'SqlQuery'
-- into actual results.
--
-- This looks very similar to @RawSql@, and it is! However,
-- there are some crucial differences and ultimately they're
@ -571,11 +583,15 @@ class SqlSelect a r | a -> r, r -> a where
-- | Transform a row of the result into the data type.
sqlSelectProcessRow :: [PersistValue] -> Either T.Text r
-- | Not useful for 'select', but used for 'update' and 'delete'.
instance SqlSelect () () where
sqlSelectCols _ _ = mempty
sqlSelectColCount _ = 0
sqlSelectProcessRow _ = Right ()
-- | You may return an 'Entity' from a 'select' query.
instance PersistEntity a => SqlSelect (SqlExpr (Entity a)) (Entity a) where
sqlSelectCols escape expr@(EEntity ident) = ret
where
@ -602,6 +618,8 @@ instance PersistEntity a => SqlSelect (SqlExpr (Entity a)) (Entity a) where
getEntityVal :: SqlExpr (Entity a) -> a
getEntityVal = error "Esqueleto/Sql/getEntityVal"
-- | You may return a possibly-@NULL@ 'Entity' from a 'select' query.
instance PersistEntity a => SqlSelect (SqlExpr (Maybe (Entity a))) (Maybe (Entity a)) where
sqlSelectCols escape (EMaybe ent) = sqlSelectCols escape ent
sqlSelectColCount = sqlSelectColCount . fromEMaybe
@ -612,6 +630,9 @@ instance PersistEntity a => SqlSelect (SqlExpr (Maybe (Entity a))) (Maybe (Entit
| all (== PersistNull) cols = return Nothing
| otherwise = Just <$> sqlSelectProcessRow cols
-- | You may return any single value (i.e. a single column) from
-- a 'select' query.
instance PersistField a => SqlSelect (SqlExpr (Value a)) (Value a) where
sqlSelectCols esc (ERaw p f) = let (b, vals) = f esc
in (parensM p b, vals)
@ -619,6 +640,9 @@ instance PersistField a => SqlSelect (SqlExpr (Value a)) (Value a) where
sqlSelectProcessRow [pv] = Value <$> fromPersistValue pv
sqlSelectProcessRow _ = Left "SqlSelect (Value a): wrong number of columns."
-- | You may return tuples (up to 8-tuples) and tuples of tuples
-- from a 'select' query.
instance ( SqlSelect a ra
, SqlSelect b rb
) => SqlSelect (a, b) (ra, rb) where
@ -643,6 +667,7 @@ instance ( SqlSelect a ra
in colCountFst `seq` processRow
-- Avoids recalculating 'colCountFst'.
instance ( SqlSelect a ra
, SqlSelect b rb
, SqlSelect c rc