forked from arp242/goatcounter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
size.go
67 lines (56 loc) · 1.51 KB
/
size.go
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
package goatcounter
import (
"context"
"fmt"
"strconv"
"zgo.at/errors"
"zgo.at/zcache"
"zgo.at/zdb"
)
type Size struct {
ID int64 `db:"size_id"`
Width int16 `db:"width"`
Height int16 `db:"height"`
Scale float64 `db:"scale"`
Size string `db:"size"`
}
func (s *Size) Defaults(ctx context.Context) {}
func (s *Size) Validate(ctx context.Context) error { return nil }
func (s Size) String() string {
return strconv.Itoa(int(s.Width)) + "," + strconv.Itoa(int(s.Height)) +
"," + strconv.FormatFloat(s.Scale, 'f', 15, 64)
}
func (s *Size) GetOrInsert(ctx context.Context, size Floats) error {
k := fmt.Sprintf("%v", size)
c, ok := cacheSizes(ctx).Get(k)
if ok {
*s = c.(Size)
cacheSizes(ctx).Touch(k, zcache.DefaultExpiration)
return nil
}
// Sometimes people send invalid values; don't error out, just set as
// unknown size.
if len(size) != 3 {
s.ID = 0
cacheSizes(ctx).SetDefault(k, *s)
return nil
}
s.Width, s.Height, s.Scale = int16(size[0]), int16(size[1]), size[2]
err := zdb.Get(ctx, s, `/* Size.GetOrInsert */
select * from sizes where size = ? limit 1`, s.String())
if err == nil {
cacheSizes(ctx).SetDefault(k, *s)
return nil
}
if !zdb.ErrNoRows(err) {
return errors.Wrap(err, "Size.GetOrInsert get")
}
s.ID, err = zdb.InsertID(ctx, "size_id",
`insert into sizes (width, height, scale) values (?, ?, ?)`,
s.Width, s.Height, s.Scale)
if err != nil {
return errors.Wrap(err, "Size.GetOrInsert insert")
}
cacheSizes(ctx).SetDefault(k, *s)
return nil
}