all repos — homestead @ 82424b77fba708e4450c1a0cec5b0c7967b13d7b

Code for my website

shared/storage/sqlite/reader.go (view raw)

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
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
}