store.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // package store -- хранилище на диске
  2. package store
  3. import (
  4. "fmt"
  5. "os"
  6. "strings"
  7. "github.com/syndtr/goleveldb/leveldb"
  8. "github.com/syndtr/goleveldb/leveldb/util"
  9. "git.p78su.freemyip.com/svi/gostore/pkg/types"
  10. )
  11. // StoreDisk -- хранилище на диске
  12. type Store struct {
  13. serv types.IService
  14. db *leveldb.DB
  15. }
  16. // NewStore -- возвращает новое хранилище на диске
  17. func NewStore(serv types.IService) (*Store, error) {
  18. if serv == nil {
  19. return nil, fmt.Errorf("NewStore(): IService==nil")
  20. }
  21. _ = os.MkdirAll("./store/db", 0750)
  22. db, err := leveldb.OpenFile("./store/db", nil)
  23. if err != nil {
  24. if !strings.Contains(err.Error(), "leveldb: manifest corrupted") {
  25. return nil, fmt.Errorf("NewStore(): in create IStoreDisk, err=\n\t%w", err)
  26. }
  27. db, err = leveldb.RecoverFile("./stor/db", nil)
  28. if err != nil {
  29. return nil, fmt.Errorf("NewStore(): in recovery DB, err=\n\t%w", err)
  30. }
  31. }
  32. sf := &Store{
  33. serv: serv,
  34. db: db,
  35. }
  36. go sf.close()
  37. return sf, nil
  38. }
  39. // Put -- размещает в хранилище ключ и значение
  40. func (sf *Store) Put(key string, val []byte) error {
  41. if key == "" {
  42. return fmt.Errorf("Store.Put(): key is empty")
  43. }
  44. err := sf.db.Put([]byte(key), val, nil)
  45. if err != nil {
  46. return fmt.Errorf("Store.Put(): key=%q\terr=\n\t%w", key, err)
  47. }
  48. return nil
  49. }
  50. // Get -- возвращает значение ключа
  51. func (sf *Store) Get(key string) ([]byte, error) {
  52. val, err := sf.db.Get([]byte(key), nil)
  53. if err != nil {
  54. return nil, fmt.Errorf("Store.Get(): key=%q\terr=\n\t%w", key, err)
  55. }
  56. return val, nil
  57. }
  58. // Find -- ищет ключи по префиксу
  59. func (sf *Store) Find(prefixKey string) ([]string, error) {
  60. lstKey := []string{}
  61. iter := sf.db.NewIterator(util.BytesPrefix([]byte(prefixKey)), nil)
  62. for iter.Next() {
  63. key := iter.Key()
  64. lstKey = append(lstKey, string(key))
  65. }
  66. iter.Release()
  67. err := iter.Error()
  68. if err != nil {
  69. return nil, fmt.Errorf("Store.Find(): preefixKey=%q\terr=\n\t%w", prefixKey, err)
  70. }
  71. return lstKey, nil
  72. }
  73. // Del -- удаление ключа из базы
  74. func (sf *Store) Del(key string) error {
  75. err := sf.db.Delete([]byte(key), nil)
  76. if err != nil {
  77. return fmt.Errorf("Store.Del(): key=%q\terr=\n\t%w", key, err)
  78. }
  79. return nil
  80. }
  81. // Ожидание закрытия приложения
  82. func (sf *Store) close() {
  83. <-sf.serv.Ctx().Done()
  84. _ = sf.db.Close()
  85. }