mirror of
https://github.com/zhigang1992/graphql-engine.git
synced 2026-05-24 17:03:37 +08:00
server: use attoparsec-iso8601 for parsing time information
This commit is contained in:
@@ -41,6 +41,7 @@ library
|
||||
, transformers-base
|
||||
, http-types
|
||||
, attoparsec
|
||||
, attoparsec-iso8601 >= 1.0
|
||||
, time
|
||||
, scientific
|
||||
, Spock-core
|
||||
@@ -48,10 +49,7 @@ library
|
||||
, optparse-applicative
|
||||
, wai-extra
|
||||
, containers
|
||||
, hashtables
|
||||
, resource-pool
|
||||
, monad-control
|
||||
, regex-tdfa
|
||||
, wai-logger
|
||||
, fast-logger
|
||||
, wai
|
||||
@@ -60,7 +58,6 @@ library
|
||||
|
||||
-- Encoder related
|
||||
, uuid
|
||||
, reinterpret-cast
|
||||
, vector
|
||||
|
||||
-- Logging related
|
||||
@@ -70,13 +67,6 @@ library
|
||||
-- hashing for logging
|
||||
, cryptonite
|
||||
|
||||
-- Transaction related
|
||||
, focus
|
||||
, list-t
|
||||
, stm
|
||||
, stm-containers
|
||||
, alarmclock
|
||||
|
||||
-- Server related
|
||||
, warp
|
||||
, th-lift-instances
|
||||
@@ -100,7 +90,6 @@ library
|
||||
, connection
|
||||
|
||||
--
|
||||
, protolude
|
||||
, data-has
|
||||
|
||||
exposed-modules: Hasura.Server.App
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
-- |
|
||||
-- Module: Data.Aeson.Parser.Time
|
||||
-- Copyright: (c) 2015-2016 Bryan O'Sullivan
|
||||
-- License: BSD3
|
||||
-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
|
||||
-- Stability: experimental
|
||||
-- Portability: portable
|
||||
--
|
||||
-- Parsers for parsing dates and times.
|
||||
|
||||
module Hasura.SQL.Time
|
||||
( ZonedTimeOfDay(..)
|
||||
) where
|
||||
|
||||
import Control.Monad (void, when)
|
||||
import Data.Attoparsec.Text as A
|
||||
import Data.Bits ((.&.))
|
||||
import Data.Char (isDigit, ord)
|
||||
import Data.Fixed (Fixed (MkFixed), Pico)
|
||||
import Data.Int (Int64)
|
||||
import Data.Attoparsec.Time (timeOfDay, timeZone)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Hasura.Prelude
|
||||
|
||||
@@ -28,75 +13,6 @@ import qualified Data.Aeson.Types as Aeson
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Time.LocalTime as Local
|
||||
|
||||
toPico :: Integer -> Pico
|
||||
toPico = MkFixed
|
||||
|
||||
-- | Parse a two-digit integer (e.g. day of month, hour).
|
||||
twoDigits :: Parser Int
|
||||
twoDigits = do
|
||||
a <- digit
|
||||
b <- digit
|
||||
let c2d c = ord c .&. 15
|
||||
return $! c2d a * 10 + c2d b
|
||||
|
||||
-- | Parse a time of the form @HH:MM[:SS[.SSS]]@.
|
||||
timeOfDay :: Parser Local.TimeOfDay
|
||||
timeOfDay = do
|
||||
h <- twoDigits
|
||||
m <- char ':' *> twoDigits
|
||||
s <- option 0 (char ':' *> seconds)
|
||||
if h < 24 && m < 60 && s < 61
|
||||
then return (Local.TimeOfDay h m s)
|
||||
else fail "invalid time"
|
||||
|
||||
data T = T {-# UNPACK #-} !Int {-# UNPACK #-} !Int64
|
||||
|
||||
-- | Parse a count of seconds, with the integer part being two digits
|
||||
-- long.
|
||||
seconds :: Parser Pico
|
||||
seconds = do
|
||||
real <- twoDigits
|
||||
mc <- peekChar
|
||||
case mc of
|
||||
Just '.' -> do
|
||||
t <- anyChar *> takeWhile1 isDigit
|
||||
return $! parsePicos real t
|
||||
_ -> return $! fromIntegral real
|
||||
where
|
||||
parsePicos a0 t = toPico (fromIntegral (t' * 10^n))
|
||||
where T n t' = T.foldl' step (T 12 (fromIntegral a0)) t
|
||||
step ma@(T m a) c
|
||||
| m <= 0 = ma
|
||||
| otherwise = T (m-1) (10 * a + fromIntegral (ord c) .&. 15)
|
||||
|
||||
-- | Parse a time zone, and return 'Nothing' if the offset from UTC is
|
||||
-- zero. (This makes some speedups possible.)
|
||||
timeZone :: Parser (Maybe Local.TimeZone)
|
||||
timeZone = do
|
||||
let maybeSkip c = do ch <- peekChar'; when (ch == c) (void anyChar)
|
||||
maybeSkip ' '
|
||||
ch <- satisfy $ \c -> c == 'Z' || c == '+' || c == '-'
|
||||
if ch == 'Z'
|
||||
then return Nothing
|
||||
else do
|
||||
h <- twoDigits
|
||||
mm <- peekChar
|
||||
m <- case mm of
|
||||
Just ':' -> anyChar *> twoDigits
|
||||
Just d | isDigit d -> twoDigits
|
||||
_ -> return 0
|
||||
let off | ch == '-' = negate off0
|
||||
| otherwise = off0
|
||||
off0 = h * 60 + m
|
||||
case undefined of
|
||||
_ | off == 0 ->
|
||||
return Nothing
|
||||
| off < -720 || off > 840 || m > 59 ->
|
||||
fail "invalid time zone offset"
|
||||
| otherwise ->
|
||||
let !tz = Local.minutesToTimeZone off
|
||||
in return (Just tz)
|
||||
|
||||
data ZonedTimeOfDay
|
||||
= ZonedTimeOfDay
|
||||
{ ztodTime :: Local.TimeOfDay
|
||||
|
||||
Reference in New Issue
Block a user