Skip to content

Commit ba18550

Browse files
authored
Merge pull request #5895 from unisonweb/cp/change-comments
Change Comments
2 parents 1cb1120 + 54cfc44 commit ba18550

File tree

23 files changed

+641
-62
lines changed

23 files changed

+641
-62
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module U.Codebase.Config
2+
( AuthorName,
3+
ConfigKey (..),
4+
allKeys,
5+
mkAuthorName,
6+
unAuthorName,
7+
keyToText,
8+
keyFromText,
9+
allKeysText,
10+
)
11+
where
12+
13+
import Data.Text qualified as Text
14+
import Unison.Prelude
15+
import Unison.Sqlite qualified as Sqlite
16+
17+
data ConfigKey = AuthorNameKey
18+
deriving stock (Eq, Enum, Bounded)
19+
20+
instance Show ConfigKey where
21+
show k = Text.unpack . keyToText $ k
22+
23+
allKeys :: [ConfigKey]
24+
allKeys = [minBound .. maxBound]
25+
26+
allKeysText :: [Text]
27+
allKeysText = keyToText <$> allKeys
28+
29+
keyToText :: ConfigKey -> Text
30+
keyToText = \case
31+
AuthorNameKey -> "author.name"
32+
33+
keyFromText :: Text -> Maybe ConfigKey
34+
keyFromText t = case t of
35+
"author.name" -> Just AuthorNameKey
36+
_ -> Nothing
37+
38+
instance Sqlite.ToField ConfigKey where
39+
toField AuthorNameKey = Sqlite.toField (keyToText AuthorNameKey)
40+
41+
mkAuthorName :: Text -> Either Text AuthorName
42+
mkAuthorName name
43+
| Text.null (Text.strip name) = Left "Author name cannot be empty."
44+
| Text.length name > 100 = Left "Author name cannot exceed 100 characters."
45+
| otherwise = Right (AuthorName name)
46+
47+
newtype AuthorName = AuthorName {unAuthorName :: Text}
48+
deriving stock (Eq, Show)
49+
deriving newtype (Sqlite.ToField, Sqlite.FromField)

codebase2/codebase-sqlite/U/Codebase/Sqlite/DbId.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ instance Show BranchHashId where
6666

6767
instance Show CausalHashId where
6868
show h = "CausalHashId (" ++ show (unCausalHashId h) ++ ")"
69+
70+
newtype HistoryCommentId = HistoryCommentId Word64
71+
deriving (Eq, Ord, Show)
72+
deriving (Num, Real, Enum, Integral, Bits, FromField, ToField) via Word64
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module U.Codebase.Sqlite.HistoryComment (HistoryComment (..)) where
2+
3+
import Data.Text (Text)
4+
5+
data HistoryComment causal id = HistoryComment
6+
{ author :: Text,
7+
subject :: Text,
8+
content :: Text,
9+
causal :: causal,
10+
commentId :: id
11+
}
12+
deriving (Show, Eq, Functor)

codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ module U.Codebase.Sqlite.Queries
233233
expectCurrentProjectPath,
234234
setCurrentProjectPath,
235235

236+
-- * History Comments
237+
commentOnCausal,
238+
getLatestCausalComment,
239+
236240
-- * migrations
237241
runCreateSql,
238242
addTempEntityTables,
@@ -254,6 +258,7 @@ module U.Codebase.Sqlite.Queries
254258
addUpdateBranchTable,
255259
addDerivedDependentsByDependencyIndex,
256260
addUpgradeBranchTable,
261+
addHistoryComments,
257262

258263
-- ** schema version
259264
currentSchemaVersion,
@@ -284,6 +289,12 @@ module U.Codebase.Sqlite.Queries
284289
x2cDecl,
285290
checkBranchExistsForCausalHash,
286291

