úÎüSó'†      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…None !"*+02346=BEJKMT27Builder wich can be effectively concatenated. Requires + inside for string quoting implemented in libpq5<Special constructor to perform old-style query interpolation7*Things which always can be transformed to 29Typed synonym of †:CPerforms parameters interpolation and return ready to execute query let val = 10let name = "field"TrunSqlBuilder c $ "SELECT * FROM tbl WHERE " <> mkIdent name <> " = " <> mkValue val("SELECT * FROM tbl WHERE \"field\" = 10";8Shorthand function to convert identifier name to builder)runSqlBuilder c $ mkIdent "simple\"ident""\"simple\"\"ident\""$Note correct string quoting made by libpq<5Shorthand function to convert single value to builder(runSqlBuilder c $ mkValue "some ' value""'some '' value'"Note correct string quoting= Lift pure bytestring builder to 223456789:;<=>‡ˆ‰Š‹ŒŽ 23456789:;<=> 23478569:;<=>23456789:;<=>‡ˆ‰Š‹ŒŽNone !"*+02346=BEJKMT ?+Internal type. Result of parsing sql string@&String with haskell expression inside ^{..}A&String with haskell expression inside #{..}BSequence of spacesC Sql commentDPart of raw sqlE@Maybe the main feature of all library. Quasiquoter which builds  SqlBuilder½ from string query. Removes line comments and block comments (even nested) and sequences of spaces. Correctly works handles string literals and quoted identifiers. Here is examples of usagelet name = "name"let val = "some 'value'"JrunSqlBuilder c [sqlExp|SELECT * FROM tbl WHERE ^{mkIdent name} = #{val}|]5"SELECT * FROM tbl WHERE \"name\" = 'some ''value'''"And more comples example:let name = Just "name"let size = Just 10"let active = Nothing :: Maybe Bool™let condlist = catMaybes [ fmap (\a -> [sqlExp|name = #{a}|]) name, fmap (\a -> [sqlExp|size = #{a}|]) size, fmap (\a -> [sqlExp|active = #{a}|]) active]nlet cond = if L.null condlist then mempty else [sqlExp| WHERE ^{mconcat $ L.intersperse " AND " $ condlist} |]ErunSqlBuilder c [sqlExp|SELECT * FROM tbl ^{cond} -- line comment|]8"SELECT * FROM tbl WHERE name = 'name' AND size = 10 "‘Build builder from ropeHBuild % expression from rowI"Removes sequential occurencies of D` constructors. Also removes commentaries and squash sequences of spaces to single space symbolJBuild expression of type  SqlBuilder" from SQL query with interpolationK,Embed sql template and perform interpolation @let name = "name" foo = "bar" query = $(sqlExpEmbed "sqlfoobar.sql") -- using foo and bar inside L Just like K0 but uses pattern instead of file name. So, code $let query = $(sqlExpFile "foo/bar") is just the same as let query = $(sqlExpEmbed "sqlfoo bar.sql") "This function inspired by Yesod's  widgetFile?@ABCDEFG‘Expression of type %HIJExpression of type  SqlBuilderK file pathExpression of type  SqlBuilderL?@ABCDEFGHIJKLE?DCBA@GFIHJKL ?DCBA@EFG‘HIJKLNone !"*+02346=BEJKMTMDerive ' instance. i.e. you have type like that udata Entity = Entity { eField :: Text , eField2 :: Int , efield3 :: Bool } then M< will generate this instance: instance FromRow Entity where {instance FromRow Entity where fromRow = Entity <$> field <*> field <*> field FDatatype must have just one constructor with arbitrary count of fieldsNderives ! instance for datatype like udata Entity = Entity { eField :: Text , eField2 :: Int , efield3 :: Bool } "it will derive instance like that: instance ToRow Entity where toRow (Entity e1 e2 e3) = [ toField e1 , toField e2 , toField e3 ] ’“M”NO File pathPsql file patternEKLMNOPMNOPEKL’“M”NOPNone !"*+02346=BEJKMT Q&Reader of connection. Has instance of UG. So if you have a connection you can run queries in this monad using cZ. Or you can use this transformer to run sequence of queries using same connection with d.TBEmpty typeclass signing monad in which transaction is safe. i.e. Q^ have this instance, but some other monad giving connection from e.g. connection pool is not.U•Instances of this typeclass can acquire connection and pass it to computation. It can be reader of pool of connections or just reader of connectionX0generate list of pairs (field name, field value)YaMarked row is list of pairs of field name and some sql expression. Used to generate queries like: name = name AND size = 10 AND length = 20 or UPDATE tbl SET name = name, size = 10, lenght = 20 \~Dote separated field name. Each element in nested list will be properly quoted and separated by dot. It also have instance of 7 and • so you can:let a = "hello" :: FNa FN ["hello"]let b = "user.name" :: FNbFN ["user","name"]let n = "u.name" :: FN runSqlBuilder c $ toSqlBuilder n"\"u\".\"name\""("user" <> "name") :: FNFN ["user","name"]let a = "name" :: FNlet b = "email" :: FNErunSqlBuilder c [sqlExp|^{"u" <> a} = 'name', ^{"e" <> b} = 'email'|]4"\"u\".\"name\" = 'name', \"e\".\"email\" = 'email'"^type to put and get from db inet and cidrG typed postgresql fields. This should be in postgresql-simple in fact.aSingle field to \textFN "hello" FN ["hello"]textFN "user.name"FN ["user.name"]FNote that it does not split string to parts by point like instance of • doesb=Turns marked row to query intercalating it with other buildererunSqlBuilder c $ mrToBuilder "AND" $ MR [("name", mkValue "petr"), ("email", mkValue "foo@bar.com")]3" \"name\" = 'petr' AND \"email\" = 'foo@bar.com' "dIf your monad have instance of U= you maybe dont need this function, unless your instance use  withPGPoolˆ which acquires connection from pool for each query. If you want to run sequence of queries using same connection you need this function1QRSTUVWXYZ[\]^_`abBuilder to intercalate withcd–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²QRSTUVWXYZ[\]^_`abcdUVTQRScd^_`\]aYZ[bWX(QRSTUVWXYZ[\]^_`abcd–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²None !"*+02346=BEJKMTeEntity with it's idfvAuxiliary typeclass for data types which can map to rows of some table. This typeclass is used inside functions like pgSelectEntities to generate queries.gId type for this entityhTable name of this entityiField names without id and created?. The order of field names must match with order of fields in ToRow and FromRow instances of this type.efghiefghifghieefghiNone !"*+02346=BEJKMT j-Generates comma separated list of field namesOrunSqlBuilder con $ buildFields ["u" <> "name", "u" <> "phone", "e" <> "email"]2"\"u\".\"name\", \"u\".\"phone\", \"e\".\"email\""k generates UPDATE querylet name = "%vip%"wrunSqlBuilder con $ updateTable "ships" (MR [("size", mkValue 15)]) [sqlExp|WHERE size > 15 AND name NOT LIKE #{name}|]P"UPDATE \"ships\" SET \"size\" = 15 WHERE size > 15 AND name NOT LIKE '%vip%'"l%Generate INSERT INTO query for entityerunSqlBuilder con $ insertInto "foo" $ MR [("name", mkValue "vovka"), ("hobby", mkValue "president")]I"INSERT INTO \"foo\" (\"name\", \"hobby\") VALUES ('vovka', 'president')"mBuild entity fields.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"};runSqlBuilder con $ entityFields id id (Proxy :: Proxy Foo)"\"name\", \"size\""@runSqlBuilder con $ entityFields ("id":) id (Proxy :: Proxy Foo)"\"id\", \"name\", \"size\""XrunSqlBuilder con $ entityFields (\l -> ("id":l) ++ ["created"]) id (Proxy :: Proxy Foo))"\"id\", \"name\", \"size\", \"created\""@runSqlBuilder con $ entityFields id ("f"<>) (Proxy :: Proxy Foo) "\"f\".\"name\", \"f\".\"size\""GrunSqlBuilder con $ entityFields ("f.id":) ("f"<>) (Proxy :: Proxy Foo)."\"f\".\"id\", \"f\".\"name\", \"f\".\"size\""nSame as m! but prefixes list of names with id3 field. This is shorthand function for often usage..data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}:runSqlBuilder con $ entityFieldsId id (Proxy :: Proxy Foo)"\"id\", \"name\", \"size\""?runSqlBuilder con $ entityFieldsId ("f"<>) (Proxy :: Proxy Foo)."\"f\".\"id\", \"f\".\"name\", \"f\".\"size\""o'Generate SELECT query string for entity.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}IrunSqlBuilder con $ selectEntity (entityFieldsId id) (Proxy :: Proxy Foo)0"SELECT \"id\", \"name\", \"size\" FROM \"foo\""NrunSqlBuilder con $ selectEntity (entityFieldsId ("f"<>)) (Proxy :: Proxy Foo)B"SELECT \"f\".\"id\", \"f\".\"name\", \"f\".\"size\" FROM \"foo\""JrunSqlBuilder con $ selectEntity (entityFields id id) (Proxy :: Proxy Foo)("SELECT \"name\", \"size\" FROM \"foo\""p;Generates SELECT FROM WHERE query with most used conditions.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}DrunSqlBuilder con $ selectEntitiesBy id (Proxy :: Proxy Foo) $ MR []("SELECT \"name\", \"size\" FROM \"foo\""_runSqlBuilder con $ selectEntitiesBy id (Proxy :: Proxy Foo) $ MR [("name", mkValue "fooname")]E"SELECT \"name\", \"size\" FROM \"foo\" WHERE \"name\" = 'fooname' "urunSqlBuilder con $ selectEntitiesBy id (Proxy :: Proxy Foo) $ MR [("name", mkValue "fooname"), ("size", mkValue 10)]W"SELECT \"name\", \"size\" FROM \"foo\" WHERE \"name\" = 'fooname' AND \"size\" = 10 "qOConvert entity instance to marked row to perform inserts updates and same stuff.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}Kinstance ToRow Foo where { toRow Foo{..} = [toField fName, toField fSize] }HrunSqlBuilder con $ mrToBuilder ", " $ entityToMR $ Foo "Enterprise" 610-" \"name\" = 'Enterprise' , \"size\" = 610 "r Generates  INSERT INTO query for any instance of f and !.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}Kinstance ToRow Foo where { toRow Foo{..} = [toField fName, toField fSize] }7runSqlBuilder con $ insertEntity $ Foo "Enterprise" 910E"INSERT INTO \"foo\" (\"name\", \"size\") VALUES ('Enterprise', 910)"sSame as r8 but generates query to insert many queries at same time.data Foo = Foo { fName :: Text, fSize :: Int }tinstance Entity Foo where {newtype EntityId Foo = FooId Int ; fieldNames _ = ["name", "size"] ; tableName _ = "foo"}Kinstance ToRow Foo where { toRow Foo{..} = [toField fName, toField fSize] }mrunSqlBuilder con $ insertManyEntities $ NL.fromList [Foo "meter" 1, Foo "table" 2, Foo "earth" 151930000000]_"INSERT INTO \"foo\" (\"name\",\"size\") VALUES ('meter',1),('table',2),('earth',151930000000)" jk table namefields to update conditionl table name*list of pairs (name, value) to insert intom%modify list of fields. Applied secondZmodify each field name, e.g. prepend each field with prefix, like ("t"<>). Applied firstnobuild fields part from proxypqrs jklmnopqrs mnoprsqjkl jklmnopqrsNone !"*+02346=BEJKMTtNExecute all queries inside one transaction. Rollback transaction on exceptionsuSame as t& but executes queries inside savepointvExecute query generated by  SqlBuilder. Typical use case: mlet userName = "Vovka Erohin" :: Text pgQuery [sqlExp| SELECT id, name FROM users WHERE name = #{userName}|] Or jlet userName = "Vovka Erohin" :: Text pgQuery $ Qp "SELECT id, name FROM users WHERE name = ?" [userName] uWhich is almost the same. In both cases proper value escaping is performed so you stay protected from sql injections.w9Execute arbitrary query and return count of affected rowsx@Executes arbitrary query and parses it as entities and their idsy$Insert new entity and return it's idz)Select entities as pairs of (id, entity). ÿ%handler :: Handler [Ent a] handler = do now <- liftIO getCurrentTime let back = addUTCTime (days (-7)) now pgSelectEntities id [sqlExp|WHERE created BETWEEN #{now} AND #{back} ORDER BY created|] handler2 :: Text -> Handler [Ent Foo] handler2 fvalue = do pgSelectEntities ("t"<>) [sqlExp|AS t INNER JOIN table2 AS t2 ON t.t2_id = t2.id WHERE t.field = #{fvalue} ORDER BY t2.field2|] -- Here the query will be: SELECT ... FROM tbl AS t INNER JOIN ... {Same as z but do not select id|)Select entities by condition formed from Y . Usefull function when you know}Select entity by id qgetUser :: EntityId User -> Handler User getUser uid = do pgGetEntity uid >>= maybe notFound return ~$Get entity by some fields constraint ·getUser :: UserName -> Handler User getUser name = do pgGetEntityBy (MR [("name", mkValue name), ("active", mkValue True)]) >>= maybe notFound return The query here will be like CpgQuery [sqlExp|SELECT id, name, phone ... FROM users WHERE name = {name} AND active =  {True}|] Same as yS but insert many entities at one action. Returns list of id's of inserted entities€8Insert many entities without returning list of id like  doesDelete entity. MrmUser :: EntityId User -> Handler () rmUser uid = do pgDeleteEntity uid ‚Update entity using W instanced value. Requires ³ while g is not a data type. ÿÿfixUser :: Text -> EntityId User -> Handler () fixUser username uid = do pgGetEntity uid >>= maybe notFound run where run user = pgUpdateEntity uid $ MR [("active", mkValue True) ("name", mkValue username)] ƒ)Select count of entities with given query activeUsers :: Handler Integer activeUsers = do pgSelectCount (Proxy :: Proxy User) [sqlExp|WHERE active = #{True}|] „€Perform repsert of the same row, first trying "update where" then "insert" with concatenated fields. Which means that if you run VpgRepsertRow "emails" (MR [("user_id", mkValue uid)]) (MR [("email", mkValue email)]) Then firstly will be performed UPDATE "emails" SET email =  'foo@bar.com' WHERE "user_id" = 1234 4And if no one row is affected (which is returned by w), then 8INSERT INTO "emails" ("user_id", "email") VALUES (1234,  'foo@bar.com') will be performedtuvwxyz‰Entity fields name modifier, e.g. ("tablename"<>). Each field of entity will be processed by this modifier before pasting to the querypart of query just after SELECT .. FROM table.{|}~*uniq constrained list of fields and values€‚ƒ„ Table namewhere condition update rowtuvwxyz{|}~€‚ƒ„vwxtuy€z{|}~‚ƒ„tuvwxyz{|}~€‚ƒ„None !"*+02346=BEJKMT…q  !"#$%&'()*+,-./0123456789:;<=>EKLMNOPQRSTUVWXYZ[\]^_`abcdefghituvwxyz{|}~€‚ƒ„…3"! %$#('&*)10/.-,+   ……´                     ! " # $ % & ' ( ) * * +, -. -/ +0 12 13 13 14 15 15 16 16 17 18 18 19 19 1: 1:;;<==>?@ABCDEFGHIJKLMNOPQRSTUVWXXYZ[\]^_`abbccdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™šŠ›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹Šº»¼postgresql-query-1.0.0Database.PostgreSQL.Query$Database.PostgreSQL.Query.SqlBuilder#Database.PostgreSQL.Query.TH.SqlExpDatabase.PostgreSQL.Query.THDatabase.PostgreSQL.Query.Types Database.PostgreSQL.Query.Entity"Database.PostgreSQL.Query.Internal#Database.PostgreSQL.Query.Functionspostgresql-libpq-0.9.0.2Database.PostgreSQL.LibPQOidpostgresql-simple-0.4.10.0"Database.PostgreSQL.Simple.FromRowfromRow0Database.PostgreSQL.Simple.HStore.ImplementationparseHStoreListhstoretoHStoreToHStore HStoreBuilder toHStoreText ToHStoreText HStoreTextfromHStoreList HStoreList fromHStoreMap HStoreMap$Database.PostgreSQL.Simple.FromField fromFieldFromRow FromField#Database.PostgreSQL.Simple.InternalconnectPostgreSQLconnectdefaultConnectInfo ConnectionconnectDatabaseconnectPassword connectUser connectPort connectHost ConnectInfo"Database.PostgreSQL.Simple.ToFieldtoField Database.PostgreSQL.Simple.ToRowtoRowToRowToField Database.PostgreSQL.Simple.Types fromQueryQueryfromOnlyOnlyIn fromPGArrayPGArray:.Values SqlBuildersqlBuildQp ToSqlBuilder toSqlBuilderemptyB runSqlBuildermkIdentmkValuesqlBuilderPuresqlBuilderFromFieldRopeRPasteRIntRSpacesRCommentRLitsqlExp parseRope ropeParserbuildQ squashRopesqlQExp sqlExpEmbed sqlExpFile deriveFromRow deriveToRowembedSqlsqlFilePgMonadT unPgMonadTTransactionSafe HasPostgreswithPGConnection ToMarkedRow toMarkedRow MarkedRowMRunMRFNInetText unInetTexttextFN mrToBuilder runPgMonadTlaunchPGEntEntityEntityId tableName fieldNames buildFields updateTable insertInto entityFieldsentityFieldsId selectEntityselectEntitiesBy entityToMR insertEntityinsertManyEntitiespgWithTransactionpgWithSavepointpgQuery pgExecutepgQueryEntitiespgInsertEntitypgSelectEntitiespgSelectJustEntitiespgSelectEntitiesBy pgGetEntity pgGetEntityBypgInsertManyEntitiesIdpgInsertManyEntitiespgDeleteEntitypgUpdateEntity pgSelectCount pgRepsertRowsqlQQbase Data.Monoidmempty$fMonoidSqlBuilder$fToSqlBuilderText$fToSqlBuilderText0$fToSqlBuilder[]$fToSqlBuilderByteString$fToSqlBuilderByteString0$fToSqlBuilderBuilder$fToSqlBuilderSqlBuilder$fIsStringSqlBuilder$fToSqlBuilderQp buildBuildercNamecArgslookupVNameErr Data.StringIsString$fTransactionSafePgMonadT$fHasPostgresPgMonadT$fMonadReaderrPgMonadT$fMonadTransControlPgMonadT$fMonadBaseControlbPgMonadT$fTransactionSafeWriterT$fTransactionSafeWriterT0$fTransactionSafeContT$fTransactionSafeStateT$fTransactionSafeStateT0$fTransactionSafeReaderT$fTransactionSafeMaybeT$fTransactionSafeIdentityT$fTransactionSafeExceptT$fTransactionSafeEitherT$fHasPostgresWriterT$fHasPostgresWriterT0$fHasPostgresContT$fHasPostgresStateT$fHasPostgresStateT0$fHasPostgresReaderT$fHasPostgresMaybeT$fHasPostgresIdentityT$fHasPostgresExceptT$fHasPostgresEitherT$fToMarkedRowMarkedRow $fIsStringFN$fToSqlBuilderFN$fFromFieldInetText Data.ProxyProxy