-- | This module provides certain "canned" queries that would be useful for -- pulling Postgres rows into a data frame. Also contains a utility function -- for handling results of join queries. {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Frames.SQL.Beam.Postgres.Query where import Data.Vinyl.TypeLevel import Database.Beam import Database.Beam.Postgres import Database.Beam.Postgres.Syntax import Frames.Frame import Frames.InCore import Frames.SQL.Beam.Postgres.Vinylize type PostgresTable a b = DatabaseSettings Postgres b -> DatabaseEntity Postgres b (TableEntity a) type PostgresDB b = DatabaseSettings Postgres b type PostgresFilterLambda a s = (a (QExpr PgExpressionSyntax s)) -> QExpr PgExpressionSyntax s Bool type JoinQueryResults a b = [(a Identity, b Identity)] -- | Helps select all rows from a particular table in a database. -- Note that the table and database declaration is present in -- the module generated by @genBeamSchema@, invoked in the end-user code. -- Equivalent to SQL: "SELECT * FROM tbl;" when run using an appropriate -- run function from the "FramesBeam.Streaming" module. allRows :: (Database Postgres b, Table a) => PostgresTable a b -> PostgresDB b -> Q PgSelectSyntax b s (a (QExpr PgExpressionSyntax s)) allRows tbl db = all_ (tbl db) -- | Helps select all rows from a particular table in a database that -- satisfy a certain filter condition that is executed at the DB-level. -- Note that the table and database declaration is present in -- the module generated by @genBeamSchema@, invoked in the end-user code. -- Equivalent to SQL: "SELECT * FROM tbl WHERE ...;" when run using an -- appropriate run function from the "FramesBeam.Streaming" module. allRowsWhere :: (Database Postgres b, Table a) => PostgresTable a b -> PostgresDB b -> PostgresFilterLambda a s -> Q PgSelectSyntax b s (a (QExpr PgExpressionSyntax s)) allRowsWhere tbl db filterLambda = filter_ (filterLambda) (allRows tbl db) -- | Function for creating a data frame from the results of executing -- a join query. join2 :: (Table a, Table b, GenericVinyl (a Identity) a_names a_rs, GenericVinyl (b Identity) b_names b_rs, RecVec (ZipTypes a_names a_rs), RecVec (ZipTypes b_names b_rs)) => JoinQueryResults a b -> FrameRec (ZipTypes a_names a_rs ++ ZipTypes b_names b_rs) join2 joinQueryResults = zipFrames aFrame bFrame where (aQRes, bQRes) = unzip joinQueryResults aRecs = map createRecId aQRes bRecs = map createRecId bQRes aFrame = toFrame aRecs bFrame = toFrame bRecs