cookbook-2.3.2.0: Cookbook/Project/Quill/Quill2/Q2Api.hs
{- |
Module : Cookbook.Project.Quill.Quill2.Q2Api
Copyright : (c) 2014 by Nate Pisarski
License : BSD3
Maintainer : nathanpisarski@gmail.com
Stability : Stable
Portability : Portable (Cookbook)
Q2Api is the user-facing part of Quill. It has all the functions necessar to Create, Read, Update, and Delete information from the database, and turn a database back into a Quill-readable string.
-}
module Cookbook.Project.Quill.Quill2.Q2Api where
import qualified Cookbook.Ingredients.Tupples.Look as Lk
import qualified Cookbook.Essential.Common as Cm
import qualified Cookbook.Essential.Continuous as Ct
import qualified Cookbook.Ingredients.Lists.Access as Ac
import Cookbook.Project.Quill.Quill2.Q2Prelude
-- | Get the name of a Quill.
getQuillName :: Quill -> String
getQuillName = fst
-- | Return the element of the Quill, specifically useful for lists.
getQuillBody :: Quill -> Element String
getQuillBody = snd
-- | Find a quill in the database by name, returning it or a possible error type.
getQuill :: [Quill] -> String -> QuillStatus
getQuill [] _ = QuillMissing
getQuill (x:xs) c
| Ac.count (map getQuillName (x:xs)) c > 1 = QuillMultiple
| getQuillName x == c = QuillSuccess x
| otherwise = getQuill xs c
-- | Look up the value of a Quill TABLE. Will produce an error on a list.
lookUp :: [Quill] -> (String, String) -> String
lookUp x (a,b) = case (getQuill x a) of
QuillMissing -> error $ "Table not found."
QuillMultiple -> error $ "Multiple values of " ++ a ++ " detected. Database eror, fix manually."
(QuillSuccess (c,d)) -> case d of
(List f) -> error "Cannot look up the value of a list."
(Table f) -> let c = Lk.lookList f b in if (c == []) then (error $ "Item " ++ b ++ " not found in table " ++ a) else (if (length c > 1) then multipleInnerError else (head c))
where multipleInnerError = error $ "Multiple values of " ++ b ++ " found in table " ++ a ++ ". Database corrupted, change manually."
-- | Remove a quill from the database by name.
removeQuill :: [Quill] -> String -> [Quill]
removeQuill [] _ = []
removeQuill ((x,y):xs) c
| x == c = removeQuill xs c -- See [Q2N1]
| otherwise = (x,y) : removeQuill xs c
-- | Remove an item from a Quill within a database. Works aggressively, meaning it removes all copies to help sanitize QuillMultiples out.
removeItem :: [Quill] -> (String, String) -> [Quill]
removeItem x (a,b) = case (getQuill x a) of
QuillSuccess (c,j) -> case j of
(Table d) -> (c,(Table [(y,t) | (y,t) <- d, y /= b])) : (removeQuill x a)
(List d) -> (c,List $ Ct.remove d c) : removeQuill x a
_ -> (let l = lookUp x (a,b) in x) -- This goes against everything that haskell means.
-- | Adds a Quill databse to the file.
addQuill :: [Quill] -> Quill -> [Quill]
addQuill x c = c : x
-- | Add a QuillAddition to the databse. QuillAddition is a safe encapsulation of list and table values.
addItem :: [Quill] -> QuillAddition -> [Quill]
addItem x qa= case getQuill x a of
QuillSuccess (y, ys) -> case ys of
(Table d) -> case qa of
(ATable (_,b,c)) -> (y,Table $ (b,c) : d) : removeQuill x a
(AList _ ) -> error $ "$ Type Mismatch! Attempted to add a List type to Table in table " ++ (show qa)
(List d) -> case qa of
(AList (_,b)) -> (y, List $ (b:d)) : removeQuill x a
(ATable _) -> error $ "Type MisMatch! Attempted to add Table type to List in table " ++ (show qa)
QuillMultiple -> error "Multiple found"
QuillMissing -> error "Not found quill!"
where
a = case qa of
(ATable (g,b,c)) -> g
(AList (g,b)) -> g
-- | Change an item within the database using a Quill addition. Wrapper of addItem and removeItem.
changeItem :: [Quill] -> QuillAddition -> [Quill]
changeItem x y = case y of
(ATable (a,b,c)) -> addItem (removeItem x (a,b)) y
(AList (a,b)) -> addItem (removeItem x (a,b)) y
-- | Turn a Quill table into a string.
toString :: Quill -> String
toString (nm,typ) = case typ of
(List a) -> ("list(" ++ nm ++ "){" ++ (Cm.flt (map (\c -> (c ++ ";")) a))) ++ "}"
(Table a) -> ("table(" ++ nm ++ "){" ++ (Cm.flt $ stringify a)) ++ "}"
where
stringify [] = []
stringify ((a,b):xs) = (a ++ ":" ++ b ++ ";") : stringify xs