Skip to content

Think about splitting hpgsql into a core package with a lower level API and other packages #17

@mzabani

Description

@mzabani

There have been three mentions of how it'd be better if hpgsql wasn't so batteries-included, and provided a smaller core for other software to build on.

While it's not entirely clear to me what this separation would entail, some things are:

  • This core would take SQL statements as either ByteString or Text, and the Query type would not be in it, including all the parsing and template haskell/quasiquoters (would also not be in it).
    • This means this core would take dollar-numbered query arguments like postgres expects them, and would not take more than one statement in the same query.

The most basic core abstraction we have, which would very likely be in this core library, is:

-- | After sending one or more queries to the backend, run this function for each query to fetch that query's results.
-- You must call the returned IO function and consume the returned Stream completely until you get to the
-- `Either ErrorResponse CommandComplete` object.
-- For non-row returning statements like INSERT, DELETE, and UPDATE, the returned Stream will be empty but the execution status
-- will still be available in the Stream's result.
-- This function can also "consume results" of a `COPY FROM STDIN` statement, which essentially means it can receive the
-- control messages of that starting from any possible state.
-- By following these rules you will always keep the internal connection's state healthy, even in the presence of concurrency
-- and asynchronous exceptions.
consumeResults ::
  HPgConnection ->
  QueryId ->
  IO (Maybe (Either3 NoData RowDescription CopyInResponse), Stream (Of DataRow) IO (Either ErrorResponse CommandComplete))
consumeResults conn qryId = do

This still demands internally-assigned QueryIds (which are important for tracking things related to thread safety) which maybe users would prefer not to have? This raises another question: how much of thread-safety and interruption-safety should be in the core library? These things might not be easy to add on top of an API that is too basic.

Also, decoding DataRow into fields/rows is a lot of work for consumers, so maybe field and row decoders/encoders should also be part of this core package, just maybe not the typeclasses (FromPgField, ToPgField, FromPgRow, ToPgRow) currently associated with them.

I think it's best to hear feedback from potential users for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is neededquestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions