-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtype_time.go
110 lines (86 loc) · 2 KB
/
type_time.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
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
package parco
import (
"encoding/binary"
"io"
"time"
)
var (
noopTime = time.Time{}
timeByteLength = 8
)
type (
TimeType struct {
locationType OptionalType[string]
pooler Pooler
}
)
func (t TimeType) ByteLength() int {
return timeByteLength
}
func (t TimeType) Parse(r io.Reader) (time.Time, error) {
box := t.pooler.Get(timeByteLength)
defer t.pooler.Put(box)
data := *box
data = data[:timeByteLength]
n, err := r.Read(data)
if n != timeByteLength || err != nil {
return noopTime, ErrCannotRead
}
tim, err := ParseTime(data, binary.LittleEndian)
if err != nil {
return noopTime, err
}
locationRaw, err := t.locationType.Parse(r)
if err != nil || locationRaw == nil {
return noopTime, err
}
loc, err := time.LoadLocation(*locationRaw)
if err != nil {
return noopTime, err
}
return tim.In(loc), nil
}
func (t TimeType) Compile(tt time.Time, w io.Writer) error {
box := t.pooler.Get(timeByteLength)
defer t.pooler.Put(box)
data := *box
data = data[:timeByteLength]
err := CompileTime(tt, data, binary.LittleEndian)
if err != nil {
return err
}
if n, err := w.Write(data); err != nil || n != timeByteLength {
return ErrCannotWrite
}
if loc := tt.Location(); loc != nil {
return t.locationType.Compile(Ptr(loc.String()), w)
}
return nil
}
func CompileTime(t time.Time, box []byte, order binary.ByteOrder) error {
return CompileInt64(t.UnixNano(), box, order)
}
func ParseTime(box []byte, order binary.ByteOrder) (time.Time, error) {
i64, err := ParseInt64(box, order)
if err != nil {
return noopTime, err
}
return time.Unix(0, i64).UTC(), nil
}
func TimeLocation() Type[time.Time] {
return TimeType{
locationType: Option(SmallVarchar()),
pooler: SinglePool,
}
}
func TimeUTC() Type[time.Time] {
return NewFixedType[time.Time](
timeByteLength,
func(data []byte) (time.Time, error) {
return ParseTime(data, binary.LittleEndian)
},
func(t time.Time, box []byte) error {
return CompileTime(t, box, binary.LittleEndian)
},
)
}