Skip to content

Releases: morphismtech/squeal

0.9.1.3

01 Sep 21:12
Compare
Choose a tag to compare

0.9.1.2

01 Sep 19:49
Compare
Choose a tag to compare

0.9.1.2

0.9.1.1

01 Sep 18:42
693b53b
Compare
Choose a tag to compare

0.9.1.1

0.9.1.0

21 Nov 18:08
22a8d7a
Compare
Choose a tag to compare

Some GHC 9 compatibility and genericProductRow.

0.9.0.0

13 May 18:00
599ebb9
Compare
Choose a tag to compare

Version 0.9.0.0

Thanks to William Yao and Cullin Poresky for their contributions!

Prepared Statements

Squeal 0.9 adds a new Prepared type for prepared statements.

data Prepared m x y = Prepared
  { runPrepared :: x -> m y -- ^ execute a prepared statement
  , deallocate :: m () -- ^ manually clean up a prepared statement
  }

This allows to factor and generalize the functions executePrepared
and executePrepared_. Squeal 0.9 adds new methods prepare and
prepare_ to the MonadPQ typeclass.

prepare
  :: MonadPQ pq
  => Statement db x y
  -> pq (Prepared pq x (Result y))

prepare_
  :: MonadPQ pq
  => Statement db x ()
  -> pq (Prepared pq x ())

They may then be run using runPrepared and manually cleaned up
using deallocate. The Prepared type has a cornucopia of instances
allowing you to combine prepared statements in lots of ways. Instances
Prepared supports include Category, Arrow, Profunctor and more.

A function preparedFor abstracts the pattern of preparing a statement,
then doing something with it and finally deallocating. That something
can be thought of as an "optic", a generalization of lenses.

preparedFor
  :: MonadPQ db pq
  => (Prepared pq a (Result b) -> Prepared pq s t)
  -- ^ transform the input and output using an "optic"
  -> Statement db a b -- ^ query or manipulation
  -> s -> pq t

For instance, using the optic traverse' recovers the function
executePrepared and using the optic wander traverse_ recovers the
function executePrepared_, which are used for running prepared statements
over Traversable or Foldable containers of parameters respectively.

With the generalized notion of a Prepared object, you can prepare statments
and optionally combine them at the beginning of a database session and
have a Prepared object to use with runPrepared throughout the session.
This is a lower level primitive and closer to the model that PostgreSQL
actually provides than what Squeal previously allowed.

Row and Enum Types

Squeal 0.9 adds a number of new features for row and enum types.

First, new type families DbRelations and DbEnums have been added,
which filter a SchemasType down to all row or enum types.
A relation means a table, view or composite type;
other kinds of relations are not currently supported. Previously,
Squeal's support for row types only covered composite types but
Squeal 0.9 adds more support for tables and views. New TypeExpressions
typerow and typeenum have been added. A new type family FindQualified,
which looks through database schemas to find a row or enum type has been added.
Squeal will now look through all tables, views and composite types when
trying to find a user-defined relation to match your row type where previously
it had only looked for composites.

Next, new functions have been added to allow users to define manual encodings
for row and enum types. Previously, Squeal only had functions to allow users to
define manual decodings for row and enum types. For enum types,
you can now use enumParam like so:

data Dir = North | South | East | West
instance IsPG Dir where
  type PG Dir = 'PGenum '["north", "south", "east", "west"]
instance ToPG db Dir where
  toPG = enumParam $ \case
    North -> label @"north"
    South -> label @"south"
    East -> label @"east"
    West -> label @"west"

For row types you can now use rowParam together with new combinators
.# to cons and #. to end the row like so:

data Quaternion = Quaternion
  { real :: Double
  , imaginaryI :: Double
  , imaginaryJ :: Double
  , imaginaryK :: Double
  }
instance IsPG Quaternion where
  type PG Quaternion = 'PGcomposite '[
    "re" ::: 'NotNull 'PGfloat8,
    "im" ::: 'NotNull 'PGfloat8,
    "jim" ::: 'NotNull 'PGfloat8,
    "kim" ::: 'NotNull 'PGfloat8]
