-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdata.go
More file actions
187 lines (148 loc) · 4.45 KB
/
Copy pathdata.go
File metadata and controls
187 lines (148 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package main
import (
"errors"
"fmt"
"io/fs"
"os"
"strconv"
"strings"
"time"
"github.com/google/uuid"
)
const (
DefaultFilesMetaDataFileName string = "/store/file-data"
DefaultFilesFolderName string = "/store/files"
)
type FileMetaData struct {
id string
originalName string
creatingDate int
}
type FileMetaDataRepository interface {
Save(fileMetaData FileMetaData) (string, error)
GetById(id string) (FileMetaData, error)
}
type InFileFileMetaDataRepository struct {
StorageFilePath string
}
func createInFileFileMetaDataRepository(storageFilePath string) InFileFileMetaDataRepository {
if storageFilePath == "" {
fmt.Printf("Files metadata file name empty. Default file name using -> %s\n", DefaultFilesMetaDataFileName)
storageFilePath = DefaultFilesMetaDataFileName
}
return InFileFileMetaDataRepository{storageFilePath}
}
func (repo InFileFileMetaDataRepository) Save(fileMetaData FileMetaData) (string, error) {
if repo.StorageFilePath == "" {
return "", errors.New("StorageFilePath is empty")
}
file, err := os.OpenFile(repo.StorageFilePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
fmt.Printf("opening file-data file error: %s", err.Error())
if errors.Is(err, fs.ErrNotExist) {
file, err = os.Create(repo.StorageFilePath)
}
if err != nil {
fmt.Printf("creating file-data file error: %s\n", err.Error())
return "", err
}
}
defer file.Close()
_, err = file.Write([]byte(fmt.Sprintf("%s,%s,%d\n", fileMetaData.id, fileMetaData.originalName, fileMetaData.creatingDate)))
if err != nil {
fmt.Printf("writing file-data file error: %s\n", err.Error())
return "", err
}
return fileMetaData.id, nil
}
func (repo InFileFileMetaDataRepository) GetById(id string) (FileMetaData, error) {
if repo.StorageFilePath == "" {
return FileMetaData{}, errors.New("StorageFilePath is empty")
}
content, err := os.ReadFile(repo.StorageFilePath)
if err != nil {
fmt.Printf("reading file-data file: %s\n", err.Error())
return FileMetaData{}, err
}
storage := string(content)
lines := strings.Split(storage, "\n")
for _, line := range lines {
record := strings.Split(line, ",")
if len(record) < 3 {
continue
}
recordId := record[0]
if recordId == id {
originalName := record[1]
creatingDate, err := strconv.Atoi(record[2])
if err != nil {
creatingDate = 0
}
return FileMetaData{id, originalName, creatingDate}, nil
}
}
return FileMetaData{}, errors.New("file not found")
}
type OriginalFile struct {
Content []byte
Name string
}
type FileKeeper interface {
Save(file OriginalFile) (string, error)
GetById(id string) (OriginalFile, error)
}
type InFolderFileKeeper struct {
FolderName string
FileMetaDataRepository FileMetaDataRepository
}
func createInFolderFileKeeper(folderName string, fileMetaDataRepository FileMetaDataRepository) InFolderFileKeeper {
if folderName == "" {
fmt.Printf("Files folder name empty. Default folder name using -> %s\n", DefaultFilesFolderName)
folderName = DefaultFilesFolderName
}
if fileMetaDataRepository == nil {
panic("FileMetaDataRepository is nil")
}
return InFolderFileKeeper{folderName, fileMetaDataRepository}
}
func (fileKeeper InFolderFileKeeper) Save(file OriginalFile) (string, error) {
if fileKeeper.FolderName == "" {
return "", errors.New("FolderName is empty\n")
}
id := uuid.New().String()
err := os.MkdirAll(fileKeeper.FolderName, os.ModePerm)
if err != nil {
return "", err
}
f, err := os.Create(fmt.Sprintf("%s/%s", fileKeeper.FolderName, id))
if err != nil {
fmt.Printf("creating file error: %s\n", err.Error())
return "", err
}
defer f.Close()
_, err = f.Write(file.Content)
if err != nil {
fmt.Printf("writing file error: %s\n", err.Error())
return "", err
}
savedId, err := fileKeeper.FileMetaDataRepository.Save(FileMetaData{id, file.Name, int(time.Now().Unix())})
if err != nil {
fmt.Printf("saving file error: %s\n", err.Error())
return "", err
}
return savedId, nil
}
func (fileKeeper InFolderFileKeeper) GetById(id string) (OriginalFile, error) {
if fileKeeper.FolderName == "" {
return OriginalFile{}, errors.New("FolderName is empty")
}
fileMetaData, err := fileKeeper.FileMetaDataRepository.GetById(id)
if err != nil {
return OriginalFile{}, err
}
content, err := os.ReadFile(fmt.Sprintf("%s/%s", fileKeeper.FolderName, fileMetaData.id))
if err != nil {
return OriginalFile{}, err
}
return OriginalFile{content, fileMetaData.originalName}, nil
}