Skip to content

Commit

Permalink
Keep spaces for tests not to fail
Browse files Browse the repository at this point in the history
  • Loading branch information
amitaibu committed Nov 21, 2023
1 parent ebaa344 commit 62a937a
Showing 1 changed file with 40 additions and 40 deletions.
80 changes: 40 additions & 40 deletions IHP/QueryBuilder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ class IsJoined a b
instance (ModelList b) => IsJoined a (ConsModelList a b)
instance {-# OVERLAPPABLE #-} (ModelList b, IsJoined a b) => IsJoined a (ConsModelList c b)

-- Class to generalise over different QueryBuilder-providing types. The actual query builder can be extracted with 'getQueryBuilder' and injected with 'injectQueryBuilder'. Also assigns a join reqister to a queryBilderProvider.
-- Class to generalise over different QueryBuilder-providing types. The actual query builder can be extracted with 'getQueryBuilder' and injected with 'injectQueryBuilder'. Also assigns a join reqister to a queryBilderProvider.
class HasQueryBuilder queryBuilderProvider joinRegister | queryBuilderProvider -> joinRegister where
getQueryBuilder :: queryBuilderProvider table -> QueryBuilder table
injectQueryBuilder :: QueryBuilder table -> queryBuilderProvider table
getQueryIndex :: queryBuilderProvider table -> Maybe ByteString
getQueryIndex _ = Nothing
getQueryIndex _ = Nothing

-- Wrapper for QueryBuilders resulting from joins. Associates a joinRegister type.
newtype JoinQueryBuilderWrapper joinRegister table = JoinQueryBuilderWrapper (QueryBuilder table)
Expand All @@ -178,12 +178,12 @@ instance HasQueryBuilder QueryBuilder EmptyModelList where
-- JoinQueryBuilderWrappers have query builders
instance HasQueryBuilder (JoinQueryBuilderWrapper joinRegister) joinRegister where
getQueryBuilder (JoinQueryBuilderWrapper queryBuilder) = queryBuilder
injectQueryBuilder = JoinQueryBuilderWrapper
injectQueryBuilder = JoinQueryBuilderWrapper

-- NoJoinQueryBuilderWrapper have query builders and the join register does not allow any joins
instance HasQueryBuilder NoJoinQueryBuilderWrapper NoJoins where
getQueryBuilder (NoJoinQueryBuilderWrapper queryBuilder) = queryBuilder
injectQueryBuilder = NoJoinQueryBuilderWrapper
injectQueryBuilder = NoJoinQueryBuilderWrapper

instance (KnownSymbol foreignTable, foreignModel ~ GetModelByTableName foreignTable , KnownSymbol indexColumn, HasField indexColumn foreignModel indexValue) => HasQueryBuilder (LabeledQueryBuilderWrapper foreignTable indexColumn indexValue) NoJoins where
getQueryBuilder (LabeledQueryBuilderWrapper queryBuilder) = queryBuilder
Expand Down Expand Up @@ -284,7 +284,7 @@ buildQuery queryBuilderProvider = buildQueryHelper $ getQueryBuilder queryBuilde
where
buildQueryHelper NewQueryBuilder { selectFrom, columns } =
SQLQuery
{ queryIndex = getQueryIndex queryBuilderProvider
{ queryIndex = getQueryIndex queryBuilderProvider
, selectFrom = selectFrom
, distinctClause = Nothing
, distinctOnClause = Nothing
Expand Down Expand Up @@ -348,12 +348,12 @@ buildQuery queryBuilderProvider = buildQueryHelper $ getQueryBuilder queryBuilde
firstQuery { whereCondition = unionWhere }
else
error "buildQuery: Union of complex queries not supported yet"

buildQueryHelper JoinQueryBuilder { queryBuilder, joinData } =
let
let
firstQuery = buildQueryHelper queryBuilder
in firstQuery { joins = joinData:joins firstQuery }

-- | Transforms a @query @@User |> ..@ expression into a SQL Query. Returns a tuple with the sql query template and it's placeholder values.
--
-- __Example:__ Get the sql query that is represented by a QueryBuilder
Expand Down Expand Up @@ -390,7 +390,7 @@ toSQL' sqlQuery@SQLQuery { queryIndex, selectFrom, distinctClause, distinctOnCla
where
-- Generates a string like: `posts.id, posts.title, posts.body`
selectFromWithColumns :: [ByteString]
selectFromWithColumns =
selectFromWithColumns =
columns
|> map (\column -> selectFrom <> "." <> column)
fromClause :: ByteString
Expand Down Expand Up @@ -476,7 +476,7 @@ filterWhere (name, value) queryBuilderProvider = injectQueryBuilder FilterByQuer
queryBuilder = getQueryBuilder queryBuilderProvider
{-# INLINE filterWhere #-}

-- | Like 'filterWhere', but takes a type argument specifying the table which holds the column that is to be compared. The column must have been joined before using 'innerJoin' or 'innerJoinThirdTable'. Example:
-- | Like 'filterWhere', but takes a type argument specifying the table which holds the column that is to be compared. The column must have been joined before using 'innerJoin' or 'innerJoinThirdTable'. Example:
--
-- __Example:__ get posts by user Tom.
--
Expand Down Expand Up @@ -562,14 +562,14 @@ filterWhereIn (name, value) queryBuilderProvider =
{-# INLINE filterWhereIn #-}

-- | Like 'filterWhereIn', but takes a type argument specifying the table which holds the column that is compared. The table needs to have been joined before using 'innerJoin' or 'innerJoinThirdTable'.
--
--
-- __Example:__ get posts by Tom and Tim.
--
-- > tomOrTimPosts <- query @Post
-- > |> innerJoin @User (#createdBy, #id)
-- > |> filterWhereInJoinedTable @User (#name, ["Tom","Tim"])
-- > tomOrTimPosts <- query @Post
-- > |> innerJoin @User (#createdBy, #id)
-- > |> filterWhereInJoinedTable @User (#name, ["Tom","Tim"])
-- > |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name IN ('Tom', 'Tim')
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name IN ('Tom', 'Tim')
--
filterWhereInJoinedTable :: forall model name table value queryBuilderProvider joinRegister table'. (KnownSymbol table, KnownSymbol name, ToField value, HasField name model value, table ~ GetTableName model, HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, [value]) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereInJoinedTable (name, value) queryBuilderProvider = injectQueryBuilder FilterByQueryBuilder { queryBuilder, queryFilter = (columnName, InOp, toField (In value)), applyLeft = Nothing, applyRight = Nothing }
Expand Down Expand Up @@ -648,8 +648,8 @@ filterWhereLike (name, value) queryBuilderProvider = injectQueryBuilder FilterBy
--
-- __Example:__ Serach for Posts by users whose name contains "olaf" (case insensitive)
--
-- > olafPosts <- query @Post
-- > |> innerJoin @User (#createdBy, #id)
-- > olafPosts <- query @Post
-- > |> innerJoin @User (#createdBy, #id)
-- > |> filterWhereLikeJoinedTable @User (#name, "%Olaf%")
-- > |> fetch
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name LIKE '%Olaf%'
Expand Down Expand Up @@ -680,11 +680,11 @@ filterWhereILike (name, value) queryBuilderProvider = injectQueryBuilder FilterB
--
-- __Example:__ Serach for Posts by users whose name contains "olaf" (case insensitive)
--
-- > olafPosts <-
-- > query @Post
-- |> innerJoin @User (#createdBy, #id)
-- > olafPosts <-
-- > query @Post
-- |> innerJoin @User (#createdBy, #id)
-- |> filterWhereILikeJoinedTable @User (#name, "%Olaf%")
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name ILIKE '%Olaf%'
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.created_by = users.id WHERE users.name ILIKE '%Olaf%'
filterWhereILikeJoinedTable :: forall model table name table' model' value queryBuilderProvider joinRegister. (KnownSymbol table, KnownSymbol name, ToField value, HasField name model value, table ~ GetTableName model, model' ~ GetModelByTableName table', HasQueryBuilder queryBuilderProvider joinRegister, IsJoined model joinRegister, Table model) => (Proxy name, value) -> queryBuilderProvider table' -> queryBuilderProvider table'
filterWhereILikeJoinedTable (name, value) queryBuilderProvider = injectQueryBuilder FilterByQueryBuilder { queryBuilder, queryFilter = (columnName, LikeOp CaseInsensitive, toField value), applyLeft = Nothing, applyRight = Nothing }
where
Expand Down Expand Up @@ -827,25 +827,25 @@ filterWhereCaseInsensitive (name, value) queryBuilderProvider = injectQueryBuild
{-# INLINE filterWhereCaseInsensitive #-}

-- | Joins a table to an existing QueryBuilder (or something holding a QueryBuilder) on the specified columns. Example:
-- > query @Posts
-- > query @Posts
-- > |> innerJoin @Users (#author, #id)
-- > -- SELECT users.* FROM users INNER JOIN posts ON users.id = posts.author ...
innerJoin :: forall model' table' name' value' model table name value queryBuilderProvider joinRegister.
(
KnownSymbol name,
KnownSymbol name,
KnownSymbol table,
HasField name model value,
KnownSymbol name',
KnownSymbol name',
KnownSymbol table',
HasQueryBuilder queryBuilderProvider joinRegister,
ModelList joinRegister,
HasField name' model' value',
HasField name' model' value',
value ~ value',
model ~ GetModelByTableName table,
table' ~ GetTableName model'
) => (Proxy name, Proxy name') -> queryBuilderProvider table -> JoinQueryBuilderWrapper (ConsModelList model' joinRegister) table
innerJoin (name, name') queryBuilderProvider = injectQueryBuilder $ JoinQueryBuilder (getQueryBuilder queryBuilderProvider) $ Join joinTableName leftJoinColumn rightJoinColumn
where
) => (Proxy name, Proxy name') -> queryBuilderProvider table -> JoinQueryBuilderWrapper (ConsModelList model' joinRegister) table
innerJoin (name, name') queryBuilderProvider = injectQueryBuilder $ JoinQueryBuilder (getQueryBuilder queryBuilderProvider) $ Join joinTableName leftJoinColumn rightJoinColumn
where
baseTableName = symbolToByteString @table
joinTableName = symbolToByteString @table'
leftJoinColumn = baseTableName <> "." <> (Text.encodeUtf8 . fieldNameToColumnName) (symbolToText @name)
Expand All @@ -863,31 +863,31 @@ innerJoin (name, name') queryBuilderProvider = injectQueryBuilder $ JoinQueryBui
-- > |> innerJoinThirdTable @Post @Tagging (#id, #postId)
-- > |> labelResults @Post #id
-- > |> fetch
-- > -- SELECT posts.id, tags.* FROM comments INNER JOIN taggings ON tags.id = taggings.tagId INNER JOIN posts ON posts.id = taggings.postId
--
-- > -- SELECT posts.id, tags.* FROM comments INNER JOIN taggings ON tags.id = taggings.tagId INNER JOIN posts ON posts.id = taggings.postId
--
-- labeledTags is then a list of type ['LabeledData' (Id' "posts") Tag] such that "LabeledData postId tag" is contained in that list if "tag" is a tag of the post with id postId.
--
labelResults :: forall foreignModel baseModel foreignTable baseTable name value queryBuilderProvider joinRegister.
(
KnownSymbol foreignTable,
KnownSymbol baseTable,
foreignTable ~ GetTableName foreignModel,
foreignTable ~ GetTableName foreignModel,
baseModel ~ GetModelByTableName baseTable,
HasField name foreignModel value,
HasQueryBuilder queryBuilderProvider joinRegister,
KnownSymbol name,
IsJoined foreignModel joinRegister
) => Proxy name -> queryBuilderProvider baseTable -> LabeledQueryBuilderWrapper foreignTable name value baseTable
labelResults name queryBuilderProvider = LabeledQueryBuilderWrapper $ getQueryBuilder queryBuilderProvider

-- | Joins a table on a column held by a previously joined table. Example:
-- > query @Posts
-- > query @Posts
-- > |> innerJoin @Users (#author, #id)
-- > |> innerJoinThirdTable @City @Users (#id, #homeTown)
-- > -- SELECT posts.* FROM posts INNER JOIN users ON posts.author = users.id INNER JOIN cities ON user.home_town = cities.id
--
innerJoinThirdTable :: forall model model' name name' value value' table table' baseTable baseModel queryBuilderProvider joinRegister.
(
(
KnownSymbol name,
KnownSymbol table,
HasField name model value,
Expand All @@ -899,16 +899,16 @@ innerJoinThirdTable :: forall model model' name name' value value' table table'
value ~ value',
table ~ GetTableName model,
table' ~ GetTableName model',
baseModel ~ GetModelByTableName baseTable
baseModel ~ GetModelByTableName baseTable
) => (Proxy name, Proxy name') -> queryBuilderProvider baseTable -> JoinQueryBuilderWrapper (ConsModelList model joinRegister) baseTable
innerJoinThirdTable (name, name') queryBuilderProvider = injectQueryBuilder $ JoinQueryBuilder (getQueryBuilder queryBuilderProvider) $ Join joinTableName leftJoinColumn rightJoinColumn
where
where
baseTableName = symbolToByteString @table'
joinTableName = symbolToByteString @table
leftJoinColumn = baseTableName <> "." <> (Text.encodeUtf8 . fieldNameToColumnName) (symbolToText @name')
rightJoinColumn = (Text.encodeUtf8 . fieldNameToColumnName) (symbolToText @name)
{-# INLINE innerJoinThirdTable #-}



-- | Adds an @ORDER BY .. ASC@ to your query.
Expand Down Expand Up @@ -998,7 +998,7 @@ queryUnion firstQueryBuilderProvider secondQueryBuilderProvider = NoJoinQueryBui
firstQueryBuilder = getQueryBuilder firstQueryBuilderProvider
secondQueryBuilder = getQueryBuilder secondQueryBuilderProvider


{-# INLINE queryUnion #-}


Expand All @@ -1014,8 +1014,8 @@ queryUnion firstQueryBuilderProvider secondQueryBuilderProvider = NoJoinQueryBui
-- > -- SELECT * FROM pages WHERE created_by = '..' OR public = True
queryOr :: (HasQueryBuilder queryBuilderProvider joinRegister, HasQueryBuilder queryBuilderProvider'' joinRegister'', HasQueryBuilder queryBuilderProvider''' joinRegister''') => (queryBuilderProvider model -> queryBuilderProvider''' model) -> (queryBuilderProvider model -> queryBuilderProvider'' model) -> queryBuilderProvider model -> queryBuilderProvider model
queryOr firstQuery secondQuery queryBuilder = injectQueryBuilder
(UnionQueryBuilder {
firstQueryBuilder = getQueryBuilder $ firstQuery queryBuilder,
(UnionQueryBuilder {
firstQueryBuilder = getQueryBuilder $ firstQuery queryBuilder,
secondQueryBuilder = getQueryBuilder $ secondQuery queryBuilder}
)
{-# INLINE queryOr #-}
Expand Down

0 comments on commit 62a937a

Please sign in to comment.