instance ToPG db Quaternion where
  toPG = rowParam $
             real `as` #re
    .# imaginaryI `as` #im
    .# imaginaryJ `as` #jim
    #. imaginaryK `as` #kim

There is also a function genericRowParams, which can
be used with combinators like so:

data L = L {frst :: Int16, scnd :: Char}
  deriving stock (GHC.Generic, Show)
  deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
data R = R {thrd :: Bool, frth :: Bool}
  deriving stock (GHC.Generic, Show)
  deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
instance IsPG (L,R) where
  type PG (L,R) = 'PGcomposite '[
    "frst" ::: 'NotNull 'PGint2,
    "scnd" ::: 'NotNull ('PGchar 1),
    "thrd" ::: 'NotNull 'PGbool,
    "frth" ::: 'NotNull 'PGbool]
instance ToPG db (L,R) where
  toPG = rowParam $
    contramap fst genericRowParams
    `appendParams`
    contramap snd genericRowParams

All of this is made possible by generalizing the EncodeParams
type to polykinded:

newtype EncodeParams
  (db :: SchemasType)
  (tys :: [k])
  (x :: Type)

Since it is polykinded, the tys parameter can have either
the kind [NullType] or the kind RowType.

Other Changes

Squeal 0.9 adds support for GHC 9, which required fully saturating
a number of functions that involved RankNTypes, a change
required by the "simplified subsumption" proposal.

A bug for Has custom type errors, which made it expensive
in the case of a lookup failure because of use of the strict If
type family, has been fixed, thanks to Cullin.

Missing images and some small fixes were added for the Squeal
"Core Concepts Handbook", thanks to William.

CI has been fixed to properly test across different versions of GHC.

The function notNull which has a non-intuitive name has been
deprecated and a replacement function just_ has been added. The
terms null_ and just_ now intentionally connote Nothing and
Just from Haskell's Maybe type.

The operators (.<@) and (@>.) as well as the functions arrAny
and arrAll have been generalized to allow Null arguments. Previously,
they had been improperly restricted to have NotNull arguments.

PQ has been given MonadFix, Alternative and MonadPlus instances.

0.8.1.1

28 Oct 16:52
9c03fb0
Compare
Choose a tag to compare

Version 0.8.1.1

Fix a bug in how the new Has type mismatch errors
were implemented, which made it do the expensive pretty-printing
even in the non-error case, resulting in extreme memory usage
at compile time for non-trivial cases.

Version 0.8.1.0

Improvements to type errors for Has/HasErr, HasParameter,
and trying to aggregate without grouping.

0.8

19 Oct 22:59
eb3d028
Compare
Choose a tag to compare
0.8

Version 0.8

Thanks to Adam Wespiser, Cullin Poreski, Scott Fleischman
and William Yao for lots of contributions.

Materialized CTEs

Scott Fleischman contributed materialization support to Squeal's
WITH statements.

LTrees and UUID

New packages squeal-postgresql-ltree and squeal-postgresql-uuid-ossp
were created to offer functionality from those Postgres extensions.

Safe Transactions

Previously, Squeal transactions were "unsafe", allowing for arbitrary
IO. Now, Squeal provides a new type Transaction that is a RankNType.

type Transaction db x = forall m.
  ( MonadPQ db m
  , MonadResult m
  , MonadCatch m
  ) => m x

A Transaction only permits database operations and error handling,
no arbitrary IO. The class MonadResult is new but all of its
methods are old and used to be constrained as MonadIO,
now as MonadResult.

Additionally, a new function withSavepoint was added, allowing
for a kind of nested transactions.

0.7.0.1

01 Oct 17:04
Compare
Choose a tag to compare

Version 0.7

Thanks to Samuel Schlesinger, Adam Wespiser, Cullin Poreski,
Matthew Doty and Mark Wotton for tons of contributions.
Version 0.7 of Squeal makes many changes.

Inter-schema Foreign Key Bug
Unfortunately, there was a bug in inter-schema foreign keys in previous
versions of Squeal. Essentially, it was erroneously assumed that
foreign keys always point to tables in the public schema. To remedy this
the ForeignKey type has changed kind from

