Revision 7ae97c33
b/htools/Ganeti/Query/Language.hs | ||
---|---|---|
1 |
{-# LANGUAGE TemplateHaskell #-} |
|
1 |
{-# LANGUAGE TemplateHaskell, CPP #-}
|
|
2 | 2 |
|
3 | 3 |
{-| Implementation of the Ganeti Query2 language. |
4 | 4 |
|
... | ... | |
57 | 57 |
import Text.JSON.Pretty (pp_value) |
58 | 58 |
import Text.JSON.Types |
59 | 59 |
import Text.JSON |
60 |
#ifndef NO_REGEX_PCRE |
|
60 | 61 |
import qualified Text.Regex.PCRE as PCRE |
62 |
#endif |
|
61 | 63 |
|
62 | 64 |
import qualified Ganeti.Constants as C |
63 | 65 |
import Ganeti.THH |
... | ... | |
111 | 113 |
|
112 | 114 |
-- * Sub data types for query2 queries and responses. |
113 | 115 |
|
116 |
-- | Internal type of a regex expression (not exported). |
|
117 |
#ifndef NO_REGEX_PCRE |
|
118 |
type RegexType = PCRE.Regex |
|
119 |
#else |
|
120 |
type RegexType = () |
|
121 |
#endif |
|
122 |
|
|
114 | 123 |
-- | List of requested fields. |
115 | 124 |
type Fields = [ String ] |
116 | 125 |
|
... | ... | |
175 | 184 |
-> [JSValue] -- ^ Single argument |
176 | 185 |
-> Result (Filter a) |
177 | 186 |
readFilterArg constr [flt] = constr <$> readJSON flt |
178 |
readFilterArg _ v = Error $ "Cannot deserialise field, expected [filter]\
|
|
179 |
\ but got " ++ show (pp_value (showJSON v))
|
|
187 |
readFilterArg _ v = Error $ "Cannot deserialise field, expected [filter]" ++
|
|
188 |
" but got " ++ show (pp_value (showJSON v))
|
|
180 | 189 |
|
181 | 190 |
-- | Helper to deserialise an array corresponding to a single field |
182 | 191 |
-- and return the built filter. |
... | ... | |
185 | 194 |
-> [JSValue] -- ^ Single argument |
186 | 195 |
-> Result (Filter a) |
187 | 196 |
readFilterField constr [field] = constr <$> readJSON field |
188 |
readFilterField _ v = Error $ "Cannot deserialise field, expected [fieldname]\ |
|
189 |
\ but got " ++ show (pp_value (showJSON v)) |
|
197 |
readFilterField _ v = Error $ "Cannot deserialise field, expected" ++ |
|
198 |
" [fieldname] but got " ++ |
|
199 |
show (pp_value (showJSON v)) |
|
190 | 200 |
|
191 | 201 |
-- | Helper to deserialise an array corresponding to a field and |
192 | 202 |
-- value, returning the built filter. |
... | ... | |
197 | 207 |
readFilterFieldValue constr [field, value] = |
198 | 208 |
constr <$> readJSON field <*> readJSON value |
199 | 209 |
readFilterFieldValue _ v = |
200 |
Error $ "Cannot deserialise field/value pair, expected [fieldname, value]\
|
|
201 |
\ but got " ++ show (pp_value (showJSON v))
|
|
210 |
Error $ "Cannot deserialise field/value pair, expected [fieldname, value]" ++
|
|
211 |
" but got " ++ show (pp_value (showJSON v))
|
|
202 | 212 |
|
203 | 213 |
-- | Inner deserialiser for 'Filter'. |
204 | 214 |
readFilterArray :: (JSON a) => String -> [JSValue] -> Result (Filter a) |
... | ... | |
264 | 274 |
readFilterValue (JSString a) = Ok . QuotedString $ fromJSString a |
265 | 275 |
readFilterValue (JSRational _ x) = |
266 | 276 |
if denominator x /= 1 |
267 |
then Error $ "Cannot deserialise numeric filter value,\
|
|
268 |
\ expecting integral but\
|
|
269 |
\ got a fractional value: " ++ show x
|
|
277 |
then Error $ "Cannot deserialise numeric filter value," ++
|
|
278 |
" expecting integral but got a fractional value: " ++
|
|
279 |
show x |
|
270 | 280 |
else Ok . NumericValue $ numerator x |
271 |
readFilterValue v = Error $ "Cannot deserialise filter value, expecting\
|
|
272 |
\ string or integer, got " ++ show (pp_value v)
|
|
281 |
readFilterValue v = Error $ "Cannot deserialise filter value, expecting" ++
|
|
282 |
" string or integer, got " ++ show (pp_value v)
|
|
273 | 283 |
|
274 | 284 |
instance JSON FilterValue where |
275 | 285 |
showJSON = showFilterValue |
... | ... | |
280 | 290 |
-- we don't re-compile the regex at each match attempt. |
281 | 291 |
data FilterRegex = FilterRegex |
282 | 292 |
{ stringRegex :: String -- ^ The string version of the regex |
283 |
, compiledRegex :: PCRE.Regex -- ^ The compiled regex
|
|
293 |
, compiledRegex :: RegexType -- ^ The compiled regex
|
|
284 | 294 |
} |
285 | 295 |
|
286 | 296 |
-- | Builder for 'FilterRegex'. We always attempt to compile the |
287 | 297 |
-- regular expression on the initialisation of the data structure; |
288 | 298 |
-- this might fail, if the RE is not well-formed. |
289 | 299 |
mkRegex :: (Monad m) => String -> m FilterRegex |
300 |
#ifndef NO_REGEX_PCRE |
|
290 | 301 |
mkRegex str = do |
291 | 302 |
compiled <- case PCRE.getVersion of |
292 |
Nothing -> fail "regex-pcre library compiled without\
|
|
293 |
\ libpcre, regex functionality not available"
|
|
303 |
Nothing -> fail $ "regex-pcre library compiled without" ++
|
|
304 |
" libpcre, regex functionality not available"
|
|
294 | 305 |
_ -> PCRE.makeRegexM str |
295 | 306 |
return $ FilterRegex str compiled |
307 |
#else |
|
308 |
mkRegex _ = |
|
309 |
fail $ "regex-pcre not found at compile time," ++ |
|
310 |
" regex functionality not available" |
|
311 |
#endif |
|
296 | 312 |
|
297 | 313 |
-- | 'Show' instance: we show the constructor plus the string version |
298 | 314 |
-- of the regex. |
Also available in: Unified diff