<div dir="ltr"><font face="monospace, monospace">Hi guys! Here is yet another some-level library to work with PostgreSQL DB. </font><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="http://hackage.haskell.org/package/postgresql-query">http://hackage.haskell.org/package/postgresql-query</a><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">This library uses `postgresql-query` and is a list of helpers/workarounds to generate </font></div><div><font face="monospace, monospace">complex queries more safely and parse result.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">What it contains: </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">1. interplating quasiquote `sqlExp` which uses instances of `ToField` typeclass to paste </font></div><div><font face="monospace, monospace">   values inside query. </font></div><div><font face="monospace, monospace">   It looks like this:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">   let val = "'hello'" :: Text</font></div><div><font face="monospace, monospace">       q = [sqlExp|SELECT field1 FROM tbl WHERE field2 = #{val}|]</font></div><div><font face="monospace, monospace">   </font></div><div><font face="monospace, monospace">   where `val` is an arbitrary Haskell expression which type has instance of `ToField` </font></div><div><font face="monospace, monospace">   Resulting query will be like: </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">   "</font><span style="font-family:monospace,monospace">SELECT field1 FROM tbl WHERE field2 = '''hello'''"</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   Yes, proper string escaping is performed authomatically like using this '?'-like </span></div><div><span style="font-family:monospace,monospace">   queries with parameters. </span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   Resulting type of quasiquote is `SqlBuilder` which uses bytestring builders inside and </span></div><div><span style="font-family:monospace,monospace">   can be concatenated efficiently.</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   There is also posibility to paste one query inside another like: </span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   let q2 = [sqlExp|SELECT field1 f FROM (^{q}) WHERE field1 is not null|]</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   so `q2` will generate nested query.</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">   sqlExp also removes SQL comments and removes long sequences of space characters. It also </span></div><div><span style="font-family:monospace,monospace">   properly handles string literals and quoted identifiers inside quasiquotes.</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">2. Typeclass `HasPostgres`, simple connection reader `PgMonadT` and functions like</span></div><div><span style="font-family:monospace,monospace">   `pgQuery` to perform queries. </span></div><div><span style="font-family:monospace,monospace">   </span><font face="monospace, monospace"><a href="http://hackage.haskell.org/package/postgresql-query-1.0.1/docs/Database-PostgreSQL-Query-Functions.html">http://hackage.haskell.org/package/postgresql-query-1.0.1/docs/Database-PostgreSQL-Query-Functions.html</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">3. TH functions to authomatically derive `FromRow` and `ToRow` instances</font></div><div><font face="monospace, monospace">   (from postgresql-simple)</font></div><div><font face="monospace, monospace">   <a href="http://hackage.haskell.org/package/postgresql-query-1.0.1/docs/Database-PostgreSQL-Query-TH.html">http://hackage.haskell.org/package/postgresql-query-1.0.1/docs/Database-PostgreSQL-Query-TH.html</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">4. Some kind of primitive pre-ORM which generates queries for CRUD-ing simple record types. </font></div><div><font face="monospace, monospace">   It looks like:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    data User = User</font></div><div><font face="monospace, monospace">      { </font><span style="font-family:monospace,monospace">userName              :: !Text</span></div><div><font face="monospace, monospace">      , userPasswordEncrypted :: !Text</font></div><div><span style="font-family:monospace,monospace">      } deriving (Show, Eq, Ord, Typeable)</span><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    type UserId = EntityId User</font></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">    $(deriveFromRow ''User)</font></div><div><font face="monospace, monospace">    $(deriveToRow ''User)</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    instance Entity User where</font></div><div><font face="monospace, monospace">        newtype EntityId User</font></div><div><font face="monospace, monospace">            = UserId { unUserId :: UUID } -- Note that you can use any type for id</font></div><div><font face="monospace, monospace">            deriving (Show, Read, Ord, Eq,</font></div><div><font face="monospace, monospace">                      FromField, ToField, PathPiece) -- To use with Yesod</font></div><div><font face="monospace, monospace">        tableName _ = "users"</font></div><div><font face="monospace, monospace">        fieldNames _ = [ "name"</font></div><div><font face="monospace, monospace">                       , "password_encrypted" ]</font></div><div><font face="monospace, monospace">                       </font></div><div><font face="monospace, monospace">    runPgMonadT con $ do </font></div><div><font face="monospace, monospace">      uid <- pgInsertEntity $ User "name" "j27dna74ja784ha7"</font></div><div><font face="monospace, monospace">      pgUpdateEntity uid $ MR [("name", mkValue "John")]</font></div><div><font face="monospace, monospace">      pgDeleteEntity uid</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div>There is also package <a href="http://hackage.haskell.org/package/postgresql-config">http://hackage.haskell.org/package/postgresql-config</a> which contains trivial code </div><div>to make your postgresql-simple connection pool easily configurable.</div></div>