vorteil/direktiv

View on GitHub
pkg/filestore/filestoresql/filestore.go

Summary

Maintainability
A
1 hr
Test Coverage
package filestoresql

import (
    "context"
    "errors"
    "fmt"

    "github.com/direktiv/direktiv/pkg/filestore"
    "github.com/google/uuid"
    "gorm.io/gorm"
)

type sqlFileStore struct {
    db *gorm.DB
}

func (s *sqlFileStore) ForRootID(rootID uuid.UUID) filestore.RootQuery {
    return &RootQuery{
        rootID:       rootID,
        db:           s.db,
        checksumFunc: filestore.DefaultCalculateChecksum,
    }
}

func (s *sqlFileStore) ForNamespace(namespace string) filestore.RootQuery {
    return &RootQuery{
        namespace:    namespace,
        db:           s.db,
        checksumFunc: filestore.DefaultCalculateChecksum,
    }
}

func (s *sqlFileStore) ForFile(file *filestore.File) filestore.FileQuery {
    return &FileQuery{
        file:         file,
        checksumFunc: filestore.DefaultCalculateChecksum,
        db:           s.db,
    }
}

var _ filestore.FileStore = &sqlFileStore{} // Ensures sqlFileStore struct conforms to filestore.FileStore interface.

func NewSQLFileStore(db *gorm.DB) filestore.FileStore {
    return &sqlFileStore{
        db: db,
    }
}

func (s *sqlFileStore) CreateRoot(ctx context.Context, rootID uuid.UUID, namespace string) (*filestore.Root, error) {
    n := &filestore.Root{
        ID:        rootID,
        Namespace: namespace,
    }
    res := s.db.WithContext(ctx).Table("filesystem_roots").Create(n)
    if res.Error != nil {
        return nil, res.Error
    }
    if res.RowsAffected != 1 {
        return nil, fmt.Errorf("unexpected gorm create count, got: %d, want: %d", res.RowsAffected, 1)
    }

    return n, nil
}

func (s *sqlFileStore) CreateTempRoot(ctx context.Context, rootID uuid.UUID) (*filestore.Root, error) {
    n := &filestore.Root{
        ID: rootID,
    }
    res := s.db.WithContext(ctx).Table("filesystem_roots").Create(n)
    if res.Error != nil {
        return nil, res.Error
    }
    if res.RowsAffected != 1 {
        return nil, fmt.Errorf("unexpected gorm create count, got: %d, want: %d", res.RowsAffected, 1)
    }

    return n, nil
}

func (s *sqlFileStore) GetRoot(ctx context.Context, id uuid.UUID) (*filestore.Root, error) {
    var list []filestore.Root
    res := s.db.WithContext(ctx).Raw(`
                    SELECT *
                    FROM filesystem_roots
                    WHERE id = ?
                    `, id).Find(&list)
    if res.Error != nil {
        return nil, res.Error
    }

    if len(list) == 0 {
        return nil, filestore.ErrNotFound
    }

    return &list[0], nil
}

func (s *sqlFileStore) GetAllRoots(ctx context.Context) ([]*filestore.Root, error) {
    var list []filestore.Root
    res := s.db.WithContext(ctx).Raw(`
                    SELECT *
                    FROM filesystem_roots
                    `).Find(&list)
    if res.Error != nil {
        return nil, res.Error
    }

    ns := []*filestore.Root{}
    for i := range list {
        ns = append(ns, &list[i])
    }

    return ns, nil
}

func (s *sqlFileStore) GetRootByNamespace(ctx context.Context, namespace string) (*filestore.Root, error) {
    var list []filestore.Root
    res := s.db.WithContext(ctx).Raw(`
                    SELECT *
                    FROM filesystem_roots
                    WHERE namespace = ?
                    `, namespace).Find(&list)
    if res.Error != nil {
        return nil, res.Error
    }

    if len(list) == 0 {
        return nil, filestore.ErrNotFound
    }

    return &list[0], nil
}

func (s *sqlFileStore) GetFileByID(ctx context.Context, id uuid.UUID) (*filestore.File, error) {
    file := &filestore.File{}
    res := s.db.WithContext(ctx).Raw(`
                    SELECT id, root_id, path, depth, typ, created_at, updated_at, mime_type, length(data) AS size
                    FROM filesystem_files
                    WHERE id=?`, id).
        First(file)

    if res.Error != nil {
        if errors.Is(res.Error, gorm.ErrRecordNotFound) {
            return nil, fmt.Errorf("file '%s': %w", id, filestore.ErrNotFound)
        }

        return nil, res.Error
    }

    return file, nil
}