package storage import ( "errors" "strings" "github.com/redis/go-redis/v9" "github.com/rs/zerolog/log" "git.mstar.dev/mstar/linstrom/util" ) // various prefixes for accessing items in the cache (since it's a simple key-value store) const ( cacheUserHandleToIdPrefix = "acc-name-to-id:" cacheLocalUsernameToIdPrefix = "acc-local-name-to-id:" cachePasskeyIdToAccIdPrefix = "acc-pkey-id-to-id:" cacheUserIdToAccPrefix = "acc-id-to-data:" cacheNoteIdToNotePrefix = "note-id-to-data:" ) // An error describing the case where some value was just not found in the cache var errCacheNotFound = errors.New("not found in cache") // Find an account id in cache using a given user handle ("@bob@example.com" or "bob@example.com") // accId contains the Id of the account if found // err contains an error describing why an account's id couldn't be found // The most common one should be errCacheNotFound func (s *Storage) cacheHandleToAccUid(handle string) (accId *string, err error) { defer util.Untrace(util.Trace(&log.Logger)) // Where to put the data (in case it's found) var target string found, err := s.cache.Get(cacheUserHandleToIdPrefix+strings.TrimLeft(handle, "@"), &target) // If nothing was found, check error if !found { // Case error is set and NOT redis' error for nothing found: Return that error if err != nil && !errors.Is(err, redis.Nil) { return nil, err } else { // Else return errCacheNotFound return nil, errCacheNotFound } } return &target, nil } // Find a local account's id in cache using a given username ("bob") // accId containst the Id of the account if found // err contains an error describing why an account's id couldn't be found // The most common one should be errCacheNotFound func (s *Storage) cacheLocalUsernameToAccUid(username string) (accId *string, err error) { defer util.Untrace(util.Trace(&log.Logger)) // Where to put the data (in case it's found) var target string found, err := s.cache.Get(cacheLocalUsernameToIdPrefix+username, &target) // If nothing was found, check error if !found { // Case error is set and NOT redis' error for nothing found: Return that error if err != nil && !errors.Is(err, redis.Nil) { return nil, err } else { // Else return errCacheNotFound return nil, errCacheNotFound } } return &target, nil } func (s *Storage) cachePkeyIdToAccId(pkeyId []byte) (accId *string, err error) { defer util.Untrace(util.Trace(&log.Logger)) // Where to put the data (in case it's found) var target string found, err := s.cache.Get(cachePasskeyIdToAccIdPrefix+string(pkeyId), &target) // If nothing was found, check error if !found { // Case error is set and NOT redis' error for nothing found: Return that error if err != nil && !errors.Is(err, redis.Nil) { return nil, err } else { // Else return errCacheNotFound return nil, errCacheNotFound } } return &target, nil } // Find an account's data in cache using a given account id // acc contains the full account as stored last time if found // err contains an error describing why an account couldn't be found // The most common one should be errCacheNotFound func (s *Storage) cacheAccIdToData(id string) (acc *Account, err error) { defer util.Untrace(util.Trace(&log.Logger)) var target Account found, err := s.cache.Get(cacheUserIdToAccPrefix+id, &target) if !found { if err != nil && !errors.Is(err, redis.Nil) { return nil, err } else { return nil, errCacheNotFound } } return &target, nil } // Find a cached note given its ID // note contains the full note as stored last time if found // err contains an error describing why a note couldn't be found // The most common one should be errCacheNotFound func (s *Storage) cacheNoteIdToData(id string) (note *Note, err error) { defer util.Untrace(util.Trace(&log.Logger)) target := Note{} found, err := s.cache.Get(cacheNoteIdToNotePrefix+id, &target) if !found { if err != nil && !errors.Is(err, redis.Nil) { return nil, err } else { return nil, errCacheNotFound } } return &target, nil }