store.go 2.8 KB

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