Skip to content

Commit 2ac3e3b

Browse files
committed
SyncV2 WIP
1 parent f6bb8c2 commit 2ac3e3b

File tree

14 files changed

+216
-173
lines changed

14 files changed

+216
-173
lines changed

share-api.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ library
154154
Share.Web.UCM.Sync.Impl
155155
Share.Web.UCM.Sync.Types
156156
Share.Web.UCM.SyncStream.API
157+
Share.Web.UCM.SyncStream.Impl
157158
Share.Web.UCM.SyncStream.Queries
158159
Unison.PrettyPrintEnvDecl.Postgres
159160
Unison.Server.NameSearch.Postgres

src/Share/Postgres.hs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ module Share.Postgres
1919
Interp.DecodeValue (..),
2020
Interp.DecodeRow (..),
2121
Interp.DecodeField,
22-
RawBytes (..),
2322
Only (..),
2423
QueryA (..),
2524
QueryM (..),
@@ -469,17 +468,6 @@ cachedForOf trav s f = do
469468
cachedFor :: (Traversable t, Monad m, Ord a) => t a -> (a -> m b) -> m (t b)
470469
cachedFor = cachedForOf traversed
471470

472-
-- | Preferably you should use custom newtypes for your bytes, but you can use this with
473-
-- deriving via to get the encoding/decoding instances.
474-
newtype RawBytes = RawBytes {unRawBytes :: ByteString}
475-
deriving stock (Show, Eq, Ord)
476-
477-
instance Interp.EncodeValue RawBytes where
478-
encodeValue = contramap unRawBytes Encoders.bytea
479-
480-
instance Interp.DecodeValue RawBytes where
481-
decodeValue = RawBytes <$> Decoders.bytea
482-
483471
-- | Useful when running queries using a join over `toTable` which may be empty.
484472
-- Without explicitly handling the empty case we'll waste time sending a query to PG
485473
-- that we know can't return any results.

src/Share/Postgres/Definitions/Queries.hs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Data.Set qualified as Set
3939
import Data.Text qualified as Text
4040
import Data.Vector (Vector)
4141
import Data.Vector qualified as Vector
42+
import Servant (err500)
4243
import Share.Codebase.Types (CodebaseEnv (..), CodebaseM)
4344
import Share.IDs
4445
import Share.Postgres
@@ -49,9 +50,8 @@ import Share.Postgres.Hashes.Queries qualified as HashQ
4950
import Share.Postgres.IDs
5051
import Share.Prelude
5152
import Share.Utils.Logging qualified as Logging
52-
import Share.Utils.Postgres (OrdBy)
53+
import Share.Utils.Postgres (OrdBy, RawBytes (..))
5354
import Share.Web.Errors (ErrorID (..), InternalServerError (InternalServerError), ToServerError (..))
54-
import Servant (err500)
5555
import U.Codebase.Decl qualified as Decl
5656
import U.Codebase.Decl qualified as V2 hiding (Type)
5757
import U.Codebase.Decl qualified as V2Decl
@@ -270,7 +270,7 @@ expectTypeComponent componentRef = do
270270

271271
-- | This isn't in CodebaseM so that we can run it in a normal transaction to build the Code
272272
-- Lookup.
273-
loadTermById :: QueryM m => UserId -> TermId -> m (Maybe (V2.Term Symbol, V2.Type Symbol))
273+
loadTermById :: (QueryM m) => UserId -> TermId -> m (Maybe (V2.Term Symbol, V2.Type Symbol))
274274
loadTermById codebaseUser termId = runMaybeT $ do
275275
(TermComponentElement trm typ) <-
276276
MaybeT $
@@ -288,7 +288,7 @@ loadTermById codebaseUser termId = runMaybeT $ do
288288
localIds = LocalIds.LocalIds {textLookup = Vector.fromList textLookup, defnLookup = Vector.fromList defnLookup}
289289
pure $ s2cTermWithType (localIds, trm, typ)
290290

