1package entity
2
3import (
4 "time"
5
6 "github.com/MichaelMure/git-bug/repository"
7)
8
9// OperationType is an operation type identifier
10type OperationType int
11
12// Operation is a piece of data defining a change to reflect on the state of an Entity.
13// What this Operation or Entity's state looks like is not of the resort of this package as it only deals with the
14// data structure and storage.
15type Operation interface {
16 // Id return the Operation identifier
17 //
18 // Some care need to be taken to define a correct Id derivation and enough entropy in the data used to avoid
19 // collisions. Notably:
20 // - the Id of the first Operation will be used as the Id of the Entity. Collision need to be avoided across entities
21 // of the same type (example: no collision within the "bug" namespace).
22 // - collisions can also happen within the set of Operations of an Entity. Simple Operation might not have enough
23 // entropy to yield unique Ids (example: two "close" operation within the same second, same author).
24 // If this is a concern, it is recommended to include a piece of random data in the operation's data, to guarantee
25 // a minimal amount of entropy and avoid collision.
26 //
27 // Author's note: I tried to find a clever way around that inelegance (stuffing random useless data into the stored
28 // structure is not exactly elegant), but I failed to find a proper way. Essentially, anything that would reuse some
29 // other data (parent operation's Id, lamport clock) or the graph structure (depth) impose that the Id would only
30 // make sense in the context of the graph and yield some deep coupling between Entity and Operation. This in turn
31 // make the whole thing even less elegant.
32 //
33 // A common way to derive an Id will be to use the entity.DeriveId() function on the serialized operation data.
34 Id() Id
35 // Type return the type of the operation
36 Type() OperationType
37 // Validate check if the Operation data is valid
38 Validate() error
39 // Author returns the author of this operation
40 Author() Identity
41 // Time return the time when the operation was added
42 Time() time.Time
43
44 // SetMetadata store arbitrary metadata about the operation
45 SetMetadata(key string, value string)
46 // GetMetadata retrieve arbitrary metadata about the operation
47 GetMetadata(key string) (string, bool)
48 // AllMetadata return all metadata for this operation
49 AllMetadata() map[string]string
50}
51
52type OperationWithApply[SnapT Snapshot] interface {
53 Operation
54
55 // Apply the operation to a Snapshot to create the final state
56 Apply(snapshot SnapT)
57}
58
59// OperationWithFiles is an optional extension for an Operation that has files dependency, stored in git.
60type OperationWithFiles interface {
61 Operation
62
63 // GetFiles return the files needed by this operation
64 // This implies that the Operation maintain and store internally the references to those files. This is how
65 // this information is read later, when loading from storage.
66 // For example, an operation that has a text value referencing some files would maintain a mapping (text ref -->
67 // hash).
68 GetFiles() []repository.Hash
69}
70
71// OperationDoesntChangeSnapshot is an interface signaling that the Operation implementing it doesn't change the
72// snapshot, for example a metadata operation that act on other operations.
73type OperationDoesntChangeSnapshot interface {
74 DoesntChangeSnapshot()
75}