store.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package store
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. "github.com/google/uuid"
  7. )
  8. type Storable interface {
  9. GetHash() string
  10. GetID() string
  11. SetID(string)
  12. SetCreatedAt(t time.Time)
  13. SetUpdatedAt(t time.Time)
  14. GetCreatedAt() time.Time
  15. GetUpdatedAt() time.Time
  16. }
  17. type Storer[T Storable] interface {
  18. Create(T) (T, error)
  19. ReadAll() []T
  20. Read(string) (T, error)
  21. Update(T, string) (T, error)
  22. Delete(string) (T, error)
  23. }
  24. type FilterStorer[T Storable] interface {
  25. Storer[T]
  26. Filter([]T, func(T) bool) []T
  27. }
  28. type Store[T Storable] struct {
  29. ids map[string]T
  30. hashes map[string]T
  31. lock sync.RWMutex
  32. }
  33. type FilterStore[T Storable] struct {
  34. *Store[T]
  35. }
  36. func NewFilterStore[T Storable]() *FilterStore[T] {
  37. return &FilterStore[T]{NewStore[T]()}
  38. }
  39. func (fs *FilterStore[T]) Filter(slice []T, f func(T) bool) []T {
  40. result := make([]T, 0)
  41. for _, item := range slice {
  42. if f(item) {
  43. result = append(result, item)
  44. }
  45. }
  46. return result
  47. }
  48. func NewStore[T Storable]() *Store[T] {
  49. store := new(Store[T])
  50. store.ids = make(map[string]T)
  51. store.hashes = make(map[string]T)
  52. return store
  53. }
  54. func (s *Store[T]) Create(entity T) (T, error) {
  55. s.lock.Lock()
  56. defer s.lock.Unlock()
  57. if hash := entity.GetHash(); hash != "" {
  58. storedEntity, ok := s.hashes[hash]
  59. if ok {
  60. return storedEntity, nil
  61. }
  62. s.hashes[hash] = entity
  63. }
  64. id := entity.GetID()
  65. if id == "" {
  66. id = uuid.New().String()
  67. }
  68. entity.SetID(id)
  69. if !entity.GetCreatedAt().IsZero() {
  70. entity.SetUpdatedAt(time.Now())
  71. } else {
  72. entity.SetCreatedAt(time.Now())
  73. }
  74. if entity.GetUpdatedAt().IsZero() {
  75. entity.SetUpdatedAt(time.Now())
  76. }
  77. s.ids[id] = entity
  78. return entity, nil
  79. }
  80. func (s *Store[T]) ReadAll() []T {
  81. s.lock.Lock()
  82. defer s.lock.Unlock()
  83. result := make([]T, 0)
  84. for _, v := range s.ids {
  85. result = append(result, v)
  86. }
  87. return result
  88. }
  89. func (s *Store[T]) Read(id string) (T, error) {
  90. s.lock.RLock()
  91. defer s.lock.RUnlock()
  92. entity, ok := s.ids[id]
  93. if !ok {
  94. return entity, fmt.Errorf("Entity with ID %s was not found in the store.", id)
  95. }
  96. return entity, nil
  97. }
  98. func (s *Store[T]) Update(entity T, id string) (T, error) {
  99. sEntity, err := s.Read(id)
  100. if err != nil {
  101. return sEntity, err
  102. }
  103. s.lock.Lock()
  104. defer s.lock.Unlock()
  105. entity.SetID(id)
  106. s.ids[id] = entity
  107. if hash := entity.GetHash(); hash != "" {
  108. s.hashes[hash] = entity
  109. }
  110. entity.SetUpdatedAt(time.Now())
  111. return entity, nil
  112. }
  113. func (s *Store[T]) Delete(id string) (T, error) {
  114. sEntity, err := s.Read(id)
  115. if err != nil {
  116. return sEntity, err
  117. }
  118. s.lock.Lock()
  119. defer s.lock.Unlock()
  120. delete(s.ids, id)
  121. if hash := sEntity.GetHash(); hash != "" {
  122. delete(s.hashes, hash)
  123. }
  124. return sEntity, nil
  125. }