| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Hmssql.Query.Types
Description
The representations of the query types, constructors and fields included, for the tests and for libraries built on top of hmssql (a quasiquoter, a reader of responses token by token). Hmssql.Query exports these types with only the constructors that code running queries uses; nothing here is stable.
A Query is a tree of pieces. Each piece holds fragments (static text
and placeholders numbered from 1 among the piece's own positional
parameters) and its parameters; a node caches how many positional
parameters are below it. So <> is a constant-time node, and the
absolute numbering (@p1, @p2, ... across the whole query) is
computed in one pass when the query is flattened (queryFragments,
queryParams, queryText): building a query from n pieces costs
O(n) however the <>s associate.
Synopsis
- data Query = Query {
- queryPositional :: !Int
- queryNode :: Node
- data Node
- piece :: [Fragment] -> [QueryParam] -> Query
- data Fragment
- = Static !Text
- | Placeholder !Int
- data QueryParam = QueryParam {
- paramName :: !Text
- paramEncode :: TdsContext -> Either String EncodedParam
- queryFragments :: Query -> [Fragment]
- queryParams :: Query -> [QueryParam]
- queryText :: Query -> Text
- renderFragments :: [Fragment] -> Text
- placeholderText :: Int -> Text
- queryProblem :: Query -> Maybe String
- fragmentsProblem :: Int -> [Fragment] -> Maybe String
- data Request = Request {
- requestPacketType :: !PacketType
- requestBody :: !(TdsContext -> PacketWriter -> IO ())
- requestStatement :: !(Maybe Text)
- data ResponseReader = ResponseReader {
- respConn :: !Connection
- respActive :: !ActiveResponse
- respFirstError :: !(IORef (Maybe ServerMessage))
- respFailedDone :: !(IORef (Maybe Done))
- respPushback :: !(IORef (Maybe Token))
- respStatement :: !(Maybe Text)
- respEnded :: !(IORef Bool)
- respBatch :: !(Maybe BatchScope)
- data BatchScope = BatchScope {
- scopeEnded :: !(IORef Bool)
- scopeStatement :: !(IORef Text)
- scopeFail :: ServerMessage -> IO Void
- data RowBatch r = RowBatch {
- batchRows :: ![r]
- batchFailed :: !(Maybe DecodeError)
- data ResponseStep r
- data ResultSet r = ResultSet {
- resultColumns :: ![ColumnInfo]
- resultRows :: ![r]
- newtype ResultSets a = ResultSets {
- runResultSets :: TdsContext -> ResponseReader -> IO a
Queries
SQL text together with the parameters it refers to. Build one from a
string literal, with mkQuery, or from pieces joined with
<>; Hmssql.Query shows each way.
The positional parameters are sent as @p1, @p2, ... in the order
queryParams lists them, and the named parameters by name. <>
appends the text and the parameters of two queries and renumbers the
right operand's placeholders past the left operand's positional
parameters, so any two queries can be joined. A placeholder that
refers to no parameter makes sending the query throw
EncodeError.
A query with no parameters is sent as a plain SQL batch, and one with
parameters through sp_executesql. fromString (OverloadedStrings)
is text as it is, with no parameters. Show is the text as it would
be sent, without the parameter values.
Constructors
| Query | |
Fields
| |
The tree of a Query: empty, one piece, or two queries appended.
piece :: [Fragment] -> [QueryParam] -> Query Source #
A query of one piece: fragments whose placeholders are numbered among the positional parameters given, from 1.
A piece of SQL text, or a reference to a positional parameter (1-based).
Constructors
| Static !Text | |
| Placeholder !Int |
Instances
data QueryParam Source #
A parameter: its name ("" for a positional one, otherwise with the
leading @) and how to encode its value for a connection.
Constructors
| QueryParam | |
Fields
| |
Instances
| Show QueryParam Source # | The name only; the value is not shown. |
Defined in Hmssql.Query.Types Methods showsPrec :: Int -> QueryParam -> ShowS # show :: QueryParam -> String # showList :: [QueryParam] -> ShowS # | |
queryFragments :: Query -> [Fragment] Source #
The fragments of the whole query, placeholders numbered across it. Built strictly, right to left (the whole list is always consumed): lazily, every node and fragment left a thunk, about 190 bytes per fragment.
queryParams :: Query -> [QueryParam] Source #
The parameters of the whole query, in order.
queryText :: Query -> Text Source #
The SQL text as it is sent, with @pN for the placeholders.
A placeholder next to a character that could continue a variable name
gets a space between them: "x = " <> param 1 <> "1" is sent as
x = @p1 1, not x = @p11 (another parameter), and "N" <> param s
as N @p1, not the identifier N@p1.
renderFragments :: [Fragment] -> Text Source #
queryText of the fragments: the static text as it is, each
placeholder as @pN with a space on either side where a variable-name
character would otherwise run into it, concatenated once.
queryProblem :: Query -> Maybe String Source #
Why the query can't be sent, if it can't: a placeholder that refers to a positional parameter it doesn't have.
fragmentsProblem :: Int -> [Fragment] -> Maybe String Source #
queryProblem of a query's fragments, given how many positional
parameters it has.
Requests
A message to send: its packet type and its body, written for the
connection's context when it is sent. queryRequest
builds one from a Query; startResponse and
responseS send one.
Constructors
| Request | |
Fields
| |
Responses
data ResponseReader Source #
A response being read: the reader the query functions share, pulling
one step at a time (readStep) until StepEnd. ERROR
tokens are withheld (the first kept) and thrown as
SqlServerError once the response is complete, so the
connection is never left mid-message; a DONE flagged as failed in a
response with no ERROR token is thrown as SevereError
then.
Not a SQL cursor: it reads one response forwards, once.
Constructors
| ResponseReader | |
Fields
| |
data BatchScope Source #
What bounds a ResponseReader to one statement of a batch.
Constructors
| BatchScope | |
Fields
| |
The rows at the head of the response, decoded: what one nextStep
returns when it finds rows.
Constructors
| RowBatch | |
Fields
| |
data ResponseStep r Source #
What nextStep found next in the response.
Result sets
One result set of a response: its columns and its rows.
Constructors
| ResultSet | |
Fields
| |
newtype ResultSets a Source #
How to decode a response that holds several result sets, one at a
time in order, for queryResultSets. Build one from
resultSet and skipResultSet with the
Applicative or Monad combinators; as a Monad, a later decoder may
depend on earlier rows. Statements that produce no result set, such as
DECLARE, SET and UPDATE, are skipped over.
(parents, children) <- queryResultSets ((,) <$> resultSet <*> resultSet) conn "SELECT id, name FROM dbo.parent; SELECT id, parent_id FROM dbo.child"
Constructors
| ResultSets | |
Fields
| |
Instances
| Applicative ResultSets Source # | |
Defined in Hmssql.Query.Types Methods pure :: a -> ResultSets a # (<*>) :: ResultSets (a -> b) -> ResultSets a -> ResultSets b # liftA2 :: (a -> b -> c) -> ResultSets a -> ResultSets b -> ResultSets c # (*>) :: ResultSets a -> ResultSets b -> ResultSets b # (<*) :: ResultSets a -> ResultSets b -> ResultSets a # | |
| Functor ResultSets Source # | |
Defined in Hmssql.Query.Types Methods fmap :: (a -> b) -> ResultSets a -> ResultSets b # (<$) :: a -> ResultSets b -> ResultSets a # | |
| Monad ResultSets Source # | |
Defined in Hmssql.Query.Types Methods (>>=) :: ResultSets a -> (a -> ResultSets b) -> ResultSets b # (>>) :: ResultSets a -> ResultSets b -> ResultSets b # return :: a -> ResultSets a # | |