úΗÂ|pÿ¦      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥None<FT©£Represents a value containing all the configuration options for a specific backend. This abstraction makes it easier to write code that can easily swap backends. Load the config settings from a ¦-, most likely taken from a YAML config file.:Modify the config settings based on environment variables.@Create a new connection pool based on the given config settings.;Run a database action by taking a connection from the pool. None1Zú¼A SQL data type. Naming attempts to reflect the underlying Haskell datatypes, eg SqlString instead of SqlVarchar. Different SQL databases may have different translations for these types.&Always uses UTC timezone(a backend-specific name)TA raw value which can be stored in any backend and can be marshalled to and from a  PersistField.6'Intended especially for MongoDB backend7Using 7€ allows you to use types specific to a particular backend For example, below is a simple example of the PostGIS geography type: ÿdata Geo = Geo ByteString instance PersistField Geo where toPersistValue (Geo t) = PersistDbSpecific t fromPersistValue (PersistDbSpecific t) = Right $ Geo $ Data.ByteString.concat ["'", t, "'"] fromPersistValue _ = Left "Geo values must be converted from PersistDbSpecific" instance PersistFieldSql Geo where sqlType _ = SqlOther "GEOGRAPHY(POINT,4326)" toPoint :: Double -> Double -> Geo toPoint lat lon = Geo $ Data.ByteString.concat ["'POINT(", ps $ lon, " ", ps $ lat, ")'"] where ps = Data.Text.pack . show PIf Foo has a geography field, we can then perform insertions like the following: insert $ Foo (toPoint 44 44) 9Generic ExceptionH>Used instead of FieldDef to generate a smaller amount of codeS|An EmbedFieldDef is the same as a FieldDef But it is only used for embeddedFields so it only has data needed for embeddingWV< can create a cycle (issue #311) when a cycle is detected, V will be Nothing and W will be JustXAn EmbedEntityDef is the same as an EntityDef But it is only used for fieldReference so it only has data needed for embedding\pThere are 3 kinds of references 1) composite (to fields that exist in the record) 2) single field 3) embedded^“A ForeignRef has a late binding to the EntityDef it references via HaskellName and has the Haskell type of the foreign key in the form of FieldTypeacA SelfReference stops an immediate cycle which causes non-termination at compile-time (issue #311).dname of the fieldhuser annotations for a fieldi.a strict field in the data type. Default: truelOptional module and name.ƒThe reason why a field is nullable< is very important. A field that is nullable because of a Maybe& tag will have its type changed from A to Maybe A0. OTOH, a field that is nullable because of a nullable% tag will remain with the same type.‰A ‰Æ should be used as a field type whenever a uniqueness constraint should guarantee that a certain kind of record may appear at most once, but other kinds of records may appear any number of times.NOTE: You need to mark any  Checkmark fields as nullable (see the following example).For example, suppose there's a Location0 entity that represents where a user has lived: mLocation user UserId name Text current Checkmark nullable UniqueLocation user current The UniqueLocation" constraint allows any number of ‹ Locations to be current&. However, there may be at most one current Location/ per user (i.e., either zero or one per user).9This data type works because of the way that SQL treats NULLHable fields within uniqueness constraints. The SQL standard says that NULL9 values should be considered different, so we represent ‹ as SQL NULL, thus allowing any number of ‹, records. On the other hand, we represent Š as TRUE<, so the uniqueness constraint will disallow more than one Š record.Note:I There may be DBMSs that do not respect the SQL standard's treatment of NULL_ values on uniqueness constraints, please check if this data type works before relying on it.The SQL BOOLEANV type is used because it's the smallest data type available. Note that we never use FALSE, just TRUE and NULL. Provides the same behavior Maybe () would if () was a valid  PersistField.Š@When used on a uniqueness constraint, there may be at most one Š record.‹BWhen used on a uniqueness constraint, there may be any number of ‹ records.Š  ('&%$#"! )76543210/.-,+*8>=<;:9?@GFEDCBAHIJLKMNRQPOSTWVUXY[Z\a_^]`bcihgfjdeknmlopqrstuvwx‚€~|zy}{ƒ…„†ˆ‡‰‹ŠŒŽ    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnpqrstuw xyz{|}~€‚ƒ„…†‡ˆ‰Š‹ None;=COVgÛ“.A value which can be marshalled to and from a ).– FIXME Add documentation to that.§ Haskell typeOriginal bytestringInteger resultExtra bytestring Error message¨ Haskell typeOriginal bytestring Error message©6Haskell type, should match Haskell name exactly, e.g. Int64ODatabase type(s), should appear different from Haskell name, e.g. "integer" or INT, not Int.Incorrect value Error messageª6Haskell type, should match Haskell name exactly, e.g. Int64Received value Error message‘’“”•–‘’“”• None 01<CFQTVÅg—2Datatype that represents an entity, with both its ²( and its Haskell record representation.CWhen using a SQL-based backend (such as SQLite or PostgreSQL), an —€ may take any number of columns depending on how many fields it has. In order to reconstruct your entity on the Haskell side,  persistentu needs all of your entity columns and in the right order. Note that you don't need to worry about this when using  persistent@'s API since everything is handled correctly behind the scenes.AHowever, if you want to issue a raw SQL command that returns an —K, then you have to be careful with the column order. While you could use SELECT Entity.* WHERE ...Š and that would work most of the time, there are times when the order of the columns on your database is different from the order that  persistentz expects (for example, if you add a new field in the middle of you entity definition and then use the migration code --  persistentœ will expect the column to be in the middle, but your DBMS will put it as the last column). So, instead of using a query like the one above, you may use   (from the Database.Persist.GenericSqlJ module) with its /entity selection placeholder/ (a double question mark ?? ). Using rawSql$ the query above must be written as SELECT ?? WHERE ... Then rawSql will replace ??| with the list of all columns that we need from your entity in the right order. If your query returns two entities (i.e. %(Entity backend a, Entity backend b)), then you must you use SELECT ??, ?? WHERE ... , and so on.› Filters which are available for select,  updateWhere and  deleteWhere . Each filter constructor specifies the field being filtered on, the type of comparison applied (equals, not equals, etc) and the argument for the comparison.1Persistent users use combinators to create these.3convenient for internal use, not needed for the API¤Query options.$Persistent users use these directly.©Updating a database entity.1Persistent users use combinators to create these.°CPersistent serialized Haskell records to the database. A Database —> (A row in SQL, a document in MongoDB, etc) corresponds to a ² plus a Haskell record.OFor every Haskell record type stored in the database there is a corresponding °½ instance. An instance of PersistEntity contains meta-data for the record. PersistEntity also helps abstract over different record types. That way the same query interface can return a °@, with each query returning different types of Haskell records.¬Some advanced type system capabilities are used to make this process type-safe. Persistent users usually don't need to understand the class associated data and functions.±:Persistent allows multiple different backends (databases).²zBy default, a backend will automatically generate the key Instead you can specify a Primary key made up of unique values.³An ³] is parameterised by the Haskell record it belongs to and the additional type of that field.´Unique keys besides the ².µA lower-level key operation.¶A lower-level key operation.·!A meta-operation to retrieve the ² ³.¸ Retrieve the w meta-data for the record.¹Return meta-data for a given ³.º8A meta-operation to get the database fields of a record.»LA lower-level operation to convert from database values to a Haskell record.¼%A meta operation to retrieve all the ´ keys.½A lower level operation.¾A lower level operation.¿Use a “ as a lens.À1Get list of values corresponding to given entity.Á Predefined toJSON!. The resulting JSON looks like "{"key": 1, "value": {"name": ...}}.The typical usage is: Finstance ToJSON (Entity User) where toJSON = keyValueEntityToJSON  Predefined  parseJSON. The input JSON looks like "{"key": 1, "value": {"name": ...}}.The typical usage is: Minstance FromJSON (Entity User) where parseJSON = keyValueEntityFromJSON à Predefined toJSON!. The resulting JSON looks like {"id": 1, "name": ...}.The typical usage is: @instance ToJSON (Entity User) where toJSON = entityIdToJSON Ä Predefined  parseJSON. The input JSON looks like {"id": 1, "name": ...}.The typical usage is: Ginstance FromJSON (Entity User) where parseJSON = entityIdFromJSON «YRealistically this is only going to be used for MongoDB, so lets use MongoDB conventionsÅ(Convenience function for getting a free “+ instance from a type with JSON instances."Example usage in combination with Æ: sinstance PersistField MyData where fromPersistValue = fromPersistValueJSON toPersistValue = toPersistValueJSON Æ(Convenience function for getting a free “É instance from a type with JSON instances. The JSON parser used will accept JSON values other that object and arrays. So, if your instance serializes the data to a JSON string, this will still work."Example usage in combination with Å: sinstance PersistField MyData where fromPersistValue = fromPersistValueJSON toPersistValue = toPersistValueJSON ¬(Convenience function for getting a free “ instance from a type with an ­ instance. The function derivePersistFieldn from the persistent-template package should generally be preferred. However, if you want to ensure that an ORDER BYf clause that uses your field will order rows by the data constructor order, this is a better choice."Example usage in combination with ®: Édata SeverityLevel = Low | Medium | Critical | High deriving (Enum, Bounded) instance PersistField SeverityLevel where fromPersistValue = fromPersistValueEnum toPersistValue = toPersistValueEnum ®(Convenience function for getting a free “ instance from a type with an ­* instance. This function also requires a ¯- instance to improve the reporting of errors."Example usage in combination with ¬: Édata SeverityLevel = Low | Medium | Critical | High deriving (Enum, Bounded) instance PersistField SeverityLevel where fromPersistValue = fromPersistValueEnum toPersistValue = toPersistValueEnum 2—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°²´³±¶»¹µ·¸º¼½¾¿ÀÁÂÃÄÅÆ¬®—˜™š›œžŸ ¡¢¤¥¦§¨©ª«¬­®°±²µ¶·¸³¹º»´¼½¾¿NoneCFTVÇ9¦   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\`]^_abcedjfghiklmnopqrstuvwx{}yz|~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯²¥‰Š‹†‡ˆƒ„…wxyz{|}~€‚ŒŽvstupqroklmnbcdefghij\]^_`aXYZ[STUVWMNOPQRIJKLH?@ABCDEFG89:;<=>)*+,-./01234567 !"#$%&'( ‘’©ª«¬­®¯¤¥¦§¨›œžŸ ¡¢£—˜™šNone%OÛ °fields in other entity±vA line. We don't care about spaces in the middle of the line. Also, we don't care about the ammount of indentation.²A token used by the parser.³Spaces n are n consecutive spaces.´ Token tok is token tok already unquoted.Ê5Whether fields are by default strict. Default value: True.Ë*The name of the id column. Default value: idF The name of the id column can also be changed on a per-model basis Dhttps://github.com/yesodweb/persistent/wiki/Persistent-entity-syntaxÎ?Parses a quasi-quoted syntax into a list of entity definitions.µTokenize a string.¶VA string of tokens is empty when it has only spaces. There can't be two consecutive ³, so this takes O(1) time.·ERemove leading spaces and remove spaces in the middle of the tokens.¸5Divide lines into blocks and make entity definitions.¹Construct an entity definition.¹nameentity attributesindented lines ÇÈÉÊËÌÍÎÏ ÎÇÈÉÊËÌÍϺ»°¼½¾¿À±ÁÂò³´ÇÈÉÊËÄÅÆÇNone +<>?AFT>ÔkCreate a new record in the database, returning an automatically created key (in SQL an auto-increment id).ÕSame as Ô, but doesn't return a Key.Ö9Create multiple records in the database and return their ²s.If you don't need the inserted ²s, use ×.fThe MongoDB and PostgreSQL backends insert all records and retrieve their keys in one database query.GThe SQLite and MySQL backends use the slow, default implementation of  mapM insert.×Same as Ö, but doesn't return any ²s.]The MongoDB, PostgreSQL, SQLite and MySQL backends insert all records in one database query.ØSame as ×, but takes an — instead of just a record.PUseful when migrating data from one entity to another and want to preserve ids.CThe MongoDB backend inserts all the entities in one database query.:The SQL backends use the slow, default implementation of mapM_ insertKey.Ù8Create a new record in the database using the given key.Ú;Put the record in the database with the given key. Unlike ÛT, if a record with the given key does not exist then a new record will be inserted.Û˜Replace the record in the database with the given key. Note that the result is undefined if such record does not exist, so you must use 'insertKey or Ú in these cases.ÜODelete a specific record by identifier. Does nothing if record does not exist.Ý.Update individual fields on a specific record.ÞaUpdate individual fields on a specific record, and retrieve the updated value from the database._Note that this function will throw an exception if the given key is not found in the database.à)Get a record by identifier, if available.ãã converts a ° ² into a â8 This can be used by each backend to convert between a ²7 and a plain Haskell type. For Sql, that is done with toSqlKey and  fromSqlKey.By default, a ° uses the default â0 for its Key and is an instance of ToBackendKeyA ²= that instead uses a custom type will not be an instance of ã.æ-A convenient alias for common type signaturesçYThis class witnesses that two backend are compatible, and that you can convert from the sub backend into the sup" backend. This is similar to the ë and éH classes, but where you don't want to fix the type associated with the ± of a record.)Generally speaking, where you might have:  foo :: ( ° record , PeristEntityBackend record ~ ì backend ,  IsSqlBackend backend ) this can be replaced with:  foo :: ( ° record, , ± record ~ backend , ç  SqlBackend backend ) This works for SqlReadBackend because of the  instance ç  SqlBackend SqlReadBackend$, without needing to go through the ì type family.8Likewise, functions that are currently hardcoded to use  SqlBackend can be generalized: -- before: asdf :: È  SqlBackend) m () asdf = pure () -- after: asdf' :: ç@ SqlBackend backend => ReaderT backend m () asdf' = withReaderT è asdf éClass which witnesses that backend is essentially the same as BaseBackend backend#. That is, they're isomorphic and backend is just some wrapper over BaseBackend backend.ê¦This function is how we actually construct and tag a backend as having read or write capabilities. It should be used carefully and only when actually constructing a backendY. Careless use allows us to accidentally run a write query against a read-only database.ë%Class which allows the plucking of a BaseBackend backend' from some larger type. For example, œ instance HasPersistBackend (SqlReadBackend, Int) where type BaseBackend (SqlReadBackend, Int) = SqlBackend persistBackend = unSqlReadBackend . fst ïSame as àv, but for a non-null (not Maybe) foreign key. Unsafe unless your database is enforcing that the foreign key is valid.ðSame as ï, but returns an — instead of just the record.ñICurry this to make a convenience function that loads an associated model. foreign = belongsTo foreignIdòSame as ñ , but uses getJust# and therefore is similarly unsafe.óLike insert, but returns the complete Entity.ôLike get, but returns the complete Entity.õLike ó( but just returns the record instead of —.#ÓÜÔÝÛÕÖרÙÚÞßàáâãäåæçèéêëìíîïðñòóôõÓ ÔÕÖרÙÚÛÜÝÞßàáâãäåçèéêëìíNone+<FTR‘öSome functions in this module (ø, ý, and ƒ) first query the unique indexes to check for conflicts. You could instead optimistically attempt to perform the operation (e.g. Û instead of  ). However,gthere is some fragility to trying to catch the correct exception and determing the column of failure;Ban exception will automatically abort the current SQL transaction.÷KDelete a specific record by unique key. Does nothing if no record matches.øLike Ô, but returns ÉJ when the record couldn't be inserted because of a uniqueness constraint.ù2Update based on a uniqueness constraint or insert:+insert the new record if it does not exist;žIf the record exists (matched via it's uniqueness constraint), then update the existing record with the parameters which is passed on as list to the function.BThrows an exception if there is more than 1 uniqueness constraint.ú8Update based on a given uniqueness constraint or insert:+insert the new record if it does not exist;Hupdate the existing record that matches the given uniqueness constraint.ûQueries against ´ keys (other than the id ²).IPlease read the general Persistent documentation to learn how to create ´ keys.qUsing this with an Entity without a Unique key leads to undefined behavior. A few of these functions require a single ´$, so using an Entity with multiple ´”s is also undefined. In these cases persistent's goal is to throw an exception as soon as possible, but persistent is still transitioning to that.žSQL backends automatically create uniqueness constraints, but for MongoDB you must manually place a unique index on a field to have a uniqueness constraint.üFGet a record by unique key, if available. Returns also the identifier.ýInsert a value, checking for conflicts with any unique constraints. If a duplicate exists in the database, it is returned as Ê*. Otherwise, the new 'Key is returned as Ë.̳Insert a value, checking for conflicts with any unique constraints. If a duplicate exists in the database, it is left untouched. The key of the existing or new entry is returnedþLike ó, but returns ÉJ when the record couldn't be inserted because of a uniqueness constraint.ÿ*Return the single unique key for a record.A modification of ü, which takes the ° itself instead of a ´# record. Returns a record matching oneS of the unique keys. This function makes the most sense on entities with a single ´ constructor.¨Attempt to replace the record of the given key with the given new record. First query the unique fields to make sure the replacement maintains uniqueness constraints.Return ÉC if the replacement was made. If uniqueness is violated, return a Í with the ´ violationnCheck whether there are any conflicts for unique keys with this entity and existing entities in the database.Returns Ém if the entity would be unique, and could thus safely be inserted. on a conflict returns the conflicting keyùnew record to insertgupdates to perform if the record already exists (leaving this empty is the equivalent of performing a Ú on a unique key).the record in the database after the operationú uniqueness constraint to find bynew record to insertgupdates to perform if the record already exists (leaving this empty is the equivalent of performing a Ú on a unique key).the record in the database after the operation ö÷øùúûüýþÿö÷øùúûüNone+<FT^¼ 0Backends supporting conditional write operationsDUpdate individual fields on any record matching the given criterion.0Delete all records matching the given criterion.0Backends supporting conditional read operations.cGet all records matching the given criterion in the specified order. Returns also the identifiers.,Get just the first record for the criterion. Get the ².s of all records matching the given criterion. ;The total number of records fulfilling the given criterion. cGet all records matching the given criterion in the specified order. Returns also the identifiers. Get the ².s of all records matching the given criterion. Call  ! but return the result as a list.Call  ! but return the result as a list.        None>?FTcÿ´For combinations of backends and entities that support cascade-deletion. Cascade-deletion  means that entries that depend on other entries to be deleted will be deleted as well.3Perform cascade-deletion of single database entry.5Cascade-deletion of entries satisfying given filters.None+ma¿A backwards-compatible alias for those that don't care about distinguishing between read and write queries. It signifies the assumption that, by default, a backend can write as well as read.¿A backwards-compatible alias for those that don't care about distinguishing between read and write queries. It signifies the assumption that, by default, a backend can write as well as read.¿A backwards-compatible alias for those that don't care about distinguishing between read and write queries. It signifies the assumption that, by default, a backend can write as well as read.b“”•°²´³±¶»¹µ·¸º¼½¾¿ÀÁÂÃÄÅÆÓÜÔÝÛÕÖרÙÚÞßàáâãäåæçèéëìíîïðñòóôõö÷øùúûüýþÿ     bãäåáâßàÓÔÕÖרÙÚÛÜÝÞæïðôñòóõûüö÷øùúýþÿ     °±²µ¶·¸³¹º»´¼½¾¿“”•ÀëìíéîçèÁÂÃÄÅÆNone +1>?FQTV‚™ $A backend which is a wrapper around  SqlBackend.Like  SqlPersistTM but compatible with any SQL backend which can handle read and write queries.Like  SqlPersistTC but compatible with any SQL backend which can handle read queries.^A constraint synonym which witnesses that a backend is SQL and can run read and write queries.TA constraint synonym which witnesses that a backend is SQL and can run read queries.5An SQL backend which can handle read or write queries1An SQL backend which can only handle read queries!Btable name, column names, id name, either 1 or 2 statements to run"oSQL for inserting many rows and returning their primary keys, for backends that support this functioanlity. If É,, rows will be inserted one-at-a-time using !./sSome databases (probably only Sqlite) have a limit on how many question-mark parameters may be used in a statement;WUseful for running a write query against an untagged backend with unknown capabilities.<SUseful for running a read query against a backend with read and write capabilities.=LUseful for running a read query against a backend with unknown capabilities..éêëìí* !"#$%&'()+,-./0123456789:;<=.ëìíéê=<;:6789012345 !"#$%&'()*+,-./ÎÏ !"#$%&'()*+,-./0123456789None+1;<=>?EFKQTV‡ÔDA single column (see rawSql). Any  PersistField may be used here, including )% (which does not do any processing).ZDeprecated synonym for  SqlBackend.@* !"#$%&'()+,-./0123456789:;<=DEFGHIJKLMNOPQRSTUVWXYZDEFNOPQRSTUVWXYNoneOŠ$\0Create the list of columns for the given entity.[\None<CFTVí-]Assign a field a value. Example usage pupdateAge :: MonadIO m => ReaderT SqlBackend m () updateAge = updateWhere [UserName ==. "SPJ" ] [UserAge =. 45]  Similar to W which is shown in the above example you can use other functions present in the module Database.Persist.Class#. Note that the first parameter of  is [› val] and second parameter is [©* val]. By comparing this with the type of b and ]4, you can see that they match up in the above usage. The above query when applied on  #dataset dataset-1, will produce this:  +-----+-----+--------+ |id |name |age | +-----+-----+--------+ |1 |SPJ |40 -> 45| +-----+-----+--------+ |2 |Simon|41 | +-----+-----+--------+^Assign a field by addition (+=). Example usage jaddAge :: MonadIO m => ReaderT SqlBackend m () addAge = updateWhere [UserName ==. "SPJ" ] [UserAge +=. 1]  The above query when applied on  #dataset dataset-1, will produce this: §+-----+-----+---------+ |id |name |age | +-----+-----+---------+ |1 |SPJ |40 -> 41 | +-----+-----+---------+ |2 |Simon|41 | +-----+-----+---------+_Assign a field by subtraction (-=). Example usage tsubtractAge :: MonadIO m => ReaderT SqlBackend m () subtractAge = updateWhere [UserName ==. "SPJ" ] [UserAge -=. 1]  The above query when applied on  #dataset dataset-1, will produce this: §+-----+-----+---------+ |id |name |age | +-----+-----+---------+ |1 |SPJ |40 -> 39 | +-----+-----+---------+ |2 |Simon|41 | +-----+-----+---------+`"Assign a field by multiplication (*=). Example usage tmultiplyAge :: MonadIO m => ReaderT SqlBackend m () multiplyAge = updateWhere [UserName ==. "SPJ" ] [UserAge *=. 2]  The above query when applied on  #dataset dataset-1, will produce this:  +-----+-----+--------+ |id |name |age | +-----+-----+--------+ |1 |SPJ |40 -> 80| +-----+-----+--------+ |2 |Simon|41 | +-----+-----+--------+aAssign a field by division (/=). Example usage pdivideAge :: MonadIO m => ReaderT SqlBackend m () divideAge = updateWhere [UserName ==. "SPJ" ] [UserAge /=. 2]  The above query when applied on  #dataset dataset-1, will produce this: §+-----+-----+---------+ |id |name |age | +-----+-----+---------+ |1 |SPJ |40 -> 20 | +-----+-----+---------+ |2 |Simon|41 | +-----+-----+---------+bCheck for equality. Example usage mselectSPJ :: MonadIO m => ReaderT SqlBackend m [Entity User] selectSPJ = selectList [UserName ==. "SPJ" ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+cNon-equality check. Example usage qselectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User] selectSimon = selectList [UserName !=. "SPJ" ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+dLess-than check. Example usage pselectLessAge :: MonadIO m => ReaderT SqlBackend m [Entity User] selectLessAge = selectList [UserAge <. 41 ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+eLess-than or equal check. Example usage {selectLessEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User] selectLessEqualAge = selectList [UserAge <=. 40 ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+fGreater-than check. Example usage vselectGreaterAge :: MonadIO m => ReaderT SqlBackend m [Entity User] selectGreaterAge = selectList [UserAge >. 40 ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+gGreater-than or equal check. Example usage selectGreaterEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User] selectGreaterEqualAge = selectList [UserAge >=. 41 ] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+h Check if value is in given list. Example usage rselectUsers :: MonadIO m => ReaderT SqlBackend m [Entity User] selectUsers = selectList [UserAge <-. [40, 41]] []  The above query when applied on  #dataset dataset-1, will produce this: ‹+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+ jselectSPJ :: MonadIO m => ReaderT SqlBackend m [Entity User] selectSPJ = selectList [UserAge <-. [40]] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |1 |SPJ |40 | +-----+-----+-----+i$Check if value is not in given list. Example usage oselectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User] selectSimon = selectList [UserAge /<-. [40]] []  The above query when applied on  #dataset dataset-1, will produce this: c+-----+-----+-----+ |id |name |age | +-----+-----+-----+ |2 |Simon|41 | +-----+-----+-----+j,The OR of two lists of filters. For example: ‚selectList ([ PersonAge >. 25 , PersonAge <. 30 ] ||. [ PersonIncome >. 15000 , PersonIncome <. 25000 ]) []>will filter records where a person's age is between 25 and 30 or1 a person's income is between (15000 and 25000).If you are looking for an (&&.) operator to do (A AND B AND (C OR D)) you can use the (++)! operator instead as there is no (&&.). For example: ‚selectList ([ PersonAge >. 25 , PersonAge <. 30 ] ++ ([PersonCategory ==. 1] ||. [PersonCategory ==. 5])) []>will filter records where a person's age is between 25 and 30 and' (person's category is either 1 or 5).kConvert list of )Vs into textual representation of JSON object. This is a type-constrained synonym for m.lqConvert map (list of tuples) into textual representation of JSON object. This is a type-constrained synonym for m.m+A more general way to convert instances of Ð type class to strict text Ñ.nFIXME What's this exactly?ÿ   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\`]^_abcedjfghiklmnopqrstuvwx{}yz|~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°²´³±¶»¹µ·¸º¼½¾¿ÀÁÂÃÄÅÆÓÜÔÝÛÕÖרÙÚÞßàáâãäåæçèéëìíîïðñòóôõö÷øùúûüýþÿ     ]^_`abcdefghijklmn]^_`abcdfeghijklm–n]3^3_3`3a3b4c4d4e4f4g4h4i4j3Noneó/ opqrstuvw vopqwrstuNone7;<=FOTVøÃz1Class for data types that may be retrived from a rawSql query.{ONumber of columns that this data type needs and the list of substitutions for SELECT placeholders ??.|>A string telling the user why the column count is what it is.}1Transform a row of the result into the data type.Òxyz{|}xyz{|}None+<FT2þ€Execute a raw SQL statementKExecute a raw SQL statement and return the number of rows it has modified.ƒ>Execute a raw SQL statement and return its results as a list.If you're using —s$ (which is quite likely), then you must; use entity selection placeholders (double question mark, ?? ). These ??ª placeholders are then replaced for the names of the columns that we need for your entities. You'll receive an error if you don't use the placeholders. Please see the —s documentation for more details.0You may put value placeholders (question marks, ?) in your SQL query. These placeholders are then replaced by the values you pass on the second parameter, already correctly escaped. You may want to use ”2 to help you constructing the placeholder values.]Since you're giving a raw SQL statement, you don't get any guarantees regarding safety. If ƒ¬ is not able to parse the results of your query back, then an exception is raised. However, most common problems are mitigated by using the entity selection placeholder ??>, and you shouldn't see any error at all if you're not using D.Some example of ƒ based on this schema: Éshare [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| Person name String age Int Maybe deriving Show BlogPost title String authorId PersonId deriving Show |] #Examples based on the above schema: ÿ„getPerson :: MonadIO m => ReaderT SqlBackend m [Entity Person] getPerson = rawSql "select ?? from person where name=?" [PersistText "john"] getAge :: MonadIO m => ReaderT SqlBackend m [Single Int] getAge = rawSql "select person.age from person where name=?" [PersistText "john"] getAgeName :: MonadIO m => ReaderT SqlBackend m [(Single Int, Single Text)] getAgeName = rawSql "select person.age, person.name from person where name=?" [PersistText "john"] getPersonBlog :: MonadIO m => ReaderT SqlBackend m [(Entity Person, Entity BlogPost)] getPersonBlog = rawSql "select ??,?? from person,blog_post where person.id = blog_post.author_id" [] KMinimal working program for PostgreSQL backend based on the above concepts: ÿ-{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Control.Monad.IO.Class (liftIO) import Control.Monad.Logger (runStderrLoggingT) import Database.Persist import Control.Monad.Reader import Data.Text import Database.Persist.Sql import Database.Persist.Postgresql import Database.Persist.TH share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| Person name String age Int Maybe deriving Show |] conn = "host=localhost dbname=new_db user=postgres password=postgres port=5432" getPerson :: MonadIO m => ReaderT SqlBackend m [Entity Person] getPerson = rawSql "select ?? from person where name=?" [PersistText "sibi"] liftSqlPersistMPool y x = liftIO (runSqlPersistMPool y x) main :: IO () main = runStderrLoggingT $ withPostgresqlPool conn 10 $ liftSqlPersistMPool $ do runMigration migrateAll xs <- getPerson liftIO (print xs) €*SQL statement, possibly with placeholders. Values to fill the placeholders.*SQL statement, possibly with placeholders. Values to fill the placeholders.ƒ*SQL statement, possibly with placeholders. Values to fill the placeholders.~€Ó‚ƒNone+<FTV;„bGet a connection from the pool, run the given action, and then return the connection to the pool.´Note: This function previously timed out after 2 seconds, but this behavior was buggy and caused more problems than it solved. Since version 2.1.2, it performs no timeout checks.…Like Ôh, but times out the operation if resource allocation does not complete within the given timeout period.…Timeout period in microsecondsŠcreate a new connectionconnection count „…†‡ˆ‰Š‹ŒŽNone<N^ Given a Hr, this parses it and returns either a list of errors associated with the migration or a list of migrations to do.Like ,, but instead of returning the value in an Õ value, it calls Ö on the error values.‘Prints a migration.’ Convert a H to a list of Ñ values corresponding to their J statements.“Return all of the J4 values associated with the given migration. Calls Ö+ if there's a parse error on any migration.”kRuns a migration. If the migration fails to parse or if any of the migrations are unsafe, then this calls Ö to halt the program.•Same as ”V, but returns a list of the SQL commands executed instead of printing them to stderr.×ÏRun the given migration against the database. If the migration fails to parse, or there are any unsafe migrations, then this will error at runtime. This returns a list of the migrations that were executed.–Like ”P, but this will perform the unsafe database migrations instead of erroring out.ØQSort the alter DB statements so tables are created before constraints are added.—1Given a list of old entity definitions and a new w in val, this creates a H9 to update the old list of definitions with the new one.× is silent? ‘’“”•–—None+7;<=>?FKQTVW#›[get the SQL string for the table that a PeristEntity represents Useful for raw SQL queries`Your backend may provide a more convenient tableName function which does not operate in a Monadœ>useful for a backend to implement tableName by adding escaping[get the SQL string for the field that an EntityField represents Useful for raw SQL queries`Your backend may provide a more convenient fieldName function which does not operate in a Monadž>useful for a backend to implement fieldName by adding escapingâÙÚÛÜÝÞ˜™š›œžßàÛÞáâÚÝãäÙÜNone]lÌŸ;QuasiQuoter for performing raw sql queries, analoguous to ƒThis and the following are convenient QuasiQuoters to perform raw SQL queries. They each follow the same pattern and are analogous to the similarly named raw functions. Neither the quoted function's behaviour, nor it's return value is altered during the translation and all documentation provided with it holds.¥These QuasiQuoters perform a simple substitution on the query text, that allows value substitutions, table name substitutions as well as column name substitutions.Here is a small example:!Given the following simple model: Category rgt Int lft Int "We can now execute this raw query: nlet lft = 10 :: Int rgt = 20 :: Int width = rgt - lft in [sqlQQ| DELETE FROM ^{Category} WHERE {CategoryLft} BETWEEN  {lft} AND !{rgt}; UPDATE category SET {CategoryRgt} = {CategoryRgt} - #{width} WHERE 2{CategoryRgt} > #{rgt}; UPDATE category SET {CategoryLft} = {CategoryLft} - {width} WHERE @{CategoryLft} > {rgt}; |]  ^{TableName}+ looks up the table's name and escapes it,  @{ColumnName}9 looks up the column's name and properly escapes it and #{value}C inserts the value via the usual parameter substitution mechanism. Analoguous to €åAnaloguous to æAnaloguous to ~çAnaloguous to Ÿ åæçèéêëìNone<FTm^None+FQTVr2¡Same as *, but returns the number of rows affected.¢Same as *, but returns the number of rows affected.£BGenerates sql for limit and offset for postgres, sqlite and mysql.íinclude table name?include WHERE?îinclude table name?ïinclude the table name¡¢£ðñòNonetj¤3Commit the current transaction and begin a new one.¥6Roll back the current transaction and begin a new one.ÿ   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\`]^_abcedjfghiklmnopqrstuvwx{}yz|~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°²´³±¶»¹µ·¸º¼½¾¿ÀÁÂÃÄÅÆÓÜÔÝÛÕÖרÙÚÞßàáâÙÚÛÜÝÞãäåæçèéëìíîïðñòóôõö÷øùúûüýþÿ     * !"#$%&'()+,-./0123456789:;<=DEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnxyz{|}~€‚ƒ„†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥pZQRSTUVWXYNOPMLKJIHGDEF !"#$%&'()*+,-./012345:6789=<;z{|}xy„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œž~€ƒŸ ¡¢¤¥‚\[£ó !" # $ % & ' ( ) * * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Z [ \ ] ^ _ ` a b c c d e f f g h i j k k l m n o o p q r s t u v w x x y z { | } ~  €  ‚ ƒ „ … … † ‡ ‡ ˆ ‰ Š Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ¡ ¢ £ £ ¤ ¥ ¦ § ¨ ¨ © ª « « ¬ ­ ® ¯ ° ± 7 ² ³ ´ µ ¶ · · ¸ ¹ º » ) ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ ÒÓÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'())*+,-./0123456789::;<=>?@ABCDEFGHIJKLMMNOPQRSTUVWXYYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰ Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­® ¯ ° ± ² ³ ´µ¶· ¸µ¶¹º»¼½¼¾¿ÀÁÂÃÃÄÅÅÆÇ»ÈÉÊËÌÍÎÏеÑÒµÓÔµÓÕÖµÑ×%'¬ØÙÚÛÜÝÞßàáµÓâµãäåæçèéêëìíîïðñòóôõ¼ö®÷øùúûüýþÿ)persistent-2.7.3.1-F4bGPMQNmSk9DOJLosx13YDatabase.Persist.ClassDatabase.Persist.TypesDatabase.PersistDatabase.Persist.Quasi#Database.Persist.Sql.Types.InternalDatabase.Persist.SqlDatabase.Persist.Sql.Util$Database.Persist.Class.PersistConfigDatabase.Persist.Types.Base#Database.Persist.Class.PersistField$Database.Persist.Class.PersistEntityDatabase.Persist.GenericSqlrawSql#Database.Persist.Class.PersistStore$Database.Persist.Class.PersistUnique#Database.Persist.Class.PersistQuery$Database.Persist.Class.DeleteCascadeDatabase.Persist.Sql.TypesDatabase.Persist.Sql.InternalDatabase.Persist.Sql.ClassDatabase.Persist.Sql.RawDatabase.Persist.Sql.RunDatabase.Persist.Sql.Migration(Database.Persist.Sql.Orphan.PersistStoreDatabase.Persist.Sql.Raw.QQ)Database.Persist.Sql.Orphan.PersistUnique(Database.Persist.Sql.Orphan.PersistQuery PersistConfigPersistConfigBackendPersistConfigPool loadConfigapplyEnvcreatePoolConfigrunPool PersistUpdateAssignAddSubtractMultiplyDivideBackendSpecificUpdateOnlyUniqueExceptionUpdateException KeyNotFound UpsertError PersistFilterEqNeGtLtGeLeInNotInBackendSpecificFilterSqlType SqlStringSqlInt32SqlInt64SqlReal SqlNumericSqlBoolSqlDaySqlTime SqlDayTimeSqlBlobSqlOther PersistValue PersistTextPersistByteString PersistInt64 PersistDoublePersistRational PersistBool PersistDayPersistTimeOfDayPersistUTCTime PersistNull PersistList PersistMapPersistObjectIdPersistDbSpecificPersistException PersistErrorPersistMarshalErrorPersistInvalidFieldPersistForeignConstraintUnmetPersistMongoDBErrorPersistMongoDBUnsupported ForeignDefforeignRefTableHaskellforeignRefTableDBNameforeignConstraintNameHaskellforeignConstraintNameDBName foreignFields foreignAttrsforeignNullableForeignFieldDef CompositeDefcompositeFieldscompositeAttrs UniqueDef uniqueHaskell uniqueDBName uniqueFields uniqueAttrs EmbedFieldDef emFieldDB emFieldEmbed emFieldCycleEmbedEntityDefembeddedHaskellembeddedFields ReferenceDef NoReference ForeignRefEmbedRef CompositeRef SelfReferenceFieldDef fieldHaskellfieldDB fieldType fieldSqlType fieldAttrs fieldStrictfieldReference FieldType FTTypeConFTAppFTListAttrDBNameunDBName HaskellName unHaskellName ExtraLine EntityDef entityHaskellentityDBentityId entityAttrs entityFields entityUniquesentityForeigns entityDerives entityExtra entitySum WhyNullable ByMaybeAttrByNullableAttr IsNullableNullable NotNullable CheckmarkActiveInactive entityPrimaryentityKeyFieldskeyAndEntityFieldstoEmbedEntityDeffromPersistValueTextSomePersistField PersistFieldtoPersistValuefromPersistValue getPersistMapEntity entityKey entityValFilter FilterAndFilterOr BackendFilter filterField filterValue filterFilter SelectOptAscDescOffsetByLimitToUpdate BackendUpdate updateField updateValue updateUpdate PersistEntityPersistEntityBackendKey EntityFieldUnique keyToValues keyFromValuespersistIdField entityDefpersistFieldDeftoPersistFieldsfromPersistValuespersistUniqueKeyspersistUniqueToFieldNamespersistUniqueToValues fieldLens entityValueskeyValueEntityToJSONkeyValueEntityFromJSONentityIdToJSONentityIdFromJSONtoPersistValueJSONfromPersistValueJSONPersistSettings psToDBNamepsStrictFieldspsIdNameupperCaseSettingslowerCaseSettingsparsenullable$fShowParseState $fShowToken $fEqTokenPersistStoreWriteinsertinsert_ insertMany insertMany_insertEntityMany insertKeyrepsertreplacedeleteupdate updateGetPersistStoreReadget PersistCore BackendKey ToBackendKey toBackendKeyfromBackendKeyPersistRecordBackendBackendCompatibleprojectBackendIsPersistBackendmkPersistBackendHasPersistBackend BaseBackendpersistBackend liftPersistgetJust getJustEntity belongsTo belongsToJust insertEntity getEntity insertRecordPersistUniqueWritedeleteBy insertUniqueupsertupsertByPersistUniqueReadgetByinsertByinsertUniqueEntity onlyUnique getByValue replaceUnique checkUniquePersistQueryWrite updateWhere deleteWherePersistQueryReadselectSourceRes selectFirst selectKeysRescount selectSource selectKeys selectListselectKeysList DeleteCascade deleteCascadedeleteCascadeWhere PersistStore PersistQuery PersistUnique IsSqlBackend SqlWriteTSqlReadTSqlBackendCanWriteSqlBackendCanReadSqlWriteBackendunSqlWriteBackendSqlReadBackendunSqlReadBackend SqlBackend connPrepare connInsertSqlconnInsertManySql connUpsertSql connStmtMap connCloseconnMigrateSql connBegin connCommit connRollbackconnEscapeName connNoLimit connRDBMSconnLimitOffset connLogFunc connMaxParams Statement stmtFinalize stmtReset stmtExecute stmtQueryInsertSqlResult ISRSingle ISRInsertGet ISRManyKeysLogFuncwriteToUnknown readToWrite readToUnknown$fIsPersistBackendSqlBackend$fHasPersistBackendSqlBackend $fIsPersistBackendSqlReadBackend!$fHasPersistBackendSqlReadBackend!$fIsPersistBackendSqlWriteBackend"$fHasPersistBackendSqlWriteBackendSingleunSingleConnectionPool MigrationCautiousMigrationSql SqlPersistM SqlPersist SqlPersistTPersistentSqlExceptionStatementAlreadyFinalizedCouldn'tGetSQLConnectionColumncNamecNullcSqlTypecDefaultcDefaultConstraintNamecMaxLen cReference ConnectiondefaultAttribute mkColumns=.+=.-=.*=./=.==.!=.<.<=.>.>=.<-./<-.||. listToJSON mapToJSON toJsonTextlimitOffsetOrderentityColumnNameskeyAndEntityColumnNamesentityColumnCounthasCompositeKey dbIdColumnsdbIdColumnsEsc dbColumnsparseEntityValues isIdFieldPersistFieldSqlsqlTypeRawSql rawSqlColsrawSqlColCountReasonrawSqlProcessRowrawQuery rawQueryRes rawExecuterawExecuteCount getStmtConn runSqlPoolwithResourceTimeout runSqlConnrunSqlPersistMrunSqlPersistMPoolliftSqlPersistMPool withSqlPool createSqlPool askLogFunc withSqlConnclose'parseMigrationparseMigration'printMigration showMigration getMigration runMigrationrunMigrationSilentrunMigrationUnsafemigrate withRawQuerytoSqlKey fromSqlKey getTableName tableDBName getFieldName fieldDBNamesqlQQ executeQQdeleteWhereCountupdateWhereCountdecorateSQLWithLimitOffsettransactionSavetransactionUndo$aeson-1.2.3.0-IKViWrdpe5qGW36sSFwXh7Data.Aeson.Types.InternalValueextraInputError intParseErrorfromPersistValueErrorfromPersistValueParseErroridFieldtoPersistValueEnumbaseGHC.EnumEnumfromPersistValueEnumBounded_unboundFieldsLineTokenSpacestokenizeempty removeSpaces parseLines mkEntityDefUnboundForeignDef_unboundForeignDefUnboundEntityDef_unboundForeignDefsunboundEntityDef lineIndenttokens ParseStatePSDonePSFail PSSuccesstransformers-0.5.2.0Control.Monad.Trans.ReaderReaderTGHC.BaseNothing Data.EitherLeftRight _insertOrGetJustData.Aeson.Types.ToJSONToJSON#text-1.2.2.2-EakMpasry3jA6OIwSZhq9MData.Text.InternalText $fRawSqlMaybegetStmt,resource-pool-0.2.3.2-8C0dYzOuAS33Ku8sfb0DvU Data.Pool withResourceEitherGHC.Errerror runMigration'sortMigrations SqlBackendKeySqlReadBackendKeySqlWriteBackendKeyunSqlBackendKeyunSqlReadBackendKeyunSqlWriteBackendKey$fPersistCoreSqlWriteBackendD:R:BackendKeySqlWriteBackend0$fPersistCoreSqlReadBackendD:R:BackendKeySqlReadBackend0$fPersistCoreSqlBackendD:R:BackendKeySqlBackend0executeCountQQqueryQQ queryResQQLiteral TableName ColumnNamefilterClauseHelper filterClause orderClauseOrNull OrNullYesOrNullNo