store_disk.go 2.4 KB

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