Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,26 @@
package leveldb
type LevelDBConfigurationProvider interface {
GetDBPath() string
GetDBName() string
}
type LevelDBConfigurationProviderImpl struct {
dbPath string
dbName string
}
func NewLevelDBConfigurationProvider(dbPath string, dbName string) LevelDBConfigurationProvider {
return &LevelDBConfigurationProviderImpl{
dbPath: dbPath,
dbName: dbName,
}
}
func (me *LevelDBConfigurationProviderImpl) GetDBPath() string {
return me.dbPath
}
func (me *LevelDBConfigurationProviderImpl) GetDBName() string {
return me.dbName
}

View file

@ -0,0 +1,218 @@
package leveldb
import (
"log"
"strings"
"github.com/syndtr/goleveldb/leveldb"
dberr "github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/filter"
"github.com/syndtr/goleveldb/leveldb/opt"
"go.uber.org/zap"
"codeberg.org/mapleopentech/monorepo/native/desktop/maplefile/pkg/storage"
)
// storageImpl implements the db.Database interface.
// It uses a LevelDB database to store key-value pairs.
type storageImpl struct {
// The LevelDB database instance.
db *leveldb.DB
transaction *leveldb.Transaction
}
// NewDiskStorage creates a new instance of the storageImpl.
// It opens the database file at the specified path and returns an error if it fails.
func NewDiskStorage(provider LevelDBConfigurationProvider, logger *zap.Logger) storage.Storage {
logger = logger.Named("leveldb")
if provider == nil {
log.Fatal("NewDiskStorage: missing LevelDB configuration provider\n")
}
if provider.GetDBPath() == "" {
log.Fatal("NewDiskStorage: cannot have empty filepath for the database\n")
}
if provider.GetDBName() == "" {
log.Fatal("NewDiskStorage: cannot have empty db name for the database\n")
}
o := &opt.Options{
Filter: filter.NewBloomFilter(10),
}
filePath := provider.GetDBPath() + "/" + provider.GetDBName()
db, err := leveldb.OpenFile(filePath, o)
if err != nil {
log.Fatalf("NewDiskStorage: failed loading up key value storer adapter at %v with error: %v\n", filePath, err)
}
return &storageImpl{
db: db,
}
}
// Get retrieves a value from the database by its key.
// It returns an error if the key is not found.
func (impl *storageImpl) Get(k string) ([]byte, error) {
if impl.transaction == nil {
bin, err := impl.db.Get([]byte(k), nil)
if err == dberr.ErrNotFound {
return nil, nil
}
return bin, nil
}
bin, err := impl.transaction.Get([]byte(k), nil)
if err == dberr.ErrNotFound {
return nil, nil
}
return bin, nil
}
// Set sets a value in the database by its key.
// It returns an error if the operation fails.
func (impl *storageImpl) Set(k string, val []byte) error {
if impl.transaction == nil {
impl.db.Delete([]byte(k), nil)
err := impl.db.Put([]byte(k), val, nil)
if err == dberr.ErrNotFound {
return nil
}
return err
}
impl.transaction.Delete([]byte(k), nil)
err := impl.transaction.Put([]byte(k), val, nil)
if err == dberr.ErrNotFound {
return nil
}
return err
}
// Delete deletes a value from the database by its key.
// It returns an error if the operation fails.
func (impl *storageImpl) Delete(k string) error {
if impl.transaction == nil {
err := impl.db.Delete([]byte(k), nil)
if err == dberr.ErrNotFound {
return nil
}
return err
}
err := impl.transaction.Delete([]byte(k), nil)
if err == dberr.ErrNotFound {
return nil
}
return err
}
// Iterate iterates over the key-value pairs in the database, starting from the specified key prefix.
// It calls the provided function for each pair.
// It returns an error if the iteration fails.
func (impl *storageImpl) Iterate(processFunc func(key, value []byte) error) error {
if impl.transaction == nil {
iter := impl.db.NewIterator(nil, nil)
for ok := iter.First(); ok; ok = iter.Next() {
// Call the passed function for each key-value pair.
err := processFunc(iter.Key(), iter.Value())
if err == dberr.ErrNotFound {
return nil
}
if err != nil {
return err // Exit early if the processing function returns an error.
}
}
iter.Release()
return iter.Error()
}
iter := impl.transaction.NewIterator(nil, nil)
for ok := iter.First(); ok; ok = iter.Next() {
// Call the passed function for each key-value pair.
err := processFunc(iter.Key(), iter.Value())
if err == dberr.ErrNotFound {
return nil
}
if err != nil {
return err // Exit early if the processing function returns an error.
}
}
iter.Release()
return iter.Error()
}
func (impl *storageImpl) IterateWithFilterByKeys(ks []string, processFunc func(key, value []byte) error) error {
if impl.transaction == nil {
iter := impl.db.NewIterator(nil, nil)
for ok := iter.First(); ok; ok = iter.Next() {
// Iterate over our keys to search by.
for _, k := range ks {
searchKey := strings.ToLower(k)
targetKey := strings.ToLower(string(iter.Key()))
// If the item we currently have matches our keys then execute.
if searchKey == targetKey {
// Call the passed function for each key-value pair.
err := processFunc(iter.Key(), iter.Value())
if err == dberr.ErrNotFound {
return nil
}
if err != nil {
return err // Exit early if the processing function returns an error.
}
}
}
}
iter.Release()
return iter.Error()
}
iter := impl.transaction.NewIterator(nil, nil)
for ok := iter.First(); ok; ok = iter.Next() {
// Call the passed function for each key-value pair.
err := processFunc(iter.Key(), iter.Value())
if err == dberr.ErrNotFound {
return nil
}
if err != nil {
return err // Exit early if the processing function returns an error.
}
}
iter.Release()
return iter.Error()
}
// Close closes the database.
// It returns an error if the operation fails.
func (impl *storageImpl) Close() error {
if impl.transaction != nil {
impl.transaction.Discard()
}
return impl.db.Close()
}
func (impl *storageImpl) OpenTransaction() error {
transaction, err := impl.db.OpenTransaction()
if err != nil {
return nil
}
impl.transaction = transaction
return nil
}
func (impl *storageImpl) CommitTransaction() error {
defer func() {
impl.transaction = nil
}()
// Commit the snapshot to the database
return impl.transaction.Commit()
}
func (impl *storageImpl) DiscardTransaction() {
defer func() {
impl.transaction = nil
}()
impl.transaction.Discard()
}