292+
-- * Config
293+
getAuthorName,
294+
setAuthorName,
295+
getConfigValue,
296+
setConfigValue,
297+
287298
-- * Types
288299
TextPathSegments,
289300
JsonParseFailure (..),
@@ -319,6 +330,8 @@ import Data.Time qualified as Time
319330
import Data.Vector qualified as Vector
320331
import Network.URI (URI)
321332
import U.Codebase.Branch.Type (NamespaceStats (..))
333+
import U.Codebase.Config (AuthorName, ConfigKey)
334+
import U.Codebase.Config qualified as Config
322335
import U.Codebase.Decl qualified as C
323336
import U.Codebase.Decl qualified as C.Decl
324337
import U.Codebase.HashTags (BranchHash (..), CausalHash (..), PatchHash (..))
@@ -336,6 +349,7 @@ import U.Codebase.Sqlite.DbId
336349
CausalHashId (..),
337350
HashId (..),
338351
HashVersion,
352+
HistoryCommentId,
339353
ObjectId (..),
340354
PatchObjectId (..),
341355
ProjectBranchId (..),
@@ -351,6 +365,7 @@ import U.Codebase.Sqlite.Decode
351365
import U.Codebase.Sqlite.Entity (SyncEntity)
352366
import U.Codebase.Sqlite.Entity qualified as Entity
353367
import U.Codebase.Sqlite.HashHandle (HashHandle (..))
368+
import U.Codebase.Sqlite.HistoryComment (HistoryComment (..))
354369
import U.Codebase.Sqlite.LocalIds
355370
( LocalDefnId (..),
356371
LocalIds,
@@ -413,7 +428,7 @@ type TextPathSegments = [Text]
413428
-- * main squeeze
414429

415430
currentSchemaVersion :: SchemaVersion
416-
currentSchemaVersion = 22
431+
currentSchemaVersion = 23
417432

418433
runCreateSql :: Transaction ()
419434
runCreateSql =
@@ -499,6 +514,10 @@ addUpgradeBranchTable :: Transaction ()
499514
addUpgradeBranchTable =
500515
executeStatements $(embedProjectStringFile "sql/019-add-upgrade-branch-table.sql")
501516

517+
addHistoryComments :: Transaction ()
518+
addHistoryComments =
519+
executeStatements $(embedProjectStringFile "sql/020-add-history-comments.sql")
520+
502521
schemaVersion :: Transaction SchemaVersion
503522
schemaVersion =
504523
queryOneCol
@@ -4022,3 +4041,73 @@ saveSquashResult bhId chId =
40224041
)
40234042
ON CONFLICT DO NOTHING
40244043
|]
4044+
4045+
getLatestCausalComment ::
4046+
CausalHashId ->
4047+
Transaction (Maybe (HistoryComment CausalHashId HistoryCommentId))
4048+
getLatestCausalComment causalHashId =
4049+
queryMaybeRow @(HistoryCommentId, CausalHashId, Text, Text, Text)
4050+
[sql|
4051+
SELECT cc.id, cc.causal_hash_id, cc.author, ccr.subject, ccr.contents
4052+
FROM history_comments AS cc
4053+
JOIN history_comment_revisions AS ccr ON cc.id = ccr.comment_id
4054+
WHERE cc.causal_hash_id = :causalHashId
4055+
ORDER BY ccr.created_at DESC
4056+
LIMIT 1
4057+
|]
4058+
<&> fmap \(commentId, causal, author, subject, content) ->
4059+
HistoryComment {author, subject, content, commentId, causal}
4060+
4061+
commentOnCausal :: HistoryComment CausalHashId () -> Transaction ()
4062+
commentOnCausal HistoryComment {author, content, subject, causal = causalHashId} = do
4063+
mayExistingCommentId <-
4064+
queryMaybeCol @HistoryCommentId
4065+
[sql|
4066+
SELECT id
4067+
FROM history_comments
4068+
WHERE causal_hash_id = :causalHashId
4069+
|]
4070+
commentId <- case mayExistingCommentId of
4071+
Nothing ->
4072+
queryOneCol @HistoryCommentId
4073+
[sql|
4074+
INSERT INTO history_comments (author, causal_hash_id, created_at)
4075+
VALUES (:author, :causalHashId, strftime('%s', 'now', 'subsec'))
4076+
RETURNING id
4077+
|]
4078+
Just cid -> pure cid
4079+
execute
4080+
[sql|
4081+
INSERT INTO history_comment_revisions (comment_id, subject, contents, created_at)
4082+
VALUES (:commentId, :subject, :content, strftime('%s', 'now', 'subsec'))
4083+
|]
4084+
4085+
getAuthorName :: Transaction (Maybe AuthorName)
4086+
getAuthorName = do
4087+
r <- getConfigValue Config.AuthorNameKey <&> fmap Config.mkAuthorName
4088+
case r of
4089+
Just (Left err) -> error $ "getAuthorName: " <> Text.unpack err
4090+
Just (Right authorName) -> pure (Just authorName)
4091+
Nothing -> pure Nothing
4092+
4093+
setAuthorName :: AuthorName -> Transaction ()
4094+
setAuthorName authorName =
4095+
setConfigValue Config.AuthorNameKey (Config.unAuthorName authorName)
4096+
4097+
setConfigValue :: ConfigKey -> Text -> Transaction ()
4098+
setConfigValue key value =
4099+
execute
4100+
[sql|
4101+
INSERT INTO config (key, value)
4102+
VALUES (:key, :value)
4103+
ON CONFLICT (key) DO UPDATE SET value = excluded.value
4104+
|]
4105+
4106+
getConfigValue :: ConfigKey -> Transaction (Maybe Text)
4107+
getConfigValue key =
4108+
queryMaybeCol
4109+
[sql|
4110+
SELECT value
4111+
FROM config
4112+
WHERE key = :key
4113+
|]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
-- A simple table for storing user preferences as key/value pairs.
2+
CREATE TABLE config (
3+
key TEXT NOT NULL PRIMARY KEY,
4+
value TEXT NOT NULL
5+
);
6+
7+
-- Add tables for storing history comments
8+
-- These tables deliberately contain less information than we'll probably need, with the
9+
-- plan that we'll migrate them and add new features on the way.
10+
11+
CREATE TABLE history_comments (
12+
id INTEGER PRIMARY KEY,
13+
causal_hash_id INTEGER REFERENCES hash(id) NOT NULL,
14+
author TEXT NOT NULL,
15+
16+
-- Remember that SQLITE doesn't have any actual 'time' type,
17+
-- This column contains float values constructed
18+
-- using strftime('%s', 'now', 'subsec')
19+
created_at TEXT NOT NULL
20+
);
21+
22+
CREATE INDEX history_comments_by_causal_hash_id ON history_comments(causal_hash_id, created_at DESC);
23+
24+
CREATE TABLE history_comment_revisions (
25+
id INTEGER PRIMARY KEY,
26+
comment_id INTEGER REFERENCES history_comments(id),
27+
subject TEXT NOT NULL,
28+
contents TEXT NOT NULL,
29+
30+
-- Remember that SQLITE doesn't have any actual 'time' type,
31+
-- This column contains float values constructed
32+
-- using strftime('%s', 'now', 'subsec')
33+
created_at TEXT NOT NULL,
34+
35+
-- - In a distributed system you really can’t ever truly delete comments,
36+
-- but you can ask to hide them.
37+
hidden BOOL NOT NULL DEFAULT FALSE
38+
);
39+
40+
CREATE INDEX history_comment_revisions_by_comment_id_and_created_at ON history_comment_revisions(comment_id, created_at DESC);

