nullable

package
v0.0.0-...-ee62482 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 22 Imported by: 11

README

nullable

SQL-friendly nullable wrapper types and generic nullability interfaces. Each type has a single zero-like value (empty string, zero time, the zero-valued generic) that round-trips as SQL NULL and JSON null.

import "github.com/domonda/go-types/nullable"

Why "zero == null"?

Go has no native nullable-with-default sentinel for string/time.Time, and *string/*time.Time is awkward in struct fields. This package leans on a convention: the type's natural zero value ("", time.Time{}) maps to SQL/JSON null on both directions. Methods like IsNull, Get, GetOr, Set, SetNull make the convention explicit.

For "empty is meaningful, null is separate" semantics, use Type[T] (a generic struct with a valid flag).

Interfaces

type Nullable interface { IsNull() bool }

type NullSetable[T any] interface {
    Nullable
    SetNull()
    Set(T)
    Get() T              // panics if null
    GetOr(T) T
}

type Zeroable interface { IsZero() bool }

type NullableValidator interface {
    Nullable
    types.Validator
    ValidAndNotNull() bool
}

Helper: ReflectIsNull(v reflect.Value) bool walks pointers/maps/slices/etc. and checks Nullable or Zeroable if implemented. Safe on the zero reflect.Value.

Type[T] — generic nullable wrapper

type Type[T any] struct { /* unexported */ }

The zero Type[T]{} represents null; a valid flag distinguishes "absent" from "present with the zero value of T". Useful for int, bool, structs — anywhere 0 or false is a legal value.

nullable.TypeFrom(42)              // valid, value 42
nullable.TypeFromPtr[int](nil)     // null
nullable.TypeFromPtr(&someInt)     // valid

t.IsNull(); t.IsNotNull()
t.Get(); t.GetOr(defaultVal); t.Ptr()
t.Set(value); t.SetNull()

Implements driver.Valuer, sql.Scanner, json.Marshaler, json.Unmarshaler, JSONSchema. JSON null ↔ null; otherwise dispatch to T's JSON behavior. SQL uses an embedded convertAssign (copied from database/sql/convert.go) so most scalar conversions work without T needing to implement Scanner.

String wrappers

Type Null sentinel Notes
NonEmptyString "" Empty string ↔ null. Can't represent an explicit empty string.
TrimmedString "" (after trimming) All marshal/unmarshal trims whitespace; whitespace-only ↔ null.

Both ship constructors (...From(str), ...FromPtr(*string), ...FromError(err), ...f("%s", x)), null introspection (IsNull, IsNotNull, Get, GetOr, Ptr, StringOr), and SQL/JSON/text-marshaling interfaces.

TrimmedString additionally has the full strings-style API as methods (ToUpper, ToLower, Contains, HasPrefix, HasSuffix, TrimPrefix, TrimSuffix, ReplaceAll, Split, ToValidUTF8), each re-trimming the result. Also has XML marshal/unmarshal.

JoinNonEmptyStrings(sep, strs...) and TrimmedStringJoin(sep, strs...) skip null/empty entries.

Time

type Time struct { time.Time }

The zero time.Time{} ↔ null. IsNull uses time.Time.IsZero(). Constructors: TimeNow, TimeFrom, TimeFromPtr, TimeParse(layout, value), TimeParseInLocation. The parsers treat "", "null", "NULL" as null without error.

Wrapped methods (Add, AddDate, UTC, Format, AppendFormat, Equal) propagate null. String() returns "NULL" when null; use StringOr(s) to customize.

Text marshal: RFC 3339, with "NULL" for the null state. JSON: standard time.Time encoding with null for the null state. PrettyPrint integrates with github.com/domonda/go-pretty.

Array types

PostgreSQL array types that round-trip as SQL arrays and JSON arrays. The purpose of these types is to keep SQL NULL distinct from an empty array: only a nil slice is NULL. Scanning NULL yields a nil slice, while scanning the empty array '{}' yields a non-nil empty slice — so the NULL-vs-empty distinction survives a round-trip. (For never-null arrays where a nil slice should serialize as '{}'/[], use the sibling notnull package.)

Go value / SQL / JSON maps to
nil slice SQL NULL, JSON null
empty non-nil slice SQL '{}', JSON []
SQL NULL, JSON null nil slice
SQL empty array '{}', JSON [] empty non-nil slice

The driver.Valuer output and sql.Scanner input both use the PostgreSQL array text format ({a,b,c}). This works with PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type — MySQL, MariaDB, SQLite, SQL Server, Oracle — are not supported.

Type Element
StringArray string (aliases pq.StringArray)
IntArray int64
FloatArray float64
BoolArray bool
NullIntArray nullable elements
NullFloatArray nullable elements
NullBoolArray nullable elements

For non-nullable arrays where nil should serialize as '{}'/[], see the sibling notnull package.

