github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/state/dbstore.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package state
    18  
    19  import (
    20  	"encoding"
    21  	"encoding/json"
    22  	"errors"
    23  
    24  	"github.com/syndtr/goleveldb/leveldb"
    25  	"github.com/syndtr/goleveldb/leveldb/storage"
    26  )
    27  
    28  // ErrNotFound is returned when no results are returned from the database
    29  var ErrNotFound = errors.New("ErrorNotFound")
    30  
    31  // Store defines methods required to get, set, delete values for different keys
    32  // and close the underlying resources.
    33  type Store interface {
    34  	Get(key string, i interface{}) (err error)
    35  	Put(key string, i interface{}) (err error)
    36  	Delete(key string) (err error)
    37  	Close() error
    38  }
    39  
    40  // DBStore uses LevelDB to store values.
    41  type DBStore struct {
    42  	db *leveldb.DB
    43  }
    44  
    45  // NewDBStore creates a new instance of DBStore.
    46  func NewDBStore(path string) (s *DBStore, err error) {
    47  	db, err := leveldb.OpenFile(path, nil)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return &DBStore{
    52  		db: db,
    53  	}, nil
    54  }
    55  
    56  // NewInmemoryStore returns a new instance of DBStore. To be used only in tests and simulations.
    57  func NewInmemoryStore() *DBStore {
    58  	db, err := leveldb.Open(storage.NewMemStorage(), nil)
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  	return &DBStore{
    63  		db: db,
    64  	}
    65  }
    66  
    67  // Get retrieves a persisted value for a specific key. If there is no results
    68  // ErrNotFound is returned. The provided parameter should be either a byte slice or
    69  // a struct that implements the encoding.BinaryUnmarshaler interface
    70  func (s *DBStore) Get(key string, i interface{}) (err error) {
    71  	has, err := s.db.Has([]byte(key), nil)
    72  	if err != nil || !has {
    73  		return ErrNotFound
    74  	}
    75  
    76  	data, err := s.db.Get([]byte(key), nil)
    77  	if err == leveldb.ErrNotFound {
    78  		return ErrNotFound
    79  	}
    80  
    81  	unmarshaler, ok := i.(encoding.BinaryUnmarshaler)
    82  	if !ok {
    83  		return json.Unmarshal(data, i)
    84  	}
    85  	return unmarshaler.UnmarshalBinary(data)
    86  }
    87  
    88  // Put stores an object that implements Binary for a specific key.
    89  func (s *DBStore) Put(key string, i interface{}) (err error) {
    90  	var bytes []byte
    91  
    92  	marshaler, ok := i.(encoding.BinaryMarshaler)
    93  	if !ok {
    94  		if bytes, err = json.Marshal(i); err != nil {
    95  			return err
    96  		}
    97  	} else {
    98  		if bytes, err = marshaler.MarshalBinary(); err != nil {
    99  			return err
   100  		}
   101  	}
   102  
   103  	return s.db.Put([]byte(key), bytes, nil)
   104  }
   105  
   106  // Delete removes entries stored under a specific key.
   107  func (s *DBStore) Delete(key string) (err error) {
   108  	return s.db.Delete([]byte(key), nil)
   109  }
   110  
   111  // Close releases the resources used by the underlying LevelDB.
   112  func (s *DBStore) Close() error {
   113  	return s.db.Close()
   114  }