!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~(c) Ole Krger 2016BSD3Ole Krger <ole@vprsm.de>NoneOT !A type which can be coerced into Q Exp or Q Pat. Boolean 16-bit integer 32-bit integer64-bit integer&Single-precision floating-point number&Double-precision floating-point numberArbitrary precision numberFixed-length stringVariable-length string Unlimited variable-length string Byte arrayTimestamp without timezoneTimestamp with timezone     (c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>None!"9;BTypes which implement this type class may be used as column types.Pack column value.Unpack column value. Name of the underlying SQL type.May the column be NULL?/A condition that must hold true for the column. *Generate column description in SQL. Think  CREATE TABLE.!+Query parameter or value of a column - see  on how to generate !s manually but conveniently.$Type object identifier% Data valueDoes Word( require to be stored in type "numeric"?AProduce the two-digit hexadecimal representation of a 8-bit word.>Retrieve 8-bit word from two-digit hexadecimal representation..Unpack a byte array in textual representation.,Pack textual representation of a byte array.Finish the parsing process.Parse a ByteString.Build strict ByteString.( !"#$%&'()*+,-./0123456789  !"#$% !"#$%  !"#$%&'()*+,-./0123456789(c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>None9:;<=?DIR%= Query builder> Can build o using s and [p]. Internal state for every builder Query segment@VA type which implements this class can be used as a table in a quasi-quoted query. mkTable can implement this for you.AUnquoted name of the tableBUnquoted name of the ID fieldCPSelectors needed to retrieve all fields necessary to construct the type - think SELECT.DSELECT expressionEBSelect a field. The field nme will be quoted and properly escaped.FBSelect a special expression. The expression will be inlined as is.G(Query including statement and parametersUse the L- quasi-quoter to conveniently create queries.I StatementJ ParametersKProperly quote an identifier.+Generate the quoted identifier for a table.5Generate the quoted identifier for table's id column.1Generate the list of expression used as selector.Name Type nameQualified type nameQuoteSegmentsGReduce segments in order to resolve names and collect query parameters.Parse quasi-quoted query.L6This quasi-quoter allows you to generate instances of G7. It lets you write SQL with some small enhancements. L heavily relies on @ which can be implemented by mkTable for a type of your choice.6Some syntax definitions that might be useful later on: TypeName ::= UpperAlpha {AlphaNumeric | '_'} Name ::= (Alpha | '_') {AlphaNumeric | '_'} QualifiedTypeName ::= {TypeName '.'} TypeNameAlpha' includes all alphabetical characters;  UpperAlpha3 includes all upper-case alphabetical characters;  AlphaNumeric' includes all alpha-numeric characters. Embed values+You can embed values whose types implement . ValueExp ::= '$' Name magicNumber :: Int magicNumber = 1337 myQuery :: Query myQuery = [pgsq| SELECT * FROM table t WHERE t.column1 > $magicNumber AND t.column2 < $otherNumber |] where otherNumber = magicNumber * 2 $magicNumber and  $otherNumber are references to values  magicNumber and  otherNumber.!The quasi-quoter will generate a G% expression similar to the following. pQuery "SELECT * FROM table t WHERE t.column1 > $1 AND t.column2 < $2" [pack magicNumber, pack otherNumber] Table namesTypes that implement @~ associate a table name with themselves. Since the table name is not always known to the user, one can insert it dynamically. &TableNameExp ::= '@' QualifiedTypeNameThe @--operators is also an alias for the function ABSD. If you have an expression that triggers the quasi-quoter such as @A , but you would like to use the ABS9 functionality, then simply reformat your expression to @(A) or @"A" or ABS(A). instance QueryTable YourType where tableName _ = "YourTable" myQuery :: Query myQuery = [pgsq| SELECT * FROM @Table WHERE @Table.column = 1337 |]>The table name will be inlined which results in the following. HQuery "SELECT * FROM \"YourTable\" WHERE \"YourTable\".column = 1337" []Identifier column namesEach instance of @| also provides the name of the identifier column. Using this column name you can identify specific rows of a certain table. TableIdentExp ::= '&' TypeName&U is also the operator for bitwise-AND. To resolve the ambiguity for expressions like A&B, simply reformat it to A & B or A&(B) or A&"B". instance QueryTable YourType where tableName _ = "YourTable" tableIDName _ = "id" listIDs :: Query listIDs = [pgsq| SELECT &YourType FROM @YourType |]listIDs` is now a query which lists the IDs of each row. This is especially useful in combination with  Reference. ffetchIDs :: Errand [Reference YourType] fetchIDs = query [pgsq| SELECT &YourType FROM @YourType |]Note, just like @, the operator & is reserved. Although A&Bl is a valid SQL expression, it will trigger the quasi-quoter. To avoid this, you reform your expression to A & B or A&(B). SelectorsmkTable will automatically implement  and @@ for you. This allows you to make use of the selector expander. %SelectorExp ::= '#' QualifiedTypeName#U is also the operator for bitwise-XOR. To resolve the ambiguity for expressions like A#B, simply reformat it to A # B or A#(B) or A#"B". data Actor = Actor { actorName :: String, actorAge :: Word } deriving (Show, Eq, Ord) mkTable ''Actor [] fetchOldActors :: Errand [Actor] fetchOldActors = query [pgsq| SELECT #Actor FROM @Actor a WHERE a.actorAge >= $oldAge |] where oldAge = 70#ActorQ will expand to a list of columns that are necessary to construct an instance of Actor#. In this case it is equivalent to !@Actor.actorName, @Actor.actorAge3Parse quasi-quoted query but return only statement.M Just like Lz but only produces the statement associated with the query. Referenced values are not inlined, they are simply dismissed.NRun query builder.-Run query builder, return only the statement.O Write code.PWrite string code.QAdd an identifier.RAdd an absolute identifier.SEmbed a parameter.TEmbed a value parameter.U$Do something between other builders.8=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[=>?@ABCDEFGHIJKLMNOPQRSTUGHIJDEF@ABCLMK?>=NOPQRSTU%=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[(c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>NoneIbResult processorc+Error that occured during result processingdAOccurs when you're trying to access a column that does not exist.e:The value at a given row and column could not be unpacked.fMove cursor to the next column.gAUnpack the current column and move the cursor to the next column.hProcess the entire result set.i"Process one row of the result set. bcdefghibcdefghicdebhifgbcdefghi(c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>NoneIq(Helper type to capture an single column.tAAllows you to implement a custom result parser for your type. mkTable" can implement this for your type.v An interaction with the databasew Error codesError during errandNo t has been returned.Result set is empty.A user has thrown an error.Query execution failed.Result processing failed.Run an errand.3Execute a query and return the internal raw result.+Execute a query and process its result set.'Execute a query and dismiss its result.OExecute a query and process its result set using the provided result processor.$Combine result parsers sequencially.#qrstuvwxyz{|}~$ qrstuvwxyz{|}~$wxyz{|}~ vtuqrsqrstuvwxyz{|}~(c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>None" Options to .+A combination of fields must be unique. Unique ['name1, 'name2, ...], works analogous to the table constraint UNIQUE (name1, name2, ...) in SQL.5The given statement must evaluate to true. Just like CHECK (statement) in SQL.Table type declarationTable field declarationQualify a as a table type. " can implement this class for you.)Insert a row into the table and return a  to the inserted row.,Insert multiple rows into the table at once./Find the row identified by the given reference.Update an existing row.Delete a row from the table.FGenerate the query which creates this table inside the database. Use  for convenience.Reference a row of type a.(Generate an identifier for a table type.LMake a comma-seperated list of identifiers which correspond to given fields. Beginning of a insert statement.End of a insert statement.'Call a constructor with some variables.Generate the list of selectors.*Generate the result processor for a table.Generate the create query.&Generate the query which insert a row.7Generate the query which inserts multiple rows at once.%Generate the query for finding a row.&Generate the query for updating a row.&Generate the query for deleting a row.6Implement relevant instances for the given table type.6Check that each field's type has an implementation of .6Check that each constructor parameter type implements .<Verify that the given constructor is viable and construct a .>Make sure the given declaration can be used, then construct a .Implement the type classes @,  and t for the given type./The given type must fulfill these requirements: Data typeNo type contextNo type variables,One record constructor with 1 or more fields)All field types must have an instance of Example: o{-# LANGUAGE TemplateHaskell, QuasiQuotes #-} module Movies where ... data Movie = Movie { movieTitle :: , movieYear ::  } deriving  3 ''Movie [] data Actor = Actor { actorName :: , actorAge ::  } deriving   ''Actor [ ['actorName],  [MI| actorAge >= 18 |]] data MovieCast = MovieCast { movieCastMovie ::  Movie, movieCastActor ::  Actor } deriving   ''MovieCast [% ['movieCastMovie, 'movieCastActor]] In this example,  takes care of adding the  FOREIGN KEY" constraint, so we don't have to.)Check if the given name refers to a type. Generate a GD expression which will create the table described by the given type.Example: &data Table = Table { myField :: Int }  ''Table [] ...  $( ''Table) *(c) Ole Krger 2015-2016BSD3Ole Krger <ole@vprsm.de>NoneR  !"#$%@ABCDEFGHIJLMbcdefgqrstuvwxyz{|}~Rvwxyz{|}~ GHIJLM@ABCDEF!"#$% tubcdefgqrs               !"#$%&'()*++,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyyz{|}~k{j}%pg-store-0.1.0-1J7GMThZboAJfSEnPJlNzN Database.PostgreSQL.Store.ErrandDatabase.PostgreSQL.Store.OIDs!Database.PostgreSQL.Store.ColumnsDatabase.PostgreSQL.Store.Query Database.PostgreSQL.Store.ResultDatabase.PostgreSQL.Store.TableDatabase.PostgreSQL.Store.postgresql-libpq-0.9.2.0-pfIR3xRbgN3lAiV2rvAZpDatabase.PostgreSQL.LibPQ SingleTuple FatalError NonfatalError BadResponseCopyInCopyOutTuplesOk CommandOk EmptyQuery ExecStatusOIDQboolint2int4int8float4float8numericcharvarchartextbytea timestamp timestamptz $fGenOIDPat $fGenOIDExpColumnpackunpackcolumnTypeNamecolumnAllowNull columnCheckcolumnDescriptionValue NullValue valueType valueData$fColumnByteString$fColumnByteString0 $fColumnText $fColumnText0 $fColumn[]$fColumnUTCTime$fColumnInteger$fColumnWord64$fColumnWord32$fColumnWord16 $fColumnWord8 $fColumnWord $fColumnInt64 $fColumnInt32 $fColumnInt16 $fColumnInt8 $fColumnInt $fColumnBool $fColumnMaybe $fColumnValue $fShowValue $fEqValue $fOrdValue QueryBuilderQueryBuildable QueryCode QueryTable tableName tableIDNametableSelectorsSelectorElement SelectorFieldSelectorSpecialQueryqueryStatement queryParamsquoteIdentifierpgsqpgssrunQueryBuilder writeCodewriteStringCodewriteIdentifierwriteAbsIdentifier writeParam writeColumnintercalateBuilder$fQueryBuildable[]QQ$fQueryBuildable[]QQ0$$fQueryBuildableByteStringValueQuery $fQueryCode[]$fQueryCode[]0$fQueryCodeByteString $fShowQuery $fEqQuery $fOrdQuery$fShowSelectorElement$fEqSelectorElement$fOrdSelectorElementResultProcessor ResultErrorTooFewColumnsError UnpackError skipColumn unpackColumn processResultprocessOneResult$fShowResultError$fEqResultError$fFunctorResultProcessor$fApplicativeResultProcessor$fMonadResultProcessor$fMonadIOResultProcessor$fMonadErrorResultProcessorSingle fromSingleResultqueryResultProcessorErrand ErrorCodeUnknownErrorCauseIntegrityViolationRestrictViolationNotNullViolationForeignKeyViolationUniqueViolationCheckViolationExclusionViolation ErrandErrorNoResult EmptyResult UserError ExecError runErrandexecutequeryquery_ queryWith$fResultSingle $fShowSingle$fResult(,,,,,,)$fResult(,,,,,)$fResult(,,,,) $fResult(,,,) $fResult(,,) $fResult(,)$fShowErrorCode $fEqErrorCode$fShowErrandError$fEqErrandError$fFunctorErrand$fApplicativeErrand $fMonadErrand$fMonadIOErrand$fMonadErrorErrand $fEqSingle $fOrdSingleTableConstraintUniqueCheckTableinsert insertManyfindupdatedeletecreateTableQuery Reference referenceIDmkTable mkCreateQuery$fResultReference$fColumnReference$fShowReference $fEqReference$fOrdReference$fShowTableConstraint$fEqTableConstraint$fOrdTableConstraintGenOIDgenOIDwordRequiresNumeric word8ToHex hexToWord8decodeByteaHexencodeByteaHex finishParser parseMaybebuildByteString BuilderStateSegmentmakeTableIdentifiermakeTableIDIdentifiermakeTableSelectorsnametypeNamequalifiedTypeNamequotesegments reduceSegmentparseStoreQueryE*attoparsec-0.13.1.0-K5Fyc3MOMYs22DiprZQxLMData.Attoparsec.Text.InternalparseStoreStatementErunQueryBuilder_ buildQueryCode appendCodeappendStringCode SSelectorSTable SVariable SIdentifierSQuoteSOtherTableDec TableFieldtableIdentifiertableFieldIdentifierstableInsertStatementBegintableInsertStatementEndcallConstructormakeQuerySelectorsmakeResultProcessormakeCreateQuerymakeInsertQuerymakeInsertManyQuery makeFindQuerymakeUpdateQuerymakeDeleteQueryimplementClassescheckRecordFieldscheckNormalFieldscheckTableCtor checkTableDecbaseGHC.BaseStringghc-prim GHC.TypesIntGHC.ShowShowisTypemakeCtorPattern