Module

Control.Monad.Postgres

Package
purescript-postgresql
Repository
cakekindel/purescript-postgresql

Re-exports from Control.Monad.Postgres.Base

#PostgresT Source

type PostgresT :: (Type -> Type) -> Type -> Typetype PostgresT = RE Pool

Monad handling pool resource acquisition & release

runPostgres
  {connectionString: "postgresql://postgres:postgres@localhost:5432"}
  $ session do
      exec_ "create table foo (bar int);"
      exec_ "insert into foo values (1);"
      res <- query "select * from foo"
      pure $ res == 1

Is equivalent to:

do
  pool <- liftEffect $ Pool.make {connectionString: "postgresql://postgres:postgres@localhost:5432"}
  finally (Pool.end pool) do
    client <- Pool.connect pool
    finally (liftEffect $ Pool.release pool client) do
      Client.exec_ "create table foo (bar int);" client
      Client.exec_ "insert into foo values (1);" client
      res <- Client.query "select * from foo" client
      pure $ res == 1

Instances

#MonadPostgres Source

class MonadPostgres :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) -> Type -> Constraintclass (Monad m, MonadSession session, MonadCursor cursor ct) <= MonadPostgres m session cursor ct | m -> ct cursor session where

Typeclass generalizing PostgresT. Allows for dependency-injecting different implementations of the idea of a postgres connection.

  • session - Session monad (for PostgresT this is SessionT)
  • cursor - Cursor session monad (for PostgresT this is CursorT)
  • ct - Open type parameter for cursor type. Don't pin this to a concrete type.

Members

  • session :: session ~> m

    Run a session in m.

  • transaction :: session ~> m

    Run a session in m, wrapped in a transaction.

    If any errors are raised, the transaction is rolled back and the error rethrown.

  • cursorWith :: forall q. AsQuery q => (Array Raw -> RepT ct) -> String -> q -> cursor ~> m

    cursor, but using a custom deserialize function for the data yielded by the cursor

Instances

#withPool Source

withPool :: forall m a. PostgresT m a -> Pool -> Except m a

Execute a PostgresT using an existing connection pool.

This will not invoke Pool.end after executing.

#runPostgres Source

runPostgres :: forall m a missing trash r f. MonadBracket Error f m => MonadAff m => Union r missing (Config trash) => Record r -> PostgresT m a -> Except m a

Create a new connection pool from the provided config and execute the postgres monad, invoking Effect.Aff.Postgres.Pool.end afterwards.

#cursor Source

cursor :: forall @cursort t session cursor q a. MonadPostgres t session cursor cursort => AsQuery q => FromRow cursort => String -> q -> cursor a -> t a

Create a server-side cursor for a query in a transaction, and execute a CursorT with a view to the new cursor.

Re-exports from Control.Monad.Postgres.Cursor

#Move Source

data Move

Constructors

#CursorT Source

newtype CursorT :: forall k. Type -> (k -> Type) -> k -> Typenewtype CursorT t m a

Constructors

Instances

#MonadCursor Source

class MonadCursor :: (Type -> Type) -> Type -> Constraintclass (MonadSession m) <= MonadCursor m t  where

A monad representing a handle to a server-side cursor

runPostgres {connectionString: "..."} do
  exec_ "create table foo (id int not null primary key);"
  exec_
    $ intercalate "\n "
      [ "insert into foo (id)"
      , "values"
      , intercalate ", "
          $ map (\n -> "(" <> show n <> ")")
          $ Array.range 1 100
      ]

  cursor @Int "foo_cursor" "select id from foo" do
    a <- fetchOne -- 1
    b <- fetchOne -- 2
    c <- fetchOne -- 3
    d <- fetch 10 -- 4..14
    e <- fetchAll -- 15..100
    pure unit

Members

  • fetch :: Int -> m (Array t)

    Fetch a specified number of rows from the cursor

  • fetchAll :: m (Array t)

    Fetch all remaining rows from the cursor

  • move :: Move -> m Int

    Change the cursor's position without fetching any data, returning the number of rows skipped.

Instances

#fetchOne Source

fetchOne :: forall m t. MonadCursor m t => m (Maybe t)

Fetch the next row from the cursor

Re-exports from Control.Monad.Postgres.Session

#SessionT Source

type SessionT :: (Type -> Type) -> Type -> Typetype SessionT = RE Client

#MonadSession Source

class MonadSession :: (Type -> Type) -> Constraintclass (MonadAff m) <= MonadSession m  where

A monad representing a connected session to a database

Members

  • query :: forall q r. AsQuery q => FromRows r => q -> m r

    Executes a query and unmarshals the result into r

  • exec :: forall q. AsQuery q => q -> m Int

    Executes a query and returns the number of rows affected

  • exec_ :: forall q. AsQuery q => q -> m Unit

    Executes a query and discards the result

  • streamIn :: String -> m (Writable ())

    Execute a query with a Writable stream to STDIN

    Use with COPY .. FROM like so:

    w <- streamIn "COPY foo FROM STDIN WITH (FORMAT CSV, HEADER true)"
    liftEffect $ Stream.writeString "bar\n\"my bar column\"" UTF8 w
    
  • streamOut :: String -> m (Readable ())

    Execute a query with a Readable stream from STDOUT

    Use with COPY .. TO like so:

    r <- streamIn "COPY foo TO STDIN WITH (FORMAT CSV, HEADER true)"
    liftEffect $ Stream.readString r -- "bar\n\"my bar column\""
    

Instances

#onErrorOrClose Source

#handleStream Source

handleStream :: forall e m r. MonadEffect m => MonadError e m => Effect Unit -> m (Stream r) -> m (Stream r)