Lower-level helpers: SplitArray(s) parses an SQL/JSON array literal into its top-level elements; SQLArrayLiteral(s) joins back. null/NULL decodes to a nil slice.

  • notnull — sibling package with the same array types but never-null semantics.
  • Most domain packages in go-types expose a parallel NullableX type using these conventions.

Documentation

Overview

Package nullable provides interfaces and utilities for handling nullable values in Go. It defines common interfaces for types that can represent null/zero states and provides reflection-based utilities for null checking.

The package includes: - Nullable interface for types that can represent null values - NullSetable interface for types that can be set to null and retrieved - Zeroable interface for types that can represent zero values - Reflection utilities for null/zero checking

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsNull

func IsNull(v any) bool

IsNull is the any-typed convenience wrapper around ReflectIsNull. See ReflectIsNull for the full unwrapping and dispatch rules.

IsNull never panics.

func ReflectIsNull

func ReflectIsNull(v reflect.Value) bool

ReflectIsNull returns true if v represents a "null" value, defined as:

  • the zero reflect.Value (Kind Invalid),
  • a nil pointer, interface, map, slice, channel, function, or unsafe.Pointer anywhere along the chain of pointer/interface unwrapping,
  • a value whose type (or addressable pointer-to-type) implements Nullable and whose IsNull method returns true,
  • a value whose type (or addressable pointer-to-type) implements Zeroable and whose IsZero method returns true (only when Nullable is not implemented).

Pointers and interfaces are unwrapped iteratively, so a non-nil **T pointing at a nil *T, or a non-nil interface holding a typed-nil pointer, are both reported as null without invoking IsNull on the nil receiver.

ReflectIsNull never panics. Values that cannot be passed to reflect.Value.Interface (for example, unexported struct fields) are reported as not-null instead.

func SQLArrayLiteral

func SQLArrayLiteral(s []string) string

SQLArrayLiteral joins the passed strings as an SQL array literal. A nil slice will produce NULL, pass an empty non nil slice to get the empty SQL array literal {} (use notnull.SQLArrayLiteral if a nil slice should also produce {}).