291-
termLocalTextReferences :: QueryM m => TermId -> m [Text]
291+
termLocalTextReferences :: (QueryM m) => TermId -> m [Text]
292292
termLocalTextReferences termId =
293293
queryListCol
294294
[sql|
@@ -299,7 +299,7 @@ termLocalTextReferences termId =
299299
ORDER BY local_index ASC
300300
|]
301301

302-
termLocalComponentReferences :: QueryM m => TermId -> m [ComponentHash]
302+
termLocalComponentReferences :: (QueryM m) => TermId -> m [ComponentHash]
303303
termLocalComponentReferences termId =
304304
queryListCol
305305
[sql|
@@ -342,10 +342,10 @@ resolveConstructorTypeLocalIds (LocalIds.LocalIds {textLookup, defnLookup}) =
342342
substText i = textLookup ^?! ix (fromIntegral i)
343343
substHash i = unComponentHash $ (defnLookup ^?! ix (fromIntegral i))
344344

345-
loadDeclKind :: PG.QueryM m => Reference.Id -> m (Maybe CT.ConstructorType)
345+
loadDeclKind :: (PG.QueryM m) => Reference.Id -> m (Maybe CT.ConstructorType)
346346
loadDeclKind = loadDeclKindsOf id
347347

348-
loadDeclKindsOf :: PG.QueryM m => Traversal s t Reference.Id (Maybe CT.ConstructorType) -> s -> m t
348+
loadDeclKindsOf :: (PG.QueryM m) => Traversal s t Reference.Id (Maybe CT.ConstructorType) -> s -> m t
349349
loadDeclKindsOf trav s =
350350
s
351351
& unsafePartsOf trav %%~ \refIds -> do
@@ -517,7 +517,7 @@ constructorReferentsByPrefix prefix mayComponentIndex mayConstructorIndex = do
517517
--
518518
-- This is intentionally not in CodebaseM because this method is used to build the
519519
-- CodebaseEnv.
520-
loadCachedEvalResult :: QueryM m => UserId -> Reference.Id -> m (Maybe (V2.Term Symbol))
520+
loadCachedEvalResult :: (QueryM m) => UserId -> Reference.Id -> m (Maybe (V2.Term Symbol))
521521
loadCachedEvalResult codebaseOwnerUserId (Reference.Id hash compIndex) = runMaybeT do
522522
let compIndex' = pgComponentIndex compIndex
523523
(evalResultId :: EvalResultId, EvalResultTerm term) <-
@@ -557,12 +557,12 @@ loadCachedEvalResult codebaseOwnerUserId (Reference.Id hash compIndex) = runMayb
557557
pure $ resolveTermLocalIds localIds term
558558

559559
-- | Get text ids for all provided texts, inserting any that don't already exist.
560-
ensureTextIds :: QueryM m => Traversable t => t Text -> m (t TextId)
560+
ensureTextIds :: (QueryM m) => (Traversable t) => t Text -> m (t TextId)
561561
ensureTextIds = ensureTextIdsOf traversed
562562

563563
-- | Efficiently saves all Text's focused by the provided traversal into the database and
564564
-- replaces them with their corresponding Ids.
565-
ensureTextIdsOf :: QueryM m => Traversal s t Text TextId -> s -> m t
565+
ensureTextIdsOf :: (QueryM m) => Traversal s t Text TextId -> s -> m t
566566
ensureTextIdsOf trav s = do
567567
s
568568
& unsafePartsOf trav %%~ \texts -> do
@@ -589,12 +589,12 @@ ensureTextIdsOf trav s = do
589589
else pure results
590590

591591
-- | Get text ids for all provided texts, inserting any that don't already exist.
592-
ensureBytesIds :: QueryM m => Traversable t => t BS.ByteString -> m (t BytesId)
592+
ensureBytesIds :: (QueryM m) => (Traversable t) => t BS.ByteString -> m (t BytesId)
593593
ensureBytesIds = ensureBytesIdsOf traversed
594594

595595
-- | Efficiently saves all Text's focused by the provided traversal into the database and
596596
-- replaces them with their corresponding Ids.
597-
ensureBytesIdsOf :: QueryM m => Traversal s t BS.ByteString BytesId -> s -> m t
597+
ensureBytesIdsOf :: (QueryM m) => Traversal s t BS.ByteString BytesId -> s -> m t
598598
ensureBytesIdsOf trav s = do
599599
s
600600
& unsafePartsOf trav %%~ \bytestrings -> do
@@ -621,7 +621,7 @@ ensureBytesIdsOf trav s = do
621621
else pure results
622622

623623
-- | Efficiently loads Texts for all TextIds focused by the provided traversal.
624-
expectTextsOf :: QueryM m => Traversal s t TextId Text -> s -> m t
624+
expectTextsOf :: (QueryM m) => Traversal s t TextId Text -> s -> m t
625625
expectTextsOf trav =
626626
unsafePartsOf trav %%~ \textIds -> do
627627
let numberedTextIds = zip [0 :: Int32 ..] textIds
@@ -649,7 +649,7 @@ localizeTerm tm = do
649649

650650
-- | Replace all references in a term with local references.
651651
_localizeTermAndType ::
652-
HasCallStack =>
652+
(HasCallStack) =>
653653
V2.Term Symbol ->
654654
V2.Type Symbol ->
655655
Transaction e (PgLocalIds, TermFormat.Term, TermFormat.Type)
@@ -997,7 +997,7 @@ resolveLocalIdsOf trav s = do
997997
>>= HashQ.expectComponentHashesOf (traversed . LocalIds.h_)
998998

999999
-- | Fetch term tags for all the provided Referents.
1000-
termTagsByReferentsOf :: HasCallStack => Traversal s t Referent.Referent Tags.TermTag -> s -> Transaction e t
1000+
termTagsByReferentsOf :: (HasCallStack) => Traversal s t Referent.Referent Tags.TermTag -> s -> Transaction e t
10011001
termTagsByReferentsOf trav s = do
10021002
s
10031003
& unsafePartsOf trav %%~ \refs -> do
@@ -1080,7 +1080,7 @@ termTagsByReferentsOf trav s = do
10801080
(refTagRow Tags.Test Decls.testResultListRef)
10811081
]
10821082

