All database types must be of kind '(Type -> Type) -> Type'. If
the type parameter is named f, each field must be of the type
of f applied to some type for which an IsDatabaseEntity
instance exists.
The be type parameter is necessary so that the compiler can
ensure that backend-specific entities only work on the proper
backend.
Default derived function. Do not implement this yourself.
The idea is that, for any two databases over particular entity tags f
and g, if we can take any entity in f and g to the corresponding
entity in h (in the possibly effectful applicative functor m), then we can
transform the two databases over f and g to a database in h,
within m.
If that doesn't make sense, don't worry. This is mostly beam internal
When parameterized by this entity tag, a database type will hold
meta-information on the Haskell mappings of database entities. Under the
hood, each entity type is transformed into its DatabaseEntityDescriptor
type. For tables this includes the table name as well as the corresponding
TableSettings, which provides names for each column.
Represents a meta-description of a particular entityType. Mostly, a wrapper
around 'DatabaseEntityDescriptor be entityType', but carries around the
IsDatabaseEntity dictionary.
A newtype wrapper around 'f e -> f e' (i.e., an endomorphism between entity
types in f). You usually want to use modifyTable or another function to
contstruct these for you.
A newtype wrapper around 'Columnar f a -> Columnar f a' (i.e., an
endomorphism between Columnars over f). You usually want to use
fieldNamed or the IsString instance to rename the field, when 'f ~
TableField'
Return a table modification (for use with modifyTable) that does nothing.
Useful if you only want to change the table name, or if you only want to
modify a few fields.
For example,
tableModification { field1 = "Column1" }
is a table modification (where 'f ~ TableField tbl') that changes the
column name of field1 to Column1.
Modify a database according to a given modification. Most useful for
DatabaseSettings to change the name mappings of tables and fields. For
example, you can use this to modify the default names of a table
db :: DatabaseSettings MyDb
db = defaultDbSettings `withDbModification`
dbModification {
-- Change default name "table1" to "Table_1". Change the name of "table1Field1" to "first_name"
table1 = setEntityName "Table_1" <> modifyTableFields tableModification {
table1Field1 = "first_name"
}
}
Modify a table according to the given field modifications. Invoked by
modifyTable to apply the modification in the database. Not used as often in
user code, but provided for completeness.
Deprecated. Instead of 'modifyTable fTblNm fFields', use 'modifyEntityName _ <> modifyTableFields _'
Provide an EntityModification for TableEntitys. Allows you to modify
the name of the table and provide a modification for each field in the
table. See the examples for withDbModification for more.
Automatically provide names for tables, and descriptions for tables (using
defTblFieldSettings). Your database must implement Generic, and must be
auto-derivable. For more information on name generation, see the
manual
A type family that we use to "tag" columns in our table datatypes.
This is what allows us to use the same table type to hold table data, describe table settings,
derive lenses, and provide expressions.
The basic rules are
Columnar Identity x = x
Thus, any Beam table applied to Identity will yield a simplified version of the data type, that contains
just what you'd expect.
The Nullable type is used when referencing PrimaryKeys that we want to include optionally.
For example, if we have a table with a PrimaryKey, like the following
data BeamTableT f = BeamTableT
{ _refToAnotherTable :: PrimaryKey AnotherTableT f
, ... }
we would typically be required to provide values for the PrimaryKey embedded into BeamTableT. We can use
Nullable to lift this constraint.
data BeamTableT f = BeamTableT
{ _refToAnotherTable :: PrimaryKey AnotherTableT (Nullable f)
, ... }
Now we can use just_ and nothing_ to refer to this table optionally. The embedded PrimaryKey in _refToAnotherTable
automatically has its fields converted into Maybe using Nullable.
Use this rule if you'd like to parameterize your table type over any other functor. For example, this is used
in the query modules to write expressions such as 'TableT QExpr', which returns a table whose fields have been
turned into query expressions.
The other rules are used within Beam to provide lenses and to expose the inner structure of the data type.
If you declare a function 'Columnar f a -> b' and try to constrain your
function by a type class for f, GHC will complain, because f is
ambiguous in 'Columnar f a'. For example, 'Columnar Identity (Maybe a) ~
Maybe a' and 'Columnar (Nullable Identity) a ~ Maybe a', so given a type
'Columnar f a', we cannot know the type of f.
Thus, if you need to know f, you can instead use Columnar'. Since its a
newtype, it carries around the f paramater unambiguously. Internally, it
simply wraps 'Columnar f a'
group_ for any Beamable type. Adds every field in the type to the
grouping key. This is the equivalent of including the grouping expression
of each field in the type as part of the aggregate projection
Essentially a wrapper over the field name, but with a phantom type
parameter, so that it forms an appropriate column tag.
Usually you use the defaultDbSettings function to generate an appropriate
naming convention for you, and then modify it with withDbModification if
necessary. Under this scheme, the field n be renamed using the IsString
instance for TableField, or the fieldNamed function.
newtype mainly used to inspect the tag structure of a particular
Beamable. Prevents overlapping instances in some case. Usually not used
in end-user code.
Represents a table that contains metadata on its fields. In particular,
each field of type 'Columnar f a' is transformed into 'TableField table a'.
You can get or update the name of each field by using the fieldName lens.
The big Kahuna! All beam tables implement this class.
The kind of all table types is '(Type -> Type) -> Type'. This is
because all table types are actually table type constructors.
Every table type takes in another type constructor, called the
column tag, and uses that constructor to instantiate the column
types. See the documentation for Columnar.
This class is mostly Generic-derivable. You need only specify a
type for the table's primary key and a method to extract the
primary key given the table.
An example table:
data BlogPostT f = BlogPost
{ _blogPostSlug :: Columnar f Text
, _blogPostBody :: Columnar f Text
, _blogPostDate :: Columnar f UTCTime
, _blogPostAuthor :: PrimaryKey AuthorT f
, _blogPostTagline :: Columnar f (Maybe Text)
, _blogPostImageGallery :: PrimaryKey ImageGalleryT (Nullable f) }
deriving Generic
instance Beamable BlogPostT
instance Table BlogPostT where
data PrimaryKey BlogPostT f = BlogPostId (Columnar f Text) deriving Generic
primaryKey = BlogPostId . _blogPostSlug
instance Beamable (PrimaryKey BlogPostT)
We can interpret this as follows:
The _blogPostSlug, _blogPostBody, _blogPostDate, and _blogPostTagline fields are of types Text, Text, UTCTime, and 'Maybe Text' respectfully.
Since _blogPostSlug, _blogPostBody, _blogPostDate, _blogPostAuthor must be provided (i.e, they cannot contain Nothing), they will be given SQL NOT NULL constraints.
_blogPostTagline is declared Maybe so Nothing will be stored as NULL in the database. _blogPostImageGallery will be allowed to be empty because it uses the Nullable tag modifier.
blogPostAuthor references the AuthorT table (not given here) and is required.
blogPostImageGallery references the ImageGalleryT table (not given here), but this relation is not required (i.e., it may be Nothing. See Nullable).
A data type representing the types of primary keys for this table.
In order to play nicely with the default deriving mechanism, this type must be an instance of Generic.
Given a table, this should return the PrimaryKey from the table. By keeping this polymorphic over column,
we ensure that the primary key values come directly from the table (i.e., they can't be arbitrary constants)
Provides a number of introspection routines for the beam library. Allows us
to "zip" tables with different column tags together. Always instantiate an
empty Beamable instance for tables, primary keys, and any type that you
would like to embed within either. See the
manual for more
information on embedding.
Return a TableSettings for the appropriate table type where each column
has been given its default name. See the
manual for
information on the default naming convention.
TypeError ('Text"All Beamable types must be record types, so appropriate names can be given to columns") => GDefaultTableFieldSettings (K1rfp)Defined in beam-core-0.11.1.0 · Database.Beam.Schema.Tables