codebase2/codebase-sqlite/unison-codebase-sqlite.cabal

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22

3-
-- This file has been generated from package.yaml by hpack version 0.36.0.
3+
-- This file has been generated from package.yaml by hpack version 0.38.1.
44
--
55
-- see: https://github.com/sol/hpack
66

@@ -29,6 +29,7 @@ extra-source-files:
2929
sql/017-add-update-branch-table.sql
3030
sql/018-add-derived-dependents-by-dependency-index.sql
3131
sql/019-add-upgrade-branch-table.sql
32+
sql/020-add-history-comments.sql
3233
sql/create.sql
3334

3435
source-repository head
@@ -39,6 +40,7 @@ library
3940
exposed-modules:
4041
U.Codebase.Branch
4142
U.Codebase.Causal.Squash
43+
U.Codebase.Config
4244
U.Codebase.Sqlite.Branch.Diff
4345
U.Codebase.Sqlite.Branch.Format
4446
U.Codebase.Sqlite.Branch.Full
@@ -48,6 +50,7 @@ library
4850
U.Codebase.Sqlite.Decode
4951
U.Codebase.Sqlite.Entity
5052
U.Codebase.Sqlite.HashHandle
53+
U.Codebase.Sqlite.HistoryComment
5154
U.Codebase.Sqlite.LocalIds
5255
U.Codebase.Sqlite.LocalizeObject
5356
U.Codebase.Sqlite.ObjectType

