package ezdb import ( "os" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/opt" ) type LevelDBCollection[T any] struct { path string db *leveldb.DB m DocumentMarshaler[T, []byte] optOpen *opt.Options optRead *opt.ReadOptions optWrite *opt.WriteOptions } func (c *LevelDBCollection[T]) Close() error { if c.db != nil { if err := c.db.Close(); err != nil { return err } c.db = nil } return nil } func (c *LevelDBCollection[T]) Count() int { iter := c.Iter() defer iter.Release() return iter.Count() } func (c *LevelDBCollection[T]) Delete(key string) error { return c.db.Delete([]byte(key), c.optWrite) } func (c *LevelDBCollection[T]) DeleteAll() error { iter := c.Iter() defer iter.Release() keys := iter.GetAllKeys() for _, key := range keys { if err := c.Delete(key); err != nil { return err } } return nil } // Destroy the database completely, removing it from disk. func (c *LevelDBCollection[T]) Destroy() error { if err := c.Close(); err != nil { return err } return os.RemoveAll(c.path) } func (c *LevelDBCollection[T]) Get(key string) (T, error) { dest := c.m.Factory() src, err := c.db.Get([]byte(key), c.optRead) if err != nil { return dest, err } err = c.m.Unmarshal(src, dest) return dest, err } func (c *LevelDBCollection[T]) GetAll() (map[string]T, error) { iter := c.Iter() defer iter.Release() return iter.GetAll() } func (c *LevelDBCollection[T]) GetAllKeys() []string { iter := c.Iter() defer iter.Release() return iter.GetAllKeys() } func (c *LevelDBCollection[T]) Has(key string) (bool, error) { return c.db.Has([]byte(key), c.optRead) } func (c *LevelDBCollection[T]) Iter() Iterator[T] { i := &LevelDBIterator[T]{ i: c.db.NewIterator(nil, c.optRead), m: c.m, } return i } func (c *LevelDBCollection[T]) Open() error { if c.db == nil { db, err := leveldb.OpenFile(c.path, c.optOpen) if err != nil { return err } c.db = db } return nil } func (c *LevelDBCollection[T]) Put(key string, src T) error { if err := ValidateKey(key); err != nil { return err } dest, err := c.m.Marshal(src) if err != nil { return err } return c.db.Put([]byte(key), dest, c.optWrite) } // LevelDB creates a new collection using LevelDB storage. func LevelDB[T any](path string, m DocumentMarshaler[T, []byte], o *LevelDBOptions) *LevelDBCollection[T] { c := &LevelDBCollection[T]{ path: path, m: m, // Unpack options optOpen: o.GetOpen(), optRead: o.GetRead(), optWrite: o.GetWrite(), } return c }