Safe Haskell | None |
---|---|
Language | Haskell2010 |
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.
Synopsis
- module Database.Persist.Names
- module Database.Persist.EntityDef
- module Database.Persist.FieldDef
- module Database.Persist.PersistValue
- data SomePersistField = forall a. PersistField a => SomePersistField a
-
data
Update
record
-
=
forall
typ.
PersistField
typ =>
Update
{
- updateField :: EntityField record typ
- updateValue :: typ
- updateUpdate :: PersistUpdate
- | BackendUpdate ( BackendSpecificUpdate ( PersistEntityBackend record) record)
-
=
forall
typ.
PersistField
typ =>
Update
{
- type family BackendSpecificUpdate backend record
-
data
SelectOpt
record
- = forall typ. Asc ( EntityField record typ)
- | forall typ. Desc ( EntityField record typ)
- | OffsetBy Int
- | LimitTo Int
-
data
Filter
record
-
=
forall
typ.
PersistField
typ =>
Filter
{
- filterField :: EntityField record typ
- filterValue :: FilterValue typ
- filterFilter :: PersistFilter
- | FilterAnd [ Filter record]
- | FilterOr [ Filter record]
- | BackendFilter ( BackendSpecificFilter ( PersistEntityBackend record) record)
-
=
forall
typ.
PersistField
typ =>
Filter
{
-
data
FilterValue
typ
where
- FilterValue :: typ -> FilterValue typ
- FilterValues :: [typ] -> FilterValue typ
- UnsafeValue :: forall a typ. PersistField a => a -> FilterValue typ
- type family BackendSpecificFilter backend record
- data family Key record
- data Entity record = Entity { }
- newtype OverflowNatural = OverflowNatural { }
-
data
LiteralType
- = Escaped
- | Unescaped
- | DbSpecific
-
data
PersistValue
where
- PersistText Text
- PersistByteString ByteString
- PersistInt64 Int64
- PersistDouble Double
- PersistRational Rational
- PersistBool Bool
- PersistDay Day
- PersistTimeOfDay TimeOfDay
- PersistUTCTime UTCTime
- PersistNull
- PersistList [ PersistValue ]
- PersistMap [( Text , PersistValue )]
- PersistObjectId ByteString
- PersistArray [ PersistValue ]
- PersistLiteral_ LiteralType ByteString
- pattern PersistDbSpecific :: ByteString -> PersistValue
- pattern PersistLiteral :: ByteString -> PersistValue
- pattern PersistLiteralEscaped :: ByteString -> PersistValue
-
data
FieldDef
=
FieldDef
{
- fieldHaskell :: ! FieldNameHS
- fieldDB :: ! FieldNameDB
- fieldType :: ! FieldType
- fieldSqlType :: ! SqlType
- fieldAttrs :: ![ FieldAttr ]
- fieldStrict :: ! Bool
- fieldReference :: ! ReferenceDef
- fieldCascade :: ! FieldCascade
- fieldComments :: !( Maybe Text )
- fieldGenerated :: !( Maybe Text )
- fieldIsImplicitIdColumn :: ! Bool
- data PersistUpdate
- data UpdateException
- data PersistFilter
- data SqlType
- data PersistException
-
data
CascadeAction
- = Cascade
- | Restrict
- | SetNull
- | SetDefault
-
data
FieldCascade
=
FieldCascade
{
- fcOnUpdate :: !( Maybe CascadeAction )
- fcOnDelete :: !( Maybe CascadeAction )
-
data
ForeignDef
=
ForeignDef
{
- foreignRefTableHaskell :: ! EntityNameHS
- foreignRefTableDBName :: ! EntityNameDB
- foreignConstraintNameHaskell :: ! ConstraintNameHS
- foreignConstraintNameDBName :: ! ConstraintNameDB
- foreignFieldCascade :: ! FieldCascade
- foreignFields :: ![( ForeignFieldDef , ForeignFieldDef )]
- foreignAttrs :: ![ Attr ]
- foreignNullable :: Bool
- foreignToPrimary :: Bool
- type ForeignFieldDef = ( FieldNameHS , FieldNameDB )
-
data
CompositeDef
=
CompositeDef
{
- compositeFields :: !( NonEmpty FieldDef )
- compositeAttrs :: ![ Attr ]
-
data
UniqueDef
=
UniqueDef
{
- uniqueHaskell :: ! ConstraintNameHS
- uniqueDBName :: ! ConstraintNameDB
- uniqueFields :: !( NonEmpty ( FieldNameHS , FieldNameDB ))
- uniqueAttrs :: ![ Attr ]
-
data
EmbedFieldDef
=
EmbedFieldDef
{
- emFieldDB :: FieldNameDB
- emFieldEmbed :: Maybe ( Either SelfEmbed EntityNameHS )
- data EmbedEntityDef = EmbedEntityDef { }
- data ReferenceDef
- data FieldType
- data FieldAttr
- type Attr = Text
- type ExtraLine = [ Text ]
- data WhyNullable
-
data
IsNullable
- = Nullable ! WhyNullable
- | NotNullable
- data Checkmark
- fieldAttrsContainsNullable :: [ FieldAttr ] -> IsNullable
- keyAndEntityFields :: EntityDef -> NonEmpty FieldDef
- parseFieldAttrs :: [ Text ] -> [ FieldAttr ]
- noCascade :: FieldCascade
Various Types of Names
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
module Database.Persist.Names
Database Definitions
Entity/Table Definitions
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
.
module Database.Persist.EntityDef
Field definitions
The
FieldDef
type is used to describe how a field should be
represented at the Haskell and database layers.
module Database.Persist.FieldDef
Intermediate Values
The
PersistValue
type is used as an intermediate layer between
database and Haskell types.
Other Useful Stuff
Updating a database entity.
Persistent users use combinators to create these.
forall typ. PersistField typ => Update | |
|
|
BackendUpdate ( BackendSpecificUpdate ( PersistEntityBackend record) record) |
type family BackendSpecificUpdate backend record Source #
data SelectOpt record Source #
Query options.
Persistent users use these directly.
forall typ. Asc ( EntityField record typ) | |
forall typ. Desc ( EntityField record typ) | |
OffsetBy Int | |
LimitTo Int |
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
In
PersistFilter
requires that you have an array- or list-shaped
EntityField
. It is possible to construct values using this that will
create malformed runtime values.
forall typ. PersistField typ => Filter | |
|
|
FilterAnd [ Filter record] |
convenient for internal use, not needed for the API |
FilterOr [ Filter record] | |
BackendFilter ( BackendSpecificFilter ( PersistEntityBackend record) record) |
data FilterValue typ where Source #
Value to filter with. Highly dependant on the type of filter used.
Since: 2.10.0
FilterValue :: typ -> FilterValue typ | |
FilterValues :: [typ] -> FilterValue typ | |
UnsafeValue :: forall a typ. PersistField a => a -> FilterValue typ |
type family BackendSpecificFilter backend record Source #
data family Key record Source #
By default, a backend will automatically generate the key Instead you can specify a Primary key made up of unique values.
Instances
( PersistEntity a, PersistEntityBackend a ~ backend, IsPersistBackend backend) => RawSql ( Key a) Source # | |
Defined in Database.Persist.Sql.Class rawSqlCols :: ( Text -> Text ) -> Key a -> ( Int , [ Text ]) Source # rawSqlColCountReason :: Key a -> String Source # rawSqlProcessRow :: [ PersistValue ] -> Either Text ( Key a) Source # |
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.GenericSql
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.
Instances
newtype OverflowNatural Source #
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.
Since: 2.11.0
Instances
The rest of the types
data LiteralType Source #
A type that determines how a backend should handle the literal.
Since: 2.12.0.0
Escaped |
The accompanying value will be escaped before inserting into the database. This is the correct default choice to use. Since: 2.12.0.0 |
Unescaped |
The accompanying value will not be escaped when inserting into the database. This is potentially dangerous - use this with care. Since: 2.12.0.0 |
DbSpecific |
The
Since: 2.12.0.0 |
Instances
Eq LiteralType Source # | |
Defined in Database.Persist.PersistValue (==) :: LiteralType -> LiteralType -> Bool Source # (/=) :: LiteralType -> LiteralType -> Bool Source # |
|
Ord LiteralType Source # | |
Defined in Database.Persist.PersistValue compare :: LiteralType -> LiteralType -> Ordering Source # (<) :: LiteralType -> LiteralType -> Bool Source # (<=) :: LiteralType -> LiteralType -> Bool Source # (>) :: LiteralType -> LiteralType -> Bool Source # (>=) :: LiteralType -> LiteralType -> Bool Source # max :: LiteralType -> LiteralType -> LiteralType Source # min :: LiteralType -> LiteralType -> LiteralType Source # |
|
Read LiteralType Source # | |
Defined in Database.Persist.PersistValue readsPrec :: Int -> ReadS LiteralType Source # readList :: ReadS [ LiteralType ] Source # readPrec :: ReadPrec LiteralType Source # readListPrec :: ReadPrec [ LiteralType ] Source # |
|
Show LiteralType Source # | |
Defined in Database.Persist.PersistValue |
data PersistValue Source #
A raw value which can be stored in any backend and can be marshalled to
and from a
PersistField
.
PersistText Text | |
PersistByteString ByteString | |
PersistInt64 Int64 | |
PersistDouble Double | |
PersistRational Rational | |
PersistBool Bool | |
PersistDay Day | |
PersistTimeOfDay TimeOfDay | |
PersistUTCTime UTCTime | |
PersistNull | |
PersistList [ PersistValue ] | |
PersistMap [( Text , PersistValue )] | |
PersistObjectId ByteString |
Intended especially for MongoDB backend |
PersistArray [ PersistValue ] |
Intended especially for PostgreSQL backend for text arrays |
PersistLiteral_ LiteralType ByteString |
This constructor is used to specify some raw literal value for the
backend. The
Since: 2.12.0.0 |
pattern PersistDbSpecific :: ByteString -> PersistValue |
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
This pattern synonym used to be a data constructor for the
If you use this, it will overlap a patern match on the 'PersistLiteral_,
Since: 2.12.0.0 |
pattern PersistLiteral :: ByteString -> PersistValue |
This pattern synonym used to be a data constructor on
Since: 2.12.0.0 |
pattern PersistLiteralEscaped :: ByteString -> PersistValue |
This pattern synonym used to be a data constructor on
Since: 2.12.0.0 |
Instances
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.
FieldDef | |
|
Instances
Eq FieldDef Source # | |
Ord FieldDef Source # | |
Defined in Database.Persist.Types.Base |
|
Read FieldDef Source # | |
Show FieldDef Source # | |
Lift FieldDef Source # | |
data PersistUpdate Source #
Instances
Read PersistUpdate Source # | |
Defined in Database.Persist.Types.Base readsPrec :: Int -> ReadS PersistUpdate Source # readList :: ReadS [ PersistUpdate ] Source # readPrec :: ReadPrec PersistUpdate Source # readListPrec :: ReadPrec [ PersistUpdate ] Source # |
|
Show PersistUpdate Source # | |
Defined in Database.Persist.Types.Base |
|
Lift PersistUpdate Source # | |
Defined in Database.Persist.Types.Base lift :: PersistUpdate -> Q Exp Source # liftTyped :: PersistUpdate -> Q ( TExp PersistUpdate ) Source # |
data UpdateException Source #
Instances
Show UpdateException Source # | |
Defined in Database.Persist.Types.Base |
|
Exception UpdateException Source # | |
Defined in Database.Persist.Types.Base |
data PersistFilter Source #
Instances
Read PersistFilter Source # | |
Defined in Database.Persist.Types.Base readsPrec :: Int -> ReadS PersistFilter Source # readList :: ReadS [ PersistFilter ] Source # readPrec :: ReadPrec PersistFilter Source # readListPrec :: ReadPrec [ PersistFilter ] Source # |
|
Show PersistFilter Source # | |
Defined in Database.Persist.Types.Base |
|
Lift PersistFilter Source # | |
Defined in Database.Persist.Types.Base lift :: PersistFilter -> Q Exp Source # liftTyped :: PersistFilter -> Q ( TExp PersistFilter ) Source # |
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.
SqlString | |
SqlInt32 | |
SqlInt64 | |
SqlReal | |
SqlNumeric Word32 Word32 | |
SqlBool | |
SqlDay | |
SqlTime | |
SqlDayTime |
Always uses UTC timezone |
SqlBlob | |
SqlOther Text |
a backend-specific name |
Instances
Eq SqlType Source # | |
Ord SqlType Source # | |
Defined in Database.Persist.Types.Base |
|
Read SqlType Source # | |
Show SqlType Source # | |
Lift SqlType Source # | |
data PersistException Source #
PersistError Text |
Generic Exception |
PersistMarshalError Text | |
PersistInvalidField Text | |
PersistForeignConstraintUnmet Text | |
PersistMongoDBError Text | |
PersistMongoDBUnsupported Text |
Instances
Show PersistException Source # | |
Defined in Database.Persist.Types.Base |
|
Exception PersistException Source # | |
Defined in Database.Persist.Types.Base |
data CascadeAction Source #
An action that might happen on a deletion or update on a foreign key change.
Since: 2.11.0
Instances
data FieldCascade Source #
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.
Since: 2.11.0
FieldCascade | |
|
Instances
data ForeignDef Source #
ForeignDef | |
|
Instances
type ForeignFieldDef = ( FieldNameHS , FieldNameDB ) Source #
Used instead of FieldDef to generate a smaller amount of code
data CompositeDef Source #
CompositeDef | |
|
Instances
Type for storing the Uniqueness constraint in the Schema. Assume you have the following schema with a uniqueness constraint:
Person name String age Int UniqueAge age
This will be represented as:
UniqueDef { uniqueHaskell = ConstraintNameHS (packPTH UniqueAge) , uniqueDBName = ConstraintNameDB (packPTH "unique_age") , uniqueFields = [(FieldNameHS (packPTH "age"), FieldNameDB (packPTH "age"))] , uniqueAttrs = [] }
UniqueDef | |
|
Instances
Eq UniqueDef Source # | |
Ord UniqueDef Source # | |
Defined in Database.Persist.Types.Base |
|
Read UniqueDef Source # | |
Show UniqueDef Source # | |
Lift UniqueDef Source # | |
data EmbedFieldDef Source #
An EmbedFieldDef is the same as a FieldDef But it is only used for embeddedFields so it only has data needed for embedding
EmbedFieldDef | |
|
Instances
data EmbedEntityDef Source #
An EmbedEntityDef is the same as an EntityDef But it is only used for fieldReference so it only has data needed for embedding
Instances
data ReferenceDef Source #
There are 3 kinds of references 1) composite (to fields that exist in the record) 2) single field 3) embedded
NoReference | |
ForeignRef ! EntityNameHS |
A ForeignRef has a late binding to the EntityDef it references via name and has the Haskell type of the foreign key in the form of FieldType |
EmbedRef EntityNameHS | |
CompositeRef CompositeDef | |
SelfReference |
A SelfReference stops an immediate cycle which causes non-termination at compile-time (issue #311). |
Instances
A
FieldType
describes a field parsed from the QuasiQuoter and is
used to determine the Haskell type in the generated code.
name Text
parses into
FTTypeCon Nothing
Text
name T.Text
parses into
FTTypeCon (Just
T
Text
)
name (Jsonb User)
parses into:
FTApp (FTTypeCon Nothing Jsonb) (FTTypeCon Nothing User)
FTTypeCon ( Maybe Text ) Text |
Optional module and name. |
FTTypePromoted Text | |
FTApp FieldType FieldType | |
FTList FieldType |
Instances
Eq FieldType Source # | |
Ord FieldType Source # | |
Defined in Database.Persist.Types.Base |
|
Read FieldType Source # | |
Show FieldType Source # | |
Lift FieldType Source # | |
Attributes that may be attached to fields that can affect migrations and serialization in backend-specific ways.
While we endeavor to, we can't forsee all use cases for all backends,
and so
FieldAttr
is extensible through its constructor
FieldAttrOther
.
Since: 2.11.0.0
FieldAttrMaybe |
The
Example: User name Text Maybe |
FieldAttrNullable |
This indicates that the column is nullable, but should not have
a
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 |
FieldAttrMigrationOnly |
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. User oldName Text MigrationOnly newName Text |
FieldAttrSafeToRemove |
A
Useful after you've used
User oldName Text SafeToRemove newName Text |
FieldAttrNoreference |
This attribute indicates that we should create a foreign key reference
from a column. By default,
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 |
FieldAttrReference Text |
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 -
|
FieldAttrConstraint Text |
Specify a name for the constraint on the foreign key reference for this table. Post title Text Comment postId PostId constraint="my_cool_constraint_name" |
FieldAttrDefault Text |
Specify the default value for a column. User createdAt UTCTime default="NOW()"
Note that a
|
FieldAttrSqltype Text |
Specify a custom SQL type for the column. Generally, you should define
a custom datatype with a custom
User uuid Text sqltype=UUID |
FieldAttrMaxlen Integer |
Set a maximum length for a column. Useful for VARCHAR and indexes. User name Text maxlen=200 UniqueName name |
FieldAttrSql Text |
Specify the database name of the column. User blarghle Int sql="b_l_a_r_g_h_l_e" Useful for performing phased migrations, where one column is renamed to another column over time. |
FieldAttrOther Text |
A grab bag of random attributes that were unrecognized by the parser. |
Instances
Eq FieldAttr Source # | |
Ord FieldAttr Source # | |
Defined in Database.Persist.Types.Base |
|
Read FieldAttr Source # | |
Show FieldAttr Source # | |
Lift FieldAttr Source # | |
data WhyNullable Source #
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.
Instances
Eq WhyNullable Source # | |
Defined in Database.Persist.Types.Base (==) :: WhyNullable -> WhyNullable -> Bool Source # (/=) :: WhyNullable -> WhyNullable -> Bool Source # |
|
Show WhyNullable Source # | |
Defined in Database.Persist.Types.Base |
data IsNullable Source #
Instances
Eq IsNullable Source # | |
Defined in Database.Persist.Types.Base (==) :: IsNullable -> IsNullable -> Bool Source # (/=) :: IsNullable -> IsNullable -> Bool Source # |
|
Show IsNullable Source # | |
Defined in Database.Persist.Types.Base |
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
Inactive
Location
s to be
current
. However, there may be
at most one
current
Location
per user (i.e., either zero
or one per user).
This data type works because of the way that SQL treats
NULL
able 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
.
Active |
When used on a uniqueness constraint, there
may be at most one
|
Inactive |
When used on a uniqueness constraint, there
may be any number of
|
Instances
fieldAttrsContainsNullable :: [ FieldAttr ] -> IsNullable Source #
parseFieldAttrs :: [ Text ] -> [ FieldAttr ] Source #
Parse raw field attributes into structured form. Any unrecognized
attributes will be preserved, identically as they are encountered,
as
FieldAttrOther
values.
Since: 2.11.0.0
noCascade :: FieldCascade Source #
A
FieldCascade
that does nothing.
Since: 2.11.0