parser-typechecker/src/Unison/Codebase/SqliteCodebase/Migrations.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ migrations regionVar getDeclType termBuffer declBuffer rootCodebasePath =
8989
sqlMigration 19 Q.addMergeBranchTables,
9090
sqlMigration 20 Q.addUpdateBranchTable,
9191
sqlMigration 21 Q.addDerivedDependentsByDependencyIndex,
92-
sqlMigration 22 Q.addUpgradeBranchTable
92+
sqlMigration 22 Q.addUpgradeBranchTable,
93+
sqlMigration 23 Q.addHistoryComments
9394
]
9495
where
9596
runT :: Sqlite.Transaction () -> Sqlite.Connection -> IO ()

parser-typechecker/src/Unison/Codebase/SqliteCodebase/Operations.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ createSchema = do
8585
Q.addUpdateBranchTable
8686
Q.addDerivedDependentsByDependencyIndex
8787
Q.addUpgradeBranchTable
88+
Q.addHistoryComments
8889
(_, emptyCausalHashId) <- emptyCausalHash
8990
(_, ProjectBranchRow {projectId, branchId}) <-
9091
insertProjectAndBranch scratchProjectName scratchBranchName emptyCausalHashId

parser-typechecker/unison-parser-typechecker.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22

3-
-- This file has been generated from package.yaml by hpack version 0.36.0.
3+
-- This file has been generated from package.yaml by hpack version 0.38.1.
44
--
55
-- see: https://github.com/sol/hpack
66

