diff options
Diffstat (limited to 'pkg/types/string.go')
-rw-r--r-- | pkg/types/string.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/pkg/types/string.go b/pkg/types/string.go new file mode 100644 index 0000000..f8ead45 --- /dev/null +++ b/pkg/types/string.go @@ -0,0 +1,74 @@ +package types + +import ( + "bytes" + "database/sql" + "database/sql/driver" + "encoding" + "encoding/json" + "github.com/icinga/icingadb/internal" + "strings" +) + +// String adds JSON support to sql.NullString. +type String struct { + sql.NullString +} + +// MarshalJSON implements the json.Marshaler interface. +// Supports JSON null. +func (s String) MarshalJSON() ([]byte, error) { + var v interface{} + if s.Valid { + v = s.String + } + + return internal.MarshalJSON(v) +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (s *String) UnmarshalText(text []byte) error { + *s = String{sql.NullString{ + String: string(text), + Valid: true, + }} + + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// Supports JSON null. +func (s *String) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if bytes.HasPrefix(data, []byte{'n'}) { + return nil + } + + if err := internal.UnmarshalJSON(data, &s.String); err != nil { + return err + } + + s.Valid = true + + return nil +} + +// Value implements the driver.Valuer interface. +// Supports SQL NULL. +func (s String) Value() (driver.Value, error) { + if !s.Valid { + return nil, nil + } + + // PostgreSQL does not allow null bytes in varchar, char and text fields. + return strings.ReplaceAll(s.String, "\x00", ""), nil +} + +// Assert interface compliance. +var ( + _ json.Marshaler = String{} + _ encoding.TextUnmarshaler = (*String)(nil) + _ json.Unmarshaler = (*String)(nil) + _ driver.Valuer = String{} + _ sql.Scanner = (*String)(nil) +) |