Skip to content

Commit

Permalink
Add indexed combinator (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
shane-circuithub committed Jul 16, 2021
1 parent b0e47ec commit 7c33143
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

* The new `Rel8.Tabulate` module has been added, which gives a `Map`-esque interface to writing and composing queries. ([#70](https://github.com/circuithub/rel8/pull/70))

* The new `indexed` `Query -> Query` function was added. This function augments each row in a query with it's 0-based index. ([#117](https://github.com/circuithub/rel8/pull/117))

## Breaking changes

* `Insert`, `Delete` and `Update` have all changed. In particular, for `Insert` users should now replace `rows = xs` with `rows = values xs`. ([#85](https://github.com/circuithub/rel8/pull/85))
Expand Down
1 change: 1 addition & 0 deletions rel8.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ library
Rel8.Query.Evaluate
Rel8.Query.Exists
Rel8.Query.Filter
Rel8.Query.Indexed
Rel8.Query.Limit
Rel8.Query.List
Rel8.Query.Maybe
Expand Down
4 changes: 4 additions & 0 deletions src/Rel8.hs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ module Rel8
, nullsFirst
, nullsLast

-- ** Window functions
, indexed

-- ** Bindings
, rebind

Expand Down Expand Up @@ -322,6 +325,7 @@ import Rel8.Query.Either
import Rel8.Query.Evaluate
import Rel8.Query.Exists
import Rel8.Query.Filter
import Rel8.Query.Indexed
import Rel8.Query.Limit
import Rel8.Query.List
import Rel8.Query.Maybe
Expand Down
34 changes: 34 additions & 0 deletions src/Rel8/Query/Indexed.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Rel8.Query.Indexed
( indexed
)
where

-- base
import Data.Int ( Int64 )
import Prelude

-- opaleye
import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
import qualified Opaleye.Internal.PackMap as Opaleye
import qualified Opaleye.Internal.PrimQuery as Opaleye
import qualified Opaleye.Internal.QueryArr as Opaleye
import qualified Opaleye.Internal.Tag as Opaleye

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Opaleye ( fromPrimExpr )
import Rel8.Query ( Query )
import Rel8.Query.Opaleye ( mapOpaleye )


-- | Pair each row of a query with its index within the query.
indexed :: Query a -> Query (Expr Int64, a)
indexed = mapOpaleye $ \(Opaleye.QueryArr f) -> Opaleye.QueryArr $ \(_, tag) ->
let
(a, query, tag') = f ((), tag)
tag'' = Opaleye.next tag'
window = Opaleye.ConstExpr $ Opaleye.OtherLit "ROW_NUMBER() OVER () - 1"
(index, bindings) = Opaleye.run $ Opaleye.extractAttr "index" tag' window
query' lateral = Opaleye.Rebind True bindings . query lateral
in
((fromPrimExpr index, a), query', tag'')

0 comments on commit 7c33143

Please sign in to comment.