Add unison-codebase-sqlite-hashing-v2 package

unison-codebase-sqlite is now parameterized by the hashing functions
This commit is contained in:
Travis Staton 2022-06-13 10:13:00 -04:00
parent 3dcb952b3c
commit 535eaf98a9
29 changed files with 938 additions and 494 deletions

View File

@ -0,0 +1,56 @@
name: unison-codebase-sqlite-hashing-v2
github: unisonweb/unison
copyright: Copyright (C) 2013-2021 Unison Computing, PBC and contributors
ghc-options: -Wall
dependencies:
- base
- bytes
- bytestring
- containers
- lens
- text
- unison-codebase
- unison-codebase-sqlite
- unison-core
- unison-core1
- unison-hashing-v2
- unison-prelude
- unison-sqlite
- unison-util
- unison-util-base32hex
- unison-util-term
- vector
library:
source-dirs: src
when:
- condition: false
other-modules: Paths_unison_codebase_sqlite_hashing_v2
default-extensions:
- ApplicativeDo
- BangPatterns
- BlockArguments
- DeriveAnyClass
- DeriveFunctor
- DeriveGeneric
- DeriveTraversable
- DerivingStrategies
- DerivingVia
- DoAndIfThenElse
- FlexibleContexts
- FlexibleInstances
- GeneralizedNewtypeDeriving
- LambdaCase
- MultiParamTypeClasses
- NamedFieldPuns
- OverloadedStrings
- PatternSynonyms
- RecordWildCards
- RankNTypes
- ScopedTypeVariables
- TupleSections
- TypeApplications
- ViewPatterns

View File

@ -0,0 +1,24 @@
module U.Codebase.Sqlite.V2.Decl
( saveDeclComponent,
)
where
import qualified U.Codebase.Decl as V2
import U.Codebase.Sqlite.DbId (ObjectId)
import qualified U.Codebase.Sqlite.Queries as U.Sqlite
import U.Codebase.Sqlite.Symbol (Symbol)
import U.Codebase.Sqlite.V2.HashHandle
import U.Util.Hash (Hash)
import Unison.Prelude
import Unison.Sqlite
saveDeclComponent ::
-- | The serialized decl component if we already have it e.g. via sync
Maybe ByteString ->
-- | decl component hash
Hash ->
-- | decl component
[V2.Decl Symbol] ->
Transaction ObjectId
saveDeclComponent =
U.Sqlite.saveDeclComponent v2HashHandle

View File

@ -0,0 +1,19 @@
module U.Codebase.Sqlite.V2.HashHandle
( v2HashHandle,
)
where
import qualified Data.Set as Set
import U.Codebase.Sqlite.HashHandle
import U.Util.Type (removeAllEffectVars)
import Unison.Hashing.V2.Convert2 (h2ToV2Reference, v2ToH2Type, v2ToH2TypeD)
import qualified Unison.Hashing.V2.Type as H2
v2HashHandle :: HashHandle
v2HashHandle =
HashHandle
{ toReference = h2ToV2Reference . H2.toReference . v2ToH2Type,
toReferenceMentions = Set.map h2ToV2Reference . H2.toReferenceMentions . v2ToH2Type . removeAllEffectVars,
toReferenceDecl = \h -> h2ToV2Reference . H2.toReference . v2ToH2TypeD h,
toReferenceDeclMentions = \h -> Set.map h2ToV2Reference . H2.toReferenceMentions . v2ToH2TypeD h . removeAllEffectVars
}

View File

@ -0,0 +1,11 @@
module U.Codebase.Sqlite.V2.SyncEntity where
import qualified U.Codebase.Sqlite.DbId as Db
import U.Codebase.Sqlite.Entity (SyncEntity)
import qualified U.Codebase.Sqlite.Queries as Q
import U.Codebase.Sqlite.V2.HashHandle
import U.Util.Hash32 (Hash32)
import Unison.Sqlite
saveSyncEntity :: Hash32 -> SyncEntity -> Transaction (Either Db.CausalHashId Db.ObjectId)
saveSyncEntity = Q.saveSyncEntity v2HashHandle

View File

@ -0,0 +1,24 @@
module U.Codebase.Sqlite.V2.Term
( saveTermComponent,
)
where
import U.Codebase.Sqlite.DbId (ObjectId)
import qualified U.Codebase.Sqlite.Queries as U.Sqlite
import U.Codebase.Sqlite.Symbol (Symbol)
import U.Codebase.Sqlite.V2.HashHandle
import qualified U.Codebase.Term as V2
import U.Util.Hash (Hash)
import Unison.Prelude
import Unison.Sqlite
saveTermComponent ::
-- | The serialized term component if we already have it e.g. via sync
Maybe ByteString ->
-- | term component hash
Hash ->
-- | term component
[(V2.Term Symbol, V2.Type Symbol)] ->
Transaction ObjectId
saveTermComponent =
U.Sqlite.saveTermComponent v2HashHandle

View File

