From 088d41e8a20f2f50fa45d5d5ecf15e0d6e46fdfc Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Sun, 9 Jul 2023 21:27:59 +0200 Subject: [PATCH] option to set entry for binary file --- app/binary_service.go | 2 +- app/repository/interfaces.go | 3 +- cmd/owl/import_v1.go | 28 ++++++++++++++ infra/binary_file_repository.go | 58 +++++++++++++++++++++++----- infra/binary_file_repository_test.go | 6 +-- 5 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 cmd/owl/import_v1.go diff --git a/app/binary_service.go b/app/binary_service.go index 4ef64b7..e2b8949 100644 --- a/app/binary_service.go +++ b/app/binary_service.go @@ -14,7 +14,7 @@ func NewBinaryFileService(repo repository.BinaryRepository) *BinaryService { } func (s *BinaryService) Create(name string, file []byte) (*model.BinaryFile, error) { - return s.repo.Create(name, file) + return s.repo.Create(name, file, nil) } func (s *BinaryService) FindById(id string) (*model.BinaryFile, error) { diff --git a/app/repository/interfaces.go b/app/repository/interfaces.go index ae51e39..15341ae 100644 --- a/app/repository/interfaces.go +++ b/app/repository/interfaces.go @@ -17,8 +17,9 @@ type BinaryRepository interface { // Create creates a new binary file // The name is the original file name, and is not unique // BinaryFile.Id is a unique identifier - Create(name string, data []byte) (*model.BinaryFile, error) + Create(name string, data []byte, entry model.Entry) (*model.BinaryFile, error) FindById(id string) (*model.BinaryFile, error) + FindByNameForEntry(name string, entry model.Entry) (*model.BinaryFile, error) } type AuthorRepository interface { diff --git a/cmd/owl/import_v1.go b/cmd/owl/import_v1.go new file mode 100644 index 0000000..143fd04 --- /dev/null +++ b/cmd/owl/import_v1.go @@ -0,0 +1,28 @@ +package main + +import ( + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(importCmd) + + importCmd.Flags().StringVarP(&user, "path", "p", "", "Path to the user folder") + importCmd.MarkFlagRequired("path") +} + +var importCmd = &cobra.Command{ + Use: "import", + Short: "Import data from v1", + Long: `Import data from v1`, + Run: func(cmd *cobra.Command, args []string) { + // db := infra.NewSqliteDB(DbPath) + // App(db).ImportV1() + + // TODO: Implement this + // For each folder in the user folder + // Map to entry types + // Convert and save + // Import Binary files + }, +} diff --git a/infra/binary_file_repository.go b/infra/binary_file_repository.go index 0adba28..47d29a4 100644 --- a/infra/binary_file_repository.go +++ b/infra/binary_file_repository.go @@ -1,18 +1,19 @@ package infra import ( + "fmt" "owl-blogs/app/repository" "owl-blogs/domain/model" "strings" - "github.com/google/uuid" "github.com/jmoiron/sqlx" ) type sqlBinaryFile struct { - Id string `db:"id"` - Name string `db:"name"` - Data []byte `db:"data"` + Id string `db:"id"` + Name string `db:"name"` + EntryId *string `db:"entry_id"` + Data []byte `db:"data"` } type DefaultBinaryFileRepo struct { @@ -29,6 +30,7 @@ func NewBinaryFileRepo(db Database) repository.BinaryRepository { CREATE TABLE IF NOT EXISTS binary_files ( id VARCHAR(255) PRIMARY KEY, name VARCHAR(255) NOT NULL, + entry_id VARCHAR(255), data BLOB NOT NULL ); `) @@ -37,15 +39,41 @@ func NewBinaryFileRepo(db Database) repository.BinaryRepository { } // Create implements repository.BinaryRepository -func (repo *DefaultBinaryFileRepo) Create(name string, data []byte) (*model.BinaryFile, error) { - id := uuid.New().String() +func (repo *DefaultBinaryFileRepo) Create(name string, data []byte, entry model.Entry) (*model.BinaryFile, error) { parts := strings.Split(name, ".") - if len(parts) > 1 { - ext := parts[len(parts)-1] - id = id + "." + ext + fileName := strings.Join(parts[:len(parts)-1], ".") + fileExt := parts[len(parts)-1] + id := fileName + "." + fileExt + + // check if id exists + var count int + err := repo.db.Get(&count, "SELECT COUNT(*) FROM binary_files WHERE id = ?", id) + if err != nil { + return nil, err } - _, err := repo.db.Exec("INSERT INTO binary_files (id, name, data) VALUES (?, ?, ?)", id, name, data) + if count > 0 { + counter := 1 + for { + id = fmt.Sprintf("%s-%d.%s", fileName, counter, fileExt) + err := repo.db.Get(&count, "SELECT COUNT(*) FROM binary_files WHERE id = ?", id) + if err != nil { + return nil, err + } + if count == 0 { + break + } + counter++ + } + } + + var entryId *string + if entry != nil { + eId := entry.ID() + entryId = &eId + } + + _, err = repo.db.Exec("INSERT INTO binary_files (id, name, entry_id, data) VALUES (?, ?, ?, ?)", id, name, entryId, data) if err != nil { return nil, err } @@ -61,3 +89,13 @@ func (repo *DefaultBinaryFileRepo) FindById(id string) (*model.BinaryFile, error } return &model.BinaryFile{Id: sqlFile.Id, Name: sqlFile.Name, Data: sqlFile.Data}, nil } + +// FindByNameForEntry implements repository.BinaryRepository +func (repo *DefaultBinaryFileRepo) FindByNameForEntry(name string, entry model.Entry) (*model.BinaryFile, error) { + var sqlFile sqlBinaryFile + err := repo.db.Get(&sqlFile, "SELECT * FROM binary_files WHERE name = ? AND entry_id = ?", name, entry.ID()) + if err != nil { + return nil, err + } + return &model.BinaryFile{Id: sqlFile.Id, Name: sqlFile.Name, Data: sqlFile.Data}, nil +} diff --git a/infra/binary_file_repository_test.go b/infra/binary_file_repository_test.go index d4e7853..dcb6a5e 100644 --- a/infra/binary_file_repository_test.go +++ b/infra/binary_file_repository_test.go @@ -18,7 +18,7 @@ func setupBinaryRepo() repository.BinaryRepository { func TestBinaryRepoCreate(t *testing.T) { repo := setupBinaryRepo() - file, err := repo.Create("name", []byte("😀 😃 😄 😁")) + file, err := repo.Create("name", []byte("😀 😃 😄 😁"), nil) require.NoError(t, err) file, err = repo.FindById(file.Id) @@ -30,10 +30,10 @@ func TestBinaryRepoCreate(t *testing.T) { func TestBinaryRepoNoSideEffect(t *testing.T) { repo := setupBinaryRepo() - file, err := repo.Create("name1", []byte("111")) + file, err := repo.Create("name1", []byte("111"), nil) require.NoError(t, err) - file2, err := repo.Create("name2", []byte("222")) + file2, err := repo.Create("name2", []byte("222"), nil) require.NoError(t, err) file, err = repo.FindById(file.Id)