module Components.DataProcessors.ListDataProcessor (processReturnedValues,processAggReturnedValues) where import Data.Text (Text,unpack,pack) import Data.List (unzip4) import Text.JSON ( showJSON, showJSONs, JSValue, JSObject, toJSObject, encodeStrict, JSValue(JSNull), JSON(..), Result(Ok), decode ) import Control.Exception (throw) import Data.Foldable (foldl',foldr') import Data.Int (Int64) import Model.ServerExceptions ( VariableException(InvalidVariableTypeException), QueryException(ReadJsonException) ) import Model.ServerObjectTypes ( NestedObject(..), Field, RootObject, ServerObject, ScalarType(..), Transformation, Argument, InlinefragmentObject(..) ) import Components.ObjectHandlers.ObjectsHandler ( isServerObjectTable, getNestedObjectFieldLabel, getScalarFieldLabel, translateTableToObject, countTableIds ) import Components.Util (fst3,snd3,thd3,fst4,thd4,fth4) -- root objects to one json representation of separate graphql results processReturnedValues :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> [RootObject] -> [[[(Int,Bool,String)]]] -> [[[[[a]]]]] -> String processReturnedValues transFx sss sodn soa robjs tbls rlts = encodeStrict $ processReturnedValuesToJsonObject transFx sss sodn soa robjs tbls rlts processReturnedValuesToJsonObject :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> [RootObject] -> [[[(Int,Bool,String)]]] -> [[[[[a]]]]] -> JSObject (JSObject JSValue) processReturnedValuesToJsonObject transFx sss sodn soa robjs tbls rlts = toJSObject [("data", toJSObject [processReturnedValueByRootObject transFx sss sodn soa a b c | (a,b,c) <- zip3 robjs tbls rlts])] -- qraphql query object and sql return data to json representation on graphql query results processReturnedValueByRootObject :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> RootObject -> [[(Int,Bool,String)]] -> [[[[a]]]] -> (String, JSValue) processReturnedValueByRootObject transFx sss sodn soa (NestedObject Nothing name sobj _ sfs) tbls rlts = (name, showJSONs $ packageSubFields transFx sss sodn soa sobj tbls sfs rlts) processReturnedValueByRootObject transFx sss sodn soa (NestedObject (Just alias) name sobj _ sfs) tbls rlts = (alias, showJSONs $ packageSubFields transFx sss sodn soa sobj tbls sfs rlts) -- SubFields and data rows to json representation on qraphql query data packageSubFields :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [[(Int,Bool,String)]] -> [Field] -> [[[[a]]]] -> [JSValue] packageSubFields transFx sss sodn soa sobj tbls sfs rlts = packageSubFieldsForEveryRow transFx sss sodn soa sobj sfs grpdInstcByObjInst where dtaByInstCbntn = zip tbls rlts grpdInstcByObjInst = foldl' (\rlt (nInst,nDta)->if (snd3 $ head nInst)==False then ((init rlt)++[(last rlt)++[(nInst,(nDta,snd $ snd $ head $ last rlt))]]) else rlt++[[(nInst,(nDta,countTableIds (thd3 $ head nInst) sodn))]]) [[(fst $ head dtaByInstCbntn,(snd $ head dtaByInstCbntn,countTableIds (thd3 $ head $ fst $ head dtaByInstCbntn) sodn))]] $ tail dtaByInstCbntn packageSubFieldsForEveryRow :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [Field] -> [[([(Int,Bool,String)],([[[a]]],Int))]] -> [JSValue] packageSubFieldsForEveryRow transFx sss sodn soa sobj (sf:sfs) dt = if null objWInst then [] else (++) objects $ packageSubFieldsForEveryRow transFx sss sodn soa sobj (sf:sfs) remIs where (_,_,_,_,isNull) = transFx objInstWRw = map (filter (\(_,(nDt,_))->(null $ head nDt)==False)) dt objWInst = filter (not . null) objInstWRw (nxtObjsRw,remIs) = foldl' (\(objRows,remRows) nObj-> let (nObjRow,nObjRem) = foldl' (\(nInstRow,nInstRem) (tbls,(dSet,idC))->let (rowData,remData) = separateGqlRow isNull idC dSet in (nInstRow++[(tbls,rowData)],nInstRem++[(tbls,(remData,idC))])) ([],[]) nObj in (objRows++[unzip nObjRow],remRows++[nObjRem])) ([],[]) objWInst objects = map (\(nTbl,nDt)->showJSON $ toJSObject $ makeOneGQLObject transFx sss sodn soa sobj nTbl (sf:sfs) nDt) nxtObjsRw packageSubFieldsForEveryRow transFx sss sodn soa sobj [] dt = [] makeOneGQLObject :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [[(Int,Bool,String)]] -> [Field] -> [[[[a]]]] -> [(String,JSValue)] makeOneGQLObject _ _ _ _ _ [] _ _ = error "EOF data processing (source error)" -- no reference tables (unusual)/all removed makeOneGQLObject _ _ _ _ _ ([]:_) _ _ = error "EOF data processing (source error)" -- no reference tables in first varient (unusual) makeOneGQLObject transFx sss sodn soa sobj tbls ((Left (ScalarType alias "__typename" trans arg)):b) dat = (getScalarFieldLabel $ ScalarType alias "__typename" trans arg, showJSON $ pack $ translateTableToObject (thd3 $ head $ head tbls) sodn):(makeOneGQLObject transFx sss sodn soa sobj tbls b dat) makeOneGQLObject (fx1,fx2,fx3,fx4,isNull) sss sodn soa sobj tbls ((Left (ScalarType alias name trans arg)):b) ((((i:j):k):l):m) = (getScalarFieldLabel $ ScalarType alias name trans arg, if isNull i then JSNull else castJSType (fx1,fx2,fx3,fx4,isNull) (findPrimitiveScalarTypeType (translateTableToObject (thd3 $ head $ head tbls) sodn) name trans arg sss) i):(makeOneGQLObject (fx1,fx2,fx3,fx4,isNull) sss sodn soa sobj tbls b (((j:k):l):m)) makeOneGQLObject transFx sss sodn soa sobj tbls ((Right (Left (NestedObject alias name nso ss sfs))):b) ((j:k):l) = ((getNestedObjectFieldLabel $ NestedObject alias name nso ss sfs), showJSONs (packageSubFields transFx sss sodn soa nso nxtTbls sfs nxtData)):(makeOneGQLObject transFx sss sodn soa sobj remTbls b remData) where (nxtTbls,nxtData,remTbls,remData) = separateDataFrNstdObj tbls ((j:k):l) makeOneGQLObject transFx sss sodn soa sobj tbls ((Right (Right (InlinefragmentObject ifo sfs))):b) dat = if (isServerObjectTable (thd3 $ head $ head tbls) ifo sodn soa) then makeOneGQLObject transFx sss sodn soa sobj tbls (sfs++b) dat else makeOneGQLObject transFx sss sodn soa sobj tbls b dat makeOneGQLObject _ _ _ _ _ _ [] ((([]:_):_):_) = [] -- no columns (in first variant and first query) and no fields (done) makeOneGQLObject _ _ _ _ _ _ _ (([]:_):_) = [] -- no rows (no data) makeOneGQLObject _ _ _ _ _ _ ((Right (Left _)):[]) ([]:_) = error "EOF data processing (source error)" -- field and no queries (unusual) makeOneGQLObject _ _ _ _ _ _ _ ([]:_) = [] -- no queries (no data) makeOneGQLObject _ _ _ _ _ _ _ [] = [] -- no instance combination (unusual) makeOneGQLObject _ _ _ _ _ _ [] _ = [] -- columns and no fields (done or error) makeOneGQLObject _ _ _ _ _ _ ((Left _):_) ((([]:_):_):_) = error "EOF data processing (source error)" -- field and no result columns separateDataFrNstdObj :: [[(Int,Bool,String)]] -> [[[[a]]]] -> ([[(Int,Bool,String)]],[[[[a]]]],[[(Int,Bool,String)]],[[[[a]]]]) separateDataFrNstdObj info dat = foldl' (\(nTbls,nDt,rTbls,rDt) (instMt,instDt)-> let nxtTblsInfo = tail instMt tNxtTblsInfo = tail nxtTblsInfo (objLvl,_,_) = head nxtTblsInfo nestedObjCount = foldr' (\(nlvl,_,_) rlt->if nlvl<=objLvl then 0 else rlt+1) 0 tNxtTblsInfo fQrydPos = foldr' (\(idx,(_,fst,_)) rlt->if fst then idx else rlt) ((length nxtTblsInfo)-1) $ zip [0..] nxtTblsInfo hasQrd = (<=) fQrydPos nestedObjCount (nObjMeta,nObjData,remMeta,remData) = if hasQrd then ([tail instMt],[instDt],[],[]) else ([],[],[(head instMt):(drop (nestedObjCount+1) $ tail instMt)],[instDt]) in (nTbls++nObjMeta,nDt++nObjData,rTbls++remMeta,rDt++remData)) ([fstNObjMeta],[fstNObjData],[fstRemMeta],[fstRemData]) $ tail $ zip info dat where fstInstInfo = head info fstInstDat = head dat (fstL,fstF,fstT) = head fstInstInfo nObjPlusTblsInfo = tail fstInstInfo nObjLvl = (+) fstL 1 nstdObjsCount = foldr' (\(nlvl,_,_) rlt->if (==) nlvl nObjLvl then 1 else (+) rlt 1) 1 $ tail nObjPlusTblsInfo fstNObjMeta = take nstdObjsCount nObjPlusTblsInfo nObjPlusDat = tail $ fstInstDat fstNObjData = take nstdObjsCount nObjPlusDat fstRemMeta = (fstL,fstF,fstT):(drop nstdObjsCount nObjPlusTblsInfo) fstRemData = (head $ fstInstDat):(drop nstdObjsCount nObjPlusDat) findPrimitiveScalarTypeType :: ServerObject -> String -> Transformation -> Argument -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> String findPrimitiveScalarTypeType sobj name trans arg ((obj,flds):rst) = if sobj==obj then findScalarTypeType name trans arg flds else findPrimitiveScalarTypeType sobj name trans arg rst findPrimitiveScalarTypeType _ _ _ _ [] = error "Object is not found (source error)." findScalarTypeType :: String -> Transformation -> Argument -> [(String,String,[(String,[(String,String,String,String)])])] -> String findScalarTypeType name Nothing _ ((sName,sType,opts):rst) = if name==sName then sType else findScalarTypeType name Nothing Nothing rst findScalarTypeType name (Just trans) arg ((sName,sType,args):rst) = if name==sName then findArgumentOptionType trans arg args else findScalarTypeType name (Just trans) arg rst findScalarTypeType _ _ _ [] = error "Scalar is not found (source error)." findArgumentOptionType :: String -> Argument -> [(String,[(String,String,String,String)])] -> String findArgumentOptionType trans Nothing ((aname,((_,typ,_,_):_)):rst) = if trans==aname then typ else findArgumentOptionType trans Nothing rst findArgumentOptionType trans Nothing ((aname,[]):rst) = if trans==aname then error "Scalar argument is not found (source error)." else findArgumentOptionType trans Nothing rst findArgumentOptionType trans (Just arg) ((aname,opts):rst) = if trans==aname then findOptionType arg opts else findArgumentOptionType trans (Just arg) rst findArgumentOptionType _ _ [] = error "Scalar argument is not found (source error)." findOptionType :: String -> [(String,String,String,String)] -> String findOptionType arg ((oname,typ,_,_):rst) = if arg==oname then typ else findOptionType arg rst findOptionType _ [] = error "Scalar argument option is not found (source error)." separateGqlRow :: (Eq a) => (a -> Bool) -> Int -> [[[a]]] -> ([[[a]]],[[[a]]]) separateGqlRow isNull idCnt dat = if (all isNull fstTblIds) then unzip [([],[row | row<-tbl, not $ all isNull $ take idCnt row]) | tbl<-dat] else getGqlRow idCnt fstTblIds dat [] [] where fstTblIds = take idCnt $ head $ head dat getGqlRow :: (Eq a) => Int -> [a] -> [[[a]]] -> [[[a]]] -> [[[a]]] -> ([[[a]]],[[[a]]]) getGqlRow _ _ [] tblsRows tblsRem = (tblsRows,tblsRem) getGqlRow idCnt fstIds (tbl:dat) tblsRows tblsRem = getGqlRow idCnt fstIds dat (tblsRows++[nxtRow]) (tblsRem++[nxtRem]) where (nxtRow,nxtRem) = takeInstanceRow idCnt fstIds tbl [] takeInstanceRow :: (Eq a) => Int -> [a] -> [[a]] -> [[a]] -> ([[a]],[[a]]) takeInstanceRow idCnt fstIds (row:rem) rlt = if (==) fstIds $ take idCnt row then takeInstanceRow idCnt fstIds rem (rlt++[drop idCnt row]) else (rlt,(row:rem)) takeInstanceRow _ _ _ rlt = (rlt,[]) castJSType :: ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> String -> a -> JSValue castJSType (toText,_,_,_,_) "Text" val = showJSON $ toText val castJSType (_,toNum,_,_,_) "Double" val = showJSON $ toNum val castJSType (_,_,toInt,_,_) "Int64" val = showJSON $ toInt val castJSType (_,_,_,toBool,_) "Boolean" val = showJSON $ toBool val castJSType _ _ _ = throw InvalidVariableTypeException processAggReturnedValues :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> [RootObject] -> [[[(Int,Int,Bool,String)]]] -> [[[[[a]]]]] -> String processAggReturnedValues transFx sss sodn soa robjs tbls rlts = encodeStrict $ processAggReturnedValuesToJsonObject transFx sss sodn soa robjs tbls rlts processAggReturnedValuesToJsonObject :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> [RootObject] -> [[[(Int,Int,Bool,String)]]] -> [[[[[a]]]]] -> JSObject (JSObject JSValue) processAggReturnedValuesToJsonObject transFx sss sodn soa robjs tbls rlts = toJSObject [("data", toJSObject [processAggReturnedValueByRootObject transFx sss sodn soa a b c | (a,b,c) <- zip3 robjs tbls rlts])] processAggReturnedValueByRootObject :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> RootObject -> [[(Int,Int,Bool,String)]] -> [[[[a]]]] -> (String, JSValue) processAggReturnedValueByRootObject transFx sss sodn soa (NestedObject Nothing name sobj _ sfs) tbls rlts = (name, showJSONs $ packageAggSubFields transFx sss sodn soa sobj tbls sfs rlts) processAggReturnedValueByRootObject transFx sss sodn soa (NestedObject (Just alias) name sobj _ sfs) tbls rlts = (alias, showJSONs $ packageAggSubFields transFx sss sodn soa sobj tbls sfs rlts) packageAggSubFields :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [[(Int,Int,Bool,String)]] -> [Field] -> [[[[a]]]] -> [JSValue] packageAggSubFields transFx sss sodn soa sobj tbls sfs rlts = packageAggSubFieldsForEveryRow transFx sss sodn soa sobj sfs grpdInstcByObjInst where dtaByInstCbntn = zip tbls rlts grpdInstcByObjInst = foldl' (\rlt (nInst,nDta)->if (thd4 $ head nInst)==False then ((init rlt)++[(last rlt)++[(nInst,(nDta,snd $ snd $ head $ last rlt))]]) else rlt++[[(nInst,(nDta,countTableIds (fth4 $ head nInst) sodn))]]) [[(fst $ head dtaByInstCbntn,(snd $ head dtaByInstCbntn,countTableIds (fth4 $ head $ fst $ head dtaByInstCbntn) sodn))]] $ tail dtaByInstCbntn packageAggSubFieldsForEveryRow :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [Field] -> [[([(Int,Int,Bool,String)],([[[a]]],Int))]] -> [JSValue] -- result is root-instance/table/row/column packageAggSubFieldsForEveryRow transFx sss sodn soa sobj (sf:sfs) dt = if null objWInst then [] else (++) objects $ packageAggSubFieldsForEveryRow transFx sss sodn soa sobj (sf:sfs) remIs where (_,_,_,_,isNull) = transFx objInstWRw = map (filter (not . null . head . fst . snd)) dt objWInst = filter (\nObj->(null nObj)==False) objInstWRw (nxtObjsRw,remIs) = foldl' (\(objRows,remRows) nObj-> let (nObjRow,nObjRem) = foldl' (\(nInstRow,nInstRem) (tbls,(dSet,idC))->let (rowData,remData) = separateGqlRow isNull idC dSet in (nInstRow++[(tbls,rowData)],nInstRem++[(tbls,(remData,idC))])) ([],[]) nObj in (objRows++[unzip nObjRow],remRows++[nObjRem])) ([],[]) objWInst objects = foldl' (\rlt (nTbl,nDt)->rlt++({-if null nTbl {-no instance-} then [] else -}if (fst4 $ head $ head nTbl)<2 then map showJSON $ decodeTextToJSObj $ (\(toTxt,_,_,_,_)->toTxt) transFx $ head $ head $ head $ head $ nDt else [showJSON $ toJSObject $ makeOneGQLObjFrmAgg transFx sss sodn soa sobj nTbl (sf:sfs) nDt])) [] nxtObjsRw packageAggSubFieldsForEveryRow transFx sss sodn soa sobj [] dt = [] decodeTextToJSObj :: Text -> [JSObject JSValue] decodeTextToJSObj dta = case decode $ unpack dta of (Ok rlt) -> rlt :: [JSObject JSValue] _ -> throw ReadJsonException makeOneGQLObjFrmAgg :: (Eq a) => ((a -> Text),(a -> Double),(a -> Int64),(a -> Bool),(a -> Bool)) -> [(String,[(String,String,[(String,[(String,String,String,String)])])])] -> [(String,[String],String)] -> [(String,[String],[String])] -> String -> [[(Int,Int,Bool,String)]] -> [Field] -> [[[[a]]]] -> [(String,JSValue)] makeOneGQLObjFrmAgg _ _ _ _ _ [] _ _ = error "EOF data processing (source error)" -- no instance combinations makeOneGQLObjFrmAgg _ _ _ _ _ ([]:_) _ _ = error "EOF data processing (source error)" -- no reference tables in first instance combination makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls ((Left (ScalarType alias "__typename" trans arg)):b) dat = (getScalarFieldLabel $ ScalarType alias "__typename" trans arg, showJSON $ pack $ translateTableToObject (fth4 $ head $ head tbls) sodn):(makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls b dat) makeOneGQLObjFrmAgg (fx1,fx2,fx3,fx4,isNull) sss sodn soa sobj tbls ((Left (ScalarType alias name trans arg)):b) ((((i:j):k):l):m) = (getScalarFieldLabel $ ScalarType alias name trans arg, if isNull i then JSNull else castJSType (fx1,fx2,fx3,fx4,isNull) (findPrimitiveScalarTypeType (translateTableToObject (fth4 $ head $ head tbls) sodn) name trans arg sss) i):(makeOneGQLObjFrmAgg (fx1,fx2,fx3,fx4,isNull) sss sodn soa sobj tbls b (((j:k):l):m)) makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls ((Right (Left (NestedObject alias name nso ss sfs))):b) ((j:k):l) = ((getNestedObjectFieldLabel $ NestedObject alias name nso ss sfs), showJSONs $ packageAggSubFields transFx sss sodn soa nso objTbls sfs objData):(makeOneGQLObjFrmAgg transFx sss sodn soa sobj remTbls b remData) where (objTbls,objData,remTbls,remData) = sepAggDataFrNstdObj tbls ((j:k):l) makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls ((Right (Right (InlinefragmentObject ifo sfs))):b) dat = if isServerObjectTable (fth4 $ head $ head tbls) ifo sodn soa then makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls (sfs++b) dat else makeOneGQLObjFrmAgg transFx sss sodn soa sobj tbls b dat makeOneGQLObjFrmAgg _ _ _ _ _ _ [] ((([]:_):_):_) = [] -- no columns (in first variant and first query) and no fields (done) makeOneGQLObjFrmAgg _ _ _ _ _ _ _ (([]:_):_) = [] -- no rows (no data) makeOneGQLObjFrmAgg _ _ _ _ _ _ ((Right (Left _)):[]) ([]:_) = error "EOF data processing (source error)" -- field and no queries (unusual) makeOneGQLObjFrmAgg _ _ _ _ _ _ _ ([]:_) = [] -- no queries (no data) makeOneGQLObjFrmAgg _ _ _ _ _ _ _ [] = [] -- no variants (unusual) makeOneGQLObjFrmAgg _ _ _ _ _ _ [] _ = [] -- columns and no fields (done or error) makeOneGQLObjFrmAgg _ _ _ _ _ _ ((Left _):_) ((([]:_):_):_) = error "EOF data processing (source error)" -- field and no result columns sepAggDataFrNstdObj :: [[(Int,Int,Bool,String)]] -> [[[[a]]]] -> ([[(Int,Int,Bool,String)]],[[[[a]]]],[[(Int,Int,Bool,String)]],[[[[a]]]]) sepAggDataFrNstdObj info dat = ([fstNObjMeta]++(concat nxtRowTbls),[fstNObjData]++(concat nxtRowData),[fstRemMeta]++(concat nxtRemTbls),[fstRemData]++(concat nxtRemData)) where (nxtRowTbls,nxtRowData,nxtRemTbls,nxtRemData) = unzip4 $ map (\(instMt,instDt)-> let nxtTblsInfo = tail instMt tNxtTblsInfo = tail nxtTblsInfo (_,objLvl,_,_) = head nxtTblsInfo nestedObjCount = foldr' (\(_,nlvl,_,_) rlt->if nlvl<=objLvl then 0 else rlt+1) 0 tNxtTblsInfo fQrydPos = foldr' (\(idx,(_,_,fst,_)) rlt->if fst then idx else rlt) ((length nxtTblsInfo)-1) $ zip [0..] nxtTblsInfo hasQrd = (<=) fQrydPos nestedObjCount in if hasQrd then ([tail instMt],[instDt],[],[]) else ([],[],[(head instMt):(drop (nestedObjCount+1) $ tail instMt)],[instDt]) ) $ tail $ zip info dat fstInstInfo = head info fstInstDat = head dat (fstC,fstL,fstF,fstT) = head fstInstInfo nObjPlusTblsInfo = tail fstInstInfo nObjLvl = (+) fstL 1 nstdObjsCount = foldr' (\(_,nlvl,_,_) rlt->if (==) nlvl nObjLvl then 1 else (+) rlt 1) 1 $ tail nObjPlusTblsInfo fstNObjMeta = take nstdObjsCount nObjPlusTblsInfo nObjPlusDat = tail $ fstInstDat fstNObjData = take nstdObjsCount nObjPlusDat fstRemMeta = (fstC,fstL,fstF,fstT):(drop nstdObjsCount nObjPlusTblsInfo) fstRemData = (head $ fstInstDat):(drop nstdObjsCount nObjPlusDat)