rel8/rel8.cabal

272 lines
5.9 KiB
Plaintext
Raw Normal View History

cabal-version: 2.0
name: rel8
2024-03-19 17:48:26 +03:00
version: 1.5.0.0
synopsis: Hey! Hey! Can u rel8?
license: BSD3
license-file: LICENSE
author: Oliver Charles
maintainer: ollie@ocharles.org.uk
homepage: https://github.com/circuithub/rel8
bug-reports: https://github.com/circuithub/rel8/issues
build-type: Simple
2021-06-18 20:23:58 +03:00
extra-doc-files:
README.md
Changelog.md
source-repository head
type: git
location: https://github.com/circuithub/rel8
library
build-depends:
aeson
, attoparsec
2023-09-29 14:23:22 +03:00
, attoparsec-aeson
2024-02-21 15:40:30 +03:00
, base ^>= 4.16 || ^>= 4.17 || ^>= 4.18 || ^>= 4.19
, base16 >= 1.0
2023-07-07 20:48:21 +03:00
, base-compat ^>= 0.11 || ^>= 0.12 || ^>= 0.13
, bifunctors
, bytestring
, case-insensitive
, comonad
, contravariant
, data-textual
2023-04-14 12:56:03 +03:00
, hasql ^>= 1.6.1.2
, network-ip
, opaleye ^>= 0.10.2.1
, pretty
, profunctors
, product-profunctors
, scientific
, semialign
, semigroupoids
, text
, these
, time
Statements overhaul (support for statement-level `WITH`) (#250) The motivation behind this PR is to add support for PostreSQL's `WITH` syntax at the statement level, which gives the ability to, e.g., delete some rows from a table and then re-insert those deleted rows into another table, without any round-trips between the application and the database. To support this, this PR introduces a new type called `Statement`, which represents a single PostgreSQL statement. It has a `Monad` instance which allows sub-statements (such as `DELETE` and `INSERT` statements) to be composed together and their results bound to values that can be referenced in subsequent sub-statements. These "compound" statements are then rendered as a `WITH` statement. `select`, `insert`, `update` and `delete` have all been altered to produce the `Statement` type described above instead of the `Hasql.Statement` type. Some changes were necessary to the `Returning` type. `Returning` previously bundled two different concepts together: whether or not to generate a `RETURNING` clause in the SQL for a manipulation statement, and how to decode the returned rows (if any). It was necessary to break these concepts apart because with `WITH` we need the ability to generate manipulation statements with `RETURNING` clauses that are never actually decoded at all (the results just get passed to the next statement without touching the application). Now, the `Returning` type is only concerned with whether or not to generate a `RETURNING` clause, and the question of how to decode the returned the result of the statement is handled by the `run` functions. `run` converts a `Statement` into a runnable `Hasql.Statement`, decoding the result of the statement as a list of rows. The other variations, `run_`, `runN`, `run1`, `runMaybe` and `runVector` can be used when you want to decode as something other than a list of rows. This also gains us support for decoding the result of a query directly to a `Vector` for the first time, which brings a performance improvement over lists for those who need it.
2023-07-07 13:29:15 +03:00
, transformers
, utf8-string
, uuid
Statements overhaul (support for statement-level `WITH`) (#250) The motivation behind this PR is to add support for PostreSQL's `WITH` syntax at the statement level, which gives the ability to, e.g., delete some rows from a table and then re-insert those deleted rows into another table, without any round-trips between the application and the database. To support this, this PR introduces a new type called `Statement`, which represents a single PostgreSQL statement. It has a `Monad` instance which allows sub-statements (such as `DELETE` and `INSERT` statements) to be composed together and their results bound to values that can be referenced in subsequent sub-statements. These "compound" statements are then rendered as a `WITH` statement. `select`, `insert`, `update` and `delete` have all been altered to produce the `Statement` type described above instead of the `Hasql.Statement` type. Some changes were necessary to the `Returning` type. `Returning` previously bundled two different concepts together: whether or not to generate a `RETURNING` clause in the SQL for a manipulation statement, and how to decode the returned rows (if any). It was necessary to break these concepts apart because with `WITH` we need the ability to generate manipulation statements with `RETURNING` clauses that are never actually decoded at all (the results just get passed to the next statement without touching the application). Now, the `Returning` type is only concerned with whether or not to generate a `RETURNING` clause, and the question of how to decode the returned the result of the statement is handled by the `run` functions. `run` converts a `Statement` into a runnable `Hasql.Statement`, decoding the result of the statement as a list of rows. The other variations, `run_`, `runN`, `run1`, `runMaybe` and `runVector` can be used when you want to decode as something other than a list of rows. This also gains us support for decoding the result of a query directly to a `Vector` for the first time, which brings a performance improvement over lists for those who need it.
2023-07-07 13:29:15 +03:00
, vector
default-language:
Haskell2010
ghc-options:
-Werror=missing-methods -Werror=incomplete-patterns -Werror=missing-fields
-Weverything -Wno-unsafe -Wno-safe -Wno-missing-safe-haskell-mode
-Wno-missing-import-lists -Wno-prepositive-qualified-module
-Wno-monomorphism-restriction
-Wno-missing-local-signatures
-Wno-missing-kind-signatures
hs-source-dirs:
src
exposed-modules:
2021-03-23 17:33:23 +03:00
Rel8
Rel8.Array
2021-03-26 05:25:47 +03:00
Rel8.Expr.Num
2021-03-24 18:37:28 +03:00
Rel8.Expr.Text
Rel8.Expr.Time
Rel8.Tabulate
2021-03-26 00:57:26 +03:00
2021-03-24 16:01:56 +03:00
other-modules:
Rel8.Aggregate
Aggregation overhaul — return to Profunctor and semi-aggregations (#235) This PR makes a number of changes to how aggregation works in Rel8. The biggest change is that we drop the `Aggregate` context and we return to the `Profunctor`-based `Aggregator` that Opaleye uses (as in #37). While working with `Profunctor`s is more awkward for many common use-cases, it's ultimately more powerful. The big thing it gives you that we don't currently have is the ability to "post-map" on the result of an aggregation function. Pretend for a moment that Postgres does not have the `avg` function built-in. With the previous Rel8, there is no way to directly write `sum(x) / count(x)`. The best you could do would something like: ```haskell fmap (\(total, size) -> total / fromIntegral size) $ aggregate $ do foo <- each fooSchema pure (sum foo.x, count foo.x) ``` The key thing is that the mapping can only happen after `aggregate` is called. Whereas with the `Profunctor`-based `Aggregator` this is just `(/) <$> sum <*> fmap fromIntegral count`. This isn't too bad if the only thing you want to do is computing the average, but if you're doing a complicated aggregation with several things happening at once then you might need to do several unrelated post-processings after the `aggregate`. We really want a way to bundle up the postmapping with the aggregation itself and have that as a singular composable unit. Another example is the `listAggExpr` function. The only reason Rel8 exports this is because it can't be directly expressed in terms of `listAgg`. With the `Profunctor`-based `Aggregator` it can be, it's just `(id $*) <$> listAgg`, it no longer needs to be a special case. The original attempt in #37 recognised that it can be awkward to have to write `lmap (.x) sum`, so instead of sum having the type signature `Aggregator (Expr a) (Expr a)`, it had the type signature `(i -> Expr a) -> Aggregator i (Expr a)`, so that you wouldn't have to use `lmap`, you could just type `sum (.x)`. However, there are many ways to compose `Aggregator`s — for example, if you wanted to use combinators from `product-profunctor` to combine aggregators, then you'd rather type `sum ***! count` than `sum id ***! count id`. So in this PR we keep the type of `sum` as `Aggregator (Expr a) (Expr a)`, but we also export `sumOn`, which has the bundled `lmap`. The other major change is that this PR introduces two forms of aggregation — "semi"-aggregation and "full"-aggregation. Up until now, all aggregation in Rel8 was "semi"-aggregation, but "full"-aggregation feels a bit more natural and Haskelly. Up until now, the `aggrgegate` combinator in Rel8 would return zero rows if given a query that itself returned zero rows, even if the aggregation functions that comprised it had identity values. So it was very common to see code like `fmap (fromMaybeTable 0) $ optional $ aggregate $ sum <$> _`. Again, we "know" that `0` is the identity value for `sum` and we really want some way to bundle those together and to say "return the identity value if there are zero rows". Rel8 now has this ability — it has both `Aggregator` and `Aggregator1`, with the former having identity values and the latter not. The `aggregate` function now takes an `Aggregator` and returns the identity value when encountering zero rows, whereas the `aggregate1` function takes an `Aggregator1` and behaves as before. `count`, `sum`, `and`, `or`, `listAgg` are `Aggregator`s (with the identity values `0`, `0`, `true`, `false` and `listTable []` respectively) and `groupBy`, `max` and `min` are `Aggregator1`s. This also means that `many` is now just `aggregate listAgg` instead of `fmap (fromMaybeTable (listTable [])) . optional . aggregate . fmap listAgg`. It should also be noted that these functions are actually polymorphic — `sum` will actually give you an `Aggregator'` that can be used as either `Aggregator` or `Aggregator1` without needing to explicitly convert between them. Similarly `aggregate1` can take either an `Aggegator` or an `Aggregator1` (though it won't use the identity value of the former). Aggregation in Rel8 now supports more of the features of PostgresSQL supports. Three new combinators are introduced — `distinctAggregate`, `filterWhere` and `orderAggregateBy`. Opaleye itself already supported `distinctAggregate` and indeed we used this to implement `countDistinct` as a special case, but we now support using `DISTINCT` on arbitrary aggregation functions. `filterWhere` is new to both Rel8 and Opaleye. It corresponds to PostgreSQL's `FILTER (WHERE ...)` syntax in aggregations. It also uses the identity value of an `Aggregator` in the case where the given predicate returns zero rows. There is also `filterWhereOptional` which can be used with `Aggregator1`s. `orderAggregateBy` allows the values within an aggregation to be ordered using a given ordering, mainly non-commutative aggregation functions like `listAgg`.
2023-06-18 23:05:00 +03:00
Rel8.Aggregate.Fold
Rel8.Aggregate.Function
Rel8.Column
Rel8.Column.ADT
Rel8.Column.Either
Rel8.Column.Lift
Rel8.Column.List
Rel8.Column.Maybe
Rel8.Column.NonEmpty
Rel8.Column.Null
Rel8.Column.These
Rel8.Expr
Rel8.Expr.Aggregate
Rel8.Expr.Array
Rel8.Expr.Bool
2021-06-29 21:45:27 +03:00
Rel8.Expr.Default
Rel8.Expr.Eq
Rel8.Expr.Function
Rel8.Expr.List
Rel8.Expr.NonEmpty
Rel8.Expr.Null
Rel8.Expr.Opaleye
Rel8.Expr.Ord
Rel8.Expr.Order
Rel8.Expr.Read
Rel8.Expr.Sequence
Rel8.Expr.Serialize
Rel8.Expr.Show
2022-10-14 04:06:07 +03:00
Rel8.Expr.Window
Rel8.FCF
Rel8.Kind.Algebra
Rel8.Kind.Context
Rel8.Generic.Construction
Rel8.Generic.Construction.ADT
Rel8.Generic.Construction.Record
Rel8.Generic.Map
Rel8.Generic.Record
Rel8.Generic.Rel8able
2021-04-27 00:24:52 +03:00
Rel8.Generic.Table
2021-04-27 00:26:13 +03:00
Rel8.Generic.Table.ADT
Rel8.Generic.Table.Record
Rel8.Order
Rel8.Query
Rel8.Query.Aggregate
Rel8.Query.Distinct
Rel8.Query.Each
Rel8.Query.Either
2021-06-17 20:12:45 +03:00
Rel8.Query.Evaluate
Rel8.Query.Exists
Rel8.Query.Filter
Rel8.Query.Function
2021-07-16 18:18:43 +03:00
Rel8.Query.Indexed
Rel8.Query.Limit
Rel8.Query.List
Rel8.Query.Loop
Rel8.Query.Materialize
Rel8.Query.Maybe
Rel8.Query.Null
Rel8.Query.Opaleye
Rel8.Query.Order
Rel8.Query.Rebind
Rel8.Query.Set
Rel8.Query.SQL
Rel8.Query.These
Rel8.Query.Values
2022-10-14 04:06:07 +03:00
Rel8.Query.Window
Rel8.Schema.Context.Nullify
Rel8.Schema.Dict
Rel8.Schema.Escape
Rel8.Schema.Field
Rel8.Schema.HTable
Rel8.Schema.HTable.Either
Rel8.Schema.HTable.Identity
Rel8.Schema.HTable.Label
Rel8.Schema.HTable.List
Rel8.Schema.HTable.MapTable
Rel8.Schema.HTable.Maybe
Rel8.Schema.HTable.NonEmpty
Rel8.Schema.HTable.Nullify
Rel8.Schema.HTable.Product
Rel8.Schema.HTable.These
Rel8.Schema.HTable.Vectorize
2021-03-24 05:13:15 +03:00
Rel8.Schema.Kind
Rel8.Schema.Name
2021-04-08 00:35:40 +03:00
Rel8.Schema.Null
Rel8.Schema.QualifiedName
Rel8.Schema.Result
Rel8.Schema.Spec
Rel8.Schema.Table
Statements overhaul (support for statement-level `WITH`) (#250) The motivation behind this PR is to add support for PostreSQL's `WITH` syntax at the statement level, which gives the ability to, e.g., delete some rows from a table and then re-insert those deleted rows into another table, without any round-trips between the application and the database. To support this, this PR introduces a new type called `Statement`, which represents a single PostgreSQL statement. It has a `Monad` instance which allows sub-statements (such as `DELETE` and `INSERT` statements) to be composed together and their results bound to values that can be referenced in subsequent sub-statements. These "compound" statements are then rendered as a `WITH` statement. `select`, `insert`, `update` and `delete` have all been altered to produce the `Statement` type described above instead of the `Hasql.Statement` type. Some changes were necessary to the `Returning` type. `Returning` previously bundled two different concepts together: whether or not to generate a `RETURNING` clause in the SQL for a manipulation statement, and how to decode the returned rows (if any). It was necessary to break these concepts apart because with `WITH` we need the ability to generate manipulation statements with `RETURNING` clauses that are never actually decoded at all (the results just get passed to the next statement without touching the application). Now, the `Returning` type is only concerned with whether or not to generate a `RETURNING` clause, and the question of how to decode the returned the result of the statement is handled by the `run` functions. `run` converts a `Statement` into a runnable `Hasql.Statement`, decoding the result of the statement as a list of rows. The other variations, `run_`, `runN`, `run1`, `runMaybe` and `runVector` can be used when you want to decode as something other than a list of rows. This also gains us support for decoding the result of a query directly to a `Vector` for the first time, which brings a performance improvement over lists for those who need it.
2023-07-07 13:29:15 +03:00
Rel8.Statement
Rel8.Statement.Delete
Rel8.Statement.Insert
Rel8.Statement.OnConflict
Rel8.Statement.Returning
Statements overhaul (support for statement-level `WITH`) (#250) The motivation behind this PR is to add support for PostreSQL's `WITH` syntax at the statement level, which gives the ability to, e.g., delete some rows from a table and then re-insert those deleted rows into another table, without any round-trips between the application and the database. To support this, this PR introduces a new type called `Statement`, which represents a single PostgreSQL statement. It has a `Monad` instance which allows sub-statements (such as `DELETE` and `INSERT` statements) to be composed together and their results bound to values that can be referenced in subsequent sub-statements. These "compound" statements are then rendered as a `WITH` statement. `select`, `insert`, `update` and `delete` have all been altered to produce the `Statement` type described above instead of the `Hasql.Statement` type. Some changes were necessary to the `Returning` type. `Returning` previously bundled two different concepts together: whether or not to generate a `RETURNING` clause in the SQL for a manipulation statement, and how to decode the returned rows (if any). It was necessary to break these concepts apart because with `WITH` we need the ability to generate manipulation statements with `RETURNING` clauses that are never actually decoded at all (the results just get passed to the next statement without touching the application). Now, the `Returning` type is only concerned with whether or not to generate a `RETURNING` clause, and the question of how to decode the returned the result of the statement is handled by the `run` functions. `run` converts a `Statement` into a runnable `Hasql.Statement`, decoding the result of the statement as a list of rows. The other variations, `run_`, `runN`, `run1`, `runMaybe` and `runVector` can be used when you want to decode as something other than a list of rows. This also gains us support for decoding the result of a query directly to a `Vector` for the first time, which brings a performance improvement over lists for those who need it.
2023-07-07 13:29:15 +03:00
Rel8.Statement.Rows
Rel8.Statement.Run
Rel8.Statement.Select
Rel8.Statement.Set
Rel8.Statement.SQL
Rel8.Statement.Update
Rel8.Statement.Using
Rel8.Statement.View
Rel8.Statement.Where
Rel8.Table
Rel8.Table.ADT
Rel8.Table.Aggregate
Rel8.Table.Alternative
Rel8.Table.Bool
Rel8.Table.Cols
Rel8.Table.Either
Rel8.Table.Eq
Rel8.Table.HKD
Rel8.Table.List
Rel8.Table.Maybe
Rel8.Table.Name
Rel8.Table.NonEmpty
Rel8.Table.Null
Rel8.Table.Nullify
Rel8.Table.Opaleye
Rel8.Table.Ord
Rel8.Table.Order
Rel8.Table.Projection
Rel8.Table.Rel8able
Rel8.Table.Serialize
Rel8.Table.These
Rel8.Table.Transpose
Rel8.Table.Undefined
2022-10-14 04:06:07 +03:00
Rel8.Table.Window
Rel8.Type
2021-03-23 21:16:33 +03:00
Rel8.Type.Array
Rel8.Type.Composite
Rel8.Type.Decimal
Rel8.Type.Decoder
Rel8.Type.Eq
Rel8.Type.Enum
Rel8.Type.Information
Rel8.Type.JSONEncoded
Rel8.Type.JSONBEncoded
Rel8.Type.Monoid
Rel8.Type.Name
Rel8.Type.Num
Rel8.Type.Ord
Rel8.Type.Parser
Rel8.Type.Parser.ByteString
Rel8.Type.Parser.Time
Rel8.Type.ReadShow
Rel8.Type.Semigroup
Rel8.Type.String
Rel8.Type.Sum
Rel8.Type.Tag
2022-10-14 04:06:07 +03:00
Rel8.Window
test-suite tests
type: exitcode-stdio-1.0
build-depends:
base
, bytestring
, case-insensitive
, containers
2023-04-14 12:56:03 +03:00
, data-dword
, hasql
, hasql-transaction
2024-03-18 18:22:03 +03:00
, hedgehog ^>= 1.0 || ^>= 1.1 || ^>= 1.2 || ^>= 1.3 || ^>= 1.4 || ^>= 1.5
, mmorph
2023-04-14 12:56:03 +03:00
, network-ip
, rel8
, scientific
, tasty
, tasty-hedgehog
, text
, time
, tmp-postgres ^>=1.34.1.0
, transformers
, uuid
other-modules:
Rel8.Generic.Rel8able.Test
main-is: Main.hs
hs-source-dirs: tests
default-language: Haskell2010
ghc-options:
-Weverything -Wno-unsafe -Wno-safe -Wno-missing-safe-haskell-mode
-Wno-missing-import-lists -Wno-prepositive-qualified-module
-Wno-deprecations -Wno-monomorphism-restriction
-Wno-missing-local-signatures -Wno-implicit-prelude
Statements overhaul (support for statement-level `WITH`) (#250) The motivation behind this PR is to add support for PostreSQL's `WITH` syntax at the statement level, which gives the ability to, e.g., delete some rows from a table and then re-insert those deleted rows into another table, without any round-trips between the application and the database. To support this, this PR introduces a new type called `Statement`, which represents a single PostgreSQL statement. It has a `Monad` instance which allows sub-statements (such as `DELETE` and `INSERT` statements) to be composed together and their results bound to values that can be referenced in subsequent sub-statements. These "compound" statements are then rendered as a `WITH` statement. `select`, `insert`, `update` and `delete` have all been altered to produce the `Statement` type described above instead of the `Hasql.Statement` type. Some changes were necessary to the `Returning` type. `Returning` previously bundled two different concepts together: whether or not to generate a `RETURNING` clause in the SQL for a manipulation statement, and how to decode the returned rows (if any). It was necessary to break these concepts apart because with `WITH` we need the ability to generate manipulation statements with `RETURNING` clauses that are never actually decoded at all (the results just get passed to the next statement without touching the application). Now, the `Returning` type is only concerned with whether or not to generate a `RETURNING` clause, and the question of how to decode the returned the result of the statement is handled by the `run` functions. `run` converts a `Statement` into a runnable `Hasql.Statement`, decoding the result of the statement as a list of rows. The other variations, `run_`, `runN`, `run1`, `runMaybe` and `runVector` can be used when you want to decode as something other than a list of rows. This also gains us support for decoding the result of a query directly to a `Vector` for the first time, which brings a performance improvement over lists for those who need it.
2023-07-07 13:29:15 +03:00
-Wno-missing-kind-signatures