func (id ULID) Equals(other Identifier) bool {
	v, ok := other.(*ULID)
	if !ok {
		return false
	}
	return uuid.UUID(id) == uuid.UUID(*v)
}
Equals reports whether the ID and the given one are equals.
package kallax
import (
	"bytes"
	"crypto/rand"
	"database/sql"
	"database/sql/driver"
	"encoding/hex"
	"fmt"
	"time"
	"github.com/gofrs/uuid"
	"github.com/oklog/ulid"
)
type Model struct {
	virtualColumns map[string]Identifier
	persisted      bool
	writable       bool
	saving         bool
}
func NewModel() Model {
	return Model{
		persisted:      false,
		writable:       true,
		virtualColumns: make(map[string]Identifier),
		saving:         false,
	}
}
func (m *Model) IsPersisted() bool {
	return m.persisted
}
func (m *Model) setPersisted() {
	m.persisted = true
}
func (m *Model) IsWritable() bool {
	return m.writable
}
func (m *Model) setWritable(w bool) {
	m.writable = w
}
func (m *Model) IsSaving() bool {
	return m.saving
}
func (m *Model) SetSaving(saving bool) {
	m.saving = saving
}
func (m *Model) ClearVirtualColumns() {
	m.virtualColumns = make(map[string]Identifier)
}
func (m *Model) getVirtualColumns() map[string]Identifier {
	return m.virtualColumns
}
func (m *Model) AddVirtualColumn(name string, v Identifier) {
	if m.virtualColumns == nil {
		m.ClearVirtualColumns()
	}
	m.virtualColumns[name] = v
}
func (m *Model) VirtualColumn(name string) Identifier {
	if m.virtualColumns == nil {
		m.ClearVirtualColumns()
	}
	return m.virtualColumns[name]
}
type Identifier interface {
	sql.Scanner
	driver.Valuer
	Equals(Identifier) bool
	IsEmpty() bool
	Raw() interface{}
}
type Identifiable interface {
	GetID() Identifier
}
type Persistable interface {
	IsPersisted() bool
	setPersisted()
}
type Writable interface {
	IsWritable() bool
	setWritable(bool)
}
type ColumnAddresser interface {
	ColumnAddress(string) (interface{}, error)
}
type Relationable interface {
	NewRelationshipRecord(string) (Record, error)
	SetRelationship(string, interface{}) error
}
type Valuer interface {
	Value(string) (interface{}, error)
}
type VirtualColumnContainer interface {
	ClearVirtualColumns()
	AddVirtualColumn(string, Identifier)
	VirtualColumn(string) Identifier
	getVirtualColumns() map[string]Identifier
}
var ErrEmptyVirtualColumn = fmt.Errorf("empty virtual column")
func RecordValues(record Valuer, columns ...string) ([]interface{}, []string, error) {
	var cols = make([]string, 0, len(columns))
	var values = make([]interface{}, 0, len(columns))
	for _, col := range columns {
		v, err := record.Value(col)
		if err == ErrEmptyVirtualColumn {
			continue
		}
		if err != nil {
			return nil, nil, err
		}
		values = append(values, v)
		cols = append(cols, col)
	}
	return values, cols, nil
}
type Saveable interface {
	IsSaving() bool
	SetSaving(bool)
}
type Record interface {
	Identifiable
	Persistable
	Writable
	Relationable
	ColumnAddresser
	Valuer
	VirtualColumnContainer
	Saveable
}
type ULID uuid.UUID
func NewULID() ULID {
	return ULID(ulid.MustNew(ulid.Timestamp(time.Now()), rand.Reader))
}
func NewULIDFromText(text string) (ULID, error) {
	var id ULID
	err := id.UnmarshalText([]byte(text))
	return id, err
}
func (id *ULID) Scan(src interface{}) error {
	switch src := src.(type) {
	case []byte:
		if len(src) != 16 {
			return id.UnmarshalText(src)
		}
		var ulid ulid.ULID
		if err := ulid.UnmarshalBinary(src); err != nil {
			return err
		}
		*id = ULID(ulid)
		return nil
	case string:
		return id.Scan([]byte(src))
	default:
		return fmt.Errorf("kallax: cannot scan %T into ULID", src)
	}
}
var (
	urnPrefix  = []byte("urn:uuid:")
	byteGroups = []int{8, 4, 4, 4, 12}
)
func (u *ULID) UnmarshalText(text []byte) (err error) {
	if len(text) < 32 {
		err = fmt.Errorf("uuid: UUID string too short: %s", text)
		return
	}
	t := text[:]
	braced := false
	if bytes.Equal(t[:9], urnPrefix) {
		t = t[9:]
	} else if t[0] == '{' {
		braced = true
		t = t[1:]
	}
	b := u[:]
	for i, byteGroup := range byteGroups {
		if i > 0 && t[0] == '-' {
			t = t[1:]
		} else if i > 0 && t[0] != '-' {
			err = fmt.Errorf("kallax: invalid ulid string format")
			return
		}
		if len(t) < byteGroup {
			err = fmt.Errorf("kallax: ulid string too short: %s", text)
			return
		}
		if i == 4 && len(t) > byteGroup &&
			((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
			err = fmt.Errorf("kallax: ulid string too long: %s", t)
			return
		}
		_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
		if err != nil {
			return
		}
		t = t[byteGroup:]
		b = b[byteGroup/2:]
	}
	return
}
func (id ULID) MarshalText() ([]byte, error) {
	return []byte(id.String()), nil
}
func (id ULID) Value() (driver.Value, error) {
	return uuid.UUID(id).Value()
}
func (id ULID) IsEmpty() bool {
	return uuid.UUID(id) == uuid.Nil
}
func (id ULID) String() string {
	return uuid.UUID(id).String()
}