-- 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.4.2 -- | 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. -- --

Example

-- --
--   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 :: MonadIO m => Pool Connection -> DBT IO a -> m a -- | Query wrapper for SQL statements which do not return. execute :: (ToRow params, MonadIO m) => QueryNature -> Query -> params -> DBT m Int64 -- | Query wrapper for SQL statements that operate on multiple rows which -- do not return. executeMany :: (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) -- | Query wrapper that returns one result and does not take an argument queryOne_ :: (FromRow result, MonadIO m) => QueryNature -> Query -> 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. -- --

Note

-- -- By using these directly, you run the risk of violating internal -- invariants, or making representational changes in incompatible ways. -- This API is not stable, and is not subject to the PVP. Use at your own -- risk -- -- If at all possible, instead use the API provided by Types. module Database.PostgreSQL.Entity.Internal.Unsafe -- | A wrapper for table fields. data Field Field :: Text -> Maybe Text -> Field instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.Unsafe.Field instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.Unsafe.Field instance Database.PostgreSQL.Entity.Internal.Unsafe.ForbiddenIsString => Data.String.IsString Database.PostgreSQL.Entity.Internal.Unsafe.Field -- | A quasi-quoter for Fields, supporting optional types. -- -- There is little reason to import this module directly; instead, import -- Entity, which re-exports the field quasiquoter. module Database.PostgreSQL.Entity.Internal.QQ -- | A quasi-quoter for safely constructing Fields. -- --

Example:

-- --
--   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: -- -- -- --

Example

-- --
--   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 schema; will be appended to the table name: -- schema."tablename" schema :: Entity e => Maybe 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. -- --

Example:

-- --
--   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 data SortKeyword ASC :: SortKeyword DESC :: SortKeyword -- | Term-level options data Options Options :: (Text -> Text) -> Maybe Text -> (Text -> Text) -> (Text -> Text) -> Options [$sel:tableNameModifiers:Options] :: Options -> Text -> Text [$sel:schemaModifier:Options] :: Options -> Maybe Text [$sel:primaryKeyModifiers:Options] :: Options -> Text -> Text [$sel:fieldModifiers: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 :: Symbol) data Schema (t :: Symbol) data TableName (t :: Symbol) -- | Contains a list of TextModifiers modifiers data FieldModifiers ms -- | The modifiers that you can apply to the fields: -- -- class TextModifier t getTextModifier :: TextModifier t => Text -> Text -- | TextModifier to remove a certain prefix from the fields data StripPrefix (prefix :: Symbol) -- | FieldModifier taking a separator Char when transforming from -- CamelCase. data CamelTo (separator :: Symbol) -- | CamelCase to snake_case type CamelToSnake = CamelTo "_" -- | CamelCase to kebab-case type CamelToKebab = CamelTo "-" 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 Data.Text.Display.Display Database.PostgreSQL.Entity.Types.SortKeyword instance GHC.Show.Show Database.PostgreSQL.Entity.Types.SortKeyword instance GHC.Classes.Eq Database.PostgreSQL.Entity.Types.SortKeyword instance Database.PostgreSQL.Simple.ToRow.ToRow a => Database.PostgreSQL.Simple.ToRow.ToRow (Database.PostgreSQL.Entity.Types.UpdateRow a) instance (GHC.TypeLits.KnownSymbol separator, Database.PostgreSQL.Entity.Types.NonEmptyText separator) => Database.PostgreSQL.Entity.Types.TextModifier (Database.PostgreSQL.Entity.Types.CamelTo separator) instance (GHC.TypeLits.KnownSymbol name, Database.PostgreSQL.Entity.Types.NonEmptyText name) => Database.PostgreSQL.Entity.Types.GetName name instance (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 (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 (Database.PostgreSQL.Entity.Types.GetName name, Database.PostgreSQL.Entity.Types.EntityOptions xs) => Database.PostgreSQL.Entity.Types.EntityOptions (Database.PostgreSQL.Entity.Types.Schema name : xs) instance forall k (mods :: k) (xs :: [*]). (Database.PostgreSQL.Entity.Types.TextModifier mods, Database.PostgreSQL.Entity.Types.EntityOptions xs) => Database.PostgreSQL.Entity.Types.EntityOptions (Database.PostgreSQL.Entity.Types.FieldModifiers mods : xs) instance Database.PostgreSQL.Entity.Types.TextModifier '[] instance forall a (x :: a) (xs :: [a]). (Database.PostgreSQL.Entity.Types.TextModifier x, Database.PostgreSQL.Entity.Types.TextModifier xs) => Database.PostgreSQL.Entity.Types.TextModifier (x : xs) instance GHC.TypeLits.KnownSymbol prefix => Database.PostgreSQL.Entity.Types.TextModifier (Database.PostgreSQL.Entity.Types.StripPrefix prefix) 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 isIn :: Field -> Vector Text -> 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 -- | Wrap the given text between single quotes, for literal text in an SQL -- query. -- -- Examples -- --
--   >>> literal "meow."
--   "'meow.'"
--   
literal :: Text -> Text -- | Safe getter that quotes a table name -- -- Examples -- --
--   >>> getTableName @Author
--   "\"authors\""
--   
--   >>> getTableName @Tags
--   "public.\"tags\""
--   
getTableName :: forall e. Entity e => Text -- | Accessor to the name of a field, with quotation. -- --
--   >>> getFieldName ([field| author_id |])
--   "\"author_id\""
--   
getFieldName :: Field -> Text -- | Safe getter that quotes a table's primary key -- -- Examples -- --
--   >>> getPrimaryKey @Author
--   "\"author_id\""
--   
--   >>> getPrimaryKey @Tags
--   "\"category\""
--   
getPrimaryKey :: forall e. Entity e => Text prefix :: Maybe Text -> 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 -- --
--   >>> qualifyField @Author [field| name |]
--   "authors.\"name\""
--   
qualifyField :: forall e. Entity e => Field -> 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\"" Nothing,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 |]
--   "\"ids\" = ?"
--   
-- --
--   >>> fmap placeholder $ fields @BlogPost
--   ["\"blogpost_id\" = ?","\"author_id\" = ?","\"uuid_list\" = ?","\"title\" = ?","\"content\" = ?","\"created_at\" = ?"]
--   
placeholder :: Field -> Text -- | Produce a placeholder of the form table."field" = ? with an -- optional type annotation. -- -- Examples -- --
--   >>> placeholder' @BlogPost [field| id |]
--   "blogposts.\"id\" = ?"
--   
-- --
--   >>> placeholder' @BlogPost $ [field| ids |]
--   "blogposts.\"ids\" = ?"
--   
placeholder' :: forall e. Entity e => Field -> Text -- | Generate an appropriate number of “?” placeholders given a vector of -- fields. -- -- Used to generate INSERT queries. -- -- Examples -- --
--   >>> generatePlaceholders $ fields @BlogPost
--   "?, ?, ?, ?, ?, ?"
--   
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 -- | Examples -- --
--   >>> renderSortExpression ([field| title |], ASC)
--   "\"title\" ASC"
--   
renderSortExpression :: (Field, SortKeyword) -> 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: -- -- -- --

Example

-- --
--   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 schema; will be appended to the table name: -- schema."tablename" schema :: Entity e => Maybe 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) -- | Select statement when for an entity where the field is one of the -- options passed selectOneWhereIn :: forall e m. (Entity e, FromRow e, MonadIO m) => Field -> Vector Text -> DBT m (Maybe 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) -- | Perform a INNER JOIN ON field1 WHERE field2 = value between -- two entities joinSelectOneByField :: forall e1 e2 value m. (Entity e1, Entity e2, FromRow e1, MonadIO m, ToField value) => Field -> Field -> value -> DBT m (Vector e1) -- | Perform a SELECT + ORDER BY query on an entity selectOrderBy :: forall e m. (Entity e, FromRow e, MonadIO m) => Vector (Field, SortKeyword) -> DBT m (Vector e) -- | Insert an entity. insert :: forall e values m. (Entity e, ToRow values, MonadIO m) => values -> DBT m () -- | Insert multiple rows of an entity. insertMany :: forall e values m. (Entity e, ToRow values, MonadIO m) => [values] -> DBT m () -- | Insert an entity with a "ON CONFLICT DO UPDATE" clause on the primary -- key as the conflict target upsert :: forall e values m. (Entity e, ToRow values, MonadIO m) => values -> Vector Field -> 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 -- --

Example

-- --
--   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 -- --

Example