The result uses the PostgreSQL array text format ({"a","b"}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func SplitArray

func SplitArray(array string) ([]string, error)

SplitArray splits an SQL or JSON array into its top level elements. Array elements that are quoted strings will not be unquoted. Returns nil in case of an empty array ("{}" or "[]"). Passing "null" or "NULL" as array will return nil without an error.

Types

type BoolArray

type BoolArray = pq.BoolArray

BoolArray implements the sql.Scanner and driver.Valuer interfaces for a slice of bool. A nil slice is mapped to the SQL NULL value, and a non nil zero length slice to an empty SQL array '{}'.

Value and Scan use the PostgreSQL array text format ({t,f,t}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

type FloatArray

type FloatArray []float64

FloatArray implements the sql.Scanner and driver.Valuer interfaces for a slice of float64. A nil slice is mapped to the SQL NULL value, and a non nil zero length slice to an empty SQL array '{}'.

Value and Scan use the PostgreSQL array text format ({1.5,2,3}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func (FloatArray) Contains

func (a FloatArray) Contains(value float64) bool

Contains reports if the passed value is present in a.

func (FloatArray) IsNull

func (a FloatArray) IsNull() bool

IsNull returns true if a is nil. IsNull implements the Nullable interface.

func (FloatArray) Len

func (a FloatArray) Len() int

Len is the number of elements in the collection. One of the methods to implement sort.Interface.

func (FloatArray) Less

func (a FloatArray) Less(i, j int) bool

Less reports whether the element with index i should sort before the element with index j. One of the methods to implement sort.Interface.

func (*FloatArray) Scan

func (a *FloatArray) Scan(src any) error

Scan implements the sql.Scanner interface. A nil source scans to a nil slice (SQL NULL). Any other source scans to a non-nil slice: {} to an empty slice, otherwise the parsed PostgreSQL float array literal like {1.5,2,3}.

func (FloatArray) String

func (a FloatArray) String() string

String implements the fmt.Stringer interface

func (FloatArray) StringOr

func (a FloatArray) StringOr(nilStr string) string

StringOr returns the string representation of a or nilStr if a is null.

func (FloatArray) Swap

func (a FloatArray) Swap(i, j int)

Swap swaps the elements with indexes i and j. One of the methods to implement sort.Interface.

func (FloatArray) Value

func (a FloatArray) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. A nil slice returns SQL NULL. Otherwise it returns the slice as a PostgreSQL float array literal like {1.5,2,3}, an empty slice returning the empty array {}.

type IntArray

type IntArray []int64

IntArray implements the sql.Scanner and driver.Valuer interfaces for a slice of int64. A nil slice is mapped to the SQL NULL value, and a non nil zero length slice to an empty SQL array '{}'.

Value and Scan use the PostgreSQL array text format ({1,2,3}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func (IntArray) Contains

func (a IntArray) Contains(value int64) bool

Contains reports if the passed value is present in a.

func (IntArray) IsNull

func (a IntArray) IsNull() bool

IsNull returns true if a is nil. IsNull implements the Nullable interface.

func (IntArray) Len

func (a IntArray) Len() int

Len is the number of elements in the collection. One of the methods to implement sort.Interface.

func (IntArray) Less

func (a IntArray) Less(i, j int) bool

Less reports whether the element with index i should sort before the element with index j. One of the methods to implement sort.Interface.

func (*IntArray) Scan

func (a *IntArray) Scan(src any) error

Scan implements the sql.Scanner interface. A nil source scans to a nil slice (SQL NULL). Any other source scans to a non-nil slice: {} to an empty slice, otherwise the parsed PostgreSQL integer array literal like {1,2,3}.

func (IntArray) String

func (a IntArray) String() string

String implements the fmt.Stringer interface.

func (IntArray) Swap

func (a IntArray) Swap(i, j int)

Swap swaps the elements with indexes i and j. One of the methods to implement sort.Interface.

func (IntArray) Value

func (a IntArray) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. A nil slice returns SQL NULL. Otherwise it returns the slice as a PostgreSQL integer array literal like {1,2,3}, an empty slice returning the empty array {}.

type JSON

type JSON []byte

JSON is a []byte slice containing JSON text or nil as the representation of the JSON "null" value. that implements the interfaces: json.Marshaler, json.Unmarshaler, driver.Value, sql.Scanner. The nil value of the type JSON is marshalled as the JSON "null" and SQL NULL values. The JSON "null" and SQL NULL values are unmarshalled as nil value ot the type JSON.

func MarshalJSON

func MarshalJSON(source any) (JSON, error)

MarshalJSON marshals source as JSON and returns it as a nullable JSON value. The result is nil (null) if source marshals to the JSON "null" value.

func (JSON) Clone

func (j JSON) Clone() JSON

Clone returns a copy of j

func (JSON) GoString

func (j JSON) GoString() string

GoString returns a Go syntax representation of j as a nullable.JSON literal. GoString implements the fmt.GoStringer interface.

func (JSON) IsEmpty

func (j JSON) IsEmpty() bool

IsEmpty returns true if j is nil, or an empty JSON value like "", "{}", or "[]"

func (JSON) IsNull

func (j JSON) IsNull() bool

IsNull returns true if j is nil. IsNull implements the Nullable interface.

func (*JSON) MarshalFrom

func (j *JSON) MarshalFrom(source any) error

MarshalFrom marshalles source as JSON and sets it at j when there was no error.

func (JSON) MarshalJSON

func (j JSON) MarshalJSON() ([]byte, error)

MarshalJSON returns j as the JSON encoding of j. MarshalJSON implements encoding/json.Marshaler See the package function MarshalJSON to marshal a struct into JSON

func (JSON) PrettyPrint

func (j JSON) PrettyPrint(w io.Writer) (int, error)

PrettyPrint implements the pretty.PrintableWithResult interface returning the JSON as a Go literal.

func (*JSON) Scan

func (j *JSON) Scan(src any) error

Scan stores the src in *j. No validation is done.

func (JSON) String

func (j JSON) String() string

String returns the JSON as string. String implements the fmt.Stringer interface.

func (*JSON) UnmarshalJSON

func (j *JSON) UnmarshalJSON(sourceJSON []byte) error

UnmarshalJSON sets *j to a copy of sourceJSON. UnarshalJSON implements encoding/json.Unmarshaler See method Unmarshal for unmarshalling into a struct.

func (JSON) UnmarshalTo

func (j JSON) UnmarshalTo(dest any) error

UnmarshalTo unmashalles the JSON of j to dest

func (JSON) Valid

func (j JSON) Valid() bool

Valid reports whether j is a valid JSON encoding.

func (JSON) Value

func (j JSON) Value() (driver.Value, error)

Value returns j as a SQL value.

type NonEmptyString

type NonEmptyString string

NonEmptyString is a string type where the empty string value is interpreted as SQL NULL and JSON null by implementing the sql.Scanner and driver.Valuer interfaces and also json.Marshaler and json.Unmarshaler. Note that this type can't hold an empty string without interpreting it as not null SQL or JSON value.

const NonEmptyStringNull NonEmptyString = ""

NonEmptyStringNull is the SQL NULL and JSON null value for NonEmptyString.

func JoinNonEmptyStrings

func JoinNonEmptyStrings(separator string, strs ...NonEmptyString) NonEmptyString

JoinNonEmptyStrings joins only those strings that are not empty/null with the passed separator between them.

func NonEmptyStringFromError

func NonEmptyStringFromError(err error) NonEmptyString

NonEmptyStringFromError converts an error to a NonEmptyString interpreting a nil error as null value "" or else using err.Error() as value.

func NonEmptyStringFromPtr

func NonEmptyStringFromPtr(ptr *string) NonEmptyString

NonEmptyStringFromPtr converts a string pointer to a NonEmptyString interpreting nil as null value "".

func NonEmptyStringTrimSpace

func NonEmptyStringTrimSpace(str string) NonEmptyString

NonEmptyStringTrimSpace returns a NonEmptyString by trimming space from the passed string. If the passed string with trimmed space is an empty string then the NonEmptyString will represent null.

func NonEmptyStringf

func NonEmptyStringf(format string, a ...any) NonEmptyString

NonEmptyStringf formats a string using fmt.Sprintf and returns it as NonEmptyString. An empty string will be interpreted as null value.

func (NonEmptyString) Get

func (n NonEmptyString) Get() string

Get returns the non nullable string value or panics if the NonEmptyString is null. Note: check with IsNull before using Get!

func (NonEmptyString) IsNotNull

func (n NonEmptyString) IsNotNull() bool

IsNotNull returns true if the string n is not empty.

func (NonEmptyString) IsNull

func (n NonEmptyString) IsNull() bool

IsNull returns true if the string n is empty. IsNull implements the Nullable interface.

func (NonEmptyString) MarshalJSON

func (n NonEmptyString) MarshalJSON() ([]byte, error)

MarshalJSON implements encoding/json.Marshaler by returning the JSON null value for an empty (null) string.

func (NonEmptyString) Ptr

func (n NonEmptyString) Ptr() *string

Ptr returns the address of the string value or nil if n.IsNull()

func (*NonEmptyString) Scan

func (n *NonEmptyString) Scan(value any) error

Scan implements the database/sql.Scanner interface.

func (*NonEmptyString) Set

func (n *NonEmptyString) Set(s string)

Set the passed string as NonEmptyString. Passing an empty string will be interpreted as setting NULL.

func (*NonEmptyString) SetNull

func (n *NonEmptyString) SetNull()

SetNull sets the string to its null value

func (NonEmptyString) StringOr

func (n NonEmptyString) StringOr(nullString string) string

StringOr returns the string value of n or the passed nullString if n.IsNull()

func (NonEmptyString) TrimSpace

func (n NonEmptyString) TrimSpace() NonEmptyString

TrimSpace returns the string with all white-space characters trimmed from beginning and end. A potentially resulting empty string will be interpreted as null.

func (*NonEmptyString) UnmarshalJSON

func (n *NonEmptyString) UnmarshalJSON(j []byte) error

UnmarshalJSON implements encoding/json.Unmarshaler by interpreting the JSON null value as an empty (null) string.

func (*NonEmptyString) UnmarshalText

func (n *NonEmptyString) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface

func (NonEmptyString) Value

func (n NonEmptyString) Value() (driver.Value, error)

Value implements the driver database/sql/driver.Valuer interface.

type NullBoolArray

type NullBoolArray []Type[bool]

NullBoolArray is a slice of nullable bool values, each element stored as a Type[bool]. It implements the sql.Scanner and driver.Valuer interfaces for a SQL array. JSON marshalling needs no methods on the slice itself: encoding/json handles the slice and each Type[bool] element marshals a value as true/false and a null element as JSON null, e.g. [true,null,false].

A nil slice maps to SQL NULL and JSON null, a non-nil zero length slice to the empty SQL array '{}' and JSON [].

Value and Scan use the PostgreSQL array text format ({t,NULL,f}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func (NullBoolArray) Bools

func (a NullBoolArray) Bools() []bool

Bools returns all NullBoolArray elements as []bool with null elements set to false.

func (NullBoolArray) IsNull

func (a NullBoolArray) IsNull() bool

IsNull returns true if a is nil. IsNull implements the Nullable interface.

func (*NullBoolArray) Scan

func (a *NullBoolArray) Scan(src any) error

Scan implements the sql.Scanner interface. A nil source scans to a nil slice (SQL NULL), the empty array {} to a non-nil empty slice. Otherwise it parses a PostgreSQL boolean array literal like {t,NULL,f} from a string or []byte; elements other than t and f scan as a null Type[bool].

func (NullBoolArray) String

func (a NullBoolArray) String() string

String implements the fmt.Stringer interface.

func (NullBoolArray) Value

func (a NullBoolArray) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. A nil slice returns SQL NULL. Otherwise it returns the slice as a PostgreSQL boolean array literal like {t,NULL,f}, with null elements written as NULL.

type NullFloatArray

type NullFloatArray []Type[float64]

NullFloatArray is a slice of nullable float64 values, each element stored as a Type[float64]. It implements the sql.Scanner and driver.Valuer interfaces for a SQL array. JSON marshalling needs no methods on the slice itself: encoding/json handles the slice and each Type[float64] element marshals a value as a number and a null element as JSON null, e.g. [1.5,null,3].

A nil slice maps to SQL NULL and JSON null, a non-nil zero length slice to the empty SQL array '{}' and JSON [].

Value and Scan use the PostgreSQL array text format ({1.5,NULL,3}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func (NullFloatArray) Floats

func (a NullFloatArray) Floats() []float64

Floats returns all NullFloatArray elements as []float64 with null elements set to 0.

func (NullFloatArray) IsNull

func (a NullFloatArray) IsNull() bool

IsNull returns true if a is nil. IsNull implements the Nullable interface.

func (*NullFloatArray) Scan

func (a *NullFloatArray) Scan(src any) error

Scan implements the sql.Scanner interface. A nil source scans to a nil slice (SQL NULL), the empty array {} to a non-nil empty slice. Otherwise it parses a PostgreSQL float array literal like {1.5,NULL,3} from a string or []byte, NULL elements scanning as a null Type[float64].

func (NullFloatArray) String

func (a NullFloatArray) String() string

String implements the fmt.Stringer interface.

func (NullFloatArray) Value

func (a NullFloatArray) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. A nil slice returns SQL NULL. Otherwise it returns the slice as a PostgreSQL float array literal like {1.5,NULL,3}, with null elements written as NULL.

type NullIntArray

type NullIntArray []Type[int64]

NullIntArray is a slice of nullable int64 values, each element stored as a Type[int64]. It implements the sql.Scanner and driver.Valuer interfaces for a SQL array. JSON marshalling needs no methods on the slice itself: encoding/json handles the slice and each Type[int64] element marshals a value as a number and a null element as JSON null, e.g. [1,null,3].

A nil slice maps to SQL NULL and JSON null, a non-nil zero length slice to the empty SQL array '{}' and JSON [].

Value and Scan use the PostgreSQL array text format ({1,NULL,3}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

func (NullIntArray) Ints

func (a NullIntArray) Ints() []int64

Ints returns all NullIntArray elements as []int64 with null elements set to 0.

func (NullIntArray) IsNull

func (a NullIntArray) IsNull() bool

IsNull returns true if a is nil. IsNull implements the Nullable interface.

func (*NullIntArray) Scan

func (a *NullIntArray) Scan(src any) error

Scan implements the sql.Scanner interface. A nil source scans to a nil slice (SQL NULL), the empty array {} to a non-nil empty slice. Otherwise it parses a PostgreSQL integer array literal like {1,NULL,3} from a string or []byte, NULL elements scanning as a null Type[int64].

func (NullIntArray) String

func (a NullIntArray) String() string

String implements the fmt.Stringer interface.

func (NullIntArray) Value

func (a NullIntArray) Value() (driver.Value, error)

Value implements the database/sql/driver.Valuer interface. A nil slice returns SQL NULL. Otherwise it returns the slice as a PostgreSQL integer array literal like {1,NULL,3}, with null elements written as NULL.

type NullSetable

type NullSetable[T any] interface {
	Nullable

	// SetNull sets the value to null/empty state.
	SetNull()

	// Set assigns a non-null value of type T.
	Set(T)

	// Get returns the non-null value or panics if the value is null.
	// Use IsNull() to check before calling Get() to avoid panics.
	Get() T

	// GetOr returns the non-null value or the provided default value if null.
	// This is a safe alternative to Get() that never panics.
	GetOr(T) T
}

NullSetable is a generic interface that extends Nullable for types that can be set to null and have their values retrieved with fallback options. This interface is typically implemented by nullable wrapper types that provide safe handling of optional values with null state management.

type Nullable

type Nullable interface {
	// IsNull returns true if the implementing value is considered null.
	IsNull() bool
}

Nullable is an interface with an IsNull method for types that can represent null values.

type NullableValidator

type NullableValidator interface {
	Nullable
	types.Validator

	ValidAndNotNull() bool
}

NullableValidator is a generic interface that extends Nullable and Validator for types that can be set to null and have their values retrieved with fallback options. This interface is typically implemented by nullable wrapper types that provide safe handling of optional values with null state management.

type StringArray

type StringArray = pq.StringArray

StringArray implements the sql.Scanner and driver.Valuer interfaces for a slice of strings. A nil slice is mapped to the SQL NULL value, and a non nil zero length slice to an empty SQL array '{}'.

Value and Scan use the PostgreSQL array text format ({"a","b"}), see https://www.postgresql.org/docs/current/arrays.html. That format is understood by PostgreSQL and array-compatible databases such as CockroachDB and YugabyteDB; databases without a native array type (MySQL, MariaDB, SQLite, SQL Server, Oracle) are not supported.

type Time

type Time struct {
	time.Time
}

Time represents a time.Time where the zero time instant (which is the empty default value of the type) is interpreted as SQL NULL and JSON null. It implements the sql.Scanner and driver.Valuer interfaces and also json.Marshaler and json.Unmarshaler. It assumes that zero time instant is never used in any real life application so it's free to be used as magical value for representing NULL. IsNull uses time.Time.IsZero internally.

var TimeNull Time

TimeNull is a null Time value.

Note: use Time.IsNull or IsNotNull to check for null instead of comparing a Time with TimeNull because Time.IsNull uses time.Time.IsZero internally which can return true for times that are not the empty time.Time{} default value.

func TimeFrom

func TimeFrom(t time.Time) Time

TimeFrom returns a nullable.Time from a time.Time

func TimeFromPtr

func TimeFromPtr(ptr *time.Time) Time

TimeFromPtr returns a nullable.Time from a time.Time pointer with nil interpreted as null.

func TimeNow

func TimeNow() Time

TimeNow returns the current time

func TimeParse

func TimeParse(layout, value string) (Time, error)

TimeParse parses a time value with the provided layout using time.Parse(layout, value) except for when value is on of "", "null", "NULL", then a null/zero time and no error are returned.

func TimeParseInLocation

func TimeParseInLocation(layout, value string, loc *time.Location) (Time, error)

TimeParseInLocation parses a time value with the provided layout and location using time.ParseInLocation(layout, value, loc) except for when value is on of "", "null", "NULL", then a null/zero time and no error are returned.

func (Time) Add

func (n Time) Add(duration time.Duration) Time

Add returns n+duration or null if n is null

func (Time) AddDate

func (n Time) AddDate(years int, months int, days int) Time

AddDate returns the nullable time corresponding to adding the given number of years, months, and days to t. For example, AddDate(-1, 2, 3) applied to January 1, 2011 returns March 4, 2010.

AddDate normalizes its result in the same way that Date does, so, for example, adding one month to October 31 yields December 1, the normalized form for November 31.

Returns null if n is null.

func (Time) AppendFormat

func (n Time) AppendFormat(b []byte, layout string) []byte

AppendFormat the time to b using time.Time.AppendFormat or b if n is null.

func (Time) Equal

func (n Time) Equal(o Time) bool

Equal reports whether n and o represent the same time instant or both are null. Two times can be equal even if they are in different locations. For example, 6:00 +0200 and 4:00 UTC are Equal. See the documentation on the Time type for the pitfalls of using == with Time values; most code should use Equal instead.

func (Time) Format

func (n Time) Format(layout string) string

Format the time using time.Time.Format or return and empty string if n is null.

func (Time) Get

func (n Time) Get() time.Time

Get returns the non nullable time.Time value or panics if the Time is null. Note: check with IsNull before using Get!

func (Time) GetOr

func (n Time) GetOr(defaultTime time.Time) time.Time

GetOr returns the non nullable time.Time value or the passed defaultTime if the Time is null.

func (Time) IsNotNull

func (n Time) IsNotNull() bool

IsNotNull returns true if the Time is not null. Uses time.Time.IsZero internally.

func (Time) IsNull

func (n Time) IsNull() bool

IsNull returns true if the Time is null. Uses time.Time.IsZero internally. IsNull implements the Nullable interface.

func (Time) JSONSchema

func (Time) JSONSchema() *jsonschema.Schema

JSONSchema returns a JSON schema for Time as a nullable date-time string, allowing either an RFC 3339 date-time string or null. JSONSchema implements the github.com/invopop/jsonschema.Schema interface.

func (Time) MarshalJSON

func (n Time) MarshalJSON() ([]byte, error)

MarshalJSON implements encoding/json.Marshaler

func (Time) MarshalText

func (n Time) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface. The time is formatted in RFC 3339 format, with sub-second precision added if present. "NULL" is returned as text if the time is null.

func (Time) PrettyPrint

func (n Time) PrettyPrint(w io.Writer) (int, error)

PrettyPrint implements the pretty.PrintableWithResult interface

func (Time) Ptr

func (n Time) Ptr() *time.Time

Ptr returns a pointer to Time or nil if n is null

func (*Time) Scan

func (n *Time) Scan(value any) error

Scan implements the database/sql.Scanner interface.

func (*Time) Set

func (n *Time) Set(t time.Time)

Set a time.Time. Note that if t.IsZero() then n will be set to null.

func (*Time) SetNull

func (n *Time) SetNull()

SetNull sets the time to its null value

func (Time) String

func (n Time) String() string

String returns Time.String() or "NULL" if n is null.

func (Time) StringOr

func (n Time) StringOr(nullStr string) string

StringOr returns Time.String() or the passed nullStr if n is null.

func (Time) UTC

func (n Time) UTC() Time

UTC returns the time in UTC or null if n is null

func (*Time) UnmarshalJSON

func (n *Time) UnmarshalJSON(sourceJSON []byte) error

UnarshalJSON implements encoding/json.Unmarshaler. Interprets []byte(nil), []byte(""), []byte("null") as null.

func (*Time) UnmarshalText

func (n *Time) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface. The time is expected to be in RFC 3339 format. Empty text, "null", or "NULL" will set the time to null.

func (Time) Value

func (n Time) Value() (driver.Value, error)

Value implements the driver database/sql/driver.Valuer interface.

type TrimmedString

type TrimmedString string

TrimmedString is a string type where the empty trimmed string value is interpreted as SQL NULL and JSON null by implementing the sql.Scanner and driver.Valuer interfaces and also json.Marshaler and json.Unmarshaler.

Note that this type can't hold a not null empty string, because it will interpret it as null SQL or JSON value.

const TrimmedStringNull TrimmedString = ""

TrimmedStringNull is the NULL value "" for TrimmedString

func TrimmedStringFrom

func TrimmedStringFrom(str string) TrimmedString

TrimmedStringFrom trims the passed str and returns it as TrimmedString An empty trimmed string will be interpreted as null value.

func TrimmedStringFromError

func TrimmedStringFromError(err error) TrimmedString

TrimmedStringFromError converts an error to a TrimmedString interpreting a nil error as null value "" or else using err.Error() as value.

func TrimmedStringFromPtr

func TrimmedStringFromPtr(ptr *string) TrimmedString

TrimmedStringFromPtr converts a string pointer to a TrimmedString interpreting nil as null value "". An empty trimmed string will be interpreted as null value.

func TrimmedStringJoin

func TrimmedStringJoin[S ~string](separator string, strs ...S) TrimmedString

TrimmedStringJoin joins only those strings that are not empty after trimming with the passed separator between them.

func TrimmedStringf

func TrimmedStringf(format string, a ...any) TrimmedString

TrimmedStringf formats a string using fmt.Sprintf and returns it as TrimmedString. An empty trimmed string will be interpreted as null value.

func (TrimmedString) Contains

func (s TrimmedString) Contains(substr string) bool

Contains reports whether substr is within s.

func (TrimmedString) ContainsAny

func (s TrimmedString) ContainsAny(chars string) bool

ContainsAny reports whether any Unicode code points in chars are within s.

func (TrimmedString) ContainsRune

func (s TrimmedString) ContainsRune(r rune) bool

ContainsRune reports whether the Unicode code point r is within s.

func (TrimmedString) Get

func (s TrimmedString) Get() string

Get returns the non nullable string value or panics if the TrimmedString is null. Note: check with IsNull before using Get!

func (TrimmedString) HasPrefix

func (s TrimmedString) HasPrefix(prefix string) bool

HasPrefix tests whether the TrimmedString begins with prefix.

func (TrimmedString) HasSuffix

func (s TrimmedString) HasSuffix(suffix string) bool

HasSuffix tests whether the TrimmedString ends with suffix.

func (TrimmedString) IsNotNull

func (s TrimmedString) IsNotNull() bool

IsNotNull returns true if the string is not empty.

func (TrimmedString) IsNull

func (s TrimmedString) IsNull() bool

IsNull returns true if the string is empty.

IsNull implements the Nullable interface.

func (TrimmedString) JSONSchema

func (TrimmedString) JSONSchema() *jsonschema.Schema

JSONSchema returns a JSON schema for TrimmedString as a nullable string, allowing either a plain string or null. JSONSchema implements the github.com/invopop/jsonschema.Schema interface.

func (TrimmedString) MarshalJSON

func (s TrimmedString) MarshalJSON() ([]byte, error)

MarshalJSON implements encoding/json.Marshaler by returning the JSON null value for an empty (null) string.

func (TrimmedString) MarshalText

func (s TrimmedString) MarshalText() ([]byte, error)

UnmarshalText implements the encoding.TextMarshaler interface

func (TrimmedString) MarshalXML

func (s TrimmedString) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML implements encoding/xml.Marshaler by encoding the trimmed string as the character data of an XML element. A null (empty) string encodes as an empty element.

func (TrimmedString) Ptr

func (s TrimmedString) Ptr() *string

Ptr returns the address of the string value or nil if n.IsNull()

func (TrimmedString) ReplaceAll

func (s TrimmedString) ReplaceAll(old, new string) TrimmedString

ReplaceAll returns a copy of the TrimmedString with all non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string.

func (*TrimmedString) Scan

func (s *TrimmedString) Scan(value any) error

Scan implements the database/sql.Scanner interface.

func (*TrimmedString) Set

func (s *TrimmedString) Set(str string)

Set the passed string as TrimmedString. Passing an empty trimmed string will be interpreted as setting NULL.

func (*TrimmedString) SetNull

func (s *TrimmedString) SetNull()

SetNull sets the string to its null value

func (TrimmedString) Split

func (s TrimmedString) Split(sep string) []TrimmedString

Split slices s into all substrings separated by sep and returns a slice of the substrings between those separators.

If s does not contain sep and sep is not empty, Split returns a slice of length 1 whose only element is s.

If sep is empty, Split splits after each UTF-8 sequence. If both s and sep are empty, Split returns an empty slice.

It is equivalent to SplitN with a count of -1.

To split around the first instance of a separator, see Cut.

func (TrimmedString) String

func (s TrimmedString) String() string

String implements the fmt.Stringer interface by returning a trimmed string that might be empty in case of the NULL value or an underlying string consisting only of whitespace.

func (TrimmedString) StringOr

func (s TrimmedString) StringOr(nullString string) string

StringOr returns the trimmed string value of n or the passed nullString if n.IsNull()

func (TrimmedString) ToLower

func (s TrimmedString) ToLower() TrimmedString

ToLower returns s with all Unicode letters mapped to their lower case.

func (TrimmedString) ToUpper

func (s TrimmedString) ToUpper() TrimmedString

ToUpper returns s with all Unicode letters mapped to their upper case.

func (TrimmedString) ToValidUTF8

func (s TrimmedString) ToValidUTF8(replacement string) TrimmedString

ToValidUTF8 returns a copy of the TrimmedString with each run of invalid UTF-8 byte sequences replaced by the replacement string, which may be empty.

func (TrimmedString) TrimPrefix

func (s TrimmedString) TrimPrefix(prefix string) TrimmedString

TrimPrefix returns s without the provided leading prefix string. If the TrimmedString doesn't start with prefix, s is returned unchanged.

func (TrimmedString) TrimSuffix

func (s TrimmedString) TrimSuffix(suffix string) TrimmedString

TrimSuffix returns s without the provided trailing suffix string. If the TrimmedString doesn't end with suffix, s is returned unchanged.

func (*TrimmedString) UnmarshalJSON

func (s *TrimmedString) UnmarshalJSON(j []byte) error

UnmarshalJSON implements encoding/json.Unmarshaler.

func (*TrimmedString) UnmarshalText

func (s *TrimmedString) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface

func (*TrimmedString) UnmarshalXML

func (s *TrimmedString) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements encoding/xml.Unmarshaler by decoding the character data of the XML element, trimming whitespace, and storing the result. An empty element sets s to the null value.

func (TrimmedString) Value

func (s TrimmedString) Value() (driver.Value, error)

Value implements the driver database/sql/driver.Valuer interface.

type Type

type Type[T any] struct {
	// contains filtered or unexported fields
}

Type wraps a type T to support null values without resorting to pointers.

The zero value represents null.

Type implements the following interfaces:

  • database/sql/driver.Valuer
  • database/sql.Scanner
  • encoding/json.Marshaler
  • encoding/json.Unmarshaler

It also provides a JSONSchema method to generate a JSON Schema for the type using the github.com/invopop/jsonschema package.

Use TypeFromPtr to create a valid nullable type from a pointer. Use Type.Ptr to get a pointer to the value. Use Type.Get to get a non-null value. Use Type.GetOr to get a non-null value or a default value if the value is null. Use Type.Set to set the value. Use Type.SetNull to set the value to null.

func TypeFrom

func TypeFrom[T any](value T) Type[T]

TypeFrom returns a valid (non-null) nullable type wrapping the given value.

func TypeFromPtr

func TypeFromPtr[T any](ptr *T) Type[T]

TypeFromPtr returns a nullable type from a pointer. If the pointer is nil, the returned type is null. If the pointer is non-nil, the returned type is valid and contains a copy of the dereferenced pointer value.

See Type[T].Ptr for the inverse.

func (Type[T]) Get

func (t Type[T]) Get() T

Get returns the non-null value or panics if the value is null.

Use IsNotNull first to check if the value is not null.

func (Type[T]) GetOr

func (t Type[T]) GetOr(defaultValue T) T

GetOr returns the non-null value or a default value if the value is null.

func (Type[T]) IsNotNull

func (t Type[T]) IsNotNull() bool

IsNotNull returns true if the value is not null.

func (Type[T]) IsNull

func (t Type[T]) IsNull() bool

IsNull returns true if the value is null.

func (Type[T]) JSONSchema

func (t Type[T]) JSONSchema() *jsonschema.Schema

JSONSchema returns a JSON Schema for the type using the github.com/invopop/jsonschema package.

func (Type[T]) MarshalJSON

func (t Type[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements encoding/json.Marshaler

func (Type[T]) Ptr

func (t Type[T]) Ptr() *T

Ptr returns a pointer to the value or nil if the value is null.

See TypeFromPtr[T] for the inverse.

func (*Type[T]) Scan

func (t *Type[T]) Scan(value any) error

Scan implements the database/sql.Scanner interface.

func (*Type[T]) Set

func (t *Type[T]) Set(value T)

Set sets a non-null value.

func (*Type[T]) SetNull

func (t *Type[T]) SetNull()

SetNull sets the value to null.

func (*Type[T]) UnmarshalJSON

func (t *Type[T]) UnmarshalJSON(sourceJSON []byte) error

UnarshalJSON implements encoding/json.Unmarshaler. Interprets []byte(nil), []byte(""), []byte("null") as null.

func (Type[T]) Value

func (t Type[T]) Value() (driver.Value, error)

Value implements the driver database/sql/driver.Valuer interface.

type Zeroable

type Zeroable interface {
	// IsZero returns true if the implementing value is considered zero.
	IsZero() bool
}

Zeroable is an interface with an IsZero method for types that can represent zero values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL