package main import ( // External "github.com/jmoiron/sqlx" // Standard "fmt" "os" "path" "time" ) type File struct { ID int UUID string UserID int `db:"user_id"` Filename string Size int MIME string Modified time.Time } var ( fileUUIDCache map[string]int ) func init() { fileUUIDCache = make(map[string]int) } func AddFileToDb(userID int, file *File) (err error) { // {{{ file.UserID = userID var rows *sqlx.Rows rows, err = db.Queryx(` INSERT INTO public.file(user_id, uuid, name, size, type, modified, upload_complete) VALUES($1, $2, $3, $4, $5, $6, false) ON CONFLICT (user_id, uuid) DO UPDATE set name = public.file.name RETURNING id `, file.UserID, file.UUID, file.Filename, file.Size, file.MIME, file.Modified, ) if err != nil { return } defer rows.Close() rows.Next() err = rows.Scan(&file.ID) return } // }}} func Files(userID int, nodeUUID string, fileID int) (files []File, err error) { // {{{ var rows *sqlx.Rows rows, err = db.Queryx( `SELECT * FROM file WHERE user_id = $1 AND node_uuid = $2 AND CASE $3::int WHEN 0 THEN true ELSE id = $3 END`, userID, nodeUUID, fileID, ) if err != nil { return } defer rows.Close() files = []File{} for rows.Next() { file := File{} if err = rows.StructScan(&file); err != nil { return } files = append(files, file) } return } // }}} func FileIDToPath(id int) (string, string) { // {{{ str := fmt.Sprintf("%012d", id) dir := path.Join(config.Storage.Files, str[0:4], str[4:8]) fpath := path.Join(config.Storage.Files, str[0:4], str[4:8], str[8:12]) return dir, fpath } // }}} func FileWriteData(userID int, dbID int, data []byte, create bool) (err error) {// {{{ dir, fpath := FileIDToPath(dbID) err = os.MkdirAll(dir, 0700) if err != nil { Log.Error("file", "error", err) return } var f *os.File if create { f, err = os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) } else { f, err = os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) } if err != nil { Log.Error("file", "error", err) return } defer f.Close() _, err = f.Write(data) if err != nil { Log.Error("file", "error", err) return } return }// }}} // vim: foldmethod=marker