Files
databasus/backend/internal/features/storages/model.go
2026-01-23 12:00:56 +03:00

168 lines
5.5 KiB
Go

package storages
import (
"context"
azure_blob_storage "databasus-backend/internal/features/storages/models/azure_blob"
ftp_storage "databasus-backend/internal/features/storages/models/ftp"
google_drive_storage "databasus-backend/internal/features/storages/models/google_drive"
local_storage "databasus-backend/internal/features/storages/models/local"
nas_storage "databasus-backend/internal/features/storages/models/nas"
rclone_storage "databasus-backend/internal/features/storages/models/rclone"
s3_storage "databasus-backend/internal/features/storages/models/s3"
sftp_storage "databasus-backend/internal/features/storages/models/sftp"
"databasus-backend/internal/util/encryption"
"errors"
"io"
"log/slog"
"github.com/google/uuid"
)
type Storage struct {
ID uuid.UUID `json:"id" gorm:"column:id;primaryKey;type:uuid;default:gen_random_uuid()"`
WorkspaceID uuid.UUID `json:"workspaceId" gorm:"column:workspace_id;not null;type:uuid;index"`
Type StorageType `json:"type" gorm:"column:type;not null;type:text"`
Name string `json:"name" gorm:"column:name;not null;type:text"`
LastSaveError *string `json:"lastSaveError" gorm:"column:last_save_error;type:text"`
IsSystem bool `json:"isSystem" gorm:"column:is_system;not null;default:false"`
// specific storage
LocalStorage *local_storage.LocalStorage `json:"localStorage" gorm:"foreignKey:StorageID"`
S3Storage *s3_storage.S3Storage `json:"s3Storage" gorm:"foreignKey:StorageID"`
GoogleDriveStorage *google_drive_storage.GoogleDriveStorage `json:"googleDriveStorage" gorm:"foreignKey:StorageID"`
NASStorage *nas_storage.NASStorage `json:"nasStorage" gorm:"foreignKey:StorageID"`
AzureBlobStorage *azure_blob_storage.AzureBlobStorage `json:"azureBlobStorage" gorm:"foreignKey:StorageID"`
FTPStorage *ftp_storage.FTPStorage `json:"ftpStorage" gorm:"foreignKey:StorageID"`
SFTPStorage *sftp_storage.SFTPStorage `json:"sftpStorage" gorm:"foreignKey:StorageID"`
RcloneStorage *rclone_storage.RcloneStorage `json:"rcloneStorage" gorm:"foreignKey:StorageID"`
}
func (s *Storage) SaveFile(
ctx context.Context,
encryptor encryption.FieldEncryptor,
logger *slog.Logger,
fileID uuid.UUID,
file io.Reader,
) error {
err := s.getSpecificStorage().SaveFile(ctx, encryptor, logger, fileID, file)
if err != nil {
lastSaveError := err.Error()
s.LastSaveError = &lastSaveError
return err
}
s.LastSaveError = nil
return nil
}
func (s *Storage) GetFile(
encryptor encryption.FieldEncryptor,
fileID uuid.UUID,
) (io.ReadCloser, error) {
return s.getSpecificStorage().GetFile(encryptor, fileID)
}
func (s *Storage) DeleteFile(encryptor encryption.FieldEncryptor, fileID uuid.UUID) error {
return s.getSpecificStorage().DeleteFile(encryptor, fileID)
}
func (s *Storage) Validate(encryptor encryption.FieldEncryptor) error {
if s.Type == "" {
return errors.New("storage type is required")
}
if s.Name == "" {
return errors.New("storage name is required")
}
return s.getSpecificStorage().Validate(encryptor)
}
func (s *Storage) TestConnection(encryptor encryption.FieldEncryptor) error {
return s.getSpecificStorage().TestConnection(encryptor)
}
func (s *Storage) HideSensitiveData() {
s.getSpecificStorage().HideSensitiveData()
}
func (s *Storage) HideAllData() {
s.LocalStorage = nil
s.S3Storage = nil
s.GoogleDriveStorage = nil
s.NASStorage = nil
s.AzureBlobStorage = nil
s.FTPStorage = nil
s.SFTPStorage = nil
s.RcloneStorage = nil
}
func (s *Storage) EncryptSensitiveData(encryptor encryption.FieldEncryptor) error {
return s.getSpecificStorage().EncryptSensitiveData(encryptor)
}
func (s *Storage) Update(incoming *Storage) {
s.Name = incoming.Name
s.Type = incoming.Type
s.IsSystem = incoming.IsSystem
switch s.Type {
case StorageTypeLocal:
if s.LocalStorage != nil && incoming.LocalStorage != nil {
s.LocalStorage.Update(incoming.LocalStorage)
}
case StorageTypeS3:
if s.S3Storage != nil && incoming.S3Storage != nil {
s.S3Storage.Update(incoming.S3Storage)
}
case StorageTypeGoogleDrive:
if s.GoogleDriveStorage != nil && incoming.GoogleDriveStorage != nil {
s.GoogleDriveStorage.Update(incoming.GoogleDriveStorage)
}
case StorageTypeNAS:
if s.NASStorage != nil && incoming.NASStorage != nil {
s.NASStorage.Update(incoming.NASStorage)
}
case StorageTypeAzureBlob:
if s.AzureBlobStorage != nil && incoming.AzureBlobStorage != nil {
s.AzureBlobStorage.Update(incoming.AzureBlobStorage)
}
case StorageTypeFTP:
if s.FTPStorage != nil && incoming.FTPStorage != nil {
s.FTPStorage.Update(incoming.FTPStorage)
}
case StorageTypeSFTP:
if s.SFTPStorage != nil && incoming.SFTPStorage != nil {
s.SFTPStorage.Update(incoming.SFTPStorage)
}
case StorageTypeRclone:
if s.RcloneStorage != nil && incoming.RcloneStorage != nil {
s.RcloneStorage.Update(incoming.RcloneStorage)
}
}
}
func (s *Storage) getSpecificStorage() StorageFileSaver {
switch s.Type {
case StorageTypeLocal:
return s.LocalStorage
case StorageTypeS3:
return s.S3Storage
case StorageTypeGoogleDrive:
return s.GoogleDriveStorage
case StorageTypeNAS:
return s.NASStorage
case StorageTypeAzureBlob:
return s.AzureBlobStorage
case StorageTypeFTP:
return s.FTPStorage
case StorageTypeSFTP:
return s.SFTPStorage
case StorageTypeRclone:
return s.RcloneStorage
default:
panic("invalid storage type: " + string(s.Type))
}
}