forked from moisespsena-go/aorm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gzb.go
111 lines (95 loc) · 1.96 KB
/
gzb.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
111
package types
import (
"bytes"
"compress/gzip"
"database/sql/driver"
"fmt"
"io/ioutil"
"reflect"
"github.com/go-aorm/aorm"
)
type (
Gzb struct {
Compressed bool
Data []byte
}
GzbAssigner struct {
}
)
func (this Gzb) Value() (driver.Value, error) {
var out = make([]byte, len(this.Data)+1, len(this.Data)+1)
if this.Compressed {
out[1] = 1
copy(out[1:], this.Data)
} else if len(this.Data) > 512 {
var w bytes.Buffer
w.WriteByte(1)
gzw := gzip.NewWriter(&w)
if _, err := gzw.Write(this.Data); err != nil {
return "", err
}
gzw.Close()
return w.Bytes(), nil
} else {
copy(out[1:], this.Data)
}
return out, nil
}
func init() {
aorm.Register(GzbAssigner{})
}
func (this *Gzb) Scan(src interface{}) error {
*this = Gzb{}
if src == nil || len(src.([]byte)) == 0 {
return nil
}
b := src.([]byte)
this.Compressed = b[0] == 1
this.Data = b[1:]
return nil
}
func (this Gzb) IsZero() bool {
return len(this.Data) == 0
}
func (this *Gzb) MustGet() (b []byte) {
b, _ = this.Get()
return
}
func (this *Gzb) String() string {
return string(this.MustGet())
}
func (this *Gzb) Get() (_ []byte, err error) {
if this.Compressed {
buf := bytes.NewBuffer(this.Data)
var r *gzip.Reader
if r, err = gzip.NewReader(buf); err != nil {
return
}
var uc []byte
if uc, err = ioutil.ReadAll(r); err != nil {
return
}
this.Compressed = false
this.Data = uc
return uc, nil
}
return this.Data, nil
}
func (GzbAssigner) Valuer(_ aorm.Dialector, value interface{}) driver.Valuer {
return value.(Gzb)
}
func (GzbAssigner) Scaner(_ *aorm.Scope, dest *aorm.Field) aorm.Scanner {
return dest.Field.Addr().Interface().(*Gzb)
}
func (GzbAssigner) SQLType(_ *aorm.StructField, d aorm.Dialector) (string, string) {
if d.GetName() == "postgres" {
return "BYTEA", ""
}
return fmt.Sprintf("BLOB"), ""
}
func (GzbAssigner) SQLSize(_ aorm.Dialector) int {
return 0
}
func (GzbAssigner) Type() reflect.Type {
return reflect.TypeOf(Gzb{})
}