unison-cli/src/Unison/Codebase/Editor/HandleInput.hs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import Unison.Codebase.Editor.HandleInput.BranchRename (handleBranchRename)
5050
import Unison.Codebase.Editor.HandleInput.BranchSquash (handleBranchSquash)
5151
import Unison.Codebase.Editor.HandleInput.Branches (handleBranches)
5252
import Unison.Codebase.Editor.HandleInput.Cancel (handleCancel)
53+
import Unison.Codebase.Editor.HandleInput.Config (handleConfigGet, handleConfigSet)
5354
import Unison.Codebase.Editor.HandleInput.DebugDefinition qualified as DebugDefinition
5455
import Unison.Codebase.Editor.HandleInput.DebugFoldRanges qualified as DebugFoldRanges
5556
import Unison.Codebase.Editor.HandleInput.DebugSynhashTerm (handleDebugSynhashTerm)
@@ -64,6 +65,8 @@ import Unison.Codebase.Editor.HandleInput.EditNamespace (handleEditNamespace)
6465
import Unison.Codebase.Editor.HandleInput.FindAndReplace (handleStructuredFindI, handleStructuredFindReplaceI, handleTextFindI)
6566
import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Format
6667
import Unison.Codebase.Editor.HandleInput.Global qualified as Global
68+
import Unison.Codebase.Editor.HandleInput.History (handleHistory)
69+
import Unison.Codebase.Editor.HandleInput.HistoryComment (handleHistoryComment)
6770
import Unison.Codebase.Editor.HandleInput.InstallLib (handleInstallLib, handleInstallLocalLib)
6871
import Unison.Codebase.Editor.HandleInput.LSPDebug qualified as LSPDebug
6972
import Unison.Codebase.Editor.HandleInput.Load (EvalMode (Sandboxed), evalUnisonFile, handleLoad, loadUnisonFile)
@@ -297,29 +300,9 @@ loop e = do
297300
success <- Cli.popd
298301
when (not success) (Cli.respond StartOfCurrentPathHistory)
299302
HistoryI resultsCap diffCap from -> do
300-
branch <-
301-
case from of
302-
BranchAtSCH hash -> Cli.resolveShortCausalHash hash
303-
BranchAtPath path' -> do
304-
pp <- Cli.resolvePath' path'
305-
Cli.getBranchFromProjectPath pp
306-
BranchAtProjectPath pp -> Cli.getBranchFromProjectPath pp
307-
schLength <- Cli.runTransaction Codebase.branchHashLength
308-
history <- liftIO (doHistory schLength 0 branch [])
309-
Cli.respondNumbered history
310-
where
311-
doHistory :: Int -> Int -> Branch IO -> [(CausalHash, Names.Diff)] -> IO NumberedOutput
312-
doHistory schLength !n b acc =
313-
if maybe False (n >=) resultsCap
314-
then pure (History diffCap schLength acc (PageEnd (Branch.headHash b) n))
315-
else case Branch._history b of
316-
Causal.One {} -> pure (History diffCap schLength acc (EndOfLog $ Branch.headHash b))
317-
Causal.Merge _ _ _ tails ->
318-
pure (History diffCap schLength acc (MergeTail (Branch.headHash b) $ Map.keys tails))
319-
Causal.Cons _ _ _ tail -> do
320-
b' <- fmap Branch.Branch $ snd tail
321-
let elem = (Branch.headHash b, Branch.namesDiff b' b)
322-
doHistory schLength (n + 1) b' (elem : acc)
303+
handleHistory resultsCap diffCap from
304+
HistoryCommentI toAnnotate -> do
305+
handleHistoryComment toAnnotate
323306
UndoI -> do
324307
rootBranch <- Cli.getCurrentProjectRoot
325308
(_, prev) <-
@@ -736,6 +719,8 @@ loop e = do
736719
BranchRenameI name -> handleBranchRename name
737720
BranchesI name -> handleBranches name
738721
CloneI remoteNames localNames -> handleClone remoteNames localNames
722+
ConfigGetI key -> handleConfigGet key
723+
ConfigSetI key value -> handleConfigSet key value
739724
BranchSquashI branchToSquash destBranch -> handleBranchSquash branchToSquash destBranch
740725
ReleaseDraftI semver -> handleReleaseDraft semver
741726
UpgradeI libs -> handleUpgrade libs
@@ -817,6 +802,8 @@ inputDescription input =
817802
BranchesI {} -> wat
818803
ClearI {} -> wat
819804
CloneI {} -> wat
805+
ConfigSetI {} -> wat
806+
ConfigGetI {} -> wat
820807
CreateMessage {} -> wat
821808
DebugClearWatchI {} -> wat
822809
DebugDoctorI {} -> wat
@@ -842,6 +829,7 @@ inputDescription input =
842829
HistoryI {} -> wat
843830
IOTestAllI -> wat
844831
IOTestI {} -> wat
832+
HistoryCommentI {} -> wat
845833
LibInstallI {} -> wat
846834
LibInstallLocalI {} -> wat
847835
ListDependenciesI {} -> wat

0 commit comments

Comments
 (0)