From 3b995ba46ffd358b09064332431933fd64c6bda4 Mon Sep 17 00:00:00 2001 From: Felipe Lessa Date: Thu, 6 Sep 2012 10:00:23 -0300 Subject: [PATCH] Better documentation of Sql's internals. --- src/Database/Esqueleto/Internal/Sql.hs | 31 +++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Database/Esqueleto/Internal/Sql.hs b/src/Database/Esqueleto/Internal/Sql.hs index f48864d..715fd19 100644 --- a/src/Database/Esqueleto/Internal/Sql.hs +++ b/src/Database/Esqueleto/Internal/Sql.hs @@ -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