package sqlite import ( "context" "database/sql" "encoding/json" "strings" "time" "alin.ovh/homestead/shared/buffer" "alin.ovh/homestead/shared/storage" "alin.ovh/homestead/shared/storage/sqlite/db" "alin.ovh/x/log" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg" ) type Reader struct { log *log.Logger queries *db.Queries } func NewReader(conn *sql.DB, log *log.Logger) (*Reader, error) { r := &Reader{ log: log, queries: db.New(conn), } return r, nil } func (r *Reader) GetFile(filename string) (*storage.File, error) { file := &storage.File{ Encodings: make(map[string]*buffer.Buffer, 1), } r.log.Debug("querying db for file", "filename", filename) rows, err := r.queries.GetFile(context.TODO(), filename) if err != nil { return nil, fault.Wrap(err, fmsg.With("querying database")) } count := 0 for _, row := range rows { count++ file.ContentType = row.File.ContentType file.LastModified = time.Unix(row.File.LastModified, 0) file.Etag = row.File.Etag file.Title = row.File.Title file.StyleHash = row.File.StyleHash if len(row.File.Headers) > 2 { err := json.Unmarshal(row.File.Headers, &file.Headers) if err != nil { return nil, fault.Wrap(err, fmsg.With("unmarshalling headers")) } } file.Encodings[row.Content.Encoding] = buffer.NewBuffer(row.Content.Body) } if count == 0 { return nil, nil } return file, nil } func (r *Reader) CanonicalisePath(path string) (cPath string, differs bool) { cPath = path switch { case path == "/": differs = false case strings.HasSuffix(path, "/index.xml"): cPath, differs = strings.TrimSuffix(path, "index.xml")+"atom.xml", true case strings.HasSuffix(path, "/index.html"): cPath, differs = strings.CutSuffix(path, "index.html") case !strings.HasSuffix(path, "/"): d, err := r.queries.CheckPath(context.TODO(), cPath+"/") if err != nil { r.log.Warn("error canonicalising path", "path", path, "error", err) return } differs = d == 1 if differs { cPath += "/" } case strings.HasSuffix(path, "/"): tmp := strings.TrimSuffix(path, "/") d, err := r.queries.CheckPath(context.TODO(), tmp) if err != nil { r.log.Warn("error canonicalising path", "path", path, "error", err) return } differs = d == 1 if differs { cPath = tmp } } return }