github.com/raphaelreyna/latte@v0.11.2-0.20220317193248-98e2fcef4eef/internal/server/database.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  
    10  	"github.com/raphaelreyna/go-recon"
    11  )
    12  
    13  type DB interface {
    14  	// Store should be capable of storing a given []byte or contents of an io.ReadCloser
    15  	Store(ctx context.Context, uid string, i interface{}) error
    16  	// Fetch should return either a []byte, or io.ReadCloser.
    17  	// If the requested resource could not be found, error should be of type NotFoundError
    18  	Fetch(ctx context.Context, uid string) (interface{}, error)
    19  	// Ping should check if the databases is reachable, if return error should be nil and non-nil otherwise.
    20  	Ping(ctx context.Context) error
    21  	recon.Source
    22  }
    23  
    24  type NotFoundError struct{}
    25  
    26  func (nfe *NotFoundError) Error() string {
    27  	return "blob not found in database"
    28  }
    29  
    30  // toDisk only accepts argument i of types []byte or io.ReadCloser
    31  func toDisk(i interface{}, path string) error {
    32  	switch t := i.(type) {
    33  	case []byte:
    34  		bytes := i.([]byte)
    35  		if bytes == nil {
    36  			return fmt.Errorf("received nil pointer to []byte")
    37  		}
    38  		return ioutil.WriteFile(path, i.([]byte), os.ModePerm)
    39  	case io.ReadCloser:
    40  		f, err := os.Create(path)
    41  		if err != nil {
    42  			return err
    43  		}
    44  		rc := i.(io.ReadCloser)
    45  		if rc == nil {
    46  			return fmt.Errorf("received nil pointer to io.ReadCloser")
    47  		}
    48  		if _, err = io.Copy(f, rc); err != nil {
    49  			return err
    50  		}
    51  
    52  	default:
    53  		return fmt.Errorf("received interface of unexpected type: %v", t)
    54  	}
    55  	return nil
    56  }