View file

@ -0,0 +1,479 @@
package leveldb
import (
"os"
"path/filepath"
"reflect"
"testing"
"go.uber.org/zap"
)
// MockLevelDBConfigProvider is a mock implementation of a presumed LevelDBConfigurationProvider interface.
// This is created to satisfy the changed signature of NewDiskStorage.
type MockLevelDBConfigProvider struct {
Path string
// Add other fields here if the actual LevelDBConfigurationProvider interface
// and NewDiskStorage function require more configuration options (e.g., LevelDB options).
}
// GetDBPath returns the database path. This method is assumed to be part of the
// LevelDBConfigurationProvider interface.
func (m *MockLevelDBConfigProvider) GetDBPath() string {
return m.Path
}
// If LevelDBConfigurationProvider requires other methods (e.g., GetOptions()),
// they would need to be implemented here as well. For this repair, we assume
// GetDBPath is sufficient based on the original parameters of NewDiskStorage.
// testDir creates a temporary directory for testing
func testDir(t *testing.T) string {
dir, err := os.MkdirTemp("", "leveldb-test-*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
return dir
}
// cleanup removes the test directory and its contents
func cleanup(t *testing.T, dir string) {
err := os.RemoveAll(dir)
if err != nil {
t.Errorf("Failed to cleanup test dir: %v", err)
}
}
// TestNewDiskStorage tests the creation of a new storage instance
func TestNewDiskStorage(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "test.db"
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
logger := zap.NewExample()
storage := NewDiskStorage(config, logger)
if storage == nil {
t.Fatal("Expected non-nil storage instance")
}
// Type assertion to verify we get the correct implementation
impl, ok := storage.(*storageImpl)
if !ok {
t.Fatal("Expected storageImpl instance")
}
if impl.db == nil {
t.Fatal("Expected non-nil leveldb instance")
}
// It's generally better to call Close on the interface, but if impl.Close() has
// specific behavior being tested or is necessary for some reason, it can stay.
// However, a defer storage.Close() would be more idiomatic if not for specific impl testing.
err := storage.Close() // Changed from impl.Close() to storage.Close() for consistency
if err != nil {
t.Fatalf("Failed to close storage: %v", err)
}
}
// TestBasicOperations tests the basic Set/Get/Delete operations
func TestBasicOperations(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "test.db"
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
defer storage.Close()
// Test Set and Get
t.Run("Set and Get", func(t *testing.T) {
key := "test-key"
value := []byte("test-value")
err := storage.Set(key, value)
if err != nil {
t.Fatalf("Set failed: %v", err)
}
retrieved, err := storage.Get(key)
if err != nil {
t.Fatalf("Get failed: %v", err)
}
if !reflect.DeepEqual(retrieved, value) {
t.Errorf("Retrieved value doesn't match: got %v, want %v", retrieved, value)
}
})
// Test Get with non-existent key
t.Run("Get Non-existent", func(t *testing.T) {
val, err := storage.Get("non-existent")
// LevelDB's Get typically returns leveldb.ErrNotFound for non-existent keys.
// If the wrapper converts this to (nil, nil), the original check is fine.
// If it propagates ErrNotFound, then err should be checked for that specific error.
// Assuming the wrapper intends (nil, nil) for not found.
if err != nil {
t.Fatalf("Expected nil error or specific 'not found' error for non-existent key, got: %v", err)
}
if val != nil {
t.Errorf("Expected nil value for non-existent key, got: %v", val)
}
})
// Test Delete
t.Run("Delete", func(t *testing.T) {
key := "delete-test"
value := []byte("delete-value")
// First set a value
err := storage.Set(key, value)
if err != nil {
t.Fatalf("Set failed: %v", err)
}
// Delete it
err = storage.Delete(key)
if err != nil {
t.Fatalf("Delete failed: %v", err)
}
// Verify it's gone
val, err := storage.Get(key)
if err != nil {
t.Fatalf("Get after delete failed: %v", err) // Similar to "Get Non-existent"
}
if val != nil {
t.Error("Expected nil value after deletion")
}
})
}
// TestIteration tests the iteration functionality
func TestIteration(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "test.db"
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
defer storage.Close()
// Prepare test data
testData := map[string][]byte{
"key1": []byte("value1"),
"key2": []byte("value2"),
"key3": []byte("value3"),
}
// Insert test data
for k, v := range testData {
if err := storage.Set(k, v); err != nil {
t.Fatalf("Failed to set test data: %v", err)
}
}
// Test basic iteration
t.Run("Basic Iteration", func(t *testing.T) {
found := make(map[string][]byte)
err := storage.Iterate(func(key, value []byte) error {
valueCopy := make([]byte, len(value))
copy(valueCopy, value)
found[string(key)] = valueCopy
return nil
})
if err != nil {
t.Fatalf("Iteration failed: %v", err)
}
if len(found) != len(testData) {
t.Errorf("Iteration found %d items, expected %d", len(found), len(testData))
}
for k, expectedValue := range testData {
actualValue, exists := found[k]
if !exists {
t.Errorf("Key %q not found in iteration results", k)
continue
}
if !reflect.DeepEqual(actualValue, expectedValue) {
t.Errorf("Value mismatch for key %q: got %q, want %q",
k, string(actualValue), string(expectedValue))
}
}
})
// Test filtered iteration
t.Run("Filtered Iteration", func(t *testing.T) {
filterKeys := []string{"key1", "key3"}
expectedFilteredData := make(map[string][]byte)
for _, k := range filterKeys {
if v, ok := testData[k]; ok {
expectedFilteredData[k] = v
}
}
found := make(map[string][]byte)
err := storage.IterateWithFilterByKeys(filterKeys, func(key, value []byte) error {
valueCopy := make([]byte, len(value))
copy(valueCopy, value)
found[string(key)] = valueCopy
return nil
})
if err != nil {
t.Fatalf("Filtered iteration failed: %v", err)
}
if len(found) != len(expectedFilteredData) {
t.Errorf("Filtered iteration found %d items, expected %d", len(found), len(expectedFilteredData))
}
for _, k := range filterKeys {
expectedValue, dataExists := testData[k]
if !dataExists { // Should not happen if filterKeys are from testData
t.Errorf("Test data sanity check: key %q from filterKeys not in testData", k)
continue
}
actualValue, exists := found[k]
if !exists {
t.Errorf("Key %q not found in filtered results", k)
continue
}
if !reflect.DeepEqual(actualValue, expectedValue) {
t.Errorf("Value mismatch for key %q: got %q, want %q",
k, string(actualValue), string(expectedValue))
}
}
})
}
// TestTransactions tests the transaction functionality
func TestTransactions(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "test.db"
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
defer storage.Close()
t.Run("Transaction Commit", func(t *testing.T) {
err := storage.OpenTransaction()
if err != nil {
t.Fatalf("Failed to open transaction: %v", err)
}
key := "tx-test"
value := []byte("tx-value")
err = storage.Set(key, value) // Inside transaction
if err != nil {
storage.DiscardTransaction() // Ensure transaction is cleaned up on failure
t.Fatalf("Failed to set in transaction: %v", err)
}
err = storage.CommitTransaction()
if err != nil {
t.Fatalf("Failed to commit transaction: %v", err)
}
retrieved, err := storage.Get(key)
if err != nil {
t.Fatalf("Failed to get after commit: %v", err)
}
if !reflect.DeepEqual(retrieved, value) {
t.Errorf("Retrieved value doesn't match after commit: got %v, want %v", retrieved, value)
}
})
t.Run("Transaction Discard", func(t *testing.T) {
err := storage.OpenTransaction()
if err != nil {
t.Fatalf("Failed to open transaction: %v", err)
}
key := "discard-test"
value := []byte("discard-value")
// Set a value outside transaction first to ensure Get behavior is clear
outerKey := "outer-key-discard"
outerValue := []byte("outer-value-discard")
if err := storage.Set(outerKey, outerValue); err != nil {
storage.DiscardTransaction()
t.Fatalf("Setup: Failed to set outer key: %v", err)
}
err = storage.Set(key, value) // Inside transaction
if err != nil {
storage.DiscardTransaction()
t.Fatalf("Failed to set in transaction: %v", err)
}
storage.DiscardTransaction()
// Verify changes were not persisted for 'key'
val, err := storage.Get(key)
if err != nil { // Assuming (nil, nil) for not found, or check for specific not-found error
t.Fatalf("Get after discard failed for transactional key: %v", err)
}
if val != nil {
t.Error("Expected nil value for transactional key after discarding transaction")
}
// Verify outer key is still accessible (if transactions don't block normal ops)
// This depends on the implementation detail of how transactions interact with non-transactional ops.
// If OpenTransaction acquires a lock, this Get might behave differently.
// For now, assuming Get outside transaction should work.
retrievedOuter, err := storage.Get(outerKey)
if err != nil {
t.Fatalf("Get after discard failed for outer key: %v", err)
}
if !reflect.DeepEqual(retrievedOuter, outerValue) {
t.Errorf("Outer key value changed or became inaccessible after discard: got %v, want %v", retrievedOuter, outerValue)
}
})
}
// TestPersistence verifies that data persists after closing and reopening the database
func TestPersistence(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "persist.db"
key := "persist-key"
value := []byte("persist-value")
// First session: write data
func() {
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
defer storage.Close()
err := storage.Set(key, value)
if err != nil {
t.Fatalf("Failed to set value: %v", err)
}
}() // storage is closed here
// Second session: verify data
func() {
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
defer storage.Close()
retrieved, err := storage.Get(key)
if err != nil {
t.Fatalf("Failed to get value: %v", err)
}
if !reflect.DeepEqual(retrieved, value) {
t.Errorf("Retrieved value doesn't match after reopen: got %v, want %v", retrieved, value)
}
}() // storage is closed here
}
// TestDatabaseError tests error handling for invalid database operations
func TestDatabaseError(t *testing.T) {
dir := testDir(t)
defer cleanup(t, dir)
dbName := "test.db"
config := &MockLevelDBConfigProvider{
Path: filepath.Join(dir, dbName),
}
storage := NewDiskStorage(config, zap.NewExample())
// Test argument validation (should ideally be tested on an open DB,
// but original test implies testing on closed DB or combined effects)
// If these are meant to be pure argument validation, they should be done before Close().
// For now, keeping original structure.
// Test Set with empty key (on an open DB first, then closed)
// Let's assume the Set method itself validates this, regardless of DB state.
// If Set returns ErrClosed when DB is closed, it might mask empty key error.
// To test empty key specifically:
if err := storage.Set("", []byte("value")); err == nil { // This might be an error from the underlying DB for empty key
t.Error("Expected error setting empty key (on open DB or for argument validation)")
}
// Test Set with nil value
if err := storage.Set("key", nil); err == nil { // This might be an error from underlying DB for nil value
t.Error("Expected error setting nil value (on open DB or for argument validation)")
}
// Now, close the database to force errors for subsequent operations
errClose := storage.Close()
if errClose != nil {
t.Fatalf("Failed to close storage for error testing: %v", errClose)
}
// Test database operations on a closed DB
t.Run("Operations on Closed DB", func(t *testing.T) {
if err := storage.Set("another-key", []byte("value")); err == nil {
t.Error("Expected error setting on a closed database")
}
if _, err := storage.Get("another-key"); err == nil {
t.Error("Expected error getting from a closed database")
}
if err := storage.Delete("another-key"); err == nil {
t.Error("Expected error deleting from a closed database")
}
if err := storage.Iterate(func(k, v []byte) error { return nil }); err == nil {
t.Error("Expected error iterating on a closed database")
}
// Test OpenTransaction on a closed DB
// Original comment: "OpenTransaction returns nil even on error per implementation"
// This behavior is unusual. A robust implementation should return an error.
err := storage.OpenTransaction()
// If the contract is that it returns nil error even if DB is closed:
if err != nil {
t.Errorf("OpenTransaction returned an error (%v), expected nil error even when db is closed based on original test comment", err)
}
// Even if OpenTransaction returns nil error, it shouldn't have actually created a transaction.
if impl, ok := storage.(*storageImpl); ok {
if impl.transaction != nil {
t.Error("Transaction should be nil after OpenTransaction on a closed DB, even if no error was returned by OpenTransaction")
}
} else {
t.Fatal("Expected storageImpl instance for checking transaction state")
}
// CommitTransaction on a closed DB (and no active transaction)
if err := storage.CommitTransaction(); err == nil {
t.Error("Expected error committing transaction on a closed database / no active transaction")
}
// DiscardTransaction on a closed DB (and no active transaction)
// Discard is often idempotent, so it might not error.
storage.DiscardTransaction() // Assuming this is safe to call.
// Closing an already closed DB
if err := storage.Close(); err == nil {
// This depends on the desired behavior of Close(). Some are idempotent, others error.
// t.Error("Expected error when closing an already closed database, if that's the contract")
}
})
}