1083-
typeTagsByReferencesOf :: HasCallStack => Traversal s t TypeReference Tags.TypeTag -> s -> Transaction e t
1083+
typeTagsByReferencesOf :: (HasCallStack) => Traversal s t TypeReference Tags.TypeTag -> s -> Transaction e t
10841084
typeTagsByReferencesOf trav s = do
10851085
s
10861086
& unsafePartsOf trav %%~ \refs -> do

src/Share/Postgres/Definitions/Types.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ module Share.Postgres.Definitions.Types
2424
)
2525
where
2626

27-
import Share.Postgres qualified as PG
28-
import Share.Postgres.Serialization qualified as S
29-
import Share.Prelude
3027
import Hasql.Decoders qualified as Decoders
3128
import Hasql.Decoders qualified as Hasql
3229
import Hasql.Encoders qualified as Encoders
3330
import Hasql.Interpolate (DecodeValue (..), EncodeValue (..))
31+
import Share.Postgres.Serialization qualified as S
32+
import Share.Prelude
33+
import Share.Utils.Postgres qualified as PG
3434
import U.Codebase.Decl qualified as DD
3535
import U.Codebase.Decl qualified as Decl
3636
import U.Codebase.Reference qualified as Reference

src/Share/Postgres/Orphans.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Servant (err500)
1818
import Servant.API
1919
import Share.Prelude
2020
import Share.Utils.Logging qualified as Logging
21+
import Share.Utils.Postgres (RawLazyBytes (..))
2122
import Share.Web.Errors (ErrorID (..), ToServerError (..))
2223
import U.Codebase.HashTags (BranchHash (..), CausalHash (..), ComponentHash (..), PatchHash (..))
2324
import U.Codebase.Reference (Id' (Id), Reference' (..))
@@ -34,6 +35,7 @@ import Unison.Hash32 (Hash32)
3435
import Unison.Hash32 qualified as Hash32
3536
import Unison.Name (Name)
3637
import Unison.NameSegment.Internal (NameSegment (..))
38+
import Unison.SyncV2.Types (CBORBytes (..))
3739
import Unison.Syntax.Name qualified as Name
3840

