github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/storage/storage_delh.go (about) 1 package storage 2 3 import ( 4 "fmt" 5 6 "github.com/keybase/client/go/chat/globals" 7 "github.com/keybase/client/go/chat/utils" 8 "github.com/keybase/client/go/libkb" 9 "github.com/keybase/client/go/protocol/chat1" 10 "github.com/keybase/client/go/protocol/gregor1" 11 "golang.org/x/net/context" 12 ) 13 14 type delhTracker struct { 15 globals.Contextified 16 utils.DebugLabeler 17 } 18 19 type delhTrackerEntry struct { 20 StorageVersion int `codec:"v"` 21 // The latest DeleteHistory upto value that has been applied locally 22 MaxDeleteHistoryUpto chat1.MessageID `codec:"ldhu"` 23 // The most ancient message that a new DeleteHistory could affect 24 MinDeletableMessage chat1.MessageID `codec:"em"` 25 } 26 27 const delhTrackerDiskVersion = 3 28 29 func newDelhTracker(g *globals.Context) *delhTracker { 30 return &delhTracker{ 31 Contextified: globals.NewContextified(g), 32 DebugLabeler: utils.NewDebugLabeler(g.ExternalG(), "DelhTracker", false), 33 } 34 } 35 36 func (t *delhTracker) makeDbKey(convID chat1.ConversationID, uid gregor1.UID) libkb.DbKey { 37 return libkb.DbKey{ 38 Typ: libkb.DBChatBlocks, 39 Key: fmt.Sprintf("delh:%s:%s", uid, convID), 40 } 41 } 42 43 func (t *delhTracker) getEntry(ctx context.Context, 44 convID chat1.ConversationID, uid gregor1.UID) (delhTrackerEntry, Error) { 45 46 var blank delhTrackerEntry 47 var res delhTrackerEntry 48 49 dbKey := t.makeDbKey(convID, uid) 50 raw, found, err := t.G().LocalChatDb.GetRaw(dbKey) 51 if err != nil { 52 return res, NewInternalError(ctx, t.DebugLabeler, "GetRaw error: %s", err.Error()) 53 } 54 if !found { 55 return res, MissError{} 56 } 57 58 err = decode(raw, &res) 59 if err != nil { 60 return blank, NewInternalError(ctx, t.DebugLabeler, "decode error: %s", err.Error()) 61 } 62 switch res.StorageVersion { 63 case delhTrackerDiskVersion: 64 return res, nil 65 default: 66 // ignore other versions 67 return blank, MissError{} 68 } 69 } 70 71 func (t *delhTracker) setEntry(ctx context.Context, 72 convID chat1.ConversationID, uid gregor1.UID, entry delhTrackerEntry) Error { 73 74 entry.StorageVersion = delhTrackerDiskVersion 75 data, err := encode(entry) 76 if err != nil { 77 return NewInternalError(ctx, t.DebugLabeler, "encode error: %s", err.Error()) 78 } 79 80 dbKey := t.makeDbKey(convID, uid) 81 err = t.G().LocalChatDb.PutRaw(dbKey, data) 82 if err != nil { 83 return NewInternalError(ctx, t.DebugLabeler, "PutRaw error: %s", err.Error()) 84 } 85 t.Debug(ctx, "delhTracker.setEntry(%v, %+v)", convID, entry) 86 return nil 87 } 88 89 func (t *delhTracker) setMaxDeleteHistoryUpto(ctx context.Context, 90 convID chat1.ConversationID, uid gregor1.UID, msgid chat1.MessageID) Error { 91 92 // No need to use transaction here since the Storage class takes lock. 93 94 entry, err := t.getEntry(ctx, convID, uid) 95 switch err.(type) { 96 case nil: 97 case MissError: 98 default: 99 return err 100 } 101 entry.MaxDeleteHistoryUpto = msgid 102 return t.setEntry(ctx, convID, uid, entry) 103 } 104 105 func (t *delhTracker) setMinDeletableMessage(ctx context.Context, 106 convID chat1.ConversationID, uid gregor1.UID, msgid chat1.MessageID) Error { 107 108 entry, err := t.getEntry(ctx, convID, uid) 109 switch err.(type) { 110 case nil: 111 case MissError: 112 default: 113 return err 114 } 115 entry.MinDeletableMessage = msgid 116 return t.setEntry(ctx, convID, uid, entry) 117 } 118 119 // Set both values to msgid 120 func (t *delhTracker) setDeletedUpto(ctx context.Context, 121 convID chat1.ConversationID, uid gregor1.UID, msgid chat1.MessageID) Error { 122 123 entry, err := t.getEntry(ctx, convID, uid) 124 switch err.(type) { 125 case nil: 126 case MissError: 127 default: 128 return err 129 } 130 entry.MaxDeleteHistoryUpto = msgid 131 entry.MinDeletableMessage = msgid 132 return t.setEntry(ctx, convID, uid, entry) 133 }