hmssql
Safe HaskellNone
LanguageHaskell2010

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

Queries

data Query Source #

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

Instances

Instances details
Monoid Query Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

mempty :: Query #

mappend :: Query -> Query -> Query #

mconcat :: [Query] -> Query #

Semigroup Query Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

(<>) :: Query -> Query -> Query #

sconcat :: NonEmpty Query -> Query #

stimes :: Integral b => b -> Query -> Query #

IsString Query Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

fromString :: String -> Query #

Show Query Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

showsPrec :: Int -> Query -> ShowS #

show :: Query -> String #

showList :: [Query] -> ShowS #

data Node Source #

The tree of a Query: empty, one piece, or two queries appended.

Constructors

Empty 
Piece [Fragment] [QueryParam]

Placeholders are numbered among this piece's own positional parameters, from 1.

Append Query Query 

piece :: [Fragment] -> [QueryParam] -> Query Source #

A query of one piece: fragments whose placeholders are numbered among the positional parameters given, from 1.

data Fragment Source #

A piece of SQL text, or a reference to a positional parameter (1-based).

Constructors

Static !Text 
Placeholder !Int 

Instances

Instances details
Show Fragment Source # 
Instance details

Defined in Hmssql.Query.Lexer

Eq Fragment Source # 
Instance details

Defined in Hmssql.Query.Lexer

data QueryParam Source #

A parameter: its name ("" for a positional one, otherwise with the leading @) and how to encode its value for a connection.

Instances

Instances details
Show QueryParam Source #

The name only; the value is not shown.

Instance details

Defined in Hmssql.Query.Types

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.

placeholderText :: Int -> Text Source #

@p and the number, as queryText writes a placeholder.

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

data Request Source #

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

data RowBatch r Source #

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.

Constructors

StepRows !(RowBatch r) 
StepToken !Token

A token other than a row.

StepEnd

The response is complete.

Result sets

data ResultSet r Source #

One result set of a response: its columns and its rows.

Constructors

ResultSet 

Fields

Instances

Instances details
Functor ResultSet Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

fmap :: (a -> b) -> ResultSet a -> ResultSet b #

(<$) :: a -> ResultSet b -> ResultSet a #

Show r => Show (ResultSet r) Source # 
Instance details

Defined in Hmssql.Query.Types

Eq r => Eq (ResultSet r) Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

(==) :: ResultSet r -> ResultSet r -> Bool #

(/=) :: ResultSet r -> ResultSet r -> Bool #

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 

Instances

Instances details
Applicative ResultSets Source # 
Instance details

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 # 
Instance details

Defined in Hmssql.Query.Types

Methods

fmap :: (a -> b) -> ResultSets a -> ResultSets b #

(<$) :: a -> ResultSets b -> ResultSets a #

Monad ResultSets Source # 
Instance details

Defined in Hmssql.Query.Types

Methods

(>>=) :: ResultSets a -> (a -> ResultSets b) -> ResultSets b #

(>>) :: ResultSets a -> ResultSets b -> ResultSets b #

return :: a -> ResultSets a #