3941
-- Orphans for 'Hash'
@@ -215,6 +217,8 @@ instance Hasql.DecodeValue SqliteTermEdit.Typing where
215217
_ -> Nothing
216218
)
217219

220+
deriving via RawLazyBytes instance Hasql.DecodeValue (CBORBytes t)
221+
218222
instance ToServerError Hasql.SessionError where
219223
toServerError _ = (ErrorID "query-error", err500)
220224

src/Share/Postgres/Sync/Queries.hs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ module Share.Postgres.Sync.Queries
1515
)
1616
where
1717

18-
import Codec.CBOR.Encoding qualified as CBOR
1918
import Codec.CBOR.Write qualified as CBOR
20-
import Codec.Serialise (Serialise (..))
2119
import Codec.Serialise.Class qualified as CBOR
2220
import Control.Lens hiding (from)
2321
import Data.ByteString.Lazy.Char8 qualified as BL
@@ -64,11 +62,11 @@ import U.Codebase.Sqlite.Queries qualified as Share
6462
import U.Codebase.Sqlite.TempEntity (TempEntity)
6563
import U.Codebase.Sqlite.TempEntityType (TempEntityType)
6664
import U.Codebase.Sqlite.Term.Format qualified as TermFormat
67-
import U.Util.Base32Hex (Base32Hex (..))
6865
import Unison.Hash32
6966
import Unison.Hash32 qualified as Hash32
7067
import Unison.Sync.Common qualified as Share
7168
import Unison.Sync.Types qualified as Share
69+
import Unison.SyncV2.Types (EntityKind (..))
7270

7371
data SyncQError
7472
= InvalidNamespaceBytes
@@ -635,4 +633,3 @@ saveSerializedNamespace hash serialised = do
635633
VALUES ((SELECT bh.id FROM branch_hashes bh where bh.base32 = #{hash}), #{bytesId})
636634
ON CONFLICT DO NOTHING
637635
|]
638-

src/Share/Postgres/Sync/Types.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
module Share.Postgres.Sync.Types (TypedTempEntity (..)) where
22

3+
import Hasql.Interpolate qualified as Hasql
34
import Share.Postgres (decodeField)
4-
import Share.Postgres qualified as PG
55
import Share.Postgres.Serialization qualified as S
6-
import Hasql.Interpolate qualified as Hasql
6+
import Share.Utils.Postgres (RawBytes (..))
77
import U.Codebase.Sqlite.TempEntity (TempEntity)
88

99
-- | Helper for deserializing typed temp entities.
@@ -14,7 +14,7 @@ newtype TypedTempEntity = TypedTempEntity {unTypedTempEntity :: TempEntity}
1414
instance Hasql.DecodeRow TypedTempEntity where
1515
decodeRow = do
1616
entityType <- decodeField
17-
PG.RawBytes entityBytes <- decodeField
17+
RawBytes entityBytes <- decodeField
1818
case S.decodeTypedTempEntity entityType entityBytes of
1919
Left err -> fail (show err)
2020
Right tempEntity -> pure (TypedTempEntity tempEntity)

src/Share/Utils/Postgres.hs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
module Share.Utils.Postgres
22
( OrdBy (..),
33
ordered,
4+
RawBytes (..),
5+
RawLazyBytes (..),
46
)
57
where
68

7-
import Share.Postgres qualified as PG
9+
import Data.ByteString.Lazy qualified as BL
10+
import Hasql.Decoders qualified as Decoders
11+
import Hasql.Encoders qualified as Encoders
12+
import Hasql.Interpolate qualified as Hasql
813
import Share.Prelude
914

1015
-- | A type for propagating an application-code ordering through a database query.
1116
-- We can't trust the order returned by PG, so we make sure to order things explicitly.
1217
newtype OrdBy = OrdBy {unOrdBy :: Int32}
1318
deriving stock (Eq, Ord, Show)
14-
deriving (PG.DecodeValue, PG.EncodeValue) via Int32
19+
deriving (Hasql.DecodeValue, Hasql.EncodeValue) via Int32
1520

1621
instance From Int OrdBy where
1722
from = OrdBy . fromIntegral
@@ -21,3 +26,25 @@ instance From Int32 OrdBy where
2126

2227
ordered :: [a] -> [(OrdBy, a)]
2328
ordered = zip (OrdBy <$> [0 ..])
29+
30+
-- | Preferably you should use custom newtypes for your bytes, but you can use this with
31+
-- deriving via to get the encoding/decoding instances.
32+
newtype RawBytes = RawBytes {unRawBytes :: ByteString}
33+
deriving stock (Show, Eq, Ord)
34+
35+
instance Hasql.EncodeValue RawBytes where
36+
encodeValue = contramap unRawBytes Encoders.bytea
37+
38+
instance Hasql.DecodeValue RawBytes where
39+
decodeValue = RawBytes <$> Decoders.bytea
40+
41+
-- | Preferably you should use custom newtypes for your bytes, but you can use this with
42+
-- deriving via to get the encoding/decoding instances.
43+
newtype RawLazyBytes = RawLazyBytes {unLazyRawBytes :: BL.ByteString}
44+
deriving stock (Show, Eq, Ord)
45+
46+
instance Hasql.EncodeValue RawLazyBytes where
47+
encodeValue = contramap (BL.toStrict . unLazyRawBytes) Encoders.bytea
48+
49+
instance Hasql.DecodeValue RawLazyBytes where
50+
decodeValue = RawLazyBytes . BL.fromStrict <$> Decoders.bytea

src/Share/Web/Impl.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Share.Web.Support.Impl qualified as Support
2424
import Share.Web.Types
2525
import Share.Web.UCM.Projects.Impl qualified as UCMProjects
2626
import Share.Web.UCM.Sync.Impl qualified as Sync
27-
import Share.Web.UCM.SyncStream.API qualified as SyncStream
27+
import Share.Web.UCM.SyncStream.Impl qualified as SyncStream
2828

2929
discoveryEndpoint :: WebApp DiscoveryDocument
3030
discoveryEndpoint = do

src/Share/Web/UCM/Sync/Impl.hs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Share.Web.UCM.Sync.Impl
99
-- This export can be removed once we've migrated away from sqlite.
1010
insertEntitiesToCodebase,
1111
ensureCausalIsFlushed,
12+
repoInfoKind,
1213
)
1314
where
1415

