Database.Persist.ImplicitIdDef

persistent-2.14.6.3: Type-safe, multi-backend data serialization.

Safe Haskell | None
Language | Haskell2010

Database.Persist.ImplicitIdDef

Contents

- The Type
- Construction
- Autoincrementing Integer Key
- Getters
- Setters

Description

This module contains types and functions for creating an `ImplicitIdDef`, which allows you to customize the implied ID column that `persistent` generates.

If this module doesn't suit your needs, you may want to import Database.Persist.ImplicitIdDef.Internal instead. If you do so, please file an issue on GitHub so we can support your needs. Breaking changes to that module will *not* be accompanied with a major version bump.

Since: 2.13.0.0

Synopsis

- data ImplicitIdDef
- mkImplicitIdDef :: (Typeable t, PersistFieldSql t) => Text -> ImplicitIdDef
- autoIncrementingInteger :: ImplicitIdDef
- setImplicitIdDefMaxLen :: Integer -> ImplicitIdDef -> ImplicitIdDef
- unsafeClearDefaultImplicitId :: ImplicitIdDef -> ImplicitIdDef

# The Type

data ImplicitIdDef #

A specification for how the implied ID columns are created.

By default, `persistent` will give each table a default column named `id` (customizable by `PersistSettings`), and the column type will be whatever you'd expect from ``BackendKey` yourBackendType`. For The `SqlBackend` type, this is an auto incrementing integer primary key.

You might want to give a different example. A common use case in postgresql is to use the UUID type, and automatically generate them using a SQL function.

Previously, you'd need to add a custom `Id` annotation for each model.

    User
        Id   UUID default="uuid_generate_v1mc()"
        name Text

    Dog
        Id   UUID default="uuid_generate_v1mc()"
        name Text
        user UserId

Now, you can simply create an `ImplicitIdDef` that corresponds to this declaration.

    newtype UUID = UUID ByteString

    instance PersistField UUID where
        toPersistValue (UUID bs) =
            PersistLiteral_ Escaped bs
        fromPersistValue pv =
            case pv of
                PersistLiteral_ Escaped bs ->
                    Right (UUID bs)
                _ ->
                    Left "nope"

    instance PersistFieldSql UUID where
        sqlType _ = SqlOther UUID

With this instance at the ready, we can now create our implicit definition:

    uuidDef :: ImplicitIdDef
    uuidDef = mkImplicitIdDef @UUID "uuid_generate_v1mc()"

And we can use `setImplicitIdDef` to use this with the `MkPersistSettings` for our block.

    mkPersist (setImplicitIdDef uuidDef sqlSettings) [persistLowerCase| ... |]

TODO: either explain interaction with mkMigrate or fix it. see issue #1249 for more details.

Since: 2.13.0.0

# Construction

mkImplicitIdDef #

Arguments

:: (Typeable t, PersistFieldSql t) |
=> Text | The default expression to use for columns. Should be valid SQL in the language you're using.
-> ImplicitIdDef |

Create an `ImplicitIdDef` based on the `Typeable` and `PersistFieldSql` constraints in scope.

This function uses the `TypeApplications` syntax. Let's look at an example that works with Postgres UUIDs.

    newtype UUID = UUID Text
        deriving newtype PersistField

    instance PersistFieldSql UUID where
        sqlType _ = SqlOther "UUID"

    idDef :: ImplicitIdDef
    idDef = mkImplicitIdDefTypeable @UUID "uuid_generate_v1mc()"

This `ImplicitIdDef` will generate default UUID columns, and the database will call the `uuid_generate_v1mc()` function to generate the value for new rows being inserted.

If the type `t` is `Text` or `String` then a `max_len` attribute of 200 is set. To customize this, use `setImplicitIdDefMaxLen`.

Since: 2.13.0.0

# Autoincrementing Integer Key

autoIncrementingInteger :: ImplicitIdDef #

This is the default variant. Setting the implicit ID definition to this value should not have any change at all on how entities are defined by default.

Since: 2.13.0.0

# Getters

# Setters

setImplicitIdDefMaxLen :: Integer -> ImplicitIdDef -> ImplicitIdDef #

Set the maximum length of the implied ID column. This is required for any type where the associated `SqlType` is a `TEXT` or `VARCHAR` sort of thing.

Since: 2.13.0.0

unsafeClearDefaultImplicitId :: ImplicitIdDef -> ImplicitIdDef #

Remove the default attribute of the `ImplicitIdDef` column. This will require you to provide an ID for the model with every insert, using `insertKey` instead of `insert`, unless the type has some means of getting around that in the migrations.

As an example, the Postgresql `SERIAL` type expands to an autoincrementing integer. Postgres will implicitly create the relevant series and set the default to be `NEXTVAL(`series_name`)`. A default is therefore unnecessary to use for this type.

However, for a `UUID`, postgres *does not* have an implicit default. You must either specify a default UUID generation function, or insert them yourself (again, using `insertKey`).

This function will be deprecated in the future when omiting the default implicit ID column is more fully supported.

Since: 2.13.0.0