@ -1,6 +1,9 @@
-- | Description: Converts V2 types to the V2 hashing types
module Unison.Hashing.V2.Convert2
( convertTerm,
( v2ToH2Term,
v2ToH2Type,
v2ToH2TypeD,
h2ToV2Reference,
)
where
@ -10,9 +13,10 @@ import qualified U.Codebase.Referent as V2.Referent
import qualified U.Codebase.Term as V2 (F, F' (..), MatchCase (..), Pattern (..), SeqOp (..), TermRef, TypeRef)
import qualified U.Codebase.Type as V2.Type
import qualified U.Core.ABT as V2
import qualified U.Core.ABT as V2.ABT
import qualified U.Util.Hash as V2 (Hash)
import qualified Unison.ABT as H2 (transform)
import Unison.Codebase.SqliteCodebase.Conversions (abt2to1)
import qualified Unison.ABT as V1.ABT
import qualified Unison.Hashing.V2.Kind as H2
import qualified Unison.Hashing.V2.Pattern as H2.Pattern
import qualified Unison.Hashing.V2.Reference as H2
@ -21,8 +25,18 @@ import qualified Unison.Hashing.V2.Term as H2
import qualified Unison.Hashing.V2.Type as H2.Type
import Unison.Prelude
convertTerm :: forall v. Ord v => V2.Hash -> V2.Term (V2.F v) v () -> H2.Term v ()
convertTerm thisTermComponentHash = H2.transform convertF . abt2to1
-- | Delete me ASAP. I am defined elsewhere.
abt2to1 :: Functor f => V2.ABT.Term f v a -> V1.ABT.Term f v a
abt2to1 (V2.ABT.Term fv a out) = V1.ABT.Term fv a (go out)
where
go = \case
V2.ABT.Cycle body -> V1.ABT.Cycle (abt2to1 body)
V2.ABT.Abs v body -> V1.ABT.Abs v (abt2to1 body)
V2.ABT.Var v -> V1.ABT.Var v
V2.ABT.Tm tm -> V1.ABT.Tm (abt2to1 <$> tm)
v2ToH2Term :: forall v. Ord v => V2.Hash -> V2.Term (V2.F v) v () -> H2.Term v ()
v2ToH2Term thisTermComponentHash = H2.transform convertF . abt2to1
where
convertF :: forall x. V2.F v x -> H2.F v () () x
convertF = \case
@ -37,7 +51,7 @@ convertTerm thisTermComponentHash = H2.transform convertF . abt2to1
V2.Request a b -> H2.Request (convertReference a) b
V2.Handle a b -> H2.Handle a b
V2.App a b -> H2.App a b
V2.Ann a b -> H2.Ann a (convertType b)
V2.Ann a b -> H2.Ann a (v2ToH2Type b)
V2.List a -> H2.List a
V2.If a b c -> H2.If a b c
V2.And a b -> H2.And a b
@ -97,12 +111,18 @@ convertReference' idConv = \case
V2.ReferenceBuiltin x -> H2.Builtin x
V2.ReferenceDerived x -> H2.DerivedId (idConv x)
convertType :: forall v. Ord v => V2.Type.TypeR V2.TypeRef v -> H2.Type.Type v ()
convertType = H2.transform convertF . abt2to1
v2ToH2Type :: forall v. Ord v => V2.Type.TypeR V2.TypeRef v -> H2.Type.Type v ()
v2ToH2Type = v2ToH2Type' convertReference
v2ToH2TypeD :: forall v. Ord v => V2.Hash -> V2.Type.TypeD v -> H2.Type.Type v ()
v2ToH2TypeD defaultHash = v2ToH2Type' (convertReference' (convertId defaultHash))
v2ToH2Type' :: forall r v. Ord v => (r -> H2.Reference) -> V2.Type.TypeR r v -> H2.Type.Type v ()
v2ToH2Type' mkReference = H2.transform convertF . abt2to1
where
convertF :: forall a. V2.Type.F' V2.TypeRef a -> H2.Type.F a
convertF :: forall a. V2.Type.F' r a -> H2.Type.F a
convertF = \case
V2.Type.Ref x -> H2.Type.Ref (convertReference x)
V2.Type.Ref x -> H2.Type.Ref (mkReference x)
V2.Type.Arrow a b -> H2.Type.Arrow a b
V2.Type.Ann a k -> H2.Type.Ann a (convertKind k)
V2.Type.App a b -> H2.Type.App a b
@ -115,3 +135,8 @@ convertKind :: V2.Kind -> H2.Kind
convertKind = \case
V2.Star -> H2.Star
V2.Arrow a b -> H2.Arrow (convertKind a) (convertKind b)
h2ToV2Reference :: H2.Reference -> V2.Reference
h2ToV2Reference = \case
H2.Builtin txt -> V2.ReferenceBuiltin txt
H2.DerivedId (H2.Id x y) -> V2.ReferenceDerived (V2.Id x y)

View File

@ -0,0 +1,71 @@
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.34.7.
--
-- see: https://github.com/sol/hpack
name: unison-codebase-sqlite-hashing-v2
version: 0.0.0
homepage: https://github.com/unisonweb/unison#readme
bug-reports: https://github.com/unisonweb/unison/issues
copyright: Copyright (C) 2013-2021 Unison Computing, PBC and contributors
build-type: Simple
source-repository head
type: git
location: https://github.com/unisonweb/unison
library
exposed-modules:
U.Codebase.Sqlite.V2.Decl
U.Codebase.Sqlite.V2.HashHandle
U.Codebase.Sqlite.V2.SyncEntity
U.Codebase.Sqlite.V2.Term
Unison.Hashing.V2.Convert2
hs-source-dirs:
src
default-extensions:
ApplicativeDo
BangPatterns
BlockArguments
DeriveAnyClass
DeriveFunctor
DeriveGeneric
DeriveTraversable
DerivingStrategies
DerivingVia
DoAndIfThenElse
FlexibleContexts
FlexibleInstances
GeneralizedNewtypeDeriving
LambdaCase
MultiParamTypeClasses
NamedFieldPuns
OverloadedStrings
PatternSynonyms
RecordWildCards
RankNTypes
ScopedTypeVariables
TupleSections
TypeApplications
ViewPatterns
ghc-options: -Wall
build-depends:
base
, bytes
, bytestring
, containers
, lens
, text
, unison-codebase
, unison-codebase-sqlite
, unison-core
, unison-core1
, unison-hashing-v2
, unison-prelude
, unison-sqlite
, unison-util
, unison-util-base32hex
, unison-util-term
, vector
default-language: Haskell2010

View File

@ -21,8 +21,8 @@ data DeclFormat = Decl LocallyIndexedComponent
type LocallyIndexedComponent =
LocallyIndexedComponent' TextId ObjectId
newtype LocallyIndexedComponent' t d
= LocallyIndexedComponent (Vector (LocalIds' t d, Decl Symbol))
newtype LocallyIndexedComponent' t d = LocallyIndexedComponent
{unLocallyIndexedComponent :: Vector (LocalIds' t d, Decl Symbol)}
deriving (Show)
type SyncDeclFormat =

View File

@ -12,6 +12,7 @@ module U.Codebase.Sqlite.Decode
decodeSyncNamespaceFormat,
decodeSyncPatchFormat,
decodeSyncTermFormat,
decodeSyncTermAndType,
decodeTermElementDiscardingTerm,
decodeTermElementDiscardingType,
decodeTermElementWithType,
@ -26,9 +27,14 @@ module U.Codebase.Sqlite.Decode
-- * @watch_result.result@
decodeWatchResultFormat,
-- * unsyncs
unsyncTermComponent,
unsyncDeclComponent,
)
where
import Control.Exception (throwIO)
import Data.Bytes.Get (runGetS)
import qualified Data.Bytes.Get as Get
import qualified U.Codebase.Reference as C.Reference
@ -53,7 +59,7 @@ data DecodeError = DecodeError
err :: String -- the error message
}
deriving stock (Show)
deriving anyclass (SqliteExceptionReason)
deriving anyclass (SqliteExceptionReason, Exception)
getFromBytesOr :: Text -> Get a -> ByteString -> Either DecodeError a
getFromBytesOr decoder get bs = case runGetS get bs of
@ -99,6 +105,18 @@ decodeSyncTermFormat :: ByteString -> Either DecodeError TermFormat.SyncTermForm
decodeSyncTermFormat =
getFromBytesOr "decomposeTermFormat" Serialization.decomposeTermFormat
-- | N.B. The bytestring here is not the entire object.bytes column --
-- it's just the serialized term and type from 'TermFormat.SyncTermFormat'.
decodeSyncTermAndType :: ByteString -> Either DecodeError (TermFormat.Term, TermFormat.Type)
decodeSyncTermAndType =
getFromBytesOr "getTermAndType" Serialization.getTermAndType
-- | N.B. The bytestring here is not the entire object.bytes column --
-- it's just the serialized decl from 'DeclFormat.SyncDeclFormat'.
decodeDecl :: ByteString -> Either DecodeError (DeclFormat.Decl Symbol)
decodeDecl =
getFromBytesOr "getDeclElement" Serialization.getDeclElement
decodeTermFormat :: ByteString -> Either DecodeError TermFormat.TermFormat
decodeTermFormat =
getFromBytesOr "getTermFormat" Serialization.getTermFormat
@ -147,3 +165,24 @@ decodeTempTermFormat =
decodeWatchResultFormat :: ByteString -> Either DecodeError TermFormat.WatchResultFormat
decodeWatchResultFormat =
getFromBytesOr "getWatchResultFormat" Serialization.getWatchResultFormat
------------------------------------------------------------------------------------------------------------------------
-- unsyncs
unsyncTermComponent :: TermFormat.SyncLocallyIndexedComponent' t d -> IO (TermFormat.LocallyIndexedComponent' t d)
unsyncTermComponent (TermFormat.SyncLocallyIndexedComponent terms) = do
let phi (localIds, bs) = do
(a, b) <- decodeSyncTermAndType bs
pure (localIds, a, b)
case traverse phi terms of
Left err -> throwIO err
Right x -> pure (TermFormat.LocallyIndexedComponent x)
unsyncDeclComponent :: DeclFormat.SyncLocallyIndexedComponent' t d -> IO (DeclFormat.LocallyIndexedComponent' t d)
unsyncDeclComponent (DeclFormat.SyncLocallyIndexedComponent decls) = do
let phi (localIds, bs) = do
decl <- decodeDecl bs
pure (localIds, decl)
case traverse phi decls of
Left err -> throwIO err
Right x -> pure (DeclFormat.LocallyIndexedComponent x)

View File

@ -0,0 +1,22 @@
module U.Codebase.Sqlite.HashHandle
( HashHandle (..),
)
where
import qualified U.Codebase.Reference as C
import U.Codebase.Sqlite.Symbol (Symbol)
import qualified U.Codebase.Term as C.Term
import qualified U.Codebase.Type as C.Type
import U.Util.Hash (Hash)
import Unison.Prelude
data HashHandle = HashHandle
{ -- | Hash type
toReference :: C.Term.Type Symbol -> C.Reference,
-- | Hash type's mentions
toReferenceMentions :: C.Term.Type Symbol -> Set C.Reference,
-- | Hash decl
toReferenceDecl :: Hash -> C.Type.TypeD Symbol -> C.Reference,
-- | Hash decl's mentions
toReferenceDeclMentions :: Hash -> C.Type.TypeD Symbol -> Set C.Reference
}

View File

@ -11,13 +11,13 @@ module U.Codebase.Sqlite.Operations
expectCausalBranchByCausalHash,
-- * terms
saveTermComponent,
Q.saveTermComponent,
loadTermComponent,
loadTermByReference,
loadTypeOfTermByTermReference,
-- * decls
saveDeclComponent,
Q.saveDeclComponent,
loadDeclComponent,
loadDeclByReference,
expectDeclTypeById,
@ -55,11 +55,11 @@ module U.Codebase.Sqlite.Operations
dependentsOfComponent,
-- ** type index
addTypeToIndexForTerm,
Q.addTypeToIndexForTerm,
termsHavingType,
-- ** type mentions index
addTypeMentionsToIndexForTerm,
Q.addTypeMentionsToIndexForTerm,
termsMentioningType,
-- ** name lookup index
@ -80,29 +80,23 @@ module U.Codebase.Sqlite.Operations
diffPatch,
decodeTermElementWithType,
loadTermWithTypeByReference,
s2cTermWithType,
Q.s2cTermWithType,
Q.s2cDecl,
declReferencesByPrefix,
branchHashesByPrefix,
derivedDependencies,
)
where
import Control.Lens (Lens')
import qualified Control.Lens as Lens
import qualified Control.Monad.Extra as Monad
import Control.Monad.State (MonadState, evalStateT)
import Control.Monad.Writer (MonadWriter, runWriterT)
import qualified Control.Monad.Writer as Writer
import Data.Bifunctor (Bifunctor (bimap))
import Data.Bitraversable (Bitraversable (bitraverse))
import qualified Data.Foldable as Foldable
import qualified Data.Map as Map
import qualified Data.Map.Merge.Lazy as Map
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import qualified Data.Text as Text
import Data.Tuple.Extra (uncurry3, (***))
import qualified Data.Vector as Vector
import qualified U.Codebase.Branch as C.Branch
import qualified U.Codebase.Causal as C
import U.Codebase.Decl (ConstructorId)
@ -125,17 +119,14 @@ import qualified U.Codebase.Sqlite.Branch.Full as S.MetadataSet
import qualified U.Codebase.Sqlite.DbId as Db
import qualified U.Codebase.Sqlite.Decl.Format as S.Decl
import U.Codebase.Sqlite.Decode
import U.Codebase.Sqlite.HashHandle (HashHandle (..))
import U.Codebase.Sqlite.LocalIds
( LocalDefnId (..),
LocalIds,
LocalIds' (..),
LocalTextId (..),
( LocalIds,
WatchLocalIds,
)
import qualified U.Codebase.Sqlite.LocalIds as LocalIds
import qualified U.Codebase.Sqlite.LocalizeObject as LocalizeObject
import qualified U.Codebase.Sqlite.NamedRef as S
import qualified U.Codebase.Sqlite.ObjectType as OT
import qualified U.Codebase.Sqlite.ObjectType as ObjectType
import qualified U.Codebase.Sqlite.Patch.Diff as S
import qualified U.Codebase.Sqlite.Patch.Format as S
import qualified U.Codebase.Sqlite.Patch.Format as S.Patch.Format
@ -156,17 +147,13 @@ import qualified U.Codebase.Term as C
import qualified U.Codebase.Term as C.Term
import qualified U.Codebase.TermEdit as C
import qualified U.Codebase.TermEdit as C.TermEdit
import qualified U.Codebase.Type as C.Type
import qualified U.Codebase.TypeEdit as C
import qualified U.Codebase.TypeEdit as C.TypeEdit
import U.Codebase.WatchKind (WatchKind)
import qualified U.Core.ABT as ABT
import qualified U.Util.Base32Hex as Base32Hex
import qualified U.Util.Hash as H
import qualified U.Util.Hash32 as Hash32
import qualified U.Util.Lens as Lens
import qualified U.Util.Serialization as S
import qualified U.Util.Term as TermUtil
import Unison.Prelude
import Unison.Sqlite
import qualified Unison.Util.Map as Map
@ -305,12 +292,8 @@ h2cReferent = bitraverse h2cReference h2cReference
-- ** convert and save references
-- | Save the text and hash parts of a Reference to the database and substitute their ids.
saveReferenceH :: C.Reference -> Transaction S.ReferenceH
saveReferenceH = bitraverse Q.saveText Q.saveHashHash
saveReferentH :: C.Referent -> Transaction S.ReferentH
saveReferentH = bitraverse saveReferenceH saveReferenceH
saveReferentH = bitraverse Q.saveReferenceH Q.saveReferenceH
-- ** Edits transformations
@ -341,7 +324,7 @@ c2sPatch :: C.Branch.Patch -> Transaction S.Patch
c2sPatch (C.Branch.Patch termEdits typeEdits) =
S.Patch
<$> Map.bitraverse saveReferentH (Set.traverse c2sTermEdit) termEdits
<*> Map.bitraverse saveReferenceH (Set.traverse c2sTypeEdit) typeEdits
<*> Map.bitraverse Q.saveReferenceH (Set.traverse c2sTypeEdit) typeEdits
where
c2sTermEdit = \case
C.TermEdit.Replace r t -> S.TermEdit.Replace <$> c2sReferent r <*> pure (c2sTyping t)
@ -402,163 +385,14 @@ loadTermComponent :: H.Hash -> MaybeT Transaction [(C.Term Symbol, C.Term.Type S
loadTermComponent h = do
oid <- MaybeT (Q.loadObjectIdForAnyHash h)
S.Term.Term (S.Term.LocallyIndexedComponent elements) <- MaybeT (Q.loadTermObject oid decodeTermFormat)
lift . traverse (uncurry3 s2cTermWithType) $ Foldable.toList elements
saveTermComponent :: H.Hash -> [(C.Term Symbol, C.Term.Type Symbol)] -> Transaction Db.ObjectId
saveTermComponent h terms = do
when debug . traceM $ "Operations.saveTermComponent " ++ show h
sTermElements <- traverse (uncurry c2sTerm) terms
hashId <- Q.saveHashHash h
let li = S.Term.LocallyIndexedComponent $ Vector.fromList sTermElements
bytes = S.putBytes S.putTermFormat $ S.Term.Term li
oId <- Q.saveObject hashId OT.TermComponent bytes
-- populate dependents index
let dependencies :: Set (S.Reference.Reference, S.Reference.Id) = foldMap unlocalizeRefs (sTermElements `zip` [0 ..])
unlocalizeRefs :: ((LocalIds, S.Term.Term, S.Term.Type), C.Reference.Pos) -> Set (S.Reference.Reference, S.Reference.Id)
unlocalizeRefs ((LocalIds tIds oIds, tm, tp), i) =
let self = C.Reference.Id oId i
dependencies :: Set S.Reference =
let (tmRefs, tpRefs, tmLinks, tpLinks) = TermUtil.dependencies tm
tpRefs' = Foldable.toList $ C.Type.dependencies tp
getTermSRef :: S.Term.TermRef -> S.Reference
getTermSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived Nothing i -> C.Reference.Derived oId i -- index self-references
C.Reference.Derived (Just h) i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
getTypeSRef :: S.Term.TypeRef -> S.Reference
getTypeSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived h i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
getSTypeLink = getTypeSRef
getSTermLink :: S.Term.TermLink -> S.Reference
getSTermLink = \case
C.Referent.Con ref _conId -> getTypeSRef ref
C.Referent.Ref ref -> getTermSRef ref
in Set.fromList $
map getTermSRef tmRefs
++ map getSTermLink tmLinks
++ map getTypeSRef (tpRefs ++ tpRefs')
++ map getSTypeLink tpLinks
in Set.map (,self) dependencies
traverse_ (uncurry Q.addToDependentsIndex) dependencies
pure oId
-- | implementation detail of c2{s,w}Term
-- The Type is optional, because we don't store them for watch expression results.
c2xTerm :: forall m t d. Monad m => (Text -> m t) -> (H.Hash -> m d) -> C.Term Symbol -> Maybe (C.Term.Type Symbol) -> m (LocalIds' t d, S.Term.Term, Maybe (S.Term.Type))
c2xTerm saveText saveDefn tm tp =
done =<< (runWriterT . flip evalStateT mempty) do
sterm <- ABT.transformM go tm
stype <- traverse (ABT.transformM goType) tp
pure (sterm, stype)
where
go :: forall m a. (MonadWriter (Seq Text, Seq H.Hash) m, MonadState (Map Text LocalTextId, Map H.Hash LocalDefnId) m) => C.Term.F Symbol a -> m (S.Term.F a)
go = \case
C.Term.Int n -> pure $ C.Term.Int n
C.Term.Nat n -> pure $ C.Term.Nat n
C.Term.Float n -> pure $ C.Term.Float n
C.Term.Boolean b -> pure $ C.Term.Boolean b
C.Term.Text t -> C.Term.Text <$> lookupText t
C.Term.Char ch -> pure $ C.Term.Char ch
C.Term.Ref r ->
C.Term.Ref <$> bitraverse lookupText (traverse lookupDefn) r
C.Term.Constructor typeRef cid ->
C.Term.Constructor
<$> bitraverse lookupText lookupDefn typeRef
<*> pure cid
C.Term.Request typeRef cid ->
C.Term.Request <$> bitraverse lookupText lookupDefn typeRef <*> pure cid
C.Term.Handle a a2 -> pure $ C.Term.Handle a a2
C.Term.App a a2 -> pure $ C.Term.App a a2
C.Term.Ann a typ -> C.Term.Ann a <$> ABT.transformM goType typ
C.Term.List as -> pure $ C.Term.List as
C.Term.If c t f -> pure $ C.Term.If c t f
C.Term.And a a2 -> pure $ C.Term.And a a2
C.Term.Or a a2 -> pure $ C.Term.Or a a2
C.Term.Lam a -> pure $ C.Term.Lam a
C.Term.LetRec bs a -> pure $ C.Term.LetRec bs a
C.Term.Let a a2 -> pure $ C.Term.Let a a2
C.Term.Match a cs -> C.Term.Match a <$> traverse goCase cs
C.Term.TermLink r ->
C.Term.TermLink
<$> bitraverse
(bitraverse lookupText (traverse lookupDefn))
(bitraverse lookupText lookupDefn)
r
C.Term.TypeLink r ->
C.Term.TypeLink <$> bitraverse lookupText lookupDefn r
goType ::
forall m a.
(MonadWriter (Seq Text, Seq H.Hash) m, MonadState (Map Text LocalTextId, Map H.Hash LocalDefnId) m) =>
C.Type.FT a ->
m (S.Term.FT a)
goType = \case
C.Type.Ref r -> C.Type.Ref <$> bitraverse lookupText lookupDefn r
C.Type.Arrow i o -> pure $ C.Type.Arrow i o
C.Type.Ann a k -> pure $ C.Type.Ann a k
C.Type.App f a -> pure $ C.Type.App f a
C.Type.Effect e a -> pure $ C.Type.Effect e a
C.Type.Effects es -> pure $ C.Type.Effects es
C.Type.Forall a -> pure $ C.Type.Forall a
C.Type.IntroOuter a -> pure $ C.Type.IntroOuter a
goCase ::
forall m w s a.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map Text LocalTextId),
Lens.Field1' w (Seq Text),
Lens.Field2' s (Map H.Hash LocalDefnId),
Lens.Field2' w (Seq H.Hash)
) =>
C.Term.MatchCase Text C.Term.TypeRef a ->
m (C.Term.MatchCase LocalTextId S.Term.TypeRef a)
goCase = \case
C.Term.MatchCase pat guard body ->
C.Term.MatchCase <$> goPat pat <*> pure guard <*> pure body
goPat ::
forall m s w.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map Text LocalTextId),
Lens.Field1' w (Seq Text),
Lens.Field2' s (Map H.Hash LocalDefnId),
Lens.Field2' w (Seq H.Hash)
) =>
C.Term.Pattern Text C.Term.TypeRef ->
m (C.Term.Pattern LocalTextId S.Term.TypeRef)
goPat = \case
C.Term.PUnbound -> pure $ C.Term.PUnbound
C.Term.PVar -> pure $ C.Term.PVar
C.Term.PBoolean b -> pure $ C.Term.PBoolean b
C.Term.PInt i -> pure $ C.Term.PInt i
C.Term.PNat n -> pure $ C.Term.PNat n
C.Term.PFloat d -> pure $ C.Term.PFloat d
C.Term.PText t -> C.Term.PText <$> lookupText t
C.Term.PChar c -> pure $ C.Term.PChar c
C.Term.PConstructor r i ps -> C.Term.PConstructor <$> bitraverse lookupText lookupDefn r <*> pure i <*> traverse goPat ps
C.Term.PAs p -> C.Term.PAs <$> goPat p
C.Term.PEffectPure p -> C.Term.PEffectPure <$> goPat p
C.Term.PEffectBind r i bindings k -> C.Term.PEffectBind <$> bitraverse lookupText lookupDefn r <*> pure i <*> traverse goPat bindings <*> goPat k
C.Term.PSequenceLiteral ps -> C.Term.PSequenceLiteral <$> traverse goPat ps
C.Term.PSequenceOp l op r -> C.Term.PSequenceOp <$> goPat l <*> pure op <*> goPat r
done :: ((S.Term.Term, Maybe S.Term.Type), (Seq Text, Seq H.Hash)) -> m (LocalIds' t d, S.Term.Term, Maybe S.Term.Type)
done ((tm, tp), (localTextValues, localDefnValues)) = do
textIds <- traverse saveText localTextValues
defnIds <- traverse saveDefn localDefnValues
let ids =
LocalIds
(Vector.fromList (Foldable.toList textIds))
(Vector.fromList (Foldable.toList defnIds))
pure (ids, void tm, void <$> tp)
lift . traverse (uncurry3 Q.s2cTermWithType) $ Foldable.toList elements
loadTermWithTypeByReference :: C.Reference.Id -> MaybeT Transaction (C.Term Symbol, C.Term.Type Symbol)
loadTermWithTypeByReference (C.Reference.Id h i) = do
oid <- MaybeT (Q.loadObjectIdForPrimaryHash h)
-- retrieve and deserialize the blob
(localIds, term, typ) <- MaybeT (Q.loadTermObject oid (decodeTermElementWithType i))
lift (s2cTermWithType localIds term typ)
lift (Q.s2cTermWithType localIds term typ)
loadTermByReference :: C.Reference.Id -> MaybeT Transaction (C.Term Symbol)
loadTermByReference r@(C.Reference.Id h i) = do
@ -576,95 +410,15 @@ loadTypeOfTermByTermReference id@(C.Reference.Id h i) = do
(localIds, typ) <- MaybeT (Q.loadTermObject oid (decodeTermElementDiscardingTerm i))
lift (s2cTypeOfTerm localIds typ)
s2cTermWithType :: LocalIds -> S.Term.Term -> S.Term.Type -> Transaction (C.Term Symbol, C.Term.Type Symbol)
s2cTermWithType ids tm tp = do
(substText, substHash) <- localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId ids
pure (x2cTerm substText substHash tm, x2cTType substText substHash tp)
s2cTerm :: LocalIds -> S.Term.Term -> Transaction (C.Term Symbol)
s2cTerm ids tm = do
(substText, substHash) <- localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId ids
pure $ x2cTerm substText substHash tm
(substText, substHash) <- Q.localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId ids
pure $ Q.x2cTerm substText substHash tm
s2cTypeOfTerm :: LocalIds -> S.Term.Type -> Transaction (C.Term.Type Symbol)
s2cTypeOfTerm ids tp = do
(substText, substHash) <- localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId ids
pure $ x2cTType substText substHash tp
-- | implementation detail of {s,w}2c*Term* & s2cDecl
localIdsToLookups :: Monad m => (t -> m Text) -> (d -> m H.Hash) -> LocalIds' t d -> m (LocalTextId -> Text, LocalDefnId -> H.Hash)
localIdsToLookups loadText loadHash localIds = do
texts <- traverse loadText $ LocalIds.textLookup localIds
hashes <- traverse loadHash $ LocalIds.defnLookup localIds
let substText (LocalTextId w) = texts Vector.! fromIntegral w
substHash (LocalDefnId w) = hashes Vector.! fromIntegral w
pure (substText, substHash)
localIdsToTypeRefLookup :: LocalIds -> Transaction (S.Decl.TypeRef -> C.Decl.TypeRef)
localIdsToTypeRefLookup localIds = do
(substText, substHash) <- localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId localIds
pure $ bimap substText (fmap substHash)
-- | implementation detail of {s,w}2c*Term*
x2cTerm :: (LocalTextId -> Text) -> (LocalDefnId -> H.Hash) -> S.Term.Term -> C.Term Symbol
x2cTerm substText substHash =
-- substitute the text and hashes back into the term
C.Term.extraMap substText substTermRef substTypeRef substTermLink substTypeLink id
where
substTermRef = bimap substText (fmap substHash)
substTypeRef = bimap substText substHash
substTermLink = bimap substTermRef substTypeRef
substTypeLink = substTypeRef
-- | implementation detail of {s,w}2c*Term*
x2cTType :: (LocalTextId -> Text) -> (LocalDefnId -> H.Hash) -> S.Term.Type -> C.Term.Type Symbol
x2cTType substText substHash = C.Type.rmap (bimap substText substHash)
lookupText ::
forall m s w t.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map t LocalTextId),
Lens.Field1' w (Seq t),
Ord t
) =>
t ->
m LocalTextId
lookupText = lookup_ Lens._1 Lens._1 LocalTextId
lookupDefn ::
forall m s w d.
( MonadState s m,
MonadWriter w m,
Lens.Field2' s (Map d LocalDefnId),
Lens.Field2' w (Seq d),
Ord d
) =>
d ->
m LocalDefnId
lookupDefn = lookup_ Lens._2 Lens._2 LocalDefnId
-- | shared implementation of lookupTextHelper and lookupDefnHelper
-- Look up a value in the LUT, or append it.
lookup_ ::
(MonadState s m, MonadWriter w m, Ord t) =>
Lens' s (Map t t') ->
Lens' w (Seq t) ->
(Word64 -> t') ->
t ->
m t'
lookup_ stateLens writerLens mk t = do
map <- Lens.use stateLens
case Map.lookup t map of
Nothing -> do
let id = mk . fromIntegral $ Map.size map
stateLens Lens.%= Map.insert t id
Writer.tell $ Lens.set writerLens (Seq.singleton t) mempty
pure id
Just t' -> pure t'
c2sTerm :: C.Term Symbol -> C.Term.Type Symbol -> Transaction (LocalIds, S.Term.Term, S.Term.Type)
c2sTerm tm tp = c2xTerm Q.saveText Q.expectObjectIdForPrimaryHash tm (Just tp) <&> \(w, tm, Just tp) -> (w, tm, tp)
(substText, substHash) <- Q.localIdsToLookups Q.expectText Q.expectPrimaryHashByObjectId ids
pure $ Q.x2cTType substText substHash tp
-- *** Watch expressions
@ -689,12 +443,12 @@ clearWatches :: Transaction ()
clearWatches = Q.clearWatches
c2wTerm :: C.Term Symbol -> Transaction (WatchLocalIds, S.Term.Term)
c2wTerm tm = c2xTerm Q.saveText Q.saveHashHash tm Nothing <&> \(w, tm, _) -> (w, tm)
c2wTerm tm = Q.c2xTerm Q.saveText Q.saveHashHash tm Nothing <&> \(w, tm, _) -> (w, tm)
w2cTerm :: WatchLocalIds -> S.Term.Term -> Transaction (C.Term Symbol)
w2cTerm ids tm = do
(substText, substHash) <- localIdsToLookups Q.expectText Q.expectHash ids
pure $ x2cTerm substText substHash tm
(substText, substHash) <- Q.localIdsToLookups Q.expectText Q.expectHash ids
pure $ Q.x2cTerm substText substHash tm
-- ** Saving & loading type decls
@ -702,80 +456,14 @@ loadDeclComponent :: H.Hash -> MaybeT Transaction [C.Decl Symbol]
loadDeclComponent h = do
oid <- MaybeT (Q.loadObjectIdForAnyHash h)
S.Decl.Decl (S.Decl.LocallyIndexedComponent elements) <- MaybeT (Q.loadDeclObject oid decodeDeclFormat)
lift . traverse (uncurry s2cDecl) $ Foldable.toList elements
saveDeclComponent :: H.Hash -> [C.Decl Symbol] -> Transaction Db.ObjectId
saveDeclComponent h decls = do
when debug . traceM $ "Operations.saveDeclComponent " ++ show h
sDeclElements <- traverse (c2sDecl Q.saveText Q.expectObjectIdForPrimaryHash) decls
hashId <- Q.saveHashHash h
let li = S.Decl.LocallyIndexedComponent $ Vector.fromList sDeclElements
bytes = S.putBytes S.putDeclFormat $ S.Decl.Decl li
oId <- Q.saveObject hashId OT.DeclComponent bytes
-- populate dependents index
let dependencies :: Set (S.Reference.Reference, S.Reference.Id) = foldMap unlocalizeRefs (sDeclElements `zip` [0 ..])
unlocalizeRefs :: ((LocalIds, S.Decl.Decl Symbol), C.Reference.Pos) -> Set (S.Reference.Reference, S.Reference.Id)
unlocalizeRefs ((LocalIds tIds oIds, decl), i) =
let self = C.Reference.Id oId i
dependencies :: Set S.Decl.TypeRef = C.Decl.dependencies decl
getSRef :: C.Reference.Reference' LocalTextId (Maybe LocalDefnId) -> S.Reference.Reference
getSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived Nothing i -> C.Reference.Derived oId i -- index self-references
C.Reference.Derived (Just h) i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
in Set.map ((,self) . getSRef) dependencies
traverse_ (uncurry Q.addToDependentsIndex) dependencies
pure oId
c2sDecl ::
forall m t d.
Monad m =>
(Text -> m t) ->
(H.Hash -> m d) ->
C.Decl Symbol ->
m (LocalIds' t d, S.Decl.Decl Symbol)
c2sDecl saveText saveDefn (C.Decl.DataDeclaration dt m b cts) = do
done =<< (runWriterT . flip evalStateT mempty) do
cts' <- traverse (ABT.transformM goType) cts
pure (C.Decl.DataDeclaration dt m b cts')
where
goType ::
forall m a.
(MonadWriter (Seq Text, Seq H.Hash) m, MonadState (Map Text LocalTextId, Map H.Hash LocalDefnId) m) =>
C.Type.FD a ->
m (S.Decl.F a)
goType = \case
C.Type.Ref r -> C.Type.Ref <$> bitraverse lookupText (traverse lookupDefn) r
C.Type.Arrow i o -> pure $ C.Type.Arrow i o
C.Type.Ann a k -> pure $ C.Type.Ann a k
C.Type.App f a -> pure $ C.Type.App f a
C.Type.Effect e a -> pure $ C.Type.Effect e a
C.Type.Effects es -> pure $ C.Type.Effects es
C.Type.Forall a -> pure $ C.Type.Forall a
C.Type.IntroOuter a -> pure $ C.Type.IntroOuter a
done :: (S.Decl.Decl Symbol, (Seq Text, Seq H.Hash)) -> m (LocalIds' t d, S.Decl.Decl Symbol)
done (decl, (localTextValues, localDefnValues)) = do
textIds <- traverse saveText localTextValues
defnIds <- traverse saveDefn localDefnValues
let ids =
LocalIds
(Vector.fromList (Foldable.toList textIds))
(Vector.fromList (Foldable.toList defnIds))
pure (ids, decl)
-- | Unlocalize a decl.
s2cDecl :: LocalIds -> S.Decl.Decl Symbol -> Transaction (C.Decl Symbol)
s2cDecl ids (C.Decl.DataDeclaration dt m b ct) = do
substTypeRef <- localIdsToTypeRefLookup ids
pure (C.Decl.DataDeclaration dt m b (C.Type.rmap substTypeRef <$> ct))
lift . traverse (uncurry Q.s2cDecl) $ Foldable.toList elements
loadDeclByReference :: C.Reference.Id -> MaybeT Transaction (C.Decl Symbol)
loadDeclByReference r@(C.Reference.Id h i) = do
when debug . traceM $ "loadDeclByReference " ++ show r
oid <- MaybeT (Q.loadObjectIdForPrimaryHash h)
(localIds, decl) <- MaybeT (Q.loadDeclObject oid (decodeDeclElement i))
lift (s2cDecl localIds decl)
lift (Q.s2cDecl localIds decl)
expectDeclByReference :: C.Reference.Id -> Transaction (C.Decl Symbol)
expectDeclByReference r@(C.Reference.Id h i) = do
@ -783,7 +471,7 @@ expectDeclByReference r@(C.Reference.Id h i) = do
-- retrieve the blob
Q.expectObjectIdForPrimaryHash h
>>= (\oid -> Q.expectDeclObject oid (decodeDeclElement i))
>>= uncurry s2cDecl
>>= uncurry Q.s2cDecl
-- * Branch transformation
@ -877,10 +565,13 @@ s2cBranch (S.Branch.Full.Branch tms tps patches children) =
boId <- Q.expectBranchObjectIdByCausalHashId chId
expectBranch boId
saveRootBranch :: C.Branch.CausalBranch Transaction -> Transaction (Db.BranchObjectId, Db.CausalHashId)
saveRootBranch c = do
saveRootBranch ::
HashHandle ->
C.Branch.CausalBranch Transaction ->
Transaction (Db.BranchObjectId, Db.CausalHashId)
saveRootBranch hh c = do
when debug $ traceM $ "Operations.saveRootBranch " ++ show (C.causalHash c)
(boId, chId) <- saveBranch c
(boId, chId) <- saveBranch hh c
Q.setNamespaceRoot chId
pure (boId, chId)
@ -923,8 +614,11 @@ saveRootBranch c = do
-- References, but also values
-- Shallow - Hash? representation of the database relationships
saveBranch :: C.Branch.CausalBranch Transaction -> Transaction (Db.BranchObjectId, Db.CausalHashId)
saveBranch (C.Causal hc he parents me) = do
saveBranch ::
HashHandle ->
C.Branch.CausalBranch Transaction ->
Transaction (Db.BranchObjectId, Db.CausalHashId)
saveBranch hh (C.Causal hc he parents me) = do
when debug $ traceM $ "\nOperations.saveBranch \n hc = " ++ show hc ++ ",\n he = " ++ show he ++ ",\n parents = " ++ show (Map.keys parents)
(chId, bhId) <- flip Monad.fromMaybeM (Q.loadCausalByCausalHash hc) do
@ -939,14 +633,14 @@ saveBranch (C.Causal hc he parents me) = do
-- by checking if there are causal parents associated with hc
(flip Monad.fromMaybeM)
(Q.loadCausalHashIdByCausalHash parentHash)
(mcausal >>= fmap snd . saveBranch)
(mcausal >>= fmap snd . saveBranch hh)
-- Save these CausalHashIds to the causal_parents table,
Q.saveCausal chId bhId parentCausalHashIds
Q.saveCausal hh chId bhId parentCausalHashIds
pure (chId, bhId)
boId <- flip Monad.fromMaybeM (Q.loadBranchObjectIdByCausalHashId chId) do
branch <- c2sBranch =<< me
saveDbBranchUnderHashId bhId branch
saveDbBranchUnderHashId hh bhId branch
pure (boId, chId)
where
c2sBranch :: C.Branch.Branch Transaction -> Transaction S.DbBranch
@ -955,7 +649,7 @@ saveBranch (C.Causal hc he parents me) = do
<$> Map.bitraverse saveNameSegment (Map.bitraverse c2sReferent c2sMetadata) terms
<*> Map.bitraverse saveNameSegment (Map.bitraverse c2sReference c2sMetadata) types
<*> Map.bitraverse saveNameSegment savePatchObjectId patches
<*> Map.bitraverse saveNameSegment saveBranch children
<*> Map.bitraverse saveNameSegment (saveBranch hh) children
saveNameSegment :: C.Branch.NameSegment -> Transaction Db.TextId
saveNameSegment = Q.saveText . C.Branch.unNameSegment
@ -971,7 +665,7 @@ saveBranch (C.Causal hc he parents me) = do
Just patchOID -> pure patchOID
Nothing -> do
patch <- mp
savePatch h patch
savePatch hh h patch
expectRootCausal :: Transaction (C.Branch.CausalBranch Transaction)
expectRootCausal = Q.expectNamespaceRoot >>= expectCausalBranchByCausalHashId
@ -1125,14 +819,22 @@ expectDbBranch id =
--
-- Note: long-standing question: should this package depend on the hashing package? (If so, we would only need to take
-- the DbBranch, and hash internally).
saveDbBranch :: BranchHash -> S.DbBranch -> Transaction Db.BranchObjectId
saveDbBranch hash branch = do
saveDbBranch ::
HashHandle ->
BranchHash ->
S.DbBranch ->
Transaction Db.BranchObjectId
saveDbBranch hh hash branch = do
hashId <- Q.saveBranchHash hash
saveDbBranchUnderHashId hashId branch
saveDbBranchUnderHashId hh hashId branch
-- | Variant of 'saveDbBranch' that might be preferred by callers that already have a hash id, not a hash.
saveDbBranchUnderHashId :: Db.BranchHashId -> S.DbBranch -> Transaction Db.BranchObjectId
saveDbBranchUnderHashId id@(Db.unBranchHashId -> hashId) branch = do
saveDbBranchUnderHashId ::
HashHandle ->
Db.BranchHashId ->
S.DbBranch ->
Transaction Db.BranchObjectId
saveDbBranchUnderHashId hh id@(Db.unBranchHashId -> hashId) branch = do
let (localBranchIds, localBranch) = LocalizeObject.localizeBranch branch
when debug $
traceM $
@ -1140,7 +842,7 @@ saveDbBranchUnderHashId id@(Db.unBranchHashId -> hashId) branch = do
++ "\n\tlBranch = "
++ show localBranch
let bytes = S.putBytes S.putBranchFormat $ S.BranchFormat.Full localBranchIds localBranch
oId <- Q.saveObject hashId OT.Namespace bytes
oId <- Q.saveObject hh hashId ObjectType.Namespace bytes
pure $ Db.BranchObjectId oId
expectBranch :: Db.BranchObjectId -> Transaction (C.Branch.Branch Transaction)
@ -1165,16 +867,24 @@ expectDbPatch patchId =
S.Patch.Format.Full li f -> pure (S.Patch.Format.applyPatchDiffs (S.Patch.Format.localPatchToPatch li f) ds)
S.Patch.Format.Diff ref' li' d' -> doDiff ref' (S.Patch.Format.localPatchDiffToPatchDiff li' d' : ds)
savePatch :: PatchHash -> C.Branch.Patch -> Transaction Db.PatchObjectId
savePatch h c = do
savePatch ::
HashHandle ->
PatchHash ->
C.Branch.Patch ->
Transaction Db.PatchObjectId
savePatch hh h c = do
(li, lPatch) <- LocalizeObject.localizePatch <$> c2sPatch c
saveDbPatch h (S.Patch.Format.Full li lPatch)
saveDbPatch hh h (S.Patch.Format.Full li lPatch)
saveDbPatch :: PatchHash -> S.PatchFormat -> Transaction Db.PatchObjectId
saveDbPatch hash patch = do
saveDbPatch ::
HashHandle ->
PatchHash ->
S.PatchFormat ->
Transaction Db.PatchObjectId
saveDbPatch hh hash patch = do
hashId <- Q.saveHashHash (unPatchHash hash)
let bytes = S.putBytes S.putPatchFormat patch
Db.PatchObjectId <$> Q.saveObject hashId OT.Patch bytes
Db.PatchObjectId <$> Q.saveObject hh hashId ObjectType.Patch bytes
s2cPatch :: S.Patch -> Transaction C.Branch.Patch
s2cPatch (S.Patch termEdits typeEdits) =
@ -1224,19 +934,10 @@ termsMentioningType cTypeRef =
set <- traverse s2cReferentId sIds
pure (Set.fromList set)
addTypeToIndexForTerm :: S.Referent.Id -> C.Reference -> Transaction ()
addTypeToIndexForTerm sTermId cTypeRef = do
sTypeRef <- saveReferenceH cTypeRef
Q.addToTypeIndex sTypeRef sTermId
addTypeMentionsToIndexForTerm :: S.Referent.Id -> Set C.Reference -> Transaction ()
addTypeMentionsToIndexForTerm sTermId cTypeMentionRefs = do
traverse_ (flip Q.addToTypeMentionsIndex sTermId <=< saveReferenceH) cTypeMentionRefs
-- something kind of funny here. first, we don't need to enumerate all the reference pos if we're just picking one
-- second, it would be nice if we could leave these as S.References a little longer
-- so that we remember how to blow up if they're missing
componentReferencesByPrefix :: OT.ObjectType -> Text -> Maybe C.Reference.Pos -> Transaction [S.Reference.Id]
componentReferencesByPrefix :: ObjectType.ObjectType -> Text -> Maybe C.Reference.Pos -> Transaction [S.Reference.Id]
componentReferencesByPrefix ot b32prefix pos = do
oIds :: [Db.ObjectId] <- Q.objectIdByBase32Prefix ot b32prefix
let test = maybe (const True) (==) pos
@ -1245,12 +946,12 @@ componentReferencesByPrefix ot b32prefix pos = do
termReferencesByPrefix :: Text -> Maybe Word64 -> Transaction [C.Reference.Id]
termReferencesByPrefix t w =
componentReferencesByPrefix OT.TermComponent t w
componentReferencesByPrefix ObjectType.TermComponent t w
>>= traverse (C.Reference.idH Q.expectPrimaryHashByObjectId)
declReferencesByPrefix :: Text -> Maybe Word64 -> Transaction [C.Reference.Id]
declReferencesByPrefix t w =
componentReferencesByPrefix OT.DeclComponent t w
componentReferencesByPrefix ObjectType.DeclComponent t w
>>= traverse (C.Reference.idH Q.expectPrimaryHashByObjectId)
termReferentsByPrefix :: Text -> Maybe Word64 -> Transaction [C.Referent.Id]
@ -1265,7 +966,7 @@ declReferentsByPrefix ::
Maybe ConstructorId ->
Transaction [(H.Hash, C.Reference.Pos, C.DeclType, [C.Decl.ConstructorId])]
declReferentsByPrefix b32prefix pos cid = do
componentReferencesByPrefix OT.DeclComponent b32prefix pos
componentReferencesByPrefix ObjectType.DeclComponent b32prefix pos
>>= traverse (loadConstructors cid)
where
loadConstructors ::

View File

@ -1,3 +1,5 @@
{-# LANGUAGE RecordWildCards #-}
-- | Some naming conventions used in this module:
--
-- * @32@: the base32 representation of a hash
@ -142,35 +144,60 @@ module U.Codebase.Sqlite.Queries
syncToTempEntity,
insertTempEntity,
saveTempEntityInMain,
expectTempEntity,
deleteTempEntity,
-- * elaborate hashes
elaborateHashes,
-- * db misc
createSchema,
addTempEntityTables,
schemaVersion,
addTypeMentionsToIndexForTerm,
addTypeToIndexForTerm,
c2xTerm,
createSchema,
expectSchemaVersion,
localIdsToLookups,
s2cDecl,
s2cTermWithType,
saveDeclComponent,
saveReferenceH,
saveSyncEntity,
saveTermComponent,
schemaVersion,
setSchemaVersion,
x2cTType,
x2cTerm,
)
where
import Control.Lens (Lens')
import qualified Control.Lens as Lens
import Control.Monad.Extra ((||^))
import Control.Monad.State (MonadState, evalStateT)
import Control.Monad.Writer (MonadWriter, runWriterT)
import qualified Control.Monad.Writer as Writer
import Data.Bifunctor (Bifunctor (bimap))
import Data.Bitraversable (bitraverse)
import Data.Bytes.Put (runPutS)
import qualified Data.Foldable as Foldable
import qualified Data.List.Extra as List
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as Nel
import qualified Data.Map as Map
import Data.Map.NonEmpty (NEMap)
import qualified Data.Map.NonEmpty as NEMap
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import Data.String.Here.Uninterpolated (here, hereFile)
import qualified Data.Vector as Vector
import qualified U.Codebase.Decl as C
import qualified U.Codebase.Decl as C.Decl
import U.Codebase.HashTags (BranchHash (..), CausalHash (..), PatchHash (..))
import U.Codebase.Reference (Reference' (..))
import qualified U.Codebase.Reference as C
import qualified U.Codebase.Reference as C.Reference
import qualified U.Codebase.Referent as C.Referent
import qualified U.Codebase.Sqlite.Branch.Format as NamespaceFormat
import qualified U.Codebase.Sqlite.Causal as Causal
import qualified U.Codebase.Sqlite.Causal as Sqlite.Causal
@ -186,9 +213,17 @@ import U.Codebase.Sqlite.DbId
TextId,
)
import qualified U.Codebase.Sqlite.Decl.Format as DeclFormat
import qualified U.Codebase.Sqlite.Decl.Format as S.Decl
import U.Codebase.Sqlite.Decode
import U.Codebase.Sqlite.Entity (SyncEntity)
import qualified U.Codebase.Sqlite.Entity as Entity
import U.Codebase.Sqlite.HashHandle (HashHandle (..))
import U.Codebase.Sqlite.LocalIds
( LocalDefnId (..),
LocalIds,
LocalIds' (..),
LocalTextId (..),
)
import qualified U.Codebase.Sqlite.LocalIds as LocalIds
import qualified U.Codebase.Sqlite.NamedRef as S
import U.Codebase.Sqlite.ObjectType (ObjectType (DeclComponent, Namespace, Patch, TermComponent))
@ -196,20 +231,32 @@ import qualified U.Codebase.Sqlite.ObjectType as ObjectType
import U.Codebase.Sqlite.Orphans ()
import qualified U.Codebase.Sqlite.Patch.Format as PatchFormat
import qualified U.Codebase.Sqlite.Reference as Reference
import qualified U.Codebase.Sqlite.Reference as S
import qualified U.Codebase.Sqlite.Reference as S.Reference
import qualified U.Codebase.Sqlite.Referent as Referent
import qualified U.Codebase.Sqlite.Referent as S.Referent
import U.Codebase.Sqlite.Serialization as Serialization
import U.Codebase.Sqlite.Symbol (Symbol)
import U.Codebase.Sqlite.TempEntity (TempEntity)
import qualified U.Codebase.Sqlite.TempEntity as TempEntity
import U.Codebase.Sqlite.TempEntityType (TempEntityType)
import qualified U.Codebase.Sqlite.TempEntityType as TempEntityType
import qualified U.Codebase.Sqlite.Term.Format as S.Term
import qualified U.Codebase.Sqlite.Term.Format as TermFormat
import qualified U.Codebase.Term as C
import qualified U.Codebase.Term as C.Term
import qualified U.Codebase.Type as C.Type
import U.Codebase.WatchKind (WatchKind)
import qualified U.Core.ABT as ABT
import qualified U.Util.Alternative as Alternative
import U.Util.Hash (Hash)
import qualified U.Util.Hash as Hash
import U.Util.Hash32 (Hash32)
import qualified U.Util.Hash32 as Hash32
import U.Util.Hash32.Orphans.Sqlite ()
import qualified U.Util.Lens as Lens
import qualified U.Util.Serialization as S
import qualified U.Util.Term as TermUtil
import Unison.Prelude
import Unison.Sqlite
@ -383,15 +430,20 @@ saveHashObject hId oId version = execute sql (hId, oId, version) where
ON CONFLICT DO NOTHING
|]
saveObject :: HashId -> ObjectType -> ByteString -> Transaction ObjectId
saveObject h t blob = do
saveObject ::
HashHandle ->
HashId ->
ObjectType ->
ByteString ->
Transaction ObjectId
saveObject hh h t blob = do
oId <- execute sql (h, t, blob) >> expectObjectIdForPrimaryHashId h
saveHashObject h oId 2 -- todo: remove this from here, and add it to other relevant places once there are v1 and v2 hashes
rowsModified >>= \case
0 -> pure ()
_ -> do
hash <- expectHash32 h
tryMoveTempEntityDependents hash
tryMoveTempEntityDependents hh hash
pure oId
where
sql = [here|
@ -629,14 +681,19 @@ recordObjectRehash old new =
-- |Maybe we would generalize this to something other than NamespaceHash if we
-- end up wanting to store other kinds of Causals here too.
saveCausal :: CausalHashId -> BranchHashId -> [CausalHashId] -> Transaction ()
saveCausal self value parents = do
saveCausal ::
HashHandle ->
CausalHashId ->
BranchHashId ->
[CausalHashId] ->
Transaction ()
saveCausal hh self value parents = do
execute insertCausalSql (self, value)
rowsModified >>= \case
0 -> pure ()
_ -> do
executeMany insertCausalParentsSql (fmap (self,) parents)
flushCausalDependents self
flushCausalDependents hh self
where
insertCausalSql = [here|
INSERT INTO causal (self_hash_id, value_hash_id)
@ -647,10 +704,13 @@ saveCausal self value parents = do
INSERT INTO causal_parent (causal_id, parent_id) VALUES (?, ?)
|]
flushCausalDependents :: CausalHashId -> Transaction ()
flushCausalDependents chId = do
flushCausalDependents ::
HashHandle ->
CausalHashId ->
Transaction ()
flushCausalDependents hh chId = do
hash <- expectHash32 (unCausalHashId chId)
tryMoveTempEntityDependents hash
tryMoveTempEntityDependents hh hash
-- | `tryMoveTempEntityDependents #foo` does this:
-- 0. Precondition: We just inserted object #foo.
@ -658,8 +718,12 @@ flushCausalDependents chId = do
-- 2. Delete #foo as dependency from temp_entity_missing_dependency. e.g. (#bar, #foo), (#baz, #foo)
-- 3. For each like #bar and #baz with no more rows in temp_entity_missing_dependency,
-- insert_entity them.
tryMoveTempEntityDependents :: Hash32 -> Transaction ()
tryMoveTempEntityDependents dependency = do
tryMoveTempEntityDependents ::
-- | Move TempEntity to main
HashHandle ->
Hash32 ->
Transaction ()
tryMoveTempEntityDependents hh dependency = do
dependents <-
queryListCol
[here|
@ -673,7 +737,7 @@ tryMoveTempEntityDependents dependency = do
flushIfReadyToFlush :: Hash32 -> Transaction ()
flushIfReadyToFlush dependent = do
readyToFlush dependent >>= \case
True -> moveTempEntityToMain dependent
True -> moveTempEntityToMain hh dependent
False -> pure ()
readyToFlush :: Hash32 -> Transaction Bool
@ -726,21 +790,6 @@ expectEntity hash = do
Namespace -> Entity.N <$> decodeSyncNamespaceFormat bytes
Patch -> Entity.P <$> decodeSyncPatchFormat bytes
moveTempEntityToMain :: Hash32 -> Transaction ()
moveTempEntityToMain hash = do
entity <- expectTempEntity hash
deleteTempEntity hash
_ <- saveTempEntityInMain hash entity
pure ()
-- | Save a temp entity in main storage.
--
-- Precondition: all of its dependencies are already in main storage.
saveTempEntityInMain :: Hash32 -> TempEntity -> Transaction (Either CausalHashId ObjectId)
saveTempEntityInMain hash entity = do
entity' <- tempToSyncEntity entity
saveSyncEntity hash entity'
-- | Read an entity out of temp storage.
expectTempEntity :: Hash32 -> Transaction TempEntity
expectTempEntity hash = do
@ -907,28 +956,6 @@ syncToTempEntity = \case
TermFormat.SyncTerm . TermFormat.SyncLocallyIndexedComponent
<$> Lens.traverseOf (traverse . Lens._1) (bitraverse expectText expectPrimaryHash32ByObjectId) terms
saveSyncEntity :: Hash32 -> SyncEntity -> Transaction (Either CausalHashId ObjectId)
saveSyncEntity hash entity = do
hashId <- saveHash hash
case entity of
Entity.TC stf -> do
let bytes = runPutS (Serialization.recomposeTermFormat stf)
Right <$> saveObject hashId ObjectType.TermComponent bytes
Entity.DC sdf -> do
let bytes = runPutS (Serialization.recomposeDeclFormat sdf)
Right <$> saveObject hashId ObjectType.DeclComponent bytes
Entity.N sbf -> do
let bytes = runPutS (Serialization.recomposeBranchFormat sbf)
Right <$> saveObject hashId ObjectType.Namespace bytes
Entity.P spf -> do
let bytes = runPutS (Serialization.recomposePatchFormat spf)
Right <$> saveObject hashId ObjectType.Patch bytes
Entity.C scf -> case scf of
Sqlite.Causal.SyncCausalFormat{valueHash, parents} -> do
let causalHashId = CausalHashId hashId
saveCausal causalHashId valueHash (Foldable.toList parents)
pure $ Left causalHashId
-- -- maybe: look at whether parent causal is "committed"; if so, then increment;
-- -- otherwise, don't.
-- getNurseryGeneration :: DB m => m Generation
@ -1624,3 +1651,407 @@ elaborateHashes hashes = do
)
execute_ [here|DROP TABLE new_temp_entity_dependents|]
pure result
moveTempEntityToMain ::
HashHandle ->
Hash32 ->
Transaction ()
moveTempEntityToMain hh hash = do
entity <- expectTempEntity hash
deleteTempEntity hash
_ <- saveTempEntityInMain hh hash entity
pure ()
-- | Save a temp entity in main storage.
--
-- Precondition: all of its dependencies are already in main storage.
saveTempEntityInMain :: HashHandle -> Hash32 -> TempEntity -> Transaction (Either CausalHashId ObjectId)
saveTempEntityInMain hh hash entity = do
entity' <- tempToSyncEntity entity
saveSyncEntity hh hash entity'
saveSyncEntity ::
HashHandle ->
Hash32 ->
SyncEntity ->
Transaction (Either CausalHashId ObjectId)
saveSyncEntity hh hash entity = do
case entity of
Entity.TC stf -> do
lic :: TermFormat.LocallyIndexedComponent <- do
let TermFormat.SyncTerm x = stf
unsafeIO (unsyncTermComponent x)
tc :: [(C.Term Symbol, C.Term.Type Symbol)] <-
traverse
(\(a, b, c) -> s2cTermWithType a b c)
(toList $ TermFormat.unLocallyIndexedComponent lic)
let bytes = runPutS (Serialization.recomposeTermFormat stf)
objId <- saveTermComponent hh (Just bytes) (Hash32.toHash hash) tc
pure (Right objId)
Entity.DC sdf -> do
lic :: S.Decl.LocallyIndexedComponent <- do
let S.Decl.SyncDecl xs = sdf
unsafeIO (unsyncDeclComponent xs)
dc :: [C.Decl.Decl Symbol] <-
traverse
(\(localIds, decl) -> s2cDecl localIds decl)
(toList $ S.Decl.unLocallyIndexedComponent lic)
let bytes = runPutS (Serialization.recomposeDeclFormat sdf)
objId <- saveDeclComponent hh (Just bytes) (Hash32.toHash hash) dc
pure (Right objId)
Entity.N sbf -> do
hashId <- saveHash hash
let bytes = runPutS (Serialization.recomposeBranchFormat sbf)
Right <$> saveObject hh hashId ObjectType.Namespace bytes
Entity.P spf -> do
hashId <- saveHash hash
let bytes = runPutS (Serialization.recomposePatchFormat spf)
Right <$> saveObject hh hashId ObjectType.Patch bytes
Entity.C scf -> case scf of
Sqlite.Causal.SyncCausalFormat {valueHash, parents} -> do
hashId <- saveHash hash
let causalHashId = CausalHashId hashId
saveCausal hh causalHashId valueHash (toList parents)
pure $ Left causalHashId
s2cTermWithType :: LocalIds.LocalIds -> S.Term.Term -> S.Term.Type -> Transaction (C.Term Symbol, C.Term.Type Symbol)
s2cTermWithType ids tm tp = do
(substText, substHash) <- localIdsToLookups expectText expectPrimaryHashByObjectId ids
pure (x2cTerm substText substHash tm, x2cTType substText substHash tp)
saveTermComponent ::
HashHandle ->
-- | The serialized term component if we already have it e.g. via sync
Maybe ByteString ->
-- | term component hash
Hash ->
-- | term component
[(C.Term Symbol, C.Term.Type Symbol)] ->
Transaction ObjectId
saveTermComponent hh@HashHandle {..} maybeEncodedTerms h terms = do
when debug . traceM $ "Operations.saveTermComponent " ++ show h
sTermElements <- traverse (uncurry c2sTerm) terms
hashId <- saveHashHash h
let bytes = fromMaybe mkByteString maybeEncodedTerms
mkByteString =
let li = S.Term.LocallyIndexedComponent $ Vector.fromList sTermElements
in S.putBytes Serialization.putTermFormat $ S.Term.Term li
oId <- saveObject hh hashId ObjectType.TermComponent bytes
-- populate dependents index
let dependencies :: Set (S.Reference.Reference, S.Reference.Id) = foldMap unlocalizeRefs (sTermElements `zip` [0 ..])
unlocalizeRefs :: ((LocalIds, S.Term.Term, S.Term.Type), C.Reference.Pos) -> Set (S.Reference.Reference, S.Reference.Id)
unlocalizeRefs ((LocalIds tIds oIds, tm, tp), i) =
let self = C.Reference.Id oId i
dependencies :: Set S.Reference =
let (tmRefs, tpRefs, tmLinks, tpLinks) = TermUtil.dependencies tm
tpRefs' = Foldable.toList $ C.Type.dependencies tp
getTermSRef :: S.Term.TermRef -> S.Reference
getTermSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived Nothing i -> C.Reference.Derived oId i -- index self-references
C.Reference.Derived (Just h) i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
getTypeSRef :: S.Term.TypeRef -> S.Reference
getTypeSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived h i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
getSTypeLink = getTypeSRef
getSTermLink :: S.Term.TermLink -> S.Reference
getSTermLink = \case
C.Referent.Con ref _conId -> getTypeSRef ref
C.Referent.Ref ref -> getTermSRef ref
in Set.fromList $
map getTermSRef tmRefs
++ map getSTermLink tmLinks
++ map getTypeSRef (tpRefs ++ tpRefs')
++ map getSTypeLink tpLinks
in Set.map (,self) dependencies
traverse_ (uncurry addToDependentsIndex) dependencies
for_ ((snd <$> terms) `zip` [0 ..]) \(tp, i) -> do
let self = C.Referent.RefId (C.Reference.Id oId i)
typeForIndexing = toReference tp
typeMentionsForIndexing = toReferenceMentions tp
addTypeToIndexForTerm self typeForIndexing
addTypeMentionsToIndexForTerm self typeMentionsForIndexing
pure oId
-- | Unlocalize a decl.
s2cDecl :: LocalIds -> S.Decl.Decl Symbol -> Transaction (C.Decl Symbol)
s2cDecl ids (C.Decl.DataDeclaration dt m b ct) = do
substTypeRef <- localIdsToTypeRefLookup ids
pure (C.Decl.DataDeclaration dt m b (C.Type.rmap substTypeRef <$> ct))
saveDeclComponent ::
HashHandle ->
Maybe ByteString ->
Hash ->
[C.Decl Symbol] ->
Transaction ObjectId
saveDeclComponent hh@HashHandle {..} maybeEncodedDecls h decls = do
when debug . traceM $ "Operations.saveDeclComponent " ++ show h
sDeclElements <- traverse (c2sDecl saveText expectObjectIdForPrimaryHash) decls
hashId <- saveHashHash h
let bytes = fromMaybe mkByteString maybeEncodedDecls
mkByteString =
let li = S.Decl.LocallyIndexedComponent $ Vector.fromList sDeclElements
in S.putBytes Serialization.putDeclFormat $ S.Decl.Decl li
oId <- saveObject hh hashId ObjectType.DeclComponent bytes
-- populate dependents index
let dependencies :: Set (S.Reference.Reference, S.Reference.Id) = foldMap unlocalizeRefs (sDeclElements `zip` [0 ..])
unlocalizeRefs :: ((LocalIds, S.Decl.Decl Symbol), C.Reference.Pos) -> Set (S.Reference.Reference, S.Reference.Id)
unlocalizeRefs ((LocalIds tIds oIds, decl), i) =
let self = C.Reference.Id oId i
dependencies :: Set S.Decl.TypeRef = C.Decl.dependencies decl
getSRef :: C.Reference.Reference' LocalTextId (Maybe LocalDefnId) -> S.Reference.Reference
getSRef = \case
C.ReferenceBuiltin t -> C.ReferenceBuiltin (tIds Vector.! fromIntegral t)
C.Reference.Derived Nothing i -> C.Reference.Derived oId i -- index self-references
C.Reference.Derived (Just h) i -> C.Reference.Derived (oIds Vector.! fromIntegral h) i
in Set.map ((,self) . getSRef) dependencies
traverse_ (uncurry addToDependentsIndex) dependencies
for_ ((fmap C.Decl.constructorTypes decls) `zip` [0 ..]) \(ctors, i) ->
for_ (ctors `zip` [0 ..]) \(tp, j) -> do
let self = C.Referent.ConId (C.Reference.Id oId i) j
typeForIndexing = toReferenceDecl h tp
typeMentionsForIndexing = toReferenceDeclMentions h tp
addTypeToIndexForTerm self typeForIndexing
addTypeMentionsToIndexForTerm self typeMentionsForIndexing
pure oId
-- | implementation detail of {s,w}2c*Term* & s2cDecl
localIdsToLookups :: Monad m => (t -> m Text) -> (d -> m Hash) -> LocalIds' t d -> m (LocalTextId -> Text, LocalDefnId -> Hash)
localIdsToLookups loadText loadHash localIds = do
texts <- traverse loadText $ LocalIds.textLookup localIds
hashes <- traverse loadHash $ LocalIds.defnLookup localIds
let substText (LocalTextId w) = texts Vector.! fromIntegral w
substHash (LocalDefnId w) = hashes Vector.! fromIntegral w
pure (substText, substHash)
-- | implementation detail of {s,w}2c*Term*
x2cTerm :: (LocalTextId -> Text) -> (LocalDefnId -> Hash) -> S.Term.Term -> C.Term Symbol
x2cTerm substText substHash =
-- substitute the text and hashes back into the term
C.Term.extraMap substText substTermRef substTypeRef substTermLink substTypeLink id
where
substTermRef = bimap substText (fmap substHash)
substTypeRef = bimap substText substHash
substTermLink = bimap substTermRef substTypeRef
substTypeLink = substTypeRef
-- | implementation detail of {s,w}2c*Term*
x2cTType :: (LocalTextId -> Text) -> (LocalDefnId -> Hash) -> S.Term.Type -> C.Term.Type Symbol
x2cTType substText substHash = C.Type.rmap (bimap substText substHash)
c2sTerm :: C.Term Symbol -> C.Term.Type Symbol -> Transaction (LocalIds, S.Term.Term, S.Term.Type)
c2sTerm tm tp = c2xTerm saveText expectObjectIdForPrimaryHash tm (Just tp) <&> \(w, tm, Just tp) -> (w, tm, tp)
addTypeToIndexForTerm :: S.Referent.Id -> C.Reference -> Transaction ()
addTypeToIndexForTerm sTermId cTypeRef = do
sTypeRef <- saveReferenceH cTypeRef
addToTypeIndex sTypeRef sTermId
addTypeMentionsToIndexForTerm :: S.Referent.Id -> Set C.Reference -> Transaction ()
addTypeMentionsToIndexForTerm sTermId cTypeMentionRefs = do
traverse_ (flip addToTypeMentionsIndex sTermId <=< saveReferenceH) cTypeMentionRefs
localIdsToTypeRefLookup :: LocalIds -> Transaction (S.Decl.TypeRef -> C.Decl.TypeRef)
localIdsToTypeRefLookup localIds = do
(substText, substHash) <- localIdsToLookups expectText expectPrimaryHashByObjectId localIds
pure $ bimap substText (fmap substHash)
c2sDecl ::
forall m t d.
Monad m =>
(Text -> m t) ->
(Hash -> m d) ->
C.Decl Symbol ->
m (LocalIds' t d, S.Decl.Decl Symbol)
c2sDecl saveText saveDefn (C.Decl.DataDeclaration dt m b cts) = do
done =<< (runWriterT . flip evalStateT mempty) do
cts' <- traverse (ABT.transformM goType) cts
pure (C.Decl.DataDeclaration dt m b cts')
where
goType ::
forall m a.
(MonadWriter (Seq Text, Seq Hash) m, MonadState (Map Text LocalTextId, Map Hash LocalDefnId) m) =>
C.Type.FD a ->
m (S.Decl.F a)
goType = \case
C.Type.Ref r -> C.Type.Ref <$> bitraverse lookupText (traverse lookupDefn) r
C.Type.Arrow i o -> pure $ C.Type.Arrow i o
C.Type.Ann a k -> pure $ C.Type.Ann a k
C.Type.App f a -> pure $ C.Type.App f a
C.Type.Effect e a -> pure $ C.Type.Effect e a
C.Type.Effects es -> pure $ C.Type.Effects es
C.Type.Forall a -> pure $ C.Type.Forall a
C.Type.IntroOuter a -> pure $ C.Type.IntroOuter a
done :: (S.Decl.Decl Symbol, (Seq Text, Seq Hash)) -> m (LocalIds' t d, S.Decl.Decl Symbol)
done (decl, (localTextValues, localDefnValues)) = do
textIds <- traverse saveText localTextValues
defnIds <- traverse saveDefn localDefnValues
let ids =
LocalIds
(Vector.fromList (Foldable.toList textIds))
(Vector.fromList (Foldable.toList defnIds))
pure (ids, decl)
-- | implementation detail of c2{s,w}Term
-- The Type is optional, because we don't store them for watch expression results.
c2xTerm :: forall m t d. Monad m => (Text -> m t) -> (Hash -> m d) -> C.Term Symbol -> Maybe (C.Term.Type Symbol) -> m (LocalIds' t d, S.Term.Term, Maybe (S.Term.Type))
c2xTerm saveText saveDefn tm tp =
done =<< (runWriterT . flip evalStateT mempty) do
sterm <- ABT.transformM go tm
stype <- traverse (ABT.transformM goType) tp
pure (sterm, stype)
where
go :: forall m a. (MonadWriter (Seq Text, Seq Hash) m, MonadState (Map Text LocalTextId, Map Hash LocalDefnId) m) => C.Term.F Symbol a -> m (S.Term.F a)
go = \case
C.Term.Int n -> pure $ C.Term.Int n
C.Term.Nat n -> pure $ C.Term.Nat n
C.Term.Float n -> pure $ C.Term.Float n
C.Term.Boolean b -> pure $ C.Term.Boolean b
C.Term.Text t -> C.Term.Text <$> lookupText t
C.Term.Char ch -> pure $ C.Term.Char ch
C.Term.Ref r ->
C.Term.Ref <$> bitraverse lookupText (traverse lookupDefn) r
C.Term.Constructor typeRef cid ->
C.Term.Constructor
<$> bitraverse lookupText lookupDefn typeRef
<*> pure cid
C.Term.Request typeRef cid ->
C.Term.Request <$> bitraverse lookupText lookupDefn typeRef <*> pure cid
C.Term.Handle a a2 -> pure $ C.Term.Handle a a2
C.Term.App a a2 -> pure $ C.Term.App a a2
C.Term.Ann a typ -> C.Term.Ann a <$> ABT.transformM goType typ
C.Term.List as -> pure $ C.Term.List as
C.Term.If c t f -> pure $ C.Term.If c t f
C.Term.And a a2 -> pure $ C.Term.And a a2
C.Term.Or a a2 -> pure $ C.Term.Or a a2
C.Term.Lam a -> pure $ C.Term.Lam a
C.Term.LetRec bs a -> pure $ C.Term.LetRec bs a
C.Term.Let a a2 -> pure $ C.Term.Let a a2
C.Term.Match a cs -> C.Term.Match a <$> traverse goCase cs
C.Term.TermLink r ->
C.Term.TermLink
<$> bitraverse
(bitraverse lookupText (traverse lookupDefn))
(bitraverse lookupText lookupDefn)
r
C.Term.TypeLink r ->
C.Term.TypeLink <$> bitraverse lookupText lookupDefn r
goType ::
forall m a.
(MonadWriter (Seq Text, Seq Hash) m, MonadState (Map Text LocalTextId, Map Hash LocalDefnId) m) =>
C.Type.FT a ->
m (S.Term.FT a)
goType = \case
C.Type.Ref r -> C.Type.Ref <$> bitraverse lookupText lookupDefn r
C.Type.Arrow i o -> pure $ C.Type.Arrow i o
C.Type.Ann a k -> pure $ C.Type.Ann a k
C.Type.App f a -> pure $ C.Type.App f a
C.Type.Effect e a -> pure $ C.Type.Effect e a
C.Type.Effects es -> pure $ C.Type.Effects es
C.Type.Forall a -> pure $ C.Type.Forall a
C.Type.IntroOuter a -> pure $ C.Type.IntroOuter a
goCase ::
forall m w s a.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map Text LocalTextId),
Lens.Field1' w (Seq Text),
Lens.Field2' s (Map Hash LocalDefnId),
Lens.Field2' w (Seq Hash)
) =>
C.Term.MatchCase Text C.Term.TypeRef a ->
m (C.Term.MatchCase LocalTextId S.Term.TypeRef a)
goCase = \case
C.Term.MatchCase pat guard body ->
C.Term.MatchCase <$> goPat pat <*> pure guard <*> pure body
goPat ::
forall m s w.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map Text LocalTextId),
Lens.Field1' w (Seq Text),
Lens.Field2' s (Map Hash LocalDefnId),
Lens.Field2' w (Seq Hash)
) =>
C.Term.Pattern Text C.Term.TypeRef ->
m (C.Term.Pattern LocalTextId S.Term.TypeRef)
goPat = \case
C.Term.PUnbound -> pure $ C.Term.PUnbound
C.Term.PVar -> pure $ C.Term.PVar
C.Term.PBoolean b -> pure $ C.Term.PBoolean b
C.Term.PInt i -> pure $ C.Term.PInt i
C.Term.PNat n -> pure $ C.Term.PNat n
C.Term.PFloat d -> pure $ C.Term.PFloat d
C.Term.PText t -> C.Term.PText <$> lookupText t
C.Term.PChar c -> pure $ C.Term.PChar c
C.Term.PConstructor r i ps -> C.Term.PConstructor <$> bitraverse lookupText lookupDefn r <*> pure i <*> traverse goPat ps
C.Term.PAs p -> C.Term.PAs <$> goPat p
C.Term.PEffectPure p -> C.Term.PEffectPure <$> goPat p
C.Term.PEffectBind r i bindings k -> C.Term.PEffectBind <$> bitraverse lookupText lookupDefn r <*> pure i <*> traverse goPat bindings <*> goPat k
C.Term.PSequenceLiteral ps -> C.Term.PSequenceLiteral <$> traverse goPat ps
C.Term.PSequenceOp l op r -> C.Term.PSequenceOp <$> goPat l <*> pure op <*> goPat r
done :: ((S.Term.Term, Maybe S.Term.Type), (Seq Text, Seq Hash)) -> m (LocalIds' t d, S.Term.Term, Maybe S.Term.Type)
done ((tm, tp), (localTextValues, localDefnValues)) = do
textIds <- traverse saveText localTextValues
defnIds <- traverse saveDefn localDefnValues
let ids =
LocalIds
(Vector.fromList (Foldable.toList textIds))
(Vector.fromList (Foldable.toList defnIds))
pure (ids, void tm, void <$> tp)
-- | Save the text and hash parts of a Reference to the database and substitute their ids.
saveReferenceH :: C.Reference -> Transaction S.ReferenceH
saveReferenceH = bitraverse saveText saveHashHash
lookupText ::
forall m s w t.
( MonadState s m,
MonadWriter w m,
Lens.Field1' s (Map t LocalTextId),
Lens.Field1' w (Seq t),
Ord t
) =>
t ->
m LocalTextId
lookupText = lookup_ Lens._1 Lens._1 LocalTextId
lookupDefn ::
forall m s w d.
( MonadState s m,
MonadWriter w m,
Lens.Field2' s (Map d LocalDefnId),
Lens.Field2' w (Seq d),
Ord d
) =>
d ->
m LocalDefnId
lookupDefn = lookup_ Lens._2 Lens._2 LocalDefnId
-- | shared implementation of lookupTextHelper and lookupDefnHelper
-- Look up a value in the LUT, or append it.
lookup_ ::
(MonadState s m, MonadWriter w m, Ord t) =>
Lens' s (Map t t') ->
Lens' w (Seq t) ->
(Word64 -> t') ->
t ->
m t'
lookup_ stateLens writerLens mk t = do
map <- Lens.use stateLens
case Map.lookup t map of
Nothing -> do
let id = mk . fromIntegral $ Map.size map
stateLens Lens.%= Map.insert t id
Writer.tell $ Lens.set writerLens (Seq.singleton t) mempty
pure id
Just t' -> pure t'

View File

@ -265,6 +265,9 @@ getTermComponent =
TermFormat.LocallyIndexedComponent
<$> getFramedArray (getTuple3 getLocalIds (getFramed getTerm) getTType)
getTermAndType :: MonadGet m => m (TermFormat.Term, TermFormat.Type)
getTermAndType = (,) <$> getFramed getTerm <*> getTType
getTerm :: MonadGet m => m TermFormat.Term
getTerm = getABT getSymbol getUnit getF
where

View File

@ -24,6 +24,7 @@ import qualified U.Codebase.Reference as Reference
import qualified U.Codebase.Sqlite.Branch.Format as BL
import U.Codebase.Sqlite.DbId
import qualified U.Codebase.Sqlite.Decl.Format as DeclFormat
import U.Codebase.Sqlite.HashHandle (HashHandle)
import qualified U.Codebase.Sqlite.LocalIds as L
import qualified U.Codebase.Sqlite.ObjectType as OT
import qualified U.Codebase.Sqlite.Patch.Format as PL
@ -89,18 +90,20 @@ sync22 ::
( MonadIO m,
MonadError Error m
) =>
HashHandle ->
Env m ->
IO (Sync m Entity)
sync22 Env {runSrc, runDest, idCacheSize = size} = do
sync22 hh Env {runSrc, runDest, idCacheSize = size} = do
tCache <- Cache.semispaceCache size
hCache <- Cache.semispaceCache size
oCache <- Cache.semispaceCache size
cCache <- Cache.semispaceCache size
pure $ Sync (trySync runSrc runDest tCache hCache oCache cCache)
pure $ Sync (trySync hh runSrc runDest tCache hCache oCache cCache)
trySync ::
forall m.
(MonadIO m, MonadError Error m) =>
HashHandle ->
(forall a. Transaction a -> m a) ->
(forall a. Transaction a -> m a) ->
Cache TextId TextId ->
@ -109,7 +112,7 @@ trySync ::
Cache CausalHashId CausalHashId ->
Entity ->
m (TrySyncResult Entity)
trySync runSrc runDest tCache hCache oCache cCache = \case
trySync hh runSrc runDest tCache hCache oCache cCache = \case
-- for causals, we need to get the value_hash_id of the thingo
-- - maybe enqueue their parents
-- - enqueue the self_ and value_ hashes
@ -126,7 +129,7 @@ trySync runSrc runDest tCache hCache oCache cCache = \case
parents' :: [CausalHashId] <- findParents' chId
bhId' <- lift $ syncBranchHashId bhId
chId' <- lift $ syncCausalHashId chId
lift (runDest (Q.saveCausal chId' bhId' parents'))
lift (runDest (Q.saveCausal hh chId' bhId' parents'))
case result of
Left deps -> pure . Sync.Missing $ toList deps
@ -164,7 +167,7 @@ trySync runSrc runDest tCache hCache oCache cCache = \case
. TermFormat.SyncLocallyIndexedComponent
$ Vector.zip localIds' bytes
lift do
oId' <- runDest $ Q.saveObject hId' objType bytes'
oId' <- runDest $ Q.saveObject hh hId' objType bytes'
-- copy reference-specific stuff
for_ [0 .. length localIds - 1] \(fromIntegral -> idx) -> do
let ref = Reference.Id oId idx
@ -197,7 +200,7 @@ trySync runSrc runDest tCache hCache oCache cCache = \case
. DeclFormat.SyncLocallyIndexedComponent
$ Vector.zip localIds' declBytes
lift do
oId' <- runDest $ Q.saveObject hId' objType bytes'
oId' <- runDest $ Q.saveObject hh hId' objType bytes'
-- copy per-element-of-the-component stuff
for_ [0 .. length localIds - 1] \(fromIntegral -> idx) -> do
let ref = Reference.Id oId idx
@ -210,26 +213,26 @@ trySync runSrc runDest tCache hCache oCache cCache = \case
Right (BL.SyncFull ids body) -> do
ids' <- syncBranchLocalIds ids
let bytes' = runPutS $ S.recomposeBranchFormat (BL.SyncFull ids' body)
oId' <- lift . runDest $ Q.saveObject hId' objType bytes'
oId' <- lift . runDest $ Q.saveObject hh hId' objType bytes'
pure oId'
Right (BL.SyncDiff boId ids body) -> do
boId' <- syncBranchObjectId boId
ids' <- syncBranchLocalIds ids
let bytes' = runPutS $ S.recomposeBranchFormat (BL.SyncDiff boId' ids' body)
oId' <- lift . runDest $ Q.saveObject hId' objType bytes'
oId' <- lift . runDest $ Q.saveObject hh hId' objType bytes'
pure oId'
Left s -> throwError $ DecodeError ErrBranchFormat bytes s
OT.Patch -> case flip runGetS bytes S.decomposePatchFormat of
Right (PL.SyncFull ids body) -> do
ids' <- syncPatchLocalIds ids
let bytes' = runPutS $ S.recomposePatchFormat (PL.SyncFull ids' body)
oId' <- lift . runDest $ Q.saveObject hId' objType bytes'
oId' <- lift . runDest $ Q.saveObject hh hId' objType bytes'
pure oId'
Right (PL.SyncDiff poId ids body) -> do
poId' <- syncPatchObjectId poId
ids' <- syncPatchLocalIds ids
let bytes' = runPutS $ S.recomposePatchFormat (PL.SyncDiff poId' ids' body)
oId' <- lift . runDest $ Q.saveObject hId' objType bytes'
oId' <- lift . runDest $ Q.saveObject hh hId' objType bytes'
pure oId'
Left s -> throwError $ DecodeError ErrPatchFormat bytes s
case result of

View File

@ -38,8 +38,8 @@ type TypeLink = TypeRef
-- * The term's type, also with internal references to local id.
type LocallyIndexedComponent = LocallyIndexedComponent' TextId ObjectId
newtype LocallyIndexedComponent' t d
= LocallyIndexedComponent (Vector (LocalIds' t d, Term, Type))
newtype LocallyIndexedComponent' t d = LocallyIndexedComponent
{unLocallyIndexedComponent :: Vector (LocalIds' t d, Term, Type)}
deriving (Show)
newtype SyncLocallyIndexedComponent' t d

View File

@ -1,6 +1,6 @@
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.34.7.
--
-- see: https://github.com/sol/hpack
@ -27,6 +27,7 @@ library
U.Codebase.Sqlite.Decl.Format
U.Codebase.Sqlite.Decode
U.Codebase.Sqlite.Entity
U.Codebase.Sqlite.HashHandle
U.Codebase.Sqlite.LocalIds
U.Codebase.Sqlite.LocalizeObject
U.Codebase.Sqlite.NamedRef

View File

@ -102,6 +102,7 @@ dependencies:
- unicode-show
- unison-codebase
- unison-codebase-sqlite
- unison-codebase-sqlite-hashing-v2
- unison-codebase-sync
- unison-core
- unison-core1

View File

@ -32,6 +32,7 @@ import U.Codebase.HashTags (CausalHash (CausalHash))
import qualified U.Codebase.Sqlite.Operations as Ops
import qualified U.Codebase.Sqlite.Queries as Q
import qualified U.Codebase.Sqlite.Sync22 as Sync22
import U.Codebase.Sqlite.V2.HashHandle (v2HashHandle)
import qualified U.Codebase.Sync as Sync
import qualified U.Util.Cache as Cache
import qualified U.Util.Hash as H2
@ -138,7 +139,7 @@ createCodebaseOrError debugName path action = do
Sqlite.trySetJournalMode conn Sqlite.JournalMode'WAL
Sqlite.runTransaction conn do
Q.createSchema
void . Ops.saveRootBranch $ Cv.causalbranch1to2 Branch.empty
void . Ops.saveRootBranch v2HashHandle $ Cv.causalbranch1to2 Branch.empty
sqliteCodebase debugName path Local action >>= \case
Left schemaVersion -> error ("Failed to open codebase with schema version: " ++ show schemaVersion ++ ", which is unexpected because I just created this codebase.")
@ -526,7 +527,7 @@ syncInternal progress runSrc runDest b = time "syncInternal" do
-- or if it exists in the source codebase, then we can sync22 it
-- if it doesn't exist in the dest or source branch,
-- then just use putBranch to the dest
sync <- liftIO (Sync22.sync22 (Sync22.hoistEnv lift syncEnv))
sync <- liftIO (Sync22.sync22 v2HashHandle (Sync22.hoistEnv lift syncEnv))
let doSync :: [Sync22.Entity] -> m ()
doSync =
throwExceptT

View File

@ -50,6 +50,7 @@ import qualified U.Codebase.Sqlite.Patch.Full as S
import qualified U.Codebase.Sqlite.Patch.TermEdit as TermEdit
import qualified U.Codebase.Sqlite.Patch.TypeEdit as TypeEdit
import qualified U.Codebase.Sqlite.Queries as Q
import U.Codebase.Sqlite.V2.HashHandle (v2HashHandle)
import U.Codebase.Sync (Sync (Sync))
import qualified U.Codebase.Sync as Sync
import U.Codebase.WatchKind (WatchKind)
@ -257,6 +258,7 @@ migrateCausal oldCausalHashId = fmap (either id id) . runExceptT $ do
}
(lift . lift) do
Q.saveCausal
v2HashHandle
(SC.DbCausal.selfHash newCausal)
(SC.DbCausal.valueHash newCausal)
(Set.toList $ SC.DbCausal.parents newCausal)
@ -335,7 +337,7 @@ migrateBranch oldObjectId = fmap (either id id) . runExceptT $ do
newHash <- lift . lift $ Hashing.dbBranchHash newBranch
newHashId <- lift . lift $ Q.saveBranchHash (coerce Cv.hash1to2 newHash)
newObjectId <- lift . lift $ Ops.saveDbBranchUnderHashId newHashId newBranch
newObjectId <- lift . lift $ Ops.saveDbBranchUnderHashId v2HashHandle newHashId newBranch
field @"objLookup"
%= Map.insert
oldObjectId
@ -398,6 +400,7 @@ migratePatch oldObjectId = fmap (either id id) . runExceptT $ do
newObjectId <-
lift . lift $
Ops.saveDbPatch
v2HashHandle
(coerce Cv.hash1to2 newHash)
(S.Patch.Format.Full localPatchIds localPatch)
newHashId <- lift . lift $ Q.expectHashIdByHash (coerce Cv.hash1to2 newHash)
@ -868,5 +871,5 @@ saveV2EmptyBranch = do
let branch = S.emptyBranch
newHash <- Hashing.dbBranchHash branch
newHashId <- Q.saveBranchHash (coerce Cv.hash1to2 newHash)
_ <- Ops.saveDbBranchUnderHashId newHashId branch
_ <- Ops.saveDbBranchUnderHashId v2HashHandle newHashId branch
pure (newHashId, newHash)

View File

@ -23,6 +23,9 @@ import qualified U.Codebase.Sqlite.NamedRef as S
import qualified U.Codebase.Sqlite.ObjectType as OT
import qualified U.Codebase.Sqlite.Operations as Ops
import qualified U.Codebase.Sqlite.Queries as Q
import U.Codebase.Sqlite.V2.Decl (saveDeclComponent)
import U.Codebase.Sqlite.V2.HashHandle (v2HashHandle)
import U.Codebase.Sqlite.V2.Term (saveTermComponent)
import qualified U.Util.Cache as Cache
import qualified U.Util.Hash as H2
import qualified Unison.Builtin as Builtins
@ -267,24 +270,17 @@ tryFlushTermBuffer termBuffer =
let loop h =
tryFlushBuffer
termBuffer
( \h2 component -> do
oId <-
Ops.saveTermComponent h2 $
fmap (bimap (Cv.term1to2 h) Cv.ttype1to2) component
addTermComponentTypeIndex oId (fmap snd component)
( \h2 component ->
void $
saveTermComponent
Nothing
h2
(fmap (bimap (Cv.term1to2 h) Cv.ttype1to2) component)
)
loop
h
in loop
addTermComponentTypeIndex :: ObjectId -> [Type Symbol Ann] -> Transaction ()
addTermComponentTypeIndex oId types = for_ (types `zip` [0 ..]) \(tp, i) -> do
let self = C.Referent.RefId (C.Reference.Id oId i)
typeForIndexing = Hashing.typeToReference tp
typeMentionsForIndexing = Hashing.typeToReferenceMentions tp
Ops.addTypeToIndexForTerm self (Cv.reference1to2 typeForIndexing)
Ops.addTypeMentionsToIndexForTerm self (Set.map Cv.reference1to2 typeMentionsForIndexing)
addDeclComponentTypeIndex :: ObjectId -> [[Type Symbol Ann]] -> Transaction ()
addDeclComponentTypeIndex oId ctorss =
for_ (ctorss `zip` [0 ..]) \(ctors, i) ->
@ -329,10 +325,12 @@ tryFlushDeclBuffer termBuffer declBuffer =
let loop h =
tryFlushBuffer
declBuffer
( \h2 component -> do
oId <- Ops.saveDeclComponent h2 $ fmap (Cv.decl1to2 h) component
addDeclComponentTypeIndex oId $
fmap (map snd . Decl.constructors . Decl.asDataDecl) component
( \h2 component ->
void $
saveDeclComponent
Nothing
h2
(fmap (Cv.decl1to2 h) component)
)
(\h -> tryFlushTermBuffer termBuffer h >> loop h)
h
@ -382,7 +380,7 @@ putRootBranch :: TVar (Maybe (Sqlite.DataVersion, Branch Transaction)) -> Branch
putRootBranch rootBranchCache branch1 = do
-- todo: check to see if root namespace hash has been externally modified
-- and do something (merge?) it if necessary. But for now, we just overwrite it.
void (Ops.saveRootBranch (Cv.causalbranch1to2 branch1))
void (Ops.saveRootBranch v2HashHandle (Cv.causalbranch1to2 branch1))
Sqlite.unsafeIO (atomically $ modifyTVar' rootBranchCache (fmap . second $ const branch1))
-- if this blows up on cromulent hashes, then switch from `hashToHashId`
@ -401,7 +399,7 @@ getBranchForHash doGetDeclType h = do
putBranch :: Branch Transaction -> Transaction ()
putBranch =
void . Ops.saveBranch . Cv.causalbranch1to2
void . Ops.saveBranch v2HashHandle . Cv.causalbranch1to2
isCausalHash :: Branch.CausalHash -> Transaction Bool
isCausalHash (Causal.CausalHash h) =
@ -418,7 +416,7 @@ getPatch h =
putPatch :: Branch.EditHash -> Patch -> Transaction ()
putPatch h p =
void $ Ops.savePatch (Cv.patchHash1to2 h) (Cv.patch1to2 p)
void $ Ops.savePatch v2HashHandle (Cv.patchHash1to2 h) (Cv.patch1to2 p)
patchExists :: Branch.EditHash -> Transaction Bool
patchExists h = fmap isJust $ Q.loadPatchObjectIdForPrimaryHash (Cv.patchHash1to2 h)

View File

@ -88,7 +88,6 @@ library
Unison.FileParser
Unison.FileParsers
Unison.Hashing.V2.Convert
Unison.Hashing.V2.Convert2
Unison.Lexer
Unison.NamePrinter
Unison.Parser
@ -269,6 +268,7 @@ library
, unicode-show
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-codebase-sync
, unison-core
, unison-core1
@ -450,6 +450,7 @@ test-suite parser-typechecker-tests
, unicode-show
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-codebase-sync
, unison-core
, unison-core1

View File

@ -18,6 +18,7 @@ packages:
- unison-share-api
- codebase2/codebase
- codebase2/codebase-sqlite
- codebase2/codebase-sqlite-hashing-v2
- codebase2/codebase-sync
- codebase2/core
- codebase2/util

View File

@ -53,6 +53,7 @@ dependencies:
- transformers
- unison-codebase
- unison-codebase-sqlite
- unison-codebase-sqlite-hashing-v2
- unison-sqlite
- unison-core1
- unison-parser-typechecker

View File

@ -43,6 +43,7 @@ import Servant.Client (BaseUrl)
import qualified Servant.Client as Servant (ClientEnv (..), ClientM, client, defaultMakeClientRequest, hoistClient, mkClientEnv, runClientM)
import U.Codebase.HashTags (CausalHash)
import qualified U.Codebase.Sqlite.Queries as Q
import U.Codebase.Sqlite.V2.SyncEntity (saveSyncEntity)
import U.Util.Hash32 (Hash32)
import Unison.Auth.HTTPClient (AuthenticatedHttpClient)
import qualified Unison.Auth.HTTPClient as Auth

View File

@ -1,6 +1,6 @@
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.34.7.
--
-- see: https://github.com/sol/hpack
@ -136,6 +136,7 @@ library
, transformers
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-core1
, unison-parser-typechecker
, unison-prelude
@ -238,6 +239,7 @@ executable cli-integration-tests
, transformers
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-core1
, unison-parser-typechecker
, unison-prelude
@ -334,6 +336,7 @@ executable transcripts
, unison-cli
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-core1
, unison-parser-typechecker
, unison-prelude
@ -435,6 +438,7 @@ executable unison
, unison-cli
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-core1
, unison-parser-typechecker
, unison-prelude
@ -540,6 +544,7 @@ test-suite cli-tests
, unison-cli
, unison-codebase
, unison-codebase-sqlite
, unison-codebase-sqlite-hashing-v2
, unison-core1
, unison-parser-typechecker
, unison-prelude

View File

@ -26,6 +26,7 @@ library:
- safe
- text
- transformers
- unison-core
- unison-prelude
- unison-util
- unison-util-base32hex

View File

@ -319,17 +319,17 @@ renames rn0 t0@(Term fvs ann t)
| Map.null rn = t0
| Var v <- t,
Just u <- Map.lookup v rn =
annotatedVar ann u
annotatedVar ann u
| Cycle body <- t =
cycle' ann (renames rn body)
cycle' ann (renames rn body)
| Abs v t <- t,
-- rename iterated variables all at once to avoid a capture issue
AbsNA' (unzip -> (as, vs)) body <- t,
(rn, us) <- mangle (freeVars body) rn (v : vs),
not $ Map.null rn =
absChain' (zip (ann : as) us) (renames rn body)
absChain' (zip (ann : as) us) (renames rn body)
| Tm body <- t =
tm' ann (renames rn <$> body)
tm' ann (renames rn <$> body)
| otherwise = t0
where
rn = Map.restrictKeys rn0 fvs
@ -339,7 +339,7 @@ renames rn0 t0@(Term fvs ann t)
mangle1 avs m v
| any (== v) vs,
u <- freshIn (avs <> Set.fromList vs) v =
(Map.insert v u m, u)
(Map.insert v u m, u)
| otherwise = (Map.delete v m, v)
where
vs = toList m
@ -403,20 +403,20 @@ subst' :: (Foldable f, Functor f, Var v) => (a -> Term f v a) -> v -> Set v -> T
subst' replace v r t2@(Term fvs ann body)
| Set.notMember v fvs = t2 -- subtrees not containing the var can be skipped
| otherwise = case body of
Var v'
| v == v' -> replace ann -- var match; perform replacement
| otherwise -> t2 -- var did not match one being substituted; ignore
Cycle body -> cycle' ann (subst' replace v r body)
Abs x _ | x == v -> t2 -- x shadows v; ignore subtree
Abs x e -> abs' ann x' e'
where
x' = freshIn (fvs `Set.union` r) x
-- rename x to something that cannot be captured by `r`
e' =
if x /= x'
then subst' replace v r (rename x x' e)
else subst' replace v r e
Tm body -> tm' ann (fmap (subst' replace v r) body)
Var v'
| v == v' -> replace ann -- var match; perform replacement
| otherwise -> t2 -- var did not match one being substituted; ignore
Cycle body -> cycle' ann (subst' replace v r body)
Abs x _ | x == v -> t2 -- x shadows v; ignore subtree
Abs x e -> abs' ann x' e'
where
x' = freshIn (fvs `Set.union` r) x
-- rename x to something that cannot be captured by `r`
e' =
if x /= x'
then subst' replace v r (rename x x' e)
else subst' replace v r e
Tm body -> tm' ann (fmap (subst' replace v r) body)
-- Like `subst`, but the annotation of the replacement is inherited from
-- the previous annotation at each replacement point.

View File

@ -1,6 +1,6 @@
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.34.7.
--
-- see: https://github.com/sol/hpack
@ -100,6 +100,7 @@ library
, safe
, text
, transformers
, unison-core
, unison-prelude
, unison-util
, unison-util-base32hex

View File

@ -121,13 +121,13 @@ unforall' :: Type v a -> ([v], Type v a)
unforall' (ForallsNamed' vs t) = (vs, t)
unforall' t = ([], t)
toReference :: (ABT.Var v, Show v) => Type v a -> Reference
toReference :: (Ord v, Show v) => Type v a -> Reference
toReference (Ref' r) = r
-- a bit of normalization - any unused type parameters aren't part of the hash
toReference (ForallNamed' v body) | not (Set.member v (ABT.freeVars body)) = toReference body
toReference t = Reference.Derived (ABT.hash t) 0
toReferenceMentions :: (ABT.Var v, Show v) => Type v a -> Set Reference
toReferenceMentions :: (Ord v, Show v) => Type v a -> Set Reference
toReferenceMentions ty =
let (vs, _) = unforall' ty
gen ty = generalize (Set.toList (freeVars ty)) $ generalize vs ty