@@ -48,7 +49,7 @@ import Share.Web.Authentication qualified as AuthN
4849
import Share.Web.Authorization qualified as AuthZ
4950
import Share.Web.Errors
5051
import Share.Web.UCM.Sync.HashJWT qualified as HashJWT
51-
import Share.Web.UCM.Sync.Types (EntityBunch (..), EntityKind (..), entityKind)
52+
import Share.Web.UCM.Sync.Types (EntityBunch (..), RepoInfoKind (..), entityKind)
5253
import U.Codebase.Causal qualified as Causal
5354
import U.Codebase.Sqlite.Orphans ()
5455
import Unison.Codebase.Path qualified as Path
@@ -63,14 +64,9 @@ import Unison.Sync.EntityValidation qualified as Sync
6364
import Unison.Sync.Types (DownloadEntitiesError (..), DownloadEntitiesRequest (..), DownloadEntitiesResponse (..), GetCausalHashByPathRequest (..), GetCausalHashByPathResponse (..), NeedDependencies (..), RepoInfo (..), UploadEntitiesError (..), UploadEntitiesRequest (..), UploadEntitiesResponse (..))
6465
import Unison.Sync.Types qualified as Share
6566
import Unison.Sync.Types qualified as Sync
67+
import Unison.SyncV2.Types (EntityKind (..))
6668
import UnliftIO qualified
6769

68-
data RepoInfoKind
69-
= RepoInfoUser UserHandle
70-
| RepoInfoProjectBranch ProjectBranchShortHand
71-
| RepoInfoProjectRelease ProjectReleaseShortHand
72-
deriving stock (Show)
73-
7470
-- | Parse a `RepoInfo` into the correct codebase view, e.g.
7571
--
7672
-- >>> repoInfoKind (RepoInfo "@unison")

0 commit comments

Comments
 (0)