2015-02-16 19:08:29 +00:00
|
|
|
{- types for SQL databases
|
|
|
|
-
|
2019-02-20 20:59:10 +00:00
|
|
|
- Copyright 2015-2019 Joey Hess <id@joeyh.name>
|
2015-02-16 19:08:29 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2015-02-16 19:08:29 +00:00
|
|
|
-}
|
|
|
|
|
2019-02-20 20:59:10 +00:00
|
|
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
2019-10-30 19:16:03 +00:00
|
|
|
{-# LANGUAGE TypeSynonymInstances #-}
|
2015-02-16 19:08:29 +00:00
|
|
|
|
2019-10-29 16:28:01 +00:00
|
|
|
module Database.Types (
|
|
|
|
module Database.Types,
|
|
|
|
Key,
|
2019-10-30 19:16:03 +00:00
|
|
|
EpochTime,
|
|
|
|
FileSize,
|
2019-10-29 16:28:01 +00:00
|
|
|
) where
|
2015-02-16 19:08:29 +00:00
|
|
|
|
2019-02-20 20:59:10 +00:00
|
|
|
import Database.Persist.Class hiding (Key)
|
|
|
|
import Database.Persist.Sql hiding (Key)
|
|
|
|
import qualified Data.ByteString as S
|
|
|
|
import qualified Data.Text as T
|
2019-10-29 16:28:01 +00:00
|
|
|
import qualified Data.Attoparsec.ByteString as A
|
2019-10-30 19:16:03 +00:00
|
|
|
import System.PosixCompat.Types
|
|
|
|
import Data.Int
|
|
|
|
import Data.Text.Read
|
|
|
|
import Foreign.C.Types
|
2015-02-16 19:08:29 +00:00
|
|
|
|
2017-02-24 17:42:30 +00:00
|
|
|
import Key
|
2015-12-09 21:00:37 +00:00
|
|
|
import Utility.InodeCache
|
2019-10-30 19:16:03 +00:00
|
|
|
import Utility.FileSize
|
2019-10-29 16:28:01 +00:00
|
|
|
import Git.Types
|
2019-02-20 20:59:10 +00:00
|
|
|
import Types.UUID
|
2019-02-21 17:38:27 +00:00
|
|
|
import Types.Import
|
2015-02-16 19:08:29 +00:00
|
|
|
|
2019-10-29 16:28:01 +00:00
|
|
|
instance PersistField Key where
|
2019-12-06 19:17:54 +00:00
|
|
|
toPersistValue = toPersistValue . serializeKey'
|
2019-10-29 16:28:01 +00:00
|
|
|
fromPersistValue b = fromPersistValue b >>= parse
|
|
|
|
where
|
|
|
|
parse = either (Left . T.pack) Right . A.parseOnly keyParser
|
2017-09-18 17:57:25 +00:00
|
|
|
|
2019-10-29 16:28:01 +00:00
|
|
|
-- A key can contain arbitrarily encoded characters, so store in sqlite as a
|
|
|
|
-- blob to avoid encoding problems.
|
|
|
|
instance PersistFieldSql Key where
|
|
|
|
sqlType _ = SqlBlob
|
2017-09-18 17:57:25 +00:00
|
|
|
|
2019-10-29 16:28:01 +00:00
|
|
|
instance PersistField InodeCache where
|
|
|
|
toPersistValue = toPersistValue . showInodeCache
|
|
|
|
fromPersistValue b = fromPersistValue b >>= parse
|
|
|
|
where
|
|
|
|
parse s = maybe
|
|
|
|
(Left $ T.pack $ "bad serialized InodeCache "++ s)
|
|
|
|
Right
|
|
|
|
(readInodeCache s)
|
2017-09-18 17:57:25 +00:00
|
|
|
|
2019-10-29 16:28:01 +00:00
|
|
|
instance PersistFieldSql InodeCache where
|
|
|
|
sqlType _ = SqlString
|
2019-02-20 20:59:10 +00:00
|
|
|
|
|
|
|
instance PersistField UUID where
|
|
|
|
toPersistValue u = toPersistValue b
|
|
|
|
where
|
|
|
|
b :: S.ByteString
|
|
|
|
b = fromUUID u
|
|
|
|
fromPersistValue v = toUUID <$> go
|
|
|
|
where
|
|
|
|
go :: Either T.Text S.ByteString
|
|
|
|
go = fromPersistValue v
|
|
|
|
|
|
|
|
instance PersistFieldSql UUID where
|
|
|
|
sqlType _ = SqlBlob
|
|
|
|
|
|
|
|
instance PersistField ContentIdentifier where
|
|
|
|
toPersistValue (ContentIdentifier b) = toPersistValue b
|
|
|
|
fromPersistValue v = ContentIdentifier <$> go
|
|
|
|
where
|
|
|
|
go :: Either T.Text S.ByteString
|
|
|
|
go = fromPersistValue v
|
|
|
|
|
|
|
|
instance PersistFieldSql ContentIdentifier where
|
|
|
|
sqlType _ = SqlBlob
|
2019-10-29 16:28:01 +00:00
|
|
|
|
2019-12-18 18:57:01 +00:00
|
|
|
-- A serialized RawFilePath.
|
2019-10-29 16:28:01 +00:00
|
|
|
newtype SFilePath = SFilePath S.ByteString
|
|
|
|
deriving (Eq, Show)
|
|
|
|
|
|
|
|
instance PersistField SFilePath where
|
|
|
|
toPersistValue (SFilePath b) = toPersistValue b
|
|
|
|
fromPersistValue v = SFilePath <$> fromPersistValue v
|
|
|
|
|
|
|
|
instance PersistFieldSql SFilePath where
|
|
|
|
sqlType _ = SqlBlob
|
|
|
|
|
|
|
|
-- A serialized git Sha
|
|
|
|
newtype SSha = SSha String
|
|
|
|
deriving (Eq, Show)
|
|
|
|
|
|
|
|
toSSha :: Sha -> SSha
|
|
|
|
toSSha (Ref s) = SSha s
|
|
|
|
|
|
|
|
fromSSha :: SSha -> Ref
|
|
|
|
fromSSha (SSha s) = Ref s
|
|
|
|
|
2019-10-29 21:08:36 +00:00
|
|
|
instance PersistField SSha where
|
2019-10-29 16:28:01 +00:00
|
|
|
toPersistValue (SSha b) = toPersistValue b
|
|
|
|
fromPersistValue v = SSha <$> fromPersistValue v
|
|
|
|
|
|
|
|
instance PersistFieldSql SSha where
|
|
|
|
sqlType _ = SqlString
|
2019-10-30 19:16:03 +00:00
|
|
|
|
|
|
|
-- A FileSize could be stored as an Int64, but some systems could
|
|
|
|
-- conceivably have a larger filesize, and no math is ever done with them
|
|
|
|
-- in sqlite, so store a string instead.
|
|
|
|
instance PersistField FileSize where
|
|
|
|
toPersistValue = toPersistValue . show
|
|
|
|
fromPersistValue v = fromPersistValue v >>= parse
|
|
|
|
where
|
|
|
|
parse = either (Left . T.pack) (Right . fst) . decimal
|
|
|
|
|
|
|
|
instance PersistFieldSql FileSize where
|
|
|
|
sqlType _ = SqlString
|
|
|
|
|
|
|
|
-- Store EpochTime as an Int64, to allow selecting values in a range.
|
|
|
|
instance PersistField EpochTime where
|
|
|
|
toPersistValue (CTime t) = toPersistValue (fromIntegral t :: Int64)
|
|
|
|
fromPersistValue v = CTime . fromIntegral <$> go
|
|
|
|
where
|
|
|
|
go :: Either T.Text Int64
|
|
|
|
go = fromPersistValue v
|
|
|
|
|
|
|
|
instance PersistFieldSql EpochTime where
|
|
|
|
sqlType _ = SqlInt64
|