>>> :kind 'ForeignKey
'ForeignKey :: [Symbol]
               -> Symbol -> [Symbol] -> TableConstraint

to

>>> :kind 'ForeignKey
'ForeignKey :: [Symbol]
               -> Symbol -> Symbol -> [Symbol] -> TableConstraint

To upgrade your database schemas type, you will have to change, e.g.

'ForeignKey '["foo_id1", "foo_id2"] "foo" '["id1", "id2"]

to

'ForeignKey '["foo_id1", "foo_id2"] "public" "foo" '["id1", "id2"]

Locking Clauses

You can now add row level locking clauses to your select queries

Polymorphic Lateral Contexts

Previously, lateral contexts which are used for lateral joins
and subquery expressions had to have monomorphic lateral contexts,
which greatly reduced composability of queries involving lateral
joins. Squeal 0.7 fixes this limitation, making it possible to
have polymorphic lateral context! When looking up a column heretofore,
the relevant typeclasses would search through Join lat from.
This is the "correct" ordering as far as the structure from
left to right in the query, making lat consistently ordered as
one goes through nested lateral joins or nested subquery expressions.
However, it doesn't really matter how the lookup orders the columns.
And if the lookup searches through Join from lat instead then thanks
to good old Haskell lazy list appending, if a query only references
columns in from then it will work no matter the lat.
With a small proviso; if you leave lat polymorphic,
then you must qualify all columns since there could be more than
one table even if from has only one table in it.

Decoders

The DecodeRow Monad now has a MonadFail instance.

New row decoder combinators have been added. The functions
appendRows and consRow let you build row decoders up
from pieces.

Previously, Squeal made it easy to decode enum types to Haskell
enum types (sum types with nullary constructors) so long as
the Haskell type exactly matches the enum type. However, because
of limitations in Haskell - constructors must be capitalized,
name conflicts are often disambiguated with extra letters, etc -
it's often the case that their constructors won't exactly match the
Postgres enum type's labels. The new function enumValue allows
to define typesafe custom enum decoders, similar to how rowValue
allows to define typesafe custom composite decoders.

>>> :{
data Dir = North | East | South | West
instance IsPG Dir where
  type PG Dir = 'PGenum '["north", "south", "east", "west"]
instance FromPG Dir where
  fromPG = enumValue $
    label @"north" North :*
    label @"south" South :*
    label @"east" East :*
    label @"west" West
:}

Definitions

New DDL statements have been added allowing to rename and
reset the schema of different schemum objects. Also, new DDL statements
have been added for adding comments to schemum objects.

Procedures

Squeal now supports procedure definitions and calls.

cmdTuples and cmdStatus

The cmdTuples and cmdStatus functions from LibPQ are now
included.

PQ Monad Instances

the PQ Monad has been given instances for MonadCatch,
MonadThrow, MonadMask, MonadBase, MonadBaseControl, and
MonadTransControl.

Referential Actions

A new type ReferentialAction has been factored out of
OnDeleteClauses and OnUpdateClauses. And Missing actions,
SetNotNull and SetDefault are now included.

To upgrade, change from e.g. OnDeleteCascade to OnDelete Cascade.

Array functions

Squeal now offers typesafe indexing for fixed length arrays and matrices,
with new functions index1 and index2. And new functions arrAny
and arrAll have been added to enable comparisons to any or all elements
of a variable length array.

Manipulations

Tables being manipulated are now re-aliasable, and updates can reference
"from" clauses, actually called UsingClauses in Squeal, similar to deletes.

Other changes
New tests and bugfixes have been added. More support for encoding and decoding
of different types has been added. Time values now use iso8601 formatting
for inlining. Also, the GitHub repo has moved from using Circle CI to using
GitHub Actions for continuous integration testing.

0.6.0.2

23 Apr 17:10
7557c2d
Compare
Choose a tag to compare

Fix documentation for defaultMode for transactions.

0.6.0.1

16 Apr 23:38
f8a89ed
Compare
Choose a tag to compare

Documentation fixes.