-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A pleasant PostgreSQL layer -- -- A PostgreSQL layer to safely expand your SQL queries with a -- lightweight eDSL. Read the tutorial at -- https://tchoutri.github.io/pg-entity/Tutorial @package pg-entity @version 0.0.1.0 -- | The DBT plumbing module to handle database queries and pools module Database.PostgreSQL.Entity.DBT -- | Create a Pool Connection with the appropriate parameters mkPool :: ConnectInfo -> Int -> NominalDiffTime -> Int -> IO (Pool Connection) -- | Run a DBT action with no explicit error handling. -- -- This functions is suited for using MonadError error handling. -- --
-- let e1 = E 1 True True -- result <- runExceptT @EntityError $ do -- withPool pool $ insertEntity e1 -- withPool pool $ markForProcessing 1 -- case result of -- Left err -> print err -- Right _ -> putStrLn "Everything went well" ---- -- See the code in the example/ directory on GitHub withPool :: MonadBaseControl IO m => Pool Connection -> DBT m a -> m a -- | Run a DBT action while handling errors as Exceptions. -- -- This function wraps the DBT actions in a try, so that -- exceptions raised will be converted to the Left branch of the Either. withPool' :: forall errorType result m. (Exception errorType, MonadCatch m, MonadBaseControl IO m) => Pool Connection -> DBT m result -> m (Either errorType result) -- | Query wrapper for SQL statements which do not return. execute :: (ToRow params, MonadIO m) => QueryNature -> Query -> params -> DBT m Int64 -- | Query wrapper that returns a Vector of results query :: (ToRow params, FromRow result, MonadIO m) => QueryNature -> Query -> params -> DBT m (Vector result) -- | Query wrapper that returns a Vector of results and does not -- take an argument query_ :: (FromRow result, MonadIO m) => QueryNature -> Query -> DBT m (Vector result) -- | Query wrapper that returns one result. queryOne :: (ToRow params, FromRow result, MonadIO m) => QueryNature -> Query -> params -> DBT m (Maybe result) -- | This sum type is given to the query, queryOne and -- execute functions to help with logging. data QueryNature Select :: QueryNature Insert :: QueryNature Update :: QueryNature Delete :: QueryNature instance GHC.Show.Show Database.PostgreSQL.Entity.DBT.QueryNature instance GHC.Classes.Eq Database.PostgreSQL.Entity.DBT.QueryNature -- | Contains the internals of several key types. -- --
-- instance Entity BlogPost where -- tableName = "blogposts" -- primaryKey = [field| blogpost_id |] -- fields = [ [field| blogpost_id |] -- , [field| author_id |] -- , [field| uuid_list :: uuid[] |] -- ← This is where we specify an optional PostgreSQL type annotation -- , [field| title |] -- , [field| content |] -- , [field| created_at |] -- ] --field :: QuasiQuoter -- | Types and classes module Database.PostgreSQL.Entity.Types -- | An Entity stores the following information about the structure -- of a database table: -- --
-- data ExampleEntity = E
-- { key :: Key
-- , field1 :: Int
-- , field2 :: Bool
-- }
-- deriving stock (Eq, Show, Generic)
-- deriving anyclass (FromRow, ToRow)
-- deriving Entity
-- via (GenericEntity '[TableName "entities"] ExampleEntity)
--
--
-- When using the functions provided by this library, you will sometimes
-- need to be explicit about the Entity you are referring to.
class Entity e
-- | The name of the table in the PostgreSQL database.
tableName :: Entity e => Text
-- | The name of the table in the PostgreSQL database.
tableName :: (Entity e, GetTableName (Rep e)) => Text
-- | The name of the primary key for the table.
primaryKey :: Entity e => Field
-- | The name of the primary key for the table.
primaryKey :: (Entity e, GetFields (Rep e)) => Field
-- | The fields of the table.
fields :: Entity e => Vector Field
-- | The fields of the table.
fields :: (Entity e, GetFields (Rep e)) => Vector Field
-- | A wrapper for table fields.
data Field
-- | A quasi-quoter for safely constructing Fields.
--
-- -- instance Entity BlogPost where -- tableName = "blogposts" -- primaryKey = [field| blogpost_id |] -- fields = [ [field| blogpost_id |] -- , [field| author_id |] -- , [field| uuid_list :: uuid[] |] -- ← This is where we specify an optional PostgreSQL type annotation -- , [field| title |] -- , [field| content |] -- , [field| created_at |] -- ] --field :: QuasiQuoter -- | Get the name of a field. fieldName :: Field -> Text -- | Get the type of a field, if any. fieldType :: Field -> Maybe Text -- | Wrapper used by the update function in order to have the primary key -- as the last parameter passed, since it appears in the WHERE clause. newtype UpdateRow a UpdateRow :: a -> UpdateRow a [$sel:getUpdate:UpdateRow] :: UpdateRow a -> a -- | Term-level options data Options Options :: (Text -> Text) -> (Text -> Text) -> (Text -> Text) -> Options [$sel:tableNameModifier:Options] :: Options -> Text -> Text [$sel:primaryKeyModifier:Options] :: Options -> Text -> Text [$sel:fieldModifier:Options] :: Options -> Text -> Text defaultEntityOptions :: Options newtype GenericEntity t e GenericEntity :: e -> GenericEntity t e [$sel:getGenericEntity:GenericEntity] :: GenericEntity t e -> e -- | Type-level options for Deriving Via class EntityOptions xs entityOptions :: EntityOptions xs => Options data PrimaryKey t data TableName t instance Database.PostgreSQL.Entity.Types.Entity a => Database.PostgreSQL.Entity.Types.Entity (Database.PostgreSQL.Entity.Types.UpdateRow a) instance GHC.Show.Show a => GHC.Show.Show (Database.PostgreSQL.Entity.Types.UpdateRow a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Database.PostgreSQL.Entity.Types.UpdateRow a) instance Database.PostgreSQL.Simple.ToRow.ToRow a => Database.PostgreSQL.Simple.ToRow.ToRow (Database.PostgreSQL.Entity.Types.UpdateRow a) instance (GHC.TypeLits.KnownSymbol name, Database.PostgreSQL.Entity.Types.NonEmptyText name) => Database.PostgreSQL.Entity.Types.GetName name instance forall k (name :: k) (xs :: [*]). (Database.PostgreSQL.Entity.Types.GetName name, Database.PostgreSQL.Entity.Types.EntityOptions xs) => Database.PostgreSQL.Entity.Types.EntityOptions (Database.PostgreSQL.Entity.Types.TableName name : xs) instance forall k (name :: k) (xs :: [*]). (Database.PostgreSQL.Entity.Types.GetName name, Database.PostgreSQL.Entity.Types.EntityOptions xs) => Database.PostgreSQL.Entity.Types.EntityOptions (Database.PostgreSQL.Entity.Types.PrimaryKey name : xs) instance forall k (t :: k) e. (Database.PostgreSQL.Entity.Types.EntityOptions t, Database.PostgreSQL.Entity.Types.GetTableName (GHC.Generics.Rep e), Database.PostgreSQL.Entity.Types.GetFields (GHC.Generics.Rep e)) => Database.PostgreSQL.Entity.Types.Entity (Database.PostgreSQL.Entity.Types.GenericEntity t e) instance Database.PostgreSQL.Entity.Types.EntityOptions '[] instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetTableName GHC.Generics.V1 instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetTableName GHC.Generics.U1 instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetTableName (e GHC.Generics.:+: f) instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetTableName (GHC.Generics.K1 i c) instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetTableName (e GHC.Generics.:*: f) instance Database.PostgreSQL.Entity.Types.GetTableName e => Database.PostgreSQL.Entity.Types.GetTableName (GHC.Generics.M1 GHC.Generics.C _1 e) instance Database.PostgreSQL.Entity.Types.GetTableName e => Database.PostgreSQL.Entity.Types.GetTableName (GHC.Generics.M1 GHC.Generics.S _1 e) instance GHC.TypeLits.KnownSymbol name => Database.PostgreSQL.Entity.Types.GetTableName (GHC.Generics.M1 GHC.Generics.D ('GHC.Generics.MetaData name _1 _2 _3) e) instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetFields GHC.Generics.V1 instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetFields GHC.Generics.U1 instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetFields (e GHC.Generics.:+: f) instance (TypeError ...) => Database.PostgreSQL.Entity.Types.GetFields (GHC.Generics.K1 i c) instance (Database.PostgreSQL.Entity.Types.GetFields e, Database.PostgreSQL.Entity.Types.GetFields f) => Database.PostgreSQL.Entity.Types.GetFields (e GHC.Generics.:*: f) instance Database.PostgreSQL.Entity.Types.GetFields e => Database.PostgreSQL.Entity.Types.GetFields (GHC.Generics.M1 GHC.Generics.C _1 e) instance Database.PostgreSQL.Entity.Types.GetFields e => Database.PostgreSQL.Entity.Types.GetFields (GHC.Generics.M1 GHC.Generics.D ('GHC.Generics.MetaData _1 _2 _3 _4) e) instance GHC.TypeLits.KnownSymbol name => Database.PostgreSQL.Entity.Types.GetFields (GHC.Generics.M1 GHC.Generics.S ('GHC.Generics.MetaSel ('GHC.Maybe.Just name) _1 _2 _3) _4) -- | Internal helpers used to implement the high-level API and SQL -- combinators. -- -- You can re-use those building blocks freely to create your own -- wrappers. module Database.PostgreSQL.Entity.Internal -- | Produce an IS NOT NULL statement given a vector of fields -- --
-- >>> isNotNull [ [field| possibly_empty |] ] -- "\"possibly_empty\" IS NOT NULL" ---- --
-- >>> isNotNull [[field| possibly_empty |], [field| that_one_too |]] -- "\"possibly_empty\" IS NOT NULL AND \"that_one_too\" IS NOT NULL" --isNotNull :: Vector Field -> Text -- | Produce an IS NULL statement given a vector of fields -- --
-- >>> isNull [ [field| possibly_empty |] ] -- "\"possibly_empty\" IS NULL" ---- --
-- >>> isNull [[field| possibly_empty |], [field| that_one_too |]] -- "\"possibly_empty\" IS NULL AND \"that_one_too\" IS NULL" --isNull :: Vector Field -> Text -- | Wrap the given text between parentheses -- -- Examples -- --
-- >>> inParens "wrap me!" -- "(wrap me!)" --inParens :: Text -> Text -- | Wrap the given text between double quotes -- -- Examples -- --
-- >>> quoteName "meow." -- "\"meow.\"" --quoteName :: Text -> Text -- | Safe getter that quotes a table name -- -- Examples -- --
-- >>> getTableName @Author -- "\"authors\"" --getTableName :: forall e. Entity e => Text -- | Produce a comma-separated list of an entity's fields. -- -- Examples -- --
-- >>> expandFields @BlogPost -- "\"blogpost_id\", \"author_id\", \"uuid_list\", \"title\", \"content\", \"created_at\"" --expandFields :: forall e. Entity e => Text -- | Produce a comma-separated list of an entity's fields, qualified with -- the table name -- -- Examples -- --
-- >>> expandQualifiedFields @BlogPost -- "blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\"" --expandQualifiedFields :: forall e. Entity e => Text -- | Produce a comma-separated list of an entity's fields, qualified -- with an arbitrary prefix -- -- Examples -- --
-- >>> expandQualifiedFields' (fields @BlogPost) "legacy" -- "legacy.\"blogpost_id\", legacy.\"author_id\", legacy.\"uuid_list\", legacy.\"title\", legacy.\"content\", legacy.\"created_at\"" --expandQualifiedFields' :: Vector Field -> Text -> Text -- | Take a prefix and a vector of fields, and qualifies each field with -- the prefix -- -- Examples -- --
-- >>> qualifyFields "legacy" (fields @BlogPost) -- [Field "legacy.\"blogpost_id\"" Nothing,Field "legacy.\"author_id\"" Nothing,Field "legacy.\"uuid_list\"" (Just "uuid[]"),Field "legacy.\"title\"" Nothing,Field "legacy.\"content\"" Nothing,Field "legacy.\"created_at\"" Nothing] --qualifyFields :: Text -> Vector Field -> Vector Field -- | Produce a placeholder of the form "field" = ? with an -- optional type annotation. -- -- Examples -- --
-- >>> placeholder [field| id |] -- "\"id\" = ?" ---- --
-- >>> placeholder $ [field| ids :: uuid[] |] -- "\"ids\" = ?::uuid[]" ---- --
-- >>> fmap placeholder $ fields @BlogPost -- ["\"blogpost_id\" = ?","\"author_id\" = ?","\"uuid_list\" = ?::uuid[]","\"title\" = ?","\"content\" = ?","\"created_at\" = ?"] --placeholder :: Field -> Text -- | Generate an appropriate number of “?” placeholders given a vector of -- fields. -- -- Used to generate INSERT queries. -- -- Examples -- --
-- >>> generatePlaceholders $ fields @BlogPost -- "?, ?, ?::uuid[], ?, ?, ?" --generatePlaceholders :: Vector Field -> Text -- | Since the Query type has an IsString instance, the -- process of converting from Text to String to -- Query is factored into this function -- -- ⚠ This may be dangerous and an unregulated usage of this function may -- expose to you SQL injection attacks @since 0.0.1.0 textToQuery :: Text -> Query -- | For cases where combinator composition is tricky, we can safely get -- back to a Text string from a Query -- -- ⚠ This may be dangerous and an unregulated usage of this function may -- expose to you SQL injection attacks @since 0.0.1.0 queryToText :: Query -> Text -- | The intercalateVector function takes a Text and a Vector Text -- and concatenates the vector after interspersing the first argument -- between each element of the list. -- -- Examples -- --
-- >>> intercalateVector "~" [] -- [] ---- --
-- >>> intercalateVector "~" ["nyan"] -- ["nyan"] ---- --
-- >>> intercalateVector "~" ["nyan", "nyan", "nyan"] -- ["nyan","~","nyan","~","nyan"] --intercalateVector :: Text -> Vector Text -> Vector Text -- | A PostgreSQL database layer that does not get in your way. -- -- See the Database.PostgreSQL.Entity.Internal.BlogPost module for -- an example of a data-type implementing the Entity typeclass. module Database.PostgreSQL.Entity -- | An Entity stores the following information about the structure -- of a database table: -- --
-- data ExampleEntity = E
-- { key :: Key
-- , field1 :: Int
-- , field2 :: Bool
-- }
-- deriving stock (Eq, Show, Generic)
-- deriving anyclass (FromRow, ToRow)
-- deriving Entity
-- via (GenericEntity '[TableName "entities"] ExampleEntity)
--
--
-- When using the functions provided by this library, you will sometimes
-- need to be explicit about the Entity you are referring to.
class Entity e
-- | The name of the table in the PostgreSQL database.
tableName :: Entity e => Text
-- | The name of the table in the PostgreSQL database.
tableName :: (Entity e, GetTableName (Rep e)) => Text
-- | The name of the primary key for the table.
primaryKey :: Entity e => Field
-- | The name of the primary key for the table.
primaryKey :: (Entity e, GetFields (Rep e)) => Field
-- | The fields of the table.
fields :: Entity e => Vector Field
-- | The fields of the table.
fields :: (Entity e, GetFields (Rep e)) => Vector Field
-- | A wrapper for table fields.
data Field
-- | Select an entity by its primary key.
selectById :: forall e value m. (Entity e, FromRow e, MonadIO m, ToRow value) => value -> DBT m (Maybe e)
-- | Select precisely one entity by a provided field.
selectOneByField :: forall e value m. (Entity e, FromRow e, MonadIO m, ToRow value) => Field -> value -> DBT m (Maybe e)
-- | Select potentially many entities by a provided field.
selectManyByField :: forall e value m. (Entity e, FromRow e, MonadIO m, ToRow value) => Field -> value -> DBT m (Vector e)
-- | Select statement with a non-null condition
--
-- See _selectWhereNotNull for the generated query.
selectWhereNotNull :: forall e m. (Entity e, FromRow e, MonadIO m) => Vector Field -> DBT m (Vector e)
-- | Select statement with a null condition
--
-- See _selectWhereNull for the generated query.
selectWhereNull :: forall e m. (Entity e, FromRow e, MonadIO m) => Vector Field -> DBT m (Vector e)
-- | Perform a INNER JOIN between two entities
joinSelectById :: forall e1 e2 m. (Entity e1, Entity e2, FromRow e1, MonadIO m) => DBT m (Vector e1)
-- | Insert an entity.
insert :: forall e values m. (Entity e, ToRow values, MonadIO m) => values -> DBT m ()
-- | Update an entity.
--
-- The Id of the entity is put at the end of the query automatically
-- through the use of UpdateRow. Examples
--
--
-- let newAuthor = oldAuthor{…}
-- update @Author newAuthor
--
update :: forall e newValue m. (Entity e, ToRow newValue, MonadIO m) => newValue -> DBT m ()
-- | Update rows of an entity matching the given value
--
-- -- let newName = "Tiberus McElroy" :: Text -- let oldName = "Johnson McElroy" :: Text -- updateFieldsBy @Author [[field| name |]] ([field| name |], oldName) (Only newName) --updateFieldsBy :: forall e v1 v2 m. (Entity e, MonadIO m, ToRow v2, ToField v1) => Vector Field -> (Field, v1) -> v2 -> DBT m Int64 -- | Delete an entity according to its primary key. delete :: forall e value m. (Entity e, ToRow value, MonadIO m) => value -> DBT m () -- | Delete rows according to the given fields -- --
-- deleteByField @BlogPost [[field| title |]] (Only "Echoes from the other world") --deleteByField :: forall e values m. (Entity e, ToRow values, MonadIO m) => Vector Field -> values -> DBT m () -- | Produce a SELECT statement for a given entity. -- -- Examples -- --
-- >>> _select @BlogPost -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\"" --_select :: forall e. Entity e => Query -- | Produce a SELECT statement with explicit fields for a given entity -- -- Examples -- --
-- >>> _selectWithFields @BlogPost [ [field| blogpost_id |], [field| created_at |] ] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"created_at\" FROM \"blogposts\"" --_selectWithFields :: forall e. Entity e => Vector Field -> Query -- | Produce a WHERE clause, given a vector of fields. -- -- It is most useful composed with a _select or _delete, -- which is why these two combinations have their dedicated functions, -- but the user is free to compose their own queries. -- -- The Entity constraint is required for _where in order to -- get any type annotation that was given in the schema, as well as to -- filter out unexisting fields. -- -- Examples -- --
-- >>> _select @BlogPost <> _where @BlogPost [[field| blogpost_id |]] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"blogpost_id\" = ?" ---- --
-- >>> _select @BlogPost <> _where @BlogPost [ [field| uuid_list |] ] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"uuid_list\" = ?::uuid[]" --_where :: forall e. Entity e => Vector Field -> Query -- | Produce a SELECT statement for a given entity and fields. -- -- Examples -- --
-- >>> _selectWhere @BlogPost [ [field| author_id |] ] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"author_id\" = ?" --_selectWhere :: forall e. Entity e => Vector Field -> Query -- | Produce a SELECT statement where the provided fields are checked for -- being non-null. r -- --
-- >>> _selectWhereNotNull @BlogPost [ [field| author_id |] ] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"author_id\" IS NOT NULL" --_selectWhereNotNull :: forall e. Entity e => Vector Field -> Query -- | Produce a SELECT statement where the provided fields are checked for -- being null. -- --
-- >>> _selectWhereNull @BlogPost [ [field| author_id |] ] -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"author_id\" IS NULL" --_selectWhereNull :: forall e. Entity e => Vector Field -> Query -- | Produce a "SELECT FROM" over two entities. -- -- Examples -- --
-- >>> _joinSelect @BlogPost @Author -- "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\", authors.\"author_id\", authors.\"name\", authors.\"created_at\" FROM \"blogposts\" INNER JOIN \"authors\" USING(author_id)" --_joinSelect :: forall e1 e2. (Entity e1, Entity e2) => Query -- | Produce a "INNER JOIN … USING(…)" fragment. -- -- Examples -- --
-- >>> _innerJoin @BlogPost [field| author_id |] -- " INNER JOIN \"blogposts\" USING(author_id)" --_innerJoin :: forall e. Entity e => Field -> Query -- | Produce a "SELECT [table1_fields, table2_fields] FROM table1 INNER -- JOIN table2 USING(table2_pk)" statement. The primary is used as the -- join point between the two tables. -- -- Examples -- --
-- >>> _joinSelectWithFields @BlogPost @Author [ [field| title |] ] [ [field| name |] ] -- "SELECT blogposts.\"title\", authors.\"name\" FROM \"blogposts\" INNER JOIN \"authors\" USING(author_id)" --_joinSelectWithFields :: forall e1 e2. (Entity e1, Entity e2) => Vector Field -> Vector Field -> Query -- | Produce an INSERT statement for the given entity. -- -- Examples -- --
-- >>> _insert @BlogPost -- "INSERT INTO \"blogposts\" (\"blogpost_id\", \"author_id\", \"uuid_list\", \"title\", \"content\", \"created_at\") VALUES (?, ?, ?::uuid[], ?, ?, ?)" --_insert :: forall e. Entity e => Query -- | Produce an UPDATE statement for the given entity by primary key -- -- Examples -- --
-- >>> _update @Author -- "UPDATE \"authors\" SET (\"name\", \"created_at\") = ROW(?, ?) WHERE \"author_id\" = ?" ---- --
-- >>> _update @BlogPost -- "UPDATE \"blogposts\" SET (\"author_id\", \"uuid_list\", \"title\", \"content\", \"created_at\") = ROW(?, ?::uuid[], ?, ?, ?) WHERE \"blogpost_id\" = ?" --_update :: forall e. Entity e => Query -- | Produce an UPDATE statement for the given entity by the given field. -- -- Examples -- --
-- >>> _updateBy @Author [field| name |] -- "UPDATE \"authors\" SET (\"name\", \"created_at\") = ROW(?, ?) WHERE \"name\" = ?" --_updateBy :: forall e. Entity e => Field -> Query -- | Produce an UPDATE statement for the given entity and fields, by -- primary key. -- --
-- >>> _updateFields @Author [ [field| name |] ] -- "UPDATE \"authors\" SET (\"name\") = ROW(?) WHERE \"author_id\" = ?" --_updateFields :: forall e. Entity e => Vector Field -> Query -- | Produce an UPDATE statement for the given entity and fields, by the -- specified field. -- --
-- >>> _updateFieldsBy @Author [ [field| name |] ] [field| name |] -- "UPDATE \"authors\" SET (\"name\") = ROW(?) WHERE \"name\" = ?" ---- --
-- >>> _updateFieldsBy @BlogPost [[field| author_id |], [field| title |]] [field| title |] -- "UPDATE \"blogposts\" SET (\"author_id\", \"title\") = ROW(?, ?) WHERE \"title\" = ?" --_updateFieldsBy :: forall e. Entity e => Vector Field -> Field -> Query -- | Produce a DELETE statement for the given entity, with a match on the -- Primary Key -- -- Examples -- --
-- >>> _delete @BlogPost -- "DELETE FROM \"blogposts\" WHERE \"blogpost_id\" = ?" --_delete :: forall e. Entity e => Query -- | Produce a DELETE statement for the given entity and fields -- -- Examples -- --
-- >>> _deleteWhere @BlogPost [[field| title |], [field| created_at |]] -- "DELETE FROM blogposts WHERE \"title\" = ? AND \"created_at\" = ?" --_deleteWhere :: forall e. Entity e => Vector Field -> Query -- | Adapted from Clément Delafargue's Yet Another Unsafe DB Layer -- article. -- -- The models described in this module are used throughout the library's -- tests and docspecs. module Database.PostgreSQL.Entity.Internal.BlogPost -- | Wrapper around the UUID type newtype AuthorId AuthorId :: UUID -> AuthorId [$sel:getAuthorId:AuthorId] :: AuthorId -> UUID -- | Author data-type data Author Author :: AuthorId -> Text -> UTCTime -> Author [$sel:authorId:Author] :: Author -> AuthorId [$sel:name:Author] :: Author -> Text [$sel:createdAt:Author] :: Author -> UTCTime -- | Wrapper around the UUID type newtype BlogPostId BlogPostId :: UUID -> BlogPostId [$sel:getBlogPostId:BlogPostId] :: BlogPostId -> UUID -- | The BlogPost data-type. Look at its Entity instance declaration -- for how to handle a "uuid[]" PostgreSQL type. data BlogPost BlogPost :: BlogPostId -> AuthorId -> Vector UUID -> Text -> Text -> UTCTime -> BlogPost -- | Primary key [$sel:blogPostId:BlogPost] :: BlogPost -> BlogPostId -- | Foreign keys, for which we need an explicit type annotation [$sel:authorId:BlogPost] :: BlogPost -> AuthorId -- | A type that will need an explicit type annotation in the schema [$sel:uuidList:BlogPost] :: BlogPost -> Vector UUID [$sel:title:BlogPost] :: BlogPost -> Text [$sel:content:BlogPost] :: BlogPost -> Text [$sel:createdAt:BlogPost] :: BlogPost -> UTCTime -- | A specialisation of the insert function. insertBlogPost = -- insert @BlogPost insertBlogPost :: BlogPost -> DBT IO () -- | A specialisation of the 'Database.PostgreSQL.Entity.insert function. -- insertAuthor = insert @Author insertAuthor :: Author -> DBT IO () instance Database.PostgreSQL.Simple.ToField.ToField Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance Database.PostgreSQL.Simple.FromField.FromField Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance Database.PostgreSQL.Entity.Types.Entity Database.PostgreSQL.Entity.Internal.BlogPost.Author instance Database.PostgreSQL.Simple.ToRow.ToRow Database.PostgreSQL.Entity.Internal.BlogPost.Author instance Database.PostgreSQL.Simple.FromRow.FromRow Database.PostgreSQL.Entity.Internal.BlogPost.Author instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.Author instance GHC.Generics.Generic Database.PostgreSQL.Entity.Internal.BlogPost.Author instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.BlogPost.Author instance Database.PostgreSQL.Simple.ToField.ToField Database.PostgreSQL.Entity.Internal.BlogPost.BlogPostId instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.BlogPostId instance Database.PostgreSQL.Simple.FromField.FromField Database.PostgreSQL.Entity.Internal.BlogPost.BlogPostId instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.BlogPost.BlogPostId instance Database.PostgreSQL.Simple.ToRow.ToRow Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance Database.PostgreSQL.Simple.FromRow.FromRow Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance GHC.Generics.Generic Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance GHC.Records.HasField x Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost a => GHC.OverloadedLabels.IsLabel x (Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost -> a) instance Database.PostgreSQL.Entity.Types.Entity Database.PostgreSQL.Entity.Internal.BlogPost.BlogPost instance GHC.Records.HasField x Database.PostgreSQL.Entity.Internal.BlogPost.Author a => GHC.OverloadedLabels.IsLabel x (Database.PostgreSQL.Entity.Internal.BlogPost.Author -> a)