Skip to content

Instantly share code, notes, and snippets.

@keidrun
Last active May 20, 2024 13:42
Show Gist options
  • Save keidrun/d1b2791f840753e25070771b857af7ba to your computer and use it in GitHub Desktop.
Save keidrun/d1b2791f840753e25070771b857af7ba to your computer and use it in GitHub Desktop.
How to marshal and unmarshal sql.Null types to JSON in golang

Answer

Use custom nullable types instead of original sql.Null types like sql.NullBool, sql.NullFloat64, sql.NullInt64 or sql.NullString.

package models
import (
"database/sql"
"encoding/json"
)
// Nullable Bool that overrides sql.NullBool
type NullBool struct {
sql.NullBool
}
func (nb NullBool) MarshalJSON() ([]byte, error) {
if nb.Valid {
return json.Marshal(nb.Bool)
}
return json.Marshal(nil)
}
func (nb *NullBool) UnmarshalJSON(data []byte) error {
var b *bool
if err := json.Unmarshal(data, &b); err != nil {
return err
}
if b != nil {
nb.Valid = true
nb.Bool = *b
} else {
nb.Valid = false
}
return nil
}
// Nullable Float64 that overrides sql.NullFloat64
type NullFloat64 struct {
sql.NullFloat64
}
func (nf NullFloat64) MarshalJSON() ([]byte, error) {
if nf.Valid {
return json.Marshal(nf.Float64)
}
return json.Marshal(nil)
}
func (nf *NullFloat64) UnmarshalJSON(data []byte) error {
var f *float64
if err := json.Unmarshal(data, &f); err != nil {
return err
}
if f != nil {
nf.Valid = true
nf.Float64 = *f
} else {
nf.Valid = false
}
return nil
}
// Nullable Int64 that overrides sql.NullInt64
type NullInt64 struct {
sql.NullInt64
}
func (ni NullInt64) MarshalJSON() ([]byte, error) {
if ni.Valid {
return json.Marshal(ni.Int64)
}
return json.Marshal(nil)
}
func (ni *NullInt64) UnmarshalJSON(data []byte) error {
var i *int64
if err := json.Unmarshal(data, &i); err != nil {
return err
}
if i != nil {
ni.Valid = true
ni.Int64 = *i
} else {
ni.Valid = false
}
return nil
}
// Nullable String that overrides sql.NullString
type NullString struct {
sql.NullString
}
func (ns NullString) MarshalJSON() ([]byte, error) {
if ns.Valid {
return json.Marshal(ns.String)
}
return json.Marshal(nil)
}
func (ns *NullString) UnmarshalJSON(data []byte) error {
var s *string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
if s != nil {
ns.Valid = true
ns.String = *s
} else {
ns.Valid = false
}
return nil
}
@pior
Copy link

pior commented Mar 27, 2024

What's the difference between this and https://github.com/guregu/null?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment