h&A>w      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Clment Delafargue, 2018 Thophile Choutri, 2021MITtheophile@choutri.eustableNone #$%-/028:<=>? pg-entityThis sum type is given to the ,   and  ! functions to help with logging. pg-entity8Create a Pool Connection with the appropriate parameters pg-entity1Run 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 pg-entity5Run a DBT action while handling errors as Exceptions.)This function wraps the DBT actions in a , so that exceptions raised will be converted to the Left branch of the Either. pg-entityQuery wrapper that returns a  of results  pg-entity&Query wrapper that returns one result.  pg-entityQuery wrapper that returns a ) of results and does not take an argument  pg-entity5Query wrapper for SQL statements which do not return.     Clment Delafargue, 2018 Thophile Choutri, 2021 Koz Ross, 2021MITtheophile@choutri.eu ExperimentalNone #$%-/028:<=>?  pg-entityA wrapper for table fields. pg-entityUsing the Overloaded String syntax for Field names is forbidden. Koz Ross, 2021MITkoz.ross@retro-freedom.nz ExperimentalNone #$%-/028:<=>? k pg-entity'A quasi-quoter for safely constructing s.Example: instance Entity BlogPost where tableName = "blogposts" primaryKey = [field| blogpost_id |] fields = [ [field| blogpost_id |] , [field| author_id |] , [field| uuid_list :: uuid[] |] -- C This is where we specify an optional PostgreSQL type annotation , [field| title |] , [field| content |] , [field| created_at |] ] Clment Delafargue, 2018 Thophile Choutri, 2021MITtheophile@choutri.eustableNone  #$%-./0289:<=>?=  pg-entityWrapper used by the update function in order to have the primary key as the last parameter passed, since it appears in the WHERE clause. pg-entity#Type-level options for Deriving Via pg-entityTerm-level options# pg-entityAn # stores the following information about the structure of a database table:Its nameIts primary keyThe fields it containsExample 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.$ pg-entity1The name of the table in the PostgreSQL database.% pg-entity*The name of the primary key for the table.& pg-entityThe fields of the table.( pg-entityGet the name of a field.) pg-entity Get the type of a field, if any. !"#$%&'()#$%&()' !" Clment Delafargue, 2018 Thophile Choutri, 2021MITtheophile@choutri.eustableNone #$%-/028:<=>?"C pg-entity'Wrap the given text between parenthesesExamplesinParens "wrap me!" "(wrap me!)"D pg-entity)Wrap the given text between double quotesExamplesquoteName "meow." "\"meow.\""E pg-entity$Safe getter that quotes a table nameExamplesgetTableName @Author "\"authors\""F pg-entity5Produce a comma-separated list of an entity's fields.ExamplesexpandFields @BlogPost"\"blogpost_id\", \"author_id\", \"uuid_list\", \"title\", \"content\", \"created_at\""G pg-entityProduce a comma-separated list of an entity's fields, qualified with the table nameExamplesexpandQualifiedFields @BlogPost"blogposts.\"blogpost_id\", blogposts.\"author_id\", blogposts.\"uuid_list\", blogposts.\"title\", blogposts.\"content\", blogposts.\"created_at\""H pg-entity.Produce a comma-separated list of an entity's &$, qualified with an arbitrary prefixExamples2expandQualifiedFields' (fields @BlogPost) "legacy""legacy.\"blogpost_id\", legacy.\"author_id\", legacy.\"uuid_list\", legacy.\"title\", legacy.\"content\", legacy.\"created_at\""I pg-entityTake a prefix and a vector of fields, and qualifies each field with the prefixExamples)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]J pg-entity"Produce a placeholder of the form  "field" = ?" with an optional type annotation.Examplesplaceholder [field| id |] "\"id\" = ?"&placeholder $ [field| ids :: uuid[] |]"\"ids\" = ?::uuid[]"#fmap placeholder $ fields @BlogPost["\"blogpost_id\" = ?","\"author_id\" = ?","\"uuid_list\" = ?::uuid[]","\"title\" = ?","\"content\" = ?","\"created_at\" = ?"]K pg-entityGenerate an appropriate number of @?@ placeholders given a vector of fields. Used to generate INSERT queries.Examples'generatePlaceholders $ fields @BlogPost"?, ?, ?::uuid[], ?, ?, ?"L pg-entity9Produce 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"M pg-entity5Produce 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 |]]9"\"possibly_empty\" IS NULL AND \"that_one_too\" IS NULL"N pg-entity Since the  type has an IsString* instance, the process of converting from  to  to  is factored into this functionM This may be dangerous and an unregulated usage of this function may expose to you SQL injection attacks @since 0.0.1.0O pg-entityFor cases where combinator composition is tricky, we can safely get back to a  string from a M This may be dangerous and an unregulated usage of this function may expose to you SQL injection attacks @since 0.0.1.0P pg-entityThe P function takes a Text and a Vector Text and concatenates the vector after interspersing the first argument between each element of the list.ExamplesintercalateVector "~" [][]intercalateVector "~" ["nyan"]["nyan"].intercalateVector "~" ["nyan", "nyan", "nyan"]["nyan","~","nyan","~","nyan"]CDEFGHIJKLMNOPLMCDEFGHIJKNOP Clment Delafargue, 2018 Thophile Choutri, 2021MITtheophile@choutri.eustableNone !#$%-/028:<=>?:Q pg-entity$Select an entity by its primary key.R pg-entitySelect precisely one entity by a provided field.S pg-entity5Select potentially many entities by a provided field.T pg-entity*Select statement with a non-null conditionSee ` for the generated query.U pg-entity&Select statement with a null conditionSee a for the generated query.V pg-entity)Perform a INNER JOIN between two entitiesW pg-entityInsert an entity.X pg-entityUpdate an entity.The Id of the entity is put at the end of the query automatically through the use of . Examples 5let newAuthor = oldAuthor{@} update @Author newAuthorY pg-entity1Update rows of an entity matching the given valueExample let newName = "Tiberus McElroy" :: Text let oldName = "Johnson McElroy" :: Text updateFieldsBy @Author [[field| name |]] ([field| name |], oldName) (Only newName)Z pg-entity.Delete an entity according to its primary key.[ pg-entity)Delete rows according to the given fieldsExample deleteByField @BlogPost [[field| title |]] (Only "Echoes from the other world")\ pg-entity.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\""] pg-entityProduce a SELECT statement with explicit fields for a given entityExamples_selectWithFields @BlogPost [ [field| blogpost_id |], [field| created_at |] ]"SELECT blogposts.\"blogpost_id\", blogposts.\"created_at\" FROM \"blogposts\""^ pg-entity1Produce a WHERE clause, given a vector of fields."It is most useful composed with a \ or j, which is why these two combinations have their dedicated functions, but the user is free to compose their own queries.The # constraint is required for ^ 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[]"_ pg-entity9Produce 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\" = ?"` pg-entityProduce a SELECT statement where the provided fields are checked for being non-null. r6_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"a pg-entityProduce a SELECT statement where the provided fields are checked for being null.3_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"b pg-entity*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)"c pg-entity+Produce a "INNER JOIN @ USING(@)" fragment.Examples)_innerJoin @BlogPost [field| author_id |]," INNER JOIN \"blogposts\" USING(author_id)"d pg-entityProduce 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)"e pg-entity1Produce 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[], ?, ?, ?)"f pg-entity?Produce an UPDATE statement for the given entity by primary keyExamples_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\" = ?"g pg-entityProduce 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\" = ?"h pg-entityProduce an UPDATE statement for the given entity and fields, by primary key.)_updateFields @Author [ [field| name |] ]"UPDATE \"authors\" SET (\"name\") = ROW(?) WHERE \"author_id\" = ?"i pg-entityProduce 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\" = ?"j pg-entityProduce a DELETE statement for the given entity, with a match on the Primary KeyExamples_delete @BlogPost5"DELETE FROM \"blogposts\" WHERE \"blogpost_id\" = ?"k pg-entity:Produce a DELETE statement for the given entity and fieldsExamples_deleteWhere @BlogPost [[field| title |], [field| created_at |]]"DELETE FROM blogposts WHERE \"title\" = ? AND \"created_at\" = ?"Y pg-entityFields to change pg-entity%Field on which to match and its value pg-entityNew values of those fieldsi pg-entityField names to update pg-entityField on which to match #$%&QRSTUVWXYZ[\]^_`abcdefghijk #$%&QRSTUVWXYZ[\]^_`abcdefghijk Clment Delafargue, 2018 Thophile Choutri, 2021 Koz Ross, 2021MITtheophile@choutri.eustableNone !#$%-/028:<=>?>G l pg-entity$The BlogPost data-type. Look at its # instance declaration for how to handle a "uuid[]" PostgreSQL type.n pg-entity Primary keyo pg-entity;Foreign keys, for which we need an explicit type annotationp pg-entity?A type that will need an explicit type annotation in the schemat pg-entityWrapper around the UUID typew pg-entityAuthor data-type| pg-entityWrapper around the UUID type pg-entityA specialisation of the W function. !insertBlogPost = insert @BlogPost pg-entityA specialisation of the 'Database.PostgreSQL.Entity.insert function. insertAuthor = insert @Authorlmrqpnsotuvwx{yz|}~|}~wx{yztuvlmrqpnso      !!"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoppqrstuvwwxyyz{|}}~pg-entity-0.0.1.0-inplaceDatabase.PostgreSQL.Entity.DBT*Database.PostgreSQL.Entity.Internal.Unsafe&Database.PostgreSQL.Entity.Internal.QQ Database.PostgreSQL.Entity.Types#Database.PostgreSQL.Entity.InternalDatabase.PostgreSQL.Entity,Database.PostgreSQL.Entity.Internal.BlogPost QueryNatureSelectInsertUpdateDeletemkPoolwithPool withPool'queryqueryOnequery_execute$fEqQueryNature$fShowQueryNatureField$fIsStringField $fEqField $fShowFieldfield UpdateRow$sel:getUpdate:UpdateRow PrimaryKey TableName EntityOptions entityOptionsOptions$sel:tableNameModifier:Options$sel:primaryKeyModifier:Options$sel:fieldModifier:Options GenericEntity#$sel:getGenericEntity:GenericEntityEntity tableName primaryKeyfieldsdefaultEntityOptions fieldName fieldType $fGetFieldsM1$fGetFieldsM10$fGetFieldsM11$fGetFields:*: $fGetFieldsK1$fGetFields:+: $fGetFieldsU1 $fGetFieldsV1$fGetTableNameM1$fGetTableNameM10$fGetTableNameM11$fGetTableName:*:$fGetTableNameK1$fGetTableName:+:$fGetTableNameU1$fGetTableNameV1$fEntityOptions[][]$fEntityGenericEntity$fEntityOptions[]:$fEntityOptions[]:0$fGetNameSymbolname$fToRowUpdateRow $fEqUpdateRow$fShowUpdateRow$fEntityUpdateRowinParens quoteName getTableName expandFieldsexpandQualifiedFieldsexpandQualifiedFields' qualifyFields placeholdergeneratePlaceholders isNotNullisNull textToQuery queryToTextintercalateVector selectByIdselectOneByFieldselectManyByFieldselectWhereNotNullselectWhereNulljoinSelectByIdinsertupdateupdateFieldsBydelete deleteByField_select_selectWithFields_where _selectWhere_selectWhereNotNull_selectWhereNull _joinSelect _innerJoin_joinSelectWithFields_insert_update _updateBy _updateFields_updateFieldsBy_delete _deleteWhereBlogPost$sel:blogPostId:BlogPost$sel:authorId:BlogPost$sel:uuidList:BlogPost$sel:title:BlogPost$sel:content:BlogPost$sel:createdAt:BlogPost BlogPostId$sel:getBlogPostId:BlogPostIdAuthor$sel:authorId:Author$sel:name:Author$sel:createdAt:AuthorAuthorId$sel:getAuthorId:AuthorIdinsertBlogPost insertAuthor $fIsLabelx->$fEntityBlogPost $fIsLabelx->0 $fEqBlogPost$fGenericBlogPost$fShowBlogPost$fFromRowBlogPost$fToRowBlogPost$fEqBlogPostId$fFromFieldBlogPostId$fShowBlogPostId$fToFieldBlogPostId $fEqAuthor$fGenericAuthor $fShowAuthor$fFromRowAuthor $fToRowAuthor$fEntityAuthor $fEqAuthorId$fFromFieldAuthorId$fShowAuthorId$fToFieldAuthorIdexceptions-0.10.4Control.Monad.Catchtryvector-0.12.3.0-b4728a9379b8ab9b27ccb36de90bb8d06c60d1649dd61d00810c485808a45b84 Data.VectorVectorpostgresql-simple-0.6.4-d10967b73963f7028a975faaa82436e1b2d34ade340b30e24f92de9b5dc89fdd Database.PostgreSQL.Simple.TypesQuery text-1.2.4.1Data.Text.InternalTextbaseGHC.BaseString