-- --
--   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. Fields that do -- not exist in the Entity will be kept so that PostgreSQL can report the -- error. -- -- Examples -- --
--   >>> _select @BlogPost <> _where [[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 [ [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\" = ?"
--   
_where :: 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 @BlogPost [ [field| author_id |], [field| title |]]
--   "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"author_id\" = ? AND \"title\" = ?"
--   
_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 statement where the given field is checked aginst the -- provided array of values . -- --
--   >>> _selectWhereIn @BlogPost [field| title |] [ "Unnamed", "Mordred's Song" ]
--   "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" WHERE \"title\" IN ('Unnamed', 'Mordred''s Song')"
--   
_selectWhereIn :: forall e. Entity e => Field -> Vector Text -> 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 a "SELECT FROM" over two entities. -- -- Examples -- --
--   >>> _joinSelectOneByField @BlogPost @Author [field| author_id |] [field| name |] :: Query
--   "SELECT blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\" FROM \"blogposts\" INNER JOIN \"authors\" ON \"blogposts\".\"author_id\" = \"authors\".\"author_id\" WHERE authors.\"name\" = ?"
--   
_joinSelectOneByField :: forall e1 e2. (Entity e1, Entity e2) => Field -> 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 (?, ?, ?, ?, ?, ?)"
--   
_insert :: forall e. Entity e => Query -- | Produce a "ON CONFLICT (target) DO UPDATE SET …" statement. -- -- Examples -- --
--   >>> _onConflictDoUpdate [[field| blogpost_id |]] [ [field| title |], [field| content |]]
--   " ON CONFLICT (blogpost_id) DO UPDATE SET title = EXCLUDED.title, content = EXCLUDED.content"
--   
-- --
--   >>> _onConflictDoUpdate [[field| blogpost_id |], [field| author_id |]] [ [field| title |], [field| content |]]
--   " ON CONFLICT (blogpost_id, author_id) DO UPDATE SET title = EXCLUDED.title, content = EXCLUDED.content"
--   
-- --
--   >>> _insert @BlogPost <> _onConflictDoUpdate [[field| blogpost_id |]] [ [field| title |], [field| content |]]
--   "INSERT INTO \"blogposts\" (\"blogpost_id\", \"author_id\", \"uuid_list\", \"title\", \"content\", \"created_at\") VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (blogpost_id) DO UPDATE SET title = EXCLUDED.title, content = EXCLUDED.content"
--   
_onConflictDoUpdate :: Vector Field -> Vector Field -> 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(?, ?, ?, ?, ?) 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 -- | Produce an ORDER BY clause with one field and a sorting keyword -- -- Examples -- --
--   >>> _orderBy ([field| title |], ASC)
--   " ORDER BY \"title\" ASC"
--   
_orderBy :: (Field, SortKeyword) -> Query -- | Produce an ORDER BY clause with many fields and sorting keywords -- -- Examples -- --
--   >>> _orderByMany (V.fromList [([field| title |], ASC), ([field| created_at |], DESC)])
--   " ORDER BY \"title\" ASC, \"created_at\" DESC"
--   
_orderByMany :: Vector (Field, SortKeyword) -> 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 newtype UUIDList UUIDList :: Vector UUID -> UUIDList [$sel:getUUIDList:UUIDList] :: UUIDList -> Vector UUID -- | The BlogPost data-type. Look at its Entity instance declaration -- for how to handle a "uuid[]" PostgreSQL type. data BlogPost BlogPost :: BlogPostId -> AuthorId -> UUIDList -> 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 -> UUIDList [$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 () upsertBlogPost :: BlogPost -> Vector Field -> DBT IO () -- | A function to insert many blogposts at once. bulkInsertBlogPosts :: [BlogPost] -> DBT IO () -- | A specialisation of the 'Database.PostgreSQL.Entity.insert function. -- insertAuthor = insert @Author insertAuthor :: Author -> DBT IO () -- | A function to insert many authors at once. bulkInsertAuthors :: [Author] -> DBT IO () data Tags Tags :: Text -> [Text] -> Tags [$sel:category:Tags] :: Tags -> Text [$sel:labels:Tags] :: Tags -> [Text] instance Database.PostgreSQL.Simple.ToField.ToField Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.AuthorId instance GHC.Classes.Ord 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.Classes.Ord 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 GHC.Classes.Ord 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 GHC.Classes.Ord Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList instance Database.PostgreSQL.Simple.FromField.FromField Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList instance GHC.Classes.Eq Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList instance GHC.Show.Show Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList instance GHC.Generics.Generic Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList 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.Classes.Ord 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 Database.PostgreSQL.Entity.Types.Entity Database.PostgreSQL.Entity.Internal.BlogPost.Tags 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 Database.PostgreSQL.Simple.ToField.ToField Database.PostgreSQL.Entity.Internal.BlogPost.UUIDList instance GHC.Records.HasField x Database.PostgreSQL.Entity.Internal.BlogPost.Author a => GHC.OverloadedLabels.IsLabel x (Database.PostgreSQL.Entity.Internal.BlogPost.Author -> a)