diff --git a/codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs b/codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs index 033efb8655..5ae0267130 100644 --- a/codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs +++ b/codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs @@ -145,6 +145,7 @@ module U.Codebase.Sqlite.Queries -- ** remote project branches loadRemoteBranch, ensureRemoteProjectBranch, + setRemoteProjectBranchLastKnownCausalHash, expectRemoteProjectBranchName, setRemoteProjectBranchName, insertBranchRemoteMapping, @@ -256,6 +257,7 @@ module U.Codebase.Sqlite.Queries addCurrentProjectPathTable, addProjectBranchReflogTable, addProjectBranchCausalHashIdColumn, + trackLatestRemoteHead, -- ** schema version currentSchemaVersion, @@ -486,6 +488,10 @@ addProjectBranchCausalHashIdColumn :: Transaction () addProjectBranchCausalHashIdColumn = executeStatements $(embedProjectStringFile "sql/014-add-project-branch-causal-hash-id.sql") +trackLatestRemoteHead :: Transaction () +trackLatestRemoteHead = + executeStatements $(embedProjectStringFile "sql/018-track-latest-remote-head.sql") + schemaVersion :: Transaction SchemaVersion schemaVersion = queryOneCol @@ -4149,7 +4155,8 @@ loadRemoteBranch rpid host rbid = project_id, branch_id, host, - name + name, + last_known_causal_hash FROM remote_project_branch WHERE @@ -4158,28 +4165,46 @@ loadRemoteBranch rpid host rbid = AND host = :host |] -ensureRemoteProjectBranch :: RemoteProjectId -> URI -> RemoteProjectBranchId -> ProjectBranchName -> Transaction () -ensureRemoteProjectBranch rpid host rbid name = +ensureRemoteProjectBranch :: RemoteProjectId -> URI -> RemoteProjectBranchId -> ProjectBranchName -> Maybe CausalHashId -> Transaction () +ensureRemoteProjectBranch rpid host rbid name lastKnownCausalHash = execute [sql| INSERT INTO remote_project_branch ( project_id, host, branch_id, - name) + name, + last_known_head) VALUES ( :rpid, :host, :rbid, - :name) + :name, + :lastKnownCausalHash + ) ON CONFLICT ( project_id, branch_id, host) - -- should this update the name instead? - DO NOTHING + DO UPDATE + SET name = :name, + last_known_causal_hash = :lastKnownCausalHash |] +setRemoteProjectBranchLastKnownCausalHash :: URI -> RemoteProjectId -> RemoteProjectBranchId -> CausalHashId -> Transaction () +setRemoteProjectBranchLastKnownCausalHash host rpid rbid causalHashId = + execute + [sql| + UPDATE + remote_project_branch + SET + last_known_causal_hash = :causalHashId + WHERE + project_id = :rpid + AND branch_id = :rbid + AND host = :host + |] + expectRemoteProjectBranchName :: URI -> RemoteProjectId -> RemoteProjectBranchId -> Transaction ProjectBranchName expectRemoteProjectBranchName host projectId branchId = queryOneCol diff --git a/codebase2/codebase-sqlite/U/Codebase/Sqlite/RemoteProjectBranch.hs b/codebase2/codebase-sqlite/U/Codebase/Sqlite/RemoteProjectBranch.hs index 5e5638c274..6dff479efc 100644 --- a/codebase2/codebase-sqlite/U/Codebase/Sqlite/RemoteProjectBranch.hs +++ b/codebase2/codebase-sqlite/U/Codebase/Sqlite/RemoteProjectBranch.hs @@ -5,7 +5,7 @@ where import Network.URI (URI) import Network.URI.Orphans.Sqlite () -import U.Codebase.Sqlite.DbId (RemoteProjectBranchId, RemoteProjectId) +import U.Codebase.Sqlite.DbId (CausalHashId, RemoteProjectBranchId, RemoteProjectId) import Unison.Core.Orphans.Sqlite () import Unison.Core.Project (ProjectBranchName) import Unison.Prelude @@ -15,7 +15,9 @@ data RemoteProjectBranch = RemoteProjectBranch { projectId :: RemoteProjectId, branchId :: RemoteProjectBranchId, host :: URI, - name :: ProjectBranchName + name :: ProjectBranchName, + -- Note that there's no guarantee that the causals for this hash have been downloaded/synced into the codebase. + lastKnownCausalHash :: CausalHashId } deriving stock (Generic, Show) deriving anyclass (ToRow, FromRow) diff --git a/codebase2/codebase-sqlite/sql/018-track-latest-remote-head.sql b/codebase2/codebase-sqlite/sql/018-track-latest-remote-head.sql new file mode 100644 index 0000000000..cb92fb4eb3 --- /dev/null +++ b/codebase2/codebase-sqlite/sql/018-track-latest-remote-head.sql @@ -0,0 +1,7 @@ +-- Add a field for tracking the latest known causal hash for each remote project branch. +-- It's helpful for when we need to tell Share how much we know about a branch. + +ALTER TABLE remote_project + -- Note that there isn't a guarantee this hash has actually been synced into the codebase. + ADD COLUMN last_known_causal_hash INTEGER NULL REFERENCES hash(id) + ON DELETE SET NULL; diff --git a/codebase2/codebase-sqlite/unison-codebase-sqlite.cabal b/codebase2/codebase-sqlite/unison-codebase-sqlite.cabal index 2641df87cd..b6c881c7c9 100644 --- a/codebase2/codebase-sqlite/unison-codebase-sqlite.cabal +++ b/codebase2/codebase-sqlite/unison-codebase-sqlite.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.36.0. +-- This file has been generated from package.yaml by hpack version 0.37.0. -- -- see: https://github.com/sol/hpack @@ -24,6 +24,7 @@ extra-source-files: sql/012-add-current-project-path-table.sql sql/013-add-project-branch-reflog-table.sql sql/014-add-project-branch-causal-hash-id.sql + sql/018-track-latest-remote-head.sql sql/create.sql source-repository head diff --git a/parser-typechecker/src/Unison/Codebase/SqliteCodebase/Migrations.hs b/parser-typechecker/src/Unison/Codebase/SqliteCodebase/Migrations.hs index 9052e5511a..61ff07d9ff 100644 --- a/parser-typechecker/src/Unison/Codebase/SqliteCodebase/Migrations.hs +++ b/parser-typechecker/src/Unison/Codebase/SqliteCodebase/Migrations.hs @@ -84,7 +84,8 @@ migrations regionVar getDeclType termBuffer declBuffer rootCodebasePath = sqlMigration 14 Q.addSquashResultTable, sqlMigration 15 Q.addSquashResultTableIfNotExists, sqlMigration 16 Q.cdToProjectRoot, - (17 {- This migration takes a raw sqlite connection -}, \conn -> migrateSchema16To17 conn) + (17 {- This migration takes a raw sqlite connection -}, \conn -> migrateSchema16To17 conn), + sqlMigration 18 Q.trackLatestRemoteHead ] where runT :: Sqlite.Transaction () -> Sqlite.Connection -> IO () diff --git a/unison-cli/src/Unison/Cli/Share/Projects.hs b/unison-cli/src/Unison/Cli/Share/Projects.hs index 52fbc56e8e..056e2790c3 100644 --- a/unison-cli/src/Unison/Cli/Share/Projects.hs +++ b/unison-cli/src/Unison/Cli/Share/Projects.hs @@ -49,9 +49,11 @@ import Unison.Codebase.Editor.Output qualified as Output import Unison.Hash32 (Hash32) import Unison.Prelude import Unison.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName) +import Unison.Share.API.Hash qualified as HashJWT import Unison.Share.API.Projects qualified as Share.API import Unison.Share.Codeserver (defaultCodeserver) import Unison.Share.Types (codeserverBaseURL) +import Unison.Sync.Common qualified as Sync -- | Get a project by id. -- @@ -193,14 +195,17 @@ onGotProjectBranch :: Share.API.ProjectBranch -> Cli RemoteProjectBranch onGotProjectBranch branch = do let projectId = RemoteProjectId (branch ^. #projectId) let branchId = RemoteProjectBranchId (branch ^. #branchId) + let causalHash = Sync.hash32ToCausalHash $ HashJWT.hashJWTHash (branch ^. #branchHead) projectName <- validateProjectName (branch ^. #projectName) branchName <- validateBranchName (branch ^. #branchName) Cli.runTransaction do + causalHashId <- Queries.saveCausalHash causalHash Queries.ensureRemoteProjectBranch projectId hardCodedUri branchId branchName + (Just causalHashId) pure RemoteProjectBranch { projectId,