mirror of
https://github.com/circuithub/rel8.git
synced 2024-09-11 16:05:41 +03:00
each
working
This commit is contained in:
parent
a69a9cb56d
commit
3408791b3f
28
opaleye.nix
Normal file
28
opaleye.nix
Normal file
@ -0,0 +1,28 @@
|
||||
{ mkDerivation, aeson, base, base16-bytestring, bytestring
|
||||
, case-insensitive, containers, contravariant, dotenv, hspec
|
||||
, hspec-discover, multiset, postgresql-simple, pretty
|
||||
, product-profunctors, profunctors, QuickCheck, scientific
|
||||
, semigroups, stdenv, text, time, time-locale-compat, transformers
|
||||
, uuid, void
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "opaleye";
|
||||
version = "0.6.7004.1";
|
||||
sha256 = "e12d1fdf762524997713db4538fe4b9477ff0c48e939d0c712e842c4276e4f26";
|
||||
libraryHaskellDepends = [
|
||||
aeson base base16-bytestring bytestring case-insensitive
|
||||
contravariant postgresql-simple pretty product-profunctors
|
||||
profunctors scientific semigroups text time time-locale-compat
|
||||
transformers uuid void
|
||||
];
|
||||
testHaskellDepends = [
|
||||
aeson base containers contravariant dotenv hspec hspec-discover
|
||||
multiset postgresql-simple product-profunctors profunctors
|
||||
QuickCheck semigroups text time transformers uuid
|
||||
];
|
||||
testToolDepends = [ hspec-discover ];
|
||||
doCheck = false;
|
||||
homepage = "https://github.com/tomjaguarpaw/haskell-opaleye";
|
||||
description = "An SQL-generating DSL targeting PostgreSQL";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
}
|
16
rel8.cabal
16
rel8.cabal
@ -8,11 +8,17 @@ build-type: Simple
|
||||
extra-source-files: CHANGELOG.md
|
||||
|
||||
library
|
||||
build-depends: base >=4.12 && <4.13
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall
|
||||
hs-source-dirs: src
|
||||
exposed-modules: Rel8.PublicFacing
|
||||
build-depends:
|
||||
base >=4.12 && <4.13
|
||||
, opaleye
|
||||
default-language:
|
||||
Haskell2010
|
||||
ghc-options:
|
||||
-Wall
|
||||
hs-source-dirs:
|
||||
src
|
||||
exposed-modules:
|
||||
Rel8.PublicFacing
|
||||
other-modules:
|
||||
Rel8.Column
|
||||
Rel8.ColumnSchema
|
||||
|
33
shell.nix
Normal file
33
shell.nix
Normal file
@ -0,0 +1,33 @@
|
||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false }:
|
||||
|
||||
let
|
||||
|
||||
inherit (nixpkgs) pkgs;
|
||||
|
||||
f = { mkDerivation, base, opaleye, stdenv }:
|
||||
mkDerivation {
|
||||
pname = "rel8";
|
||||
version = "0.1.0.0";
|
||||
src = ./.;
|
||||
libraryHaskellDepends = [ base opaleye ];
|
||||
license = "unknown";
|
||||
hydraPlatforms = stdenv.lib.platforms.none;
|
||||
};
|
||||
|
||||
haskellPackages = (if compiler == "default"
|
||||
then pkgs.haskellPackages
|
||||
else pkgs.haskell.packages.${compiler}).override { inherit overrides; };
|
||||
|
||||
overrides = self: super: {
|
||||
beam-core = self.callPackage ./beam-core.nix {};
|
||||
beam-postgres = self.callPackage ./beam-postgres.nix {};
|
||||
opaleye = self.callPackage ./opaleye.nix {};
|
||||
};
|
||||
|
||||
variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;
|
||||
|
||||
drv = variant (haskellPackages.callPackage f {});
|
||||
|
||||
in
|
||||
|
||||
if pkgs.lib.inNixShell then drv.env else drv
|
@ -4,14 +4,16 @@
|
||||
{-# language TypeFamilies #-}
|
||||
{-# language UndecidableInstances #-}
|
||||
|
||||
module Rel8.Expr ( Expr ) where
|
||||
module Rel8.Expr where
|
||||
|
||||
import Data.Kind
|
||||
import Rel8.Table
|
||||
import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
|
||||
|
||||
|
||||
-- | Typed SQL expressions
|
||||
data Expr ( m :: Type -> Type ) a
|
||||
data Expr ( m :: Type -> Type ) a =
|
||||
Expr { toPrimExpr :: Opaleye.PrimExpr }
|
||||
|
||||
type role Expr representational nominal
|
||||
|
||||
|
@ -8,7 +8,7 @@ module Rel8.FromRow ( FromRow ) where
|
||||
import Data.Functor.Identity
|
||||
import Rel8.Expr
|
||||
import Rel8.MaybeTable
|
||||
import {-# source #-} Rel8.Query
|
||||
import Rel8.Query
|
||||
|
||||
|
||||
-- | @FromRow@ witnesses the one-to-one correspondence between the type @sql@,
|
||||
|
@ -1,34 +1,110 @@
|
||||
{-# language BlockArguments #-}
|
||||
{-# language DeriveGeneric #-}
|
||||
{-# language FlexibleContexts #-}
|
||||
{-# language KindSignatures #-}
|
||||
{-# language LambdaCase #-}
|
||||
{-# language MultiParamTypeClasses #-}
|
||||
{-# language NamedFieldPuns #-}
|
||||
{-# language ScopedTypeVariables #-}
|
||||
{-# language TypeApplications #-}
|
||||
|
||||
module Rel8.MonadQuery where
|
||||
|
||||
import Data.Proxy
|
||||
import Numeric.Natural
|
||||
import Rel8.Column
|
||||
import Rel8.ColumnSchema
|
||||
import Rel8.Expr
|
||||
import Rel8.MaybeTable
|
||||
import Rel8.Nest
|
||||
import Rel8.Rewrite
|
||||
import Rel8.TableSchema
|
||||
import Rel8.ZipLeaves
|
||||
import Rel8.Top
|
||||
|
||||
import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
|
||||
import qualified Opaleye.Internal.QueryArr as Opaleye
|
||||
import qualified Opaleye.Internal.Table as Opaleye
|
||||
import qualified Opaleye.Internal.Unpackspec as Opaleye
|
||||
import qualified Opaleye.Internal.PackMap as Opaleye
|
||||
import qualified Opaleye.Table as Opaleye
|
||||
|
||||
|
||||
-- | The class of monads that can form SQL queries, along with the corresponding
|
||||
-- expression type.
|
||||
class Monad m => MonadQuery m
|
||||
class Monad m => MonadQuery m where
|
||||
liftOpaleye :: Opaleye.Query a -> m a
|
||||
|
||||
|
||||
instance MonadQuery m => MonadQuery ( Nest m ) where
|
||||
liftOpaleye =
|
||||
Nest . liftOpaleye
|
||||
|
||||
|
||||
-- | Exists checks if a query returns at least one row.
|
||||
--
|
||||
-- @exists q@ is the same as the SQL expression @EXISTS ( q )@
|
||||
exists :: m a -> m ( Expr m Bool )
|
||||
exists = undefined
|
||||
exists =
|
||||
undefined
|
||||
|
||||
|
||||
-- | Select each row from a table definition.
|
||||
--
|
||||
-- This is equivalent to @FROM table@.
|
||||
each :: ( MonadQuery m, Rewrite ColumnSchema ( Expr m ) schema row ) => TableSchema schema -> m row
|
||||
each =
|
||||
undefined
|
||||
each
|
||||
:: forall m schema row
|
||||
. ( MonadQuery m
|
||||
, Rewrite ColumnSchema ( Expr m ) schema row
|
||||
, ZipLeaves row row ( Expr m ) ( Expr m )
|
||||
, CanZipLeaves row row Top
|
||||
)
|
||||
=> TableSchema schema -> m row
|
||||
each schema =
|
||||
liftOpaleye ( Opaleye.selectTableExplicit unpackspec table )
|
||||
|
||||
where
|
||||
|
||||
unpackspec :: Opaleye.Unpackspec row row
|
||||
unpackspec =
|
||||
Opaleye.Unpackspec $ Opaleye.PackMap \f row ->
|
||||
zipLeaves
|
||||
( Proxy @Top )
|
||||
( \( C expr ) _ -> fmap ( C . Expr ) ( f ( toPrimExpr expr ) ) )
|
||||
row
|
||||
row
|
||||
|
||||
|
||||
table :: Opaleye.Table () row
|
||||
table =
|
||||
case tableSchema schema of
|
||||
Nothing ->
|
||||
Opaleye.Table ( tableName schema ) tableFields
|
||||
|
||||
Just s ->
|
||||
Opaleye.TableWithSchema s ( tableName schema ) tableFields
|
||||
|
||||
|
||||
tableFields :: Opaleye.TableFields () row
|
||||
tableFields =
|
||||
Opaleye.TableProperties writer view
|
||||
|
||||
|
||||
writer :: Opaleye.Writer () row
|
||||
writer =
|
||||
Opaleye.Writer ( Opaleye.PackMap \_ _ -> pure () )
|
||||
|
||||
|
||||
view :: Opaleye.View row
|
||||
view =
|
||||
Opaleye.View
|
||||
( rewrite
|
||||
( \( C ColumnSchema{ columnName } ) ->
|
||||
C ( Expr ( Opaleye.BaseTableAttrExpr columnName ) )
|
||||
)
|
||||
( tableColumns schema )
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- | Select all rows from another table that match a given predicate. If the
|
||||
|
@ -1,3 +0,0 @@
|
||||
module Rel8.MonadQuery where
|
||||
|
||||
class Monad m => MonadQuery m
|
@ -2,8 +2,6 @@
|
||||
|
||||
module Rel8.Nest where
|
||||
|
||||
import {-# source #-} Rel8.MonadQuery
|
||||
|
||||
|
||||
newtype Nest m a = Nest ( m a )
|
||||
deriving ( Functor, Applicative, Monad, MonadQuery )
|
||||
deriving ( Functor, Applicative, Monad )
|
||||
|
@ -1,19 +1,63 @@
|
||||
{-# language BlockArguments #-}
|
||||
{-# language FlexibleContexts #-}
|
||||
{-# language GeneralizedNewtypeDeriving #-}
|
||||
{-# language ScopedTypeVariables #-}
|
||||
{-# language TypeApplications #-}
|
||||
|
||||
module Rel8.Query where
|
||||
|
||||
import Rel8.FromRow
|
||||
import Data.Proxy
|
||||
import qualified Opaleye
|
||||
import qualified Opaleye.Internal.PackMap as Opaleye
|
||||
import qualified Opaleye.Internal.QueryArr as Opaleye
|
||||
import qualified Opaleye.Internal.Unpackspec as Opaleye
|
||||
import Rel8.Column
|
||||
import Rel8.Expr
|
||||
import Rel8.MonadQuery
|
||||
import Rel8.Top
|
||||
import Rel8.ZipLeaves
|
||||
import {-# source #-} Rel8.FromRow
|
||||
|
||||
|
||||
newtype Query a = Query ( IO a )
|
||||
deriving ( Functor, Applicative, Monad )
|
||||
newtype Query a = Query ( Opaleye.Query a )
|
||||
deriving ( Functor, Applicative )
|
||||
|
||||
|
||||
instance MonadQuery Query
|
||||
instance Monad Query where
|
||||
return = pure
|
||||
Query ( Opaleye.QueryArr f ) >>= g = Query $ Opaleye.QueryArr \input ->
|
||||
case ( f input ) of
|
||||
( a, primQuery, tag ) ->
|
||||
case g a of
|
||||
Query ( Opaleye.QueryArr h ) ->
|
||||
h ( (), primQuery, tag )
|
||||
|
||||
|
||||
instance MonadQuery Query where
|
||||
liftOpaleye =
|
||||
Query
|
||||
|
||||
|
||||
-- | Run a @SELECT@ query, returning all rows.
|
||||
select :: FromRow row haskell => Query row -> m [ haskell ]
|
||||
select _ =
|
||||
undefined
|
||||
|
||||
|
||||
showSQL
|
||||
:: forall a
|
||||
. ( CanZipLeaves a a Top, ZipLeaves a a ( Expr Query ) ( Expr Query ) )
|
||||
=> Query a -> Maybe String
|
||||
showSQL ( Query opaleye ) =
|
||||
Opaleye.showSqlExplicit unpackspec opaleye
|
||||
|
||||
where
|
||||
|
||||
unpackspec :: Opaleye.Unpackspec a a
|
||||
unpackspec =
|
||||
Opaleye.Unpackspec $ Opaleye.PackMap \f row ->
|
||||
zipLeaves
|
||||
( Proxy @Top )
|
||||
( \( C expr ) _ -> C . Expr <$> f ( toPrimExpr expr ) )
|
||||
row
|
||||
row
|
||||
|
@ -1,3 +0,0 @@
|
||||
module Rel8.Query where
|
||||
|
||||
data Query a
|
Loading…
Reference in New Issue
Block a user