Skip to content

Instantly share code, notes, and snippets.

@timbaileyjones
Forked from keidrun/README.md
Created January 3, 2024 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timbaileyjones/5d481b4c3587a8e4fa54c64be203054d to your computer and use it in GitHub Desktop.
Save timbaileyjones/5d481b4c3587a8e4fa54c64be203054d 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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment