This module exports many types and functions for operating on
persistent's database representation. It's a bit of a kitchen sink. In the
future, this module will be reorganized, and many of the dependent modules
will be viewable on their own for easier documentation and organization.
There are so many kinds of names. persistent defines newtype wrappers
for Text so you don't confuse what a name is and what it is
supposed to be used for
The EntityDef type is used by persistent to generate Haskell code,
generate database migrations, and maintain metadata about entities. These
are generated in the call to mkPersist.
Filters which are available for select, updateWhere and
deleteWhere. Each filter constructor specifies the field being
filtered on, the type of comparison applied (equals, not equals, etc)
and the argument for the comparison.
Persistent users use combinators to create these.
Note that it's important to be careful about the PersistFilter that
you are using, if you use this directly. For example, using the InPersistFilter requires that you have an array- or list-shaped
EntityField. It is possible to construct values using this that will
create malformed runtime values.
Datatype that represents an entity, with both its Key and
its Haskell record representation.
When using a SQL-based backend (such as SQLite or
PostgreSQL), an Entity may take any number of columns
depending on how many fields it has. In order to reconstruct
your entity on the Haskell side, persistent needs all of
your entity columns and in the right order. Note that you
don't need to worry about this when using persistent's API
since everything is handled correctly behind the scenes.
However, if you want to issue a raw SQL command that returns
an Entity, then you have to be careful with the column
order. While you could use SELECT Entity.* WHERE ... and
that would work most of the time, there are times when the
order of the columns on your database is different from the
order that persistent expects (for example, if you add a new
field in the middle of you entity definition and then use the
migration code -- persistent will expect the column to be in
the middle, but your DBMS will put it as the last column).
So, instead of using a query like the one above, you may use
rawSql (from the
Database.Persist.Sql module) with its /entity
selection placeholder/ (a double question mark ??). Using
rawSql the query above must be written as SELECT ?? WHERE
... Then rawSql will replace ?? with the list of all
columns that we need from your entity in the right order. If
your query returns two entities (i.e. (Entity backend a,
Entity backend b)), then you must you use SELECT ??, ??
WHERE ..., and so on.
Prior to persistent-2.11.0, we provided an instance of
PersistField for the Natural type. This was in error, because
Natural represents an infinite value, and databases don't have
reasonable types for this.
The instance for Natural used the Int64 underlying type, which will
cause underflow and overflow errors. This type has the exact same code
in the instances, and will work seamlessly.
A more appropriate type for this is the Word series of types from
Data.Word. These have a bounded size, are guaranteed to be
non-negative, and are quite efficient for the database to store.
This type uses the SqlInt64 version, which will exhibit overflow and
underflow behavior. Additionally, it permits negative values in the
database, which isn't ideal.
A FieldDef represents the inormation that persistent knows about
a field of a datatype. This includes information used to parse the field
out of the database and what the field corresponds to.
The name of the field. Note that this does not corresponds to the
record labels generated for the particular entity - record labels
are generated with the type name prefixed to the field, so
a FieldDef that contains a FieldNameHS "name" for a type
User will have a record field userName.
Defines how operations on the field cascade on to the referenced
tables. This doesn't have any meaning if the fieldReference is set
to NoReference or SelfReference. The cascade option here should
be the same as the one obtained in the fieldReference.
This constructor is used to specify some raw literal value for the
backend. The LiteralType value specifies how the value should be
escaped. This can be used to make special, custom types avaialable
in the back end.
This pattern synonym used to be a data constructor on PersistValue,
but was changed into a catch-all pattern synonym to allow backwards
compatiblity with database types. See the documentation on
PersistDbSpecific for more details.
This pattern synonym used to be a data constructor on PersistValue,
but was changed into a catch-all pattern synonym to allow backwards
compatiblity with database types. See the documentation on
PersistDbSpecific for more details.
Deprecated. Deprecated since 2.11 because of inconsistent escaping behavior across backends. The Postgres backend escapes these values, while the MySQL backend does not. If you are using this, please switch to PersistLiteral_ and provide a relevant LiteralType for your conversion.
This pattern synonym used to be a data constructor for the
PersistValue type. It was changed to be a pattern so that JSON-encoded
database values could be parsed into their corresponding values. You
should not use this, and instead prefer to pattern match on
PersistLiteral_ directly.
If you use this, it will overlap a patern match on the 'PersistLiteral_,
PersistLiteral, and PersistLiteralEscaped patterns. If you need to
disambiguate between these constructors, pattern match on
PersistLiteral_ directly.
A Checkmark should be used as a field type whenever a
uniqueness constraint should guarantee that a certain kind of
record may appear at most once, but other kinds of records may
appear any number of times.
NOTE: You need to mark any Checkmark fields as nullable
(see the following example).
For example, suppose there's a Location entity that
represents where a user has lived:
Location
user UserId
name Text
current Checkmark nullable
UniqueLocation user current
The UniqueLocation constraint allows any number of
InactiveLocations to be current. However, there may be
at most one currentLocation per user (i.e., either zero
or one per user).
This data type works because of the way that SQL treats
NULLable fields within uniqueness constraints. The SQL
standard says that NULL values should be considered
different, so we represent Inactive as SQL NULL, thus
allowing any number of Inactive records. On the other hand,
we represent Active as TRUE, so the uniqueness constraint
will disallow more than one Active record.
Note: There may be DBMSs that do not respect the SQL
standard's treatment of NULL values on uniqueness
constraints, please check if this data type works before
relying on it.
The SQL BOOLEAN type is used because it's the smallest data
type available. Note that we never use FALSE, just TRUE
and NULL. Provides the same behavior Maybe () would if
() was a valid PersistField.
This indicates that the column is nullable, but should not have
a Maybe type. For this to work out, you need to ensure that the
PersistField instance for the type in question can support
a PersistNull value.
data What = NoWhat | Hello Text
instance PersistField What where
fromPersistValue PersistNull =
pure NoWhat
fromPersistValue pv =
Hello $ fromPersistValue pv
instance PersistFieldSql What where
sqlType _ = SqlString
User
what What nullable
This tag means that the column will not be present on the Haskell code,
but will not be removed from the database. Useful to deprecate fields in
phases.
You should set the column to be nullable in the database. Otherwise,
inserts won't have values.
A SafeToRemove attribute is not present on the Haskell datatype, and
the backend migrations should attempt to drop the column without
triggering any unsafe migration warnings.
Useful after you've used MigrationOnly to remove a column from the
database in phases.
This attribute indicates that we should not create a foreign key
reference from a column. By default, persistent will try and create a
foreign key reference for a column if it can determine that the type of
the column is a Key entity or an EntityId and the Entity's name
was present in mkPersist.
This is useful if you want to use the explicit foreign key syntax.
Post
title Text
Comment
postId PostId noreference
Foreign Post fk_comment_post postId
This is set to specify precisely the database table the column refers
to.
Post
title Text
Comment
postId PostId references="post"
You should not need this - persistent should be capable of correctly
determining the target table's name. If you do need this, please file an
issue describing why.
This datatype describes how a foreign reference field cascades deletes
or updates.
This type is used in both parsing the model definitions and performing
migrations. A Nothing in either of the field values means that the
user has not specified a CascadeAction. An unspecified CascadeAction
is defaulted to Restrict when doing migrations.
The DbSpecific constructor corresponds to the legacy
PersistDbSpecific constructor. We need to keep this around because
old databases may have serialized JSON representations that
reference this. We don't want to break the ability of a database to
load rows.
Instances4Eq, Ord, Read, Show
EqLiteralTypeDefined in persistent-2.14.6.3 · Database.Persist.PersistValue
OrdLiteralTypeDefined in persistent-2.14.6.3 · Database.Persist.PersistValue
ReadLiteralTypeDefined in persistent-2.14.6.3 · Database.Persist.PersistValue
ShowLiteralTypeDefined in persistent-2.14.6.3 · Database.Persist.PersistValue
A SQL data type. Naming attempts to reflect the underlying Haskell
datatypes, eg SqlString instead of SqlVarchar. Different SQL databases may
have different translations for these types.
The reason why a field is nullable is very important. A
field that is nullable because of a Maybe tag will have its
type changed from A to Maybe A. OTOH, a field that is
nullable because of a nullable tag will remain with the same
type.
Parse raw field attributes into structured form. Any unrecognized
attributes will be preserved, identically as they are encountered,
as FieldAttrOther values.