gzip.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package types
  2. import (
  3. "bytes"
  4. "compress/gzip"
  5. "database/sql/driver"
  6. "errors"
  7. "io"
  8. )
  9. // GzippedText is a []byte which transparently gzips data being submitted to
  10. // a database and ungzips data being Scanned from a database.
  11. type GzippedText []byte
  12. // Value implements the driver.Valuer interface, gzipping the raw value of
  13. // this GzippedText.
  14. func (g GzippedText) Value() (driver.Value, error) {
  15. b := make([]byte, 0, len(g))
  16. buf := bytes.NewBuffer(b)
  17. w := gzip.NewWriter(buf)
  18. w.Write(g)
  19. w.Close()
  20. return buf.Bytes(), nil
  21. }
  22. // Scan implements the sql.Scanner interface, ungzipping the value coming off
  23. // the wire and storing the raw result in the GzippedText.
  24. func (g *GzippedText) Scan(src interface{}) error {
  25. var source []byte
  26. switch src.(type) {
  27. case string:
  28. source = []byte(src.(string))
  29. case []byte:
  30. source = src.([]byte)
  31. default:
  32. return errors.New("Incompatible type for GzippedText")
  33. }
  34. reader, err := gzip.NewReader(bytes.NewReader(source))
  35. if err != nil {
  36. return err
  37. }
  38. defer reader.Close()
  39. b, err := io.ReadAll(reader)
  40. if err != nil {
  41. return err
  42. }
  43. *g = GzippedText(b)
  44. return nil
  45. }