package models

import (
	"context"
	"database/sql"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/friendsofgo/errors"
	"github.com/volatiletech/null/v8"
	"github.com/volatiletech/sqlboiler/v4/boil"
	"github.com/volatiletech/sqlboiler/v4/queries"
	"github.com/volatiletech/sqlboiler/v4/queries/qm"
	"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
	"github.com/volatiletech/sqlboiler/v4/types"
	"github.com/volatiletech/strmangle"
)

type CloserPeer struct {
	ID                int              `boil:"id" json:"id" toml:"id" yaml:"id"`
	FindNodeRPCID     null.Int         `boil:"find_node_rpc_id" json:"find_node_rpc_id,omitempty" toml:"find_node_rpc_id" yaml:"find_node_rpc_id,omitempty"`
	GetProvidersRPCID null.Int         `boil:"get_providers_rpc_id" json:"get_providers_rpc_id,omitempty" toml:"get_providers_rpc_id" yaml:"get_providers_rpc_id,omitempty"`
	PeerID            int              `boil:"peer_id" json:"peer_id" toml:"peer_id" yaml:"peer_id"`
	MultiAddressIds   types.Int64Array `boil:"multi_address_ids" json:"multi_address_ids" toml:"multi_address_ids" yaml:"multi_address_ids"`

	R *closerPeerR `boil:"-" json:"-" toml:"-" yaml:"-"`
	L closerPeerL  `boil:"-" json:"-" toml:"-" yaml:"-"`
}

var CloserPeerColumns = struct {
	ID                string
	FindNodeRPCID     string
	GetProvidersRPCID string
	PeerID            string
	MultiAddressIds   string
}{
	ID:                "id",
	FindNodeRPCID:     "find_node_rpc_id",
	GetProvidersRPCID: "get_providers_rpc_id",
	PeerID:            "peer_id",
	MultiAddressIds:   "multi_address_ids",
}

var CloserPeerTableColumns = struct {
	ID                string
	FindNodeRPCID     string
	GetProvidersRPCID string
	PeerID            string
	MultiAddressIds   string
}{
	ID:                "closer_peers.id",
	FindNodeRPCID:     "closer_peers.find_node_rpc_id",
	GetProvidersRPCID: "closer_peers.get_providers_rpc_id",
	PeerID:            "closer_peers.peer_id",
	MultiAddressIds:   "closer_peers.multi_address_ids",
}

type whereHelpernull_Int struct{ field string }

func (w whereHelpernull_Int) EQ(x null.Int) qm.QueryMod {
	return qmhelper.WhereNullEQ(w.field, false, x)
}
func (w whereHelpernull_Int) NEQ(x null.Int) qm.QueryMod {
	return qmhelper.WhereNullEQ(w.field, true, x)
}
func (w whereHelpernull_Int) IsNull() qm.QueryMod    { return qmhelper.WhereIsNull(w.field) }
func (w whereHelpernull_Int) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) }
func (w whereHelpernull_Int) LT(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.LT, x)
}
func (w whereHelpernull_Int) LTE(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.LTE, x)
}
func (w whereHelpernull_Int) GT(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.GT, x)
}
func (w whereHelpernull_Int) GTE(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.GTE, x)
}

var CloserPeerWhere = struct {
	ID                whereHelperint
	FindNodeRPCID     whereHelpernull_Int
	GetProvidersRPCID whereHelpernull_Int
	PeerID            whereHelperint
	MultiAddressIds   whereHelpertypes_Int64Array
}{
	ID:                whereHelperint{field: "\"closer_peers\".\"id\""},
	FindNodeRPCID:     whereHelpernull_Int{field: "\"closer_peers\".\"find_node_rpc_id\""},
	GetProvidersRPCID: whereHelpernull_Int{field: "\"closer_peers\".\"get_providers_rpc_id\""},
	PeerID:            whereHelperint{field: "\"closer_peers\".\"peer_id\""},
	MultiAddressIds:   whereHelpertypes_Int64Array{field: "\"closer_peers\".\"multi_address_ids\""},
}

var CloserPeerRels = struct {
	FindNodeRPC     string
	GetProvidersRPC string
	Peer            string
}{
	FindNodeRPC:     "FindNodeRPC",
	GetProvidersRPC: "GetProvidersRPC",
	Peer:            "Peer",
}

type closerPeerR struct {
	FindNodeRPC     *FindNodesRPC    `boil:"FindNodeRPC" json:"FindNodeRPC" toml:"FindNodeRPC" yaml:"FindNodeRPC"`
	GetProvidersRPC *GetProvidersRPC `boil:"GetProvidersRPC" json:"GetProvidersRPC" toml:"GetProvidersRPC" yaml:"GetProvidersRPC"`
	Peer            *Peer            `boil:"Peer" json:"Peer" toml:"Peer" yaml:"Peer"`
}

func (*closerPeerR) NewStruct() *closerPeerR {
	return &closerPeerR{}
}

type closerPeerL struct{}

var (
	closerPeerAllColumns            = []string{"id", "find_node_rpc_id", "get_providers_rpc_id", "peer_id", "multi_address_ids"}
	closerPeerColumnsWithoutDefault = []string{"find_node_rpc_id", "get_providers_rpc_id", "peer_id", "multi_address_ids"}
	closerPeerColumnsWithDefault    = []string{"id"}
	closerPeerPrimaryKeyColumns     = []string{"id"}
)

type (

	CloserPeerSlice []*CloserPeer

	CloserPeerHook func(context.Context, boil.ContextExecutor, *CloserPeer) error

	closerPeerQuery struct {
		*queries.Query
	}
)

var (
	closerPeerType                 = reflect.TypeOf(&CloserPeer{})
	closerPeerMapping              = queries.MakeStructMapping(closerPeerType)
	closerPeerPrimaryKeyMapping, _ = queries.BindMapping(closerPeerType, closerPeerMapping, closerPeerPrimaryKeyColumns)
	closerPeerInsertCacheMut       sync.RWMutex
	closerPeerInsertCache          = make(map[string]insertCache)
	closerPeerUpdateCacheMut       sync.RWMutex
	closerPeerUpdateCache          = make(map[string]updateCache)
	closerPeerUpsertCacheMut       sync.RWMutex
	closerPeerUpsertCache          = make(map[string]insertCache)
)

var (

	_ = time.Second

	_ = qmhelper.Where
)

var closerPeerBeforeInsertHooks []CloserPeerHook
var closerPeerBeforeUpdateHooks []CloserPeerHook
var closerPeerBeforeDeleteHooks []CloserPeerHook
var closerPeerBeforeUpsertHooks []CloserPeerHook

var closerPeerAfterInsertHooks []CloserPeerHook
var closerPeerAfterSelectHooks []CloserPeerHook
var closerPeerAfterUpdateHooks []CloserPeerHook
var closerPeerAfterDeleteHooks []CloserPeerHook
var closerPeerAfterUpsertHooks []CloserPeerHook

func (o *CloserPeer) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeInsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeUpdateHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeDeleteHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeUpsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterInsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterSelectHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterUpdateHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterDeleteHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func (o *CloserPeer) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterUpsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

func AddCloserPeerHook(hookPoint boil.HookPoint, closerPeerHook CloserPeerHook) {
	switch hookPoint {
	case boil.BeforeInsertHook:
		closerPeerBeforeInsertHooks = append(closerPeerBeforeInsertHooks, closerPeerHook)
	case boil.BeforeUpdateHook:
		closerPeerBeforeUpdateHooks = append(closerPeerBeforeUpdateHooks, closerPeerHook)
	case boil.BeforeDeleteHook:
		closerPeerBeforeDeleteHooks = append(closerPeerBeforeDeleteHooks, closerPeerHook)
	case boil.BeforeUpsertHook:
		closerPeerBeforeUpsertHooks = append(closerPeerBeforeUpsertHooks, closerPeerHook)
	case boil.AfterInsertHook:
		closerPeerAfterInsertHooks = append(closerPeerAfterInsertHooks, closerPeerHook)
	case boil.AfterSelectHook:
		closerPeerAfterSelectHooks = append(closerPeerAfterSelectHooks, closerPeerHook)
	case boil.AfterUpdateHook:
		closerPeerAfterUpdateHooks = append(closerPeerAfterUpdateHooks, closerPeerHook)
	case boil.AfterDeleteHook:
		closerPeerAfterDeleteHooks = append(closerPeerAfterDeleteHooks, closerPeerHook)
	case boil.AfterUpsertHook:
		closerPeerAfterUpsertHooks = append(closerPeerAfterUpsertHooks, closerPeerHook)
	}
}

func (q closerPeerQuery) One(ctx context.Context, exec boil.ContextExecutor) (*CloserPeer, error) {
	o := &CloserPeer{}

	queries.SetLimit(q.Query, 1)

	err := q.Bind(ctx, exec, o)
	if err != nil {
		if errors.Cause(err) == sql.ErrNoRows {
			return nil, sql.ErrNoRows
		}
		return nil, errors.Wrap(err, "models: failed to execute a one query for closer_peers")
	}

	if err := o.doAfterSelectHooks(ctx, exec); err != nil {
		return o, err
	}

	return o, nil
}

func (q closerPeerQuery) All(ctx context.Context, exec boil.ContextExecutor) (CloserPeerSlice, error) {
	var o []*CloserPeer

	err := q.Bind(ctx, exec, &o)
	if err != nil {
		return nil, errors.Wrap(err, "models: failed to assign all query results to CloserPeer slice")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range o {
			if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
				return o, err
			}
		}
	}

	return o, nil
}

func (q closerPeerQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	var count int64

	queries.SetSelect(q.Query, nil)
	queries.SetCount(q.Query)

	err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to count closer_peers rows")
	}

	return count, nil
}

func (q closerPeerQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
	var count int64

	queries.SetSelect(q.Query, nil)
	queries.SetCount(q.Query)
	queries.SetLimit(q.Query, 1)

	err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
	if err != nil {
		return false, errors.Wrap(err, "models: failed to check if closer_peers exists")
	}

	return count > 0, nil
}

func (o *CloserPeer) FindNodeRPC(mods ...qm.QueryMod) findNodesRPCQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.FindNodeRPCID),
	}

	queryMods = append(queryMods, mods...)

	query := FindNodesRPCS(queryMods...)
	queries.SetFrom(query.Query, "\"find_nodes_rpcs\"")

	return query
}

func (o *CloserPeer) GetProvidersRPC(mods ...qm.QueryMod) getProvidersRPCQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.GetProvidersRPCID),
	}

	queryMods = append(queryMods, mods...)

	query := GetProvidersRPCS(queryMods...)
	queries.SetFrom(query.Query, "\"get_providers_rpcs\"")

	return query
}

func (o *CloserPeer) Peer(mods ...qm.QueryMod) peerQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.PeerID),
	}

	queryMods = append(queryMods, mods...)

	query := Peers(queryMods...)
	queries.SetFrom(query.Query, "\"peers\"")

	return query
}

func (closerPeerL) LoadFindNodeRPC(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		if !queries.IsNil(object.FindNodeRPCID) {
			args = append(args, object.FindNodeRPCID)
		}

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if queries.Equal(a, obj.FindNodeRPCID) {
					continue Outer
				}
			}

			if !queries.IsNil(obj.FindNodeRPCID) {
				args = append(args, obj.FindNodeRPCID)
			}

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`find_nodes_rpcs`),
		qm.WhereIn(`find_nodes_rpcs.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load FindNodesRPC")
	}

	var resultSlice []*FindNodesRPC
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice FindNodesRPC")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for find_nodes_rpcs")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for find_nodes_rpcs")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.FindNodeRPC = foreign
		if foreign.R == nil {
			foreign.R = &findNodesRPCR{}
		}
		foreign.R.FindNodeRPCCloserPeers = append(foreign.R.FindNodeRPCCloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if queries.Equal(local.FindNodeRPCID, foreign.ID) {
				local.R.FindNodeRPC = foreign
				if foreign.R == nil {
					foreign.R = &findNodesRPCR{}
				}
				foreign.R.FindNodeRPCCloserPeers = append(foreign.R.FindNodeRPCCloserPeers, local)
				break
			}
		}
	}

	return nil
}

func (closerPeerL) LoadGetProvidersRPC(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		if !queries.IsNil(object.GetProvidersRPCID) {
			args = append(args, object.GetProvidersRPCID)
		}

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if queries.Equal(a, obj.GetProvidersRPCID) {
					continue Outer
				}
			}

			if !queries.IsNil(obj.GetProvidersRPCID) {
				args = append(args, obj.GetProvidersRPCID)
			}

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`get_providers_rpcs`),
		qm.WhereIn(`get_providers_rpcs.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load GetProvidersRPC")
	}

	var resultSlice []*GetProvidersRPC
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice GetProvidersRPC")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for get_providers_rpcs")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for get_providers_rpcs")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.GetProvidersRPC = foreign
		if foreign.R == nil {
			foreign.R = &getProvidersRPCR{}
		}
		foreign.R.CloserPeers = append(foreign.R.CloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if queries.Equal(local.GetProvidersRPCID, foreign.ID) {
				local.R.GetProvidersRPC = foreign
				if foreign.R == nil {
					foreign.R = &getProvidersRPCR{}
				}
				foreign.R.CloserPeers = append(foreign.R.CloserPeers, local)
				break
			}
		}
	}

	return nil
}

func (closerPeerL) LoadPeer(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		args = append(args, object.PeerID)

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if a == obj.PeerID {
					continue Outer
				}
			}

			args = append(args, obj.PeerID)

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`peers`),
		qm.WhereIn(`peers.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load Peer")
	}

	var resultSlice []*Peer
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice Peer")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for peers")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for peers")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.Peer = foreign
		if foreign.R == nil {
			foreign.R = &peerR{}
		}
		foreign.R.CloserPeers = append(foreign.R.CloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if local.PeerID == foreign.ID {
				local.R.Peer = foreign
				if foreign.R == nil {
					foreign.R = &peerR{}
				}
				foreign.R.CloserPeers = append(foreign.R.CloserPeers, local)
				break
			}
		}
	}

	return nil
}

func (o *CloserPeer) SetFindNodeRPC(ctx context.Context, exec boil.ContextExecutor, insert bool, related *FindNodesRPC) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"find_node_rpc_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	queries.Assign(&o.FindNodeRPCID, related.ID)
	if o.R == nil {
		o.R = &closerPeerR{
			FindNodeRPC: related,
		}
	} else {
		o.R.FindNodeRPC = related
	}

	if related.R == nil {
		related.R = &findNodesRPCR{
			FindNodeRPCCloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.FindNodeRPCCloserPeers = append(related.R.FindNodeRPCCloserPeers, o)
	}

	return nil
}

func (o *CloserPeer) RemoveFindNodeRPC(ctx context.Context, exec boil.ContextExecutor, related *FindNodesRPC) error {
	var err error

	queries.SetScanner(&o.FindNodeRPCID, nil)
	if _, err = o.Update(ctx, exec, boil.Whitelist("find_node_rpc_id")); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	if o.R != nil {
		o.R.FindNodeRPC = nil
	}
	if related == nil || related.R == nil {
		return nil
	}

	for i, ri := range related.R.FindNodeRPCCloserPeers {
		if queries.Equal(o.FindNodeRPCID, ri.FindNodeRPCID) {
			continue
		}

		ln := len(related.R.FindNodeRPCCloserPeers)
		if ln > 1 && i < ln-1 {
			related.R.FindNodeRPCCloserPeers[i] = related.R.FindNodeRPCCloserPeers[ln-1]
		}
		related.R.FindNodeRPCCloserPeers = related.R.FindNodeRPCCloserPeers[:ln-1]
		break
	}
	return nil
}

func (o *CloserPeer) SetGetProvidersRPC(ctx context.Context, exec boil.ContextExecutor, insert bool, related *GetProvidersRPC) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"get_providers_rpc_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	queries.Assign(&o.GetProvidersRPCID, related.ID)
	if o.R == nil {
		o.R = &closerPeerR{
			GetProvidersRPC: related,
		}
	} else {
		o.R.GetProvidersRPC = related
	}

	if related.R == nil {
		related.R = &getProvidersRPCR{
			CloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.CloserPeers = append(related.R.CloserPeers, o)
	}

	return nil
}

func (o *CloserPeer) RemoveGetProvidersRPC(ctx context.Context, exec boil.ContextExecutor, related *GetProvidersRPC) error {
	var err error

	queries.SetScanner(&o.GetProvidersRPCID, nil)
	if _, err = o.Update(ctx, exec, boil.Whitelist("get_providers_rpc_id")); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	if o.R != nil {
		o.R.GetProvidersRPC = nil
	}
	if related == nil || related.R == nil {
		return nil
	}

	for i, ri := range related.R.CloserPeers {
		if queries.Equal(o.GetProvidersRPCID, ri.GetProvidersRPCID) {
			continue
		}

		ln := len(related.R.CloserPeers)
		if ln > 1 && i < ln-1 {
			related.R.CloserPeers[i] = related.R.CloserPeers[ln-1]
		}
		related.R.CloserPeers = related.R.CloserPeers[:ln-1]
		break
	}
	return nil
}

func (o *CloserPeer) SetPeer(ctx context.Context, exec boil.ContextExecutor, insert bool, related *Peer) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"peer_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	o.PeerID = related.ID
	if o.R == nil {
		o.R = &closerPeerR{
			Peer: related,
		}
	} else {
		o.R.Peer = related
	}

	if related.R == nil {
		related.R = &peerR{
			CloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.CloserPeers = append(related.R.CloserPeers, o)
	}

	return nil
}

func CloserPeers(mods ...qm.QueryMod) closerPeerQuery {
	mods = append(mods, qm.From("\"closer_peers\""))
	return closerPeerQuery{NewQuery(mods...)}
}

func FindCloserPeer(ctx context.Context, exec boil.ContextExecutor, iD int, selectCols ...string) (*CloserPeer, error) {
	closerPeerObj := &CloserPeer{}

	sel := "*"
	if len(selectCols) > 0 {
		sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
	}
	query := fmt.Sprintf(
		"select %s from \"closer_peers\" where \"id\"=$1", sel,
	)

	q := queries.Raw(query, iD)

	err := q.Bind(ctx, exec, closerPeerObj)
	if err != nil {
		if errors.Cause(err) == sql.ErrNoRows {
			return nil, sql.ErrNoRows
		}
		return nil, errors.Wrap(err, "models: unable to select from closer_peers")
	}

	if err = closerPeerObj.doAfterSelectHooks(ctx, exec); err != nil {
		return closerPeerObj, err
	}

	return closerPeerObj, nil
}

func (o *CloserPeer) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
	if o == nil {
		return errors.New("models: no closer_peers provided for insertion")
	}

	var err error

	if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
		return err
	}

	nzDefaults := queries.NonZeroDefaultSet(closerPeerColumnsWithDefault, o)

	key := makeCacheKey(columns, nzDefaults)
	closerPeerInsertCacheMut.RLock()
	cache, cached := closerPeerInsertCache[key]
	closerPeerInsertCacheMut.RUnlock()

	if !cached {
		wl, returnColumns := columns.InsertColumnSet(
			closerPeerAllColumns,
			closerPeerColumnsWithDefault,
			closerPeerColumnsWithoutDefault,
			nzDefaults,
		)

		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, wl)
		if err != nil {
			return err
		}
		cache.retMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, returnColumns)
		if err != nil {
			return err
		}
		if len(wl) != 0 {
			cache.query = fmt.Sprintf("INSERT INTO \"closer_peers\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
		} else {
			cache.query = "INSERT INTO \"closer_peers\" %sDEFAULT VALUES%s"
		}

		var queryOutput, queryReturning string

		if len(cache.retMapping) != 0 {
			queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\""))
		}

		cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
	}

	value := reflect.Indirect(reflect.ValueOf(o))
	vals := queries.ValuesFromMapping(value, cache.valueMapping)

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, vals)
	}

	if len(cache.retMapping) != 0 {
		err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
	} else {
		_, err = exec.ExecContext(ctx, cache.query, vals...)
	}

	if err != nil {
		return errors.Wrap(err, "models: unable to insert into closer_peers")
	}

	if !cached {
		closerPeerInsertCacheMut.Lock()
		closerPeerInsertCache[key] = cache
		closerPeerInsertCacheMut.Unlock()
	}

	return o.doAfterInsertHooks(ctx, exec)
}

func (o *CloserPeer) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
	var err error
	if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
		return 0, err
	}
	key := makeCacheKey(columns, nil)
	closerPeerUpdateCacheMut.RLock()
	cache, cached := closerPeerUpdateCache[key]
	closerPeerUpdateCacheMut.RUnlock()

	if !cached {
		wl := columns.UpdateColumnSet(
			closerPeerAllColumns,
			closerPeerPrimaryKeyColumns,
		)

		if !columns.IsWhitelist() {
			wl = strmangle.SetComplement(wl, []string{"created_at"})
		}
		if len(wl) == 0 {
			return 0, errors.New("models: unable to update closer_peers, could not build whitelist")
		}

		cache.query = fmt.Sprintf("UPDATE \"closer_peers\" SET %s WHERE %s",
			strmangle.SetParamNames("\"", "\"", 1, wl),
			strmangle.WhereClause("\"", "\"", len(wl)+1, closerPeerPrimaryKeyColumns),
		)
		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, append(wl, closerPeerPrimaryKeyColumns...))
		if err != nil {
			return 0, err
		}
	}

	values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, values)
	}
	var result sql.Result
	result, err = exec.ExecContext(ctx, cache.query, values...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update closer_peers row")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by update for closer_peers")
	}

	if !cached {
		closerPeerUpdateCacheMut.Lock()
		closerPeerUpdateCache[key] = cache
		closerPeerUpdateCacheMut.Unlock()
	}

	return rowsAff, o.doAfterUpdateHooks(ctx, exec)
}

func (q closerPeerQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
	queries.SetUpdate(q.Query, cols)

	result, err := q.Query.ExecContext(ctx, exec)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update all for closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to retrieve rows affected for closer_peers")
	}

	return rowsAff, nil
}

func (o CloserPeerSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
	ln := int64(len(o))
	if ln == 0 {
		return 0, nil
	}

	if len(cols) == 0 {
		return 0, errors.New("models: update all requires at least one column argument")
	}

	colNames := make([]string, len(cols))
	args := make([]interface{}, len(cols))

	i := 0
	for name, value := range cols {
		colNames[i] = name
		args[i] = value
		i++
	}

	for _, obj := range o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := fmt.Sprintf("UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, colNames),
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, closerPeerPrimaryKeyColumns, len(o)))

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args...)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update all in closerPeer slice")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to retrieve rows affected all in update all closerPeer")
	}
	return rowsAff, nil
}

func (o *CloserPeer) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
	if o == nil {
		return errors.New("models: no closer_peers provided for upsert")
	}

	if err := o.doBeforeUpsertHooks(ctx, exec); err != nil {
		return err
	}

	nzDefaults := queries.NonZeroDefaultSet(closerPeerColumnsWithDefault, o)

	buf := strmangle.GetBuffer()
	if updateOnConflict {
		buf.WriteByte('t')
	} else {
		buf.WriteByte('f')
	}
	buf.WriteByte('.')
	for _, c := range conflictColumns {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	buf.WriteString(strconv.Itoa(updateColumns.Kind))
	for _, c := range updateColumns.Cols {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	buf.WriteString(strconv.Itoa(insertColumns.Kind))
	for _, c := range insertColumns.Cols {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	for _, c := range nzDefaults {
		buf.WriteString(c)
	}
	key := buf.String()
	strmangle.PutBuffer(buf)

	closerPeerUpsertCacheMut.RLock()
	cache, cached := closerPeerUpsertCache[key]
	closerPeerUpsertCacheMut.RUnlock()

	var err error

	if !cached {
		insert, ret := insertColumns.InsertColumnSet(
			closerPeerAllColumns,
			closerPeerColumnsWithDefault,
			closerPeerColumnsWithoutDefault,
			nzDefaults,
		)
		update := updateColumns.UpdateColumnSet(
			closerPeerAllColumns,
			closerPeerPrimaryKeyColumns,
		)

		if updateOnConflict && len(update) == 0 {
			return errors.New("models: unable to upsert closer_peers, could not build update column list")
		}

		conflict := conflictColumns
		if len(conflict) == 0 {
			conflict = make([]string, len(closerPeerPrimaryKeyColumns))
			copy(conflict, closerPeerPrimaryKeyColumns)
		}
		cache.query = buildUpsertQueryPostgres(dialect, "\"closer_peers\"", updateOnConflict, ret, update, conflict, insert)

		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, insert)
		if err != nil {
			return err
		}
		if len(ret) != 0 {
			cache.retMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, ret)
			if err != nil {
				return err
			}
		}
	}

	value := reflect.Indirect(reflect.ValueOf(o))
	vals := queries.ValuesFromMapping(value, cache.valueMapping)
	var returns []interface{}
	if len(cache.retMapping) != 0 {
		returns = queries.PtrsFromMapping(value, cache.retMapping)
	}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, vals)
	}
	if len(cache.retMapping) != 0 {
		err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...)
		if err == sql.ErrNoRows {
			err = nil 
		}
	} else {
		_, err = exec.ExecContext(ctx, cache.query, vals...)
	}
	if err != nil {
		return errors.Wrap(err, "models: unable to upsert closer_peers")
	}

	if !cached {
		closerPeerUpsertCacheMut.Lock()
		closerPeerUpsertCache[key] = cache
		closerPeerUpsertCacheMut.Unlock()
	}

	return o.doAfterUpsertHooks(ctx, exec)
}

func (o *CloserPeer) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if o == nil {
		return 0, errors.New("models: no CloserPeer provided for delete")
	}

	if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
		return 0, err
	}

	args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), closerPeerPrimaryKeyMapping)
	sql := "DELETE FROM \"closer_peers\" WHERE \"id\"=$1"

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args...)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete from closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by delete for closer_peers")
	}

	if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
		return 0, err
	}

	return rowsAff, nil
}

func (q closerPeerQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if q.Query == nil {
		return 0, errors.New("models: no closerPeerQuery provided for delete all")
	}

	queries.SetDelete(q.Query)

	result, err := q.Query.ExecContext(ctx, exec)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete all from closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for closer_peers")
	}

	return rowsAff, nil
}

func (o CloserPeerSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if len(o) == 0 {
		return 0, nil
	}

	if len(closerPeerBeforeDeleteHooks) != 0 {
		for _, obj := range o {
			if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
				return 0, err
			}
		}
	}

	var args []interface{}
	for _, obj := range o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := "DELETE FROM \"closer_peers\" WHERE " +
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, closerPeerPrimaryKeyColumns, len(o))

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete all from closerPeer slice")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for closer_peers")
	}

	if len(closerPeerAfterDeleteHooks) != 0 {
		for _, obj := range o {
			if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
				return 0, err
			}
		}
	}

	return rowsAff, nil
}

func (o *CloserPeer) Reload(ctx context.Context, exec boil.ContextExecutor) error {
	ret, err := FindCloserPeer(ctx, exec, o.ID)
	if err != nil {
		return err
	}

	*o = *ret
	return nil
}

func (o *CloserPeerSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
	if o == nil || len(*o) == 0 {
		return nil
	}

	slice := CloserPeerSlice{}
	var args []interface{}
	for _, obj := range *o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := "SELECT \"closer_peers\".* FROM \"closer_peers\" WHERE " +
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, closerPeerPrimaryKeyColumns, len(*o))

	q := queries.Raw(sql, args...)

	err := q.Bind(ctx, exec, &slice)
	if err != nil {
		return errors.Wrap(err, "models: unable to reload all in CloserPeerSlice")
	}

	*o = slice

	return nil
}

func CloserPeerExists(ctx context.Context, exec boil.ContextExecutor, iD int) (bool, error) {
	var exists bool
	sql := "select exists(select 1 from \"closer_peers\" where \"id\"=$1 limit 1)"

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, iD)
	}
	row := exec.QueryRowContext(ctx, sql, iD)

	err := row.Scan(&exists)
	if err != nil {
		return false, errors.Wrap(err, "models: unable to check if closer_peers exists")
	}

	return exists, nil
}
// Code generated by SQLBoiler 4.6.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.

package models

import (
	"context"
	"database/sql"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/friendsofgo/errors"
	"github.com/volatiletech/null/v8"
	"github.com/volatiletech/sqlboiler/v4/boil"
	"github.com/volatiletech/sqlboiler/v4/queries"
	"github.com/volatiletech/sqlboiler/v4/queries/qm"
	"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
	"github.com/volatiletech/sqlboiler/v4/types"
	"github.com/volatiletech/strmangle"
)

// CloserPeer is an object representing the database table.
type CloserPeer struct {
	ID                int              `boil:"id" json:"id" toml:"id" yaml:"id"`
	FindNodeRPCID     null.Int         `boil:"find_node_rpc_id" json:"find_node_rpc_id,omitempty" toml:"find_node_rpc_id" yaml:"find_node_rpc_id,omitempty"`
	GetProvidersRPCID null.Int         `boil:"get_providers_rpc_id" json:"get_providers_rpc_id,omitempty" toml:"get_providers_rpc_id" yaml:"get_providers_rpc_id,omitempty"`
	PeerID            int              `boil:"peer_id" json:"peer_id" toml:"peer_id" yaml:"peer_id"`
	MultiAddressIds   types.Int64Array `boil:"multi_address_ids" json:"multi_address_ids" toml:"multi_address_ids" yaml:"multi_address_ids"`

	R *closerPeerR `boil:"-" json:"-" toml:"-" yaml:"-"`
	L closerPeerL  `boil:"-" json:"-" toml:"-" yaml:"-"`
}

var CloserPeerColumns = struct {
	ID                string
	FindNodeRPCID     string
	GetProvidersRPCID string
	PeerID            string
	MultiAddressIds   string
}{
	ID:                "id",
	FindNodeRPCID:     "find_node_rpc_id",
	GetProvidersRPCID: "get_providers_rpc_id",
	PeerID:            "peer_id",
	MultiAddressIds:   "multi_address_ids",
}

var CloserPeerTableColumns = struct {
	ID                string
	FindNodeRPCID     string
	GetProvidersRPCID string
	PeerID            string
	MultiAddressIds   string
}{
	ID:                "closer_peers.id",
	FindNodeRPCID:     "closer_peers.find_node_rpc_id",
	GetProvidersRPCID: "closer_peers.get_providers_rpc_id",
	PeerID:            "closer_peers.peer_id",
	MultiAddressIds:   "closer_peers.multi_address_ids",
}

// Generated where

type whereHelpernull_Int struct{ field string }

func (w whereHelpernull_Int) EQ(x null.Int) qm.QueryMod {
	return qmhelper.WhereNullEQ(w.field, false, x)
}
func (w whereHelpernull_Int) NEQ(x null.Int) qm.QueryMod {
	return qmhelper.WhereNullEQ(w.field, true, x)
}
func (w whereHelpernull_Int) IsNull() qm.QueryMod    { return qmhelper.WhereIsNull(w.field) }
func (w whereHelpernull_Int) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) }
func (w whereHelpernull_Int) LT(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.LT, x)
}
func (w whereHelpernull_Int) LTE(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.LTE, x)
}
func (w whereHelpernull_Int) GT(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.GT, x)
}
func (w whereHelpernull_Int) GTE(x null.Int) qm.QueryMod {
	return qmhelper.Where(w.field, qmhelper.GTE, x)
}

var CloserPeerWhere = struct {
	ID                whereHelperint
	FindNodeRPCID     whereHelpernull_Int
	GetProvidersRPCID whereHelpernull_Int
	PeerID            whereHelperint
	MultiAddressIds   whereHelpertypes_Int64Array
}{
	ID:                whereHelperint{field: "\"closer_peers\".\"id\""},
	FindNodeRPCID:     whereHelpernull_Int{field: "\"closer_peers\".\"find_node_rpc_id\""},
	GetProvidersRPCID: whereHelpernull_Int{field: "\"closer_peers\".\"get_providers_rpc_id\""},
	PeerID:            whereHelperint{field: "\"closer_peers\".\"peer_id\""},
	MultiAddressIds:   whereHelpertypes_Int64Array{field: "\"closer_peers\".\"multi_address_ids\""},
}

// CloserPeerRels is where relationship names are stored.
var CloserPeerRels = struct {
	FindNodeRPC     string
	GetProvidersRPC string
	Peer            string
}{
	FindNodeRPC:     "FindNodeRPC",
	GetProvidersRPC: "GetProvidersRPC",
	Peer:            "Peer",
}

// closerPeerR is where relationships are stored.
type closerPeerR struct {
	FindNodeRPC     *FindNodesRPC    `boil:"FindNodeRPC" json:"FindNodeRPC" toml:"FindNodeRPC" yaml:"FindNodeRPC"`
	GetProvidersRPC *GetProvidersRPC `boil:"GetProvidersRPC" json:"GetProvidersRPC" toml:"GetProvidersRPC" yaml:"GetProvidersRPC"`
	Peer            *Peer            `boil:"Peer" json:"Peer" toml:"Peer" yaml:"Peer"`
}

// NewStruct creates a new relationship struct
func (*closerPeerR) NewStruct() *closerPeerR {
	return &closerPeerR{}
}

// closerPeerL is where Load methods for each relationship are stored.
type closerPeerL struct{}

var (
	closerPeerAllColumns            = []string{"id", "find_node_rpc_id", "get_providers_rpc_id", "peer_id", "multi_address_ids"}
	closerPeerColumnsWithoutDefault = []string{"find_node_rpc_id", "get_providers_rpc_id", "peer_id", "multi_address_ids"}
	closerPeerColumnsWithDefault    = []string{"id"}
	closerPeerPrimaryKeyColumns     = []string{"id"}
)

type (
	// CloserPeerSlice is an alias for a slice of pointers to CloserPeer.
	// This should almost always be used instead of []CloserPeer.
	CloserPeerSlice []*CloserPeer
	// CloserPeerHook is the signature for custom CloserPeer hook methods
	CloserPeerHook func(context.Context, boil.ContextExecutor, *CloserPeer) error

	closerPeerQuery struct {
		*queries.Query
	}
)

// Cache for insert, update and upsert
var (
	closerPeerType                 = reflect.TypeOf(&CloserPeer{})
	closerPeerMapping              = queries.MakeStructMapping(closerPeerType)
	closerPeerPrimaryKeyMapping, _ = queries.BindMapping(closerPeerType, closerPeerMapping, closerPeerPrimaryKeyColumns)
	closerPeerInsertCacheMut       sync.RWMutex
	closerPeerInsertCache          = make(map[string]insertCache)
	closerPeerUpdateCacheMut       sync.RWMutex
	closerPeerUpdateCache          = make(map[string]updateCache)
	closerPeerUpsertCacheMut       sync.RWMutex
	closerPeerUpsertCache          = make(map[string]insertCache)
)

var (
	// Force time package dependency for automated UpdatedAt/CreatedAt.
	_ = time.Second
	// Force qmhelper dependency for where clause generation (which doesn't
	// always happen)
	_ = qmhelper.Where
)

var closerPeerBeforeInsertHooks []CloserPeerHook
var closerPeerBeforeUpdateHooks []CloserPeerHook
var closerPeerBeforeDeleteHooks []CloserPeerHook
var closerPeerBeforeUpsertHooks []CloserPeerHook

var closerPeerAfterInsertHooks []CloserPeerHook
var closerPeerAfterSelectHooks []CloserPeerHook
var closerPeerAfterUpdateHooks []CloserPeerHook
var closerPeerAfterDeleteHooks []CloserPeerHook
var closerPeerAfterUpsertHooks []CloserPeerHook

// doBeforeInsertHooks executes all "before insert" hooks.
func (o *CloserPeer) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeInsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doBeforeUpdateHooks executes all "before Update" hooks.
func (o *CloserPeer) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeUpdateHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doBeforeDeleteHooks executes all "before Delete" hooks.
func (o *CloserPeer) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeDeleteHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doBeforeUpsertHooks executes all "before Upsert" hooks.
func (o *CloserPeer) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerBeforeUpsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doAfterInsertHooks executes all "after Insert" hooks.
func (o *CloserPeer) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterInsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doAfterSelectHooks executes all "after Select" hooks.
func (o *CloserPeer) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterSelectHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doAfterUpdateHooks executes all "after Update" hooks.
func (o *CloserPeer) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterUpdateHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doAfterDeleteHooks executes all "after Delete" hooks.
func (o *CloserPeer) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterDeleteHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// doAfterUpsertHooks executes all "after Upsert" hooks.
func (o *CloserPeer) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
	if boil.HooksAreSkipped(ctx) {
		return nil
	}

	for _, hook := range closerPeerAfterUpsertHooks {
		if err := hook(ctx, exec, o); err != nil {
			return err
		}
	}

	return nil
}

// AddCloserPeerHook registers your hook function for all future operations.
func AddCloserPeerHook(hookPoint boil.HookPoint, closerPeerHook CloserPeerHook) {
	switch hookPoint {
	case boil.BeforeInsertHook:
		closerPeerBeforeInsertHooks = append(closerPeerBeforeInsertHooks, closerPeerHook)
	case boil.BeforeUpdateHook:
		closerPeerBeforeUpdateHooks = append(closerPeerBeforeUpdateHooks, closerPeerHook)
	case boil.BeforeDeleteHook:
		closerPeerBeforeDeleteHooks = append(closerPeerBeforeDeleteHooks, closerPeerHook)
	case boil.BeforeUpsertHook:
		closerPeerBeforeUpsertHooks = append(closerPeerBeforeUpsertHooks, closerPeerHook)
	case boil.AfterInsertHook:
		closerPeerAfterInsertHooks = append(closerPeerAfterInsertHooks, closerPeerHook)
	case boil.AfterSelectHook:
		closerPeerAfterSelectHooks = append(closerPeerAfterSelectHooks, closerPeerHook)
	case boil.AfterUpdateHook:
		closerPeerAfterUpdateHooks = append(closerPeerAfterUpdateHooks, closerPeerHook)
	case boil.AfterDeleteHook:
		closerPeerAfterDeleteHooks = append(closerPeerAfterDeleteHooks, closerPeerHook)
	case boil.AfterUpsertHook:
		closerPeerAfterUpsertHooks = append(closerPeerAfterUpsertHooks, closerPeerHook)
	}
}

// One returns a single closerPeer record from the query.
func (q closerPeerQuery) One(ctx context.Context, exec boil.ContextExecutor) (*CloserPeer, error) {
	o := &CloserPeer{}

	queries.SetLimit(q.Query, 1)

	err := q.Bind(ctx, exec, o)
	if err != nil {
		if errors.Cause(err) == sql.ErrNoRows {
			return nil, sql.ErrNoRows
		}
		return nil, errors.Wrap(err, "models: failed to execute a one query for closer_peers")
	}

	if err := o.doAfterSelectHooks(ctx, exec); err != nil {
		return o, err
	}

	return o, nil
}

// All returns all CloserPeer records from the query.
func (q closerPeerQuery) All(ctx context.Context, exec boil.ContextExecutor) (CloserPeerSlice, error) {
	var o []*CloserPeer

	err := q.Bind(ctx, exec, &o)
	if err != nil {
		return nil, errors.Wrap(err, "models: failed to assign all query results to CloserPeer slice")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range o {
			if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
				return o, err
			}
		}
	}

	return o, nil
}

// Count returns the count of all CloserPeer records in the query.
func (q closerPeerQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	var count int64

	queries.SetSelect(q.Query, nil)
	queries.SetCount(q.Query)

	err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to count closer_peers rows")
	}

	return count, nil
}

// Exists checks if the row exists in the table.
func (q closerPeerQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
	var count int64

	queries.SetSelect(q.Query, nil)
	queries.SetCount(q.Query)
	queries.SetLimit(q.Query, 1)

	err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
	if err != nil {
		return false, errors.Wrap(err, "models: failed to check if closer_peers exists")
	}

	return count > 0, nil
}

// FindNodeRPC pointed to by the foreign key.
func (o *CloserPeer) FindNodeRPC(mods ...qm.QueryMod) findNodesRPCQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.FindNodeRPCID),
	}

	queryMods = append(queryMods, mods...)

	query := FindNodesRPCS(queryMods...)
	queries.SetFrom(query.Query, "\"find_nodes_rpcs\"")

	return query
}

// GetProvidersRPC pointed to by the foreign key.
func (o *CloserPeer) GetProvidersRPC(mods ...qm.QueryMod) getProvidersRPCQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.GetProvidersRPCID),
	}

	queryMods = append(queryMods, mods...)

	query := GetProvidersRPCS(queryMods...)
	queries.SetFrom(query.Query, "\"get_providers_rpcs\"")

	return query
}

// Peer pointed to by the foreign key.
func (o *CloserPeer) Peer(mods ...qm.QueryMod) peerQuery {
	queryMods := []qm.QueryMod{
		qm.Where("\"id\" = ?", o.PeerID),
	}

	queryMods = append(queryMods, mods...)

	query := Peers(queryMods...)
	queries.SetFrom(query.Query, "\"peers\"")

	return query
}

// LoadFindNodeRPC allows an eager lookup of values, cached into the
// loaded structs of the objects. This is for an N-1 relationship.
func (closerPeerL) LoadFindNodeRPC(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		if !queries.IsNil(object.FindNodeRPCID) {
			args = append(args, object.FindNodeRPCID)
		}

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if queries.Equal(a, obj.FindNodeRPCID) {
					continue Outer
				}
			}

			if !queries.IsNil(obj.FindNodeRPCID) {
				args = append(args, obj.FindNodeRPCID)
			}

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`find_nodes_rpcs`),
		qm.WhereIn(`find_nodes_rpcs.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load FindNodesRPC")
	}

	var resultSlice []*FindNodesRPC
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice FindNodesRPC")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for find_nodes_rpcs")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for find_nodes_rpcs")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.FindNodeRPC = foreign
		if foreign.R == nil {
			foreign.R = &findNodesRPCR{}
		}
		foreign.R.FindNodeRPCCloserPeers = append(foreign.R.FindNodeRPCCloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if queries.Equal(local.FindNodeRPCID, foreign.ID) {
				local.R.FindNodeRPC = foreign
				if foreign.R == nil {
					foreign.R = &findNodesRPCR{}
				}
				foreign.R.FindNodeRPCCloserPeers = append(foreign.R.FindNodeRPCCloserPeers, local)
				break
			}
		}
	}

	return nil
}

// LoadGetProvidersRPC allows an eager lookup of values, cached into the
// loaded structs of the objects. This is for an N-1 relationship.
func (closerPeerL) LoadGetProvidersRPC(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		if !queries.IsNil(object.GetProvidersRPCID) {
			args = append(args, object.GetProvidersRPCID)
		}

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if queries.Equal(a, obj.GetProvidersRPCID) {
					continue Outer
				}
			}

			if !queries.IsNil(obj.GetProvidersRPCID) {
				args = append(args, obj.GetProvidersRPCID)
			}

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`get_providers_rpcs`),
		qm.WhereIn(`get_providers_rpcs.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load GetProvidersRPC")
	}

	var resultSlice []*GetProvidersRPC
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice GetProvidersRPC")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for get_providers_rpcs")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for get_providers_rpcs")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.GetProvidersRPC = foreign
		if foreign.R == nil {
			foreign.R = &getProvidersRPCR{}
		}
		foreign.R.CloserPeers = append(foreign.R.CloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if queries.Equal(local.GetProvidersRPCID, foreign.ID) {
				local.R.GetProvidersRPC = foreign
				if foreign.R == nil {
					foreign.R = &getProvidersRPCR{}
				}
				foreign.R.CloserPeers = append(foreign.R.CloserPeers, local)
				break
			}
		}
	}

	return nil
}

// LoadPeer allows an eager lookup of values, cached into the
// loaded structs of the objects. This is for an N-1 relationship.
func (closerPeerL) LoadPeer(ctx context.Context, e boil.ContextExecutor, singular bool, maybeCloserPeer interface{}, mods queries.Applicator) error {
	var slice []*CloserPeer
	var object *CloserPeer

	if singular {
		object = maybeCloserPeer.(*CloserPeer)
	} else {
		slice = *maybeCloserPeer.(*[]*CloserPeer)
	}

	args := make([]interface{}, 0, 1)
	if singular {
		if object.R == nil {
			object.R = &closerPeerR{}
		}
		args = append(args, object.PeerID)

	} else {
	Outer:
		for _, obj := range slice {
			if obj.R == nil {
				obj.R = &closerPeerR{}
			}

			for _, a := range args {
				if a == obj.PeerID {
					continue Outer
				}
			}

			args = append(args, obj.PeerID)

		}
	}

	if len(args) == 0 {
		return nil
	}

	query := NewQuery(
		qm.From(`peers`),
		qm.WhereIn(`peers.id in ?`, args...),
	)
	if mods != nil {
		mods.Apply(query)
	}

	results, err := query.QueryContext(ctx, e)
	if err != nil {
		return errors.Wrap(err, "failed to eager load Peer")
	}

	var resultSlice []*Peer
	if err = queries.Bind(results, &resultSlice); err != nil {
		return errors.Wrap(err, "failed to bind eager loaded slice Peer")
	}

	if err = results.Close(); err != nil {
		return errors.Wrap(err, "failed to close results of eager load for peers")
	}
	if err = results.Err(); err != nil {
		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for peers")
	}

	if len(closerPeerAfterSelectHooks) != 0 {
		for _, obj := range resultSlice {
			if err := obj.doAfterSelectHooks(ctx, e); err != nil {
				return err
			}
		}
	}

	if len(resultSlice) == 0 {
		return nil
	}

	if singular {
		foreign := resultSlice[0]
		object.R.Peer = foreign
		if foreign.R == nil {
			foreign.R = &peerR{}
		}
		foreign.R.CloserPeers = append(foreign.R.CloserPeers, object)
		return nil
	}

	for _, local := range slice {
		for _, foreign := range resultSlice {
			if local.PeerID == foreign.ID {
				local.R.Peer = foreign
				if foreign.R == nil {
					foreign.R = &peerR{}
				}
				foreign.R.CloserPeers = append(foreign.R.CloserPeers, local)
				break
			}
		}
	}

	return nil
}

// SetFindNodeRPC of the closerPeer to the related item.
// Sets o.R.FindNodeRPC to related.
// Adds o to related.R.FindNodeRPCCloserPeers.
func (o *CloserPeer) SetFindNodeRPC(ctx context.Context, exec boil.ContextExecutor, insert bool, related *FindNodesRPC) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"find_node_rpc_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	queries.Assign(&o.FindNodeRPCID, related.ID)
	if o.R == nil {
		o.R = &closerPeerR{
			FindNodeRPC: related,
		}
	} else {
		o.R.FindNodeRPC = related
	}

	if related.R == nil {
		related.R = &findNodesRPCR{
			FindNodeRPCCloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.FindNodeRPCCloserPeers = append(related.R.FindNodeRPCCloserPeers, o)
	}

	return nil
}

// RemoveFindNodeRPC relationship.
// Sets o.R.FindNodeRPC to nil.
// Removes o from all passed in related items' relationships struct (Optional).
func (o *CloserPeer) RemoveFindNodeRPC(ctx context.Context, exec boil.ContextExecutor, related *FindNodesRPC) error {
	var err error

	queries.SetScanner(&o.FindNodeRPCID, nil)
	if _, err = o.Update(ctx, exec, boil.Whitelist("find_node_rpc_id")); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	if o.R != nil {
		o.R.FindNodeRPC = nil
	}
	if related == nil || related.R == nil {
		return nil
	}

	for i, ri := range related.R.FindNodeRPCCloserPeers {
		if queries.Equal(o.FindNodeRPCID, ri.FindNodeRPCID) {
			continue
		}

		ln := len(related.R.FindNodeRPCCloserPeers)
		if ln > 1 && i < ln-1 {
			related.R.FindNodeRPCCloserPeers[i] = related.R.FindNodeRPCCloserPeers[ln-1]
		}
		related.R.FindNodeRPCCloserPeers = related.R.FindNodeRPCCloserPeers[:ln-1]
		break
	}
	return nil
}

// SetGetProvidersRPC of the closerPeer to the related item.
// Sets o.R.GetProvidersRPC to related.
// Adds o to related.R.CloserPeers.
func (o *CloserPeer) SetGetProvidersRPC(ctx context.Context, exec boil.ContextExecutor, insert bool, related *GetProvidersRPC) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"get_providers_rpc_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	queries.Assign(&o.GetProvidersRPCID, related.ID)
	if o.R == nil {
		o.R = &closerPeerR{
			GetProvidersRPC: related,
		}
	} else {
		o.R.GetProvidersRPC = related
	}

	if related.R == nil {
		related.R = &getProvidersRPCR{
			CloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.CloserPeers = append(related.R.CloserPeers, o)
	}

	return nil
}

// RemoveGetProvidersRPC relationship.
// Sets o.R.GetProvidersRPC to nil.
// Removes o from all passed in related items' relationships struct (Optional).
func (o *CloserPeer) RemoveGetProvidersRPC(ctx context.Context, exec boil.ContextExecutor, related *GetProvidersRPC) error {
	var err error

	queries.SetScanner(&o.GetProvidersRPCID, nil)
	if _, err = o.Update(ctx, exec, boil.Whitelist("get_providers_rpc_id")); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	if o.R != nil {
		o.R.GetProvidersRPC = nil
	}
	if related == nil || related.R == nil {
		return nil
	}

	for i, ri := range related.R.CloserPeers {
		if queries.Equal(o.GetProvidersRPCID, ri.GetProvidersRPCID) {
			continue
		}

		ln := len(related.R.CloserPeers)
		if ln > 1 && i < ln-1 {
			related.R.CloserPeers[i] = related.R.CloserPeers[ln-1]
		}
		related.R.CloserPeers = related.R.CloserPeers[:ln-1]
		break
	}
	return nil
}

// SetPeer of the closerPeer to the related item.
// Sets o.R.Peer to related.
// Adds o to related.R.CloserPeers.
func (o *CloserPeer) SetPeer(ctx context.Context, exec boil.ContextExecutor, insert bool, related *Peer) error {
	var err error
	if insert {
		if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
			return errors.Wrap(err, "failed to insert into foreign table")
		}
	}

	updateQuery := fmt.Sprintf(
		"UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, []string{"peer_id"}),
		strmangle.WhereClause("\"", "\"", 2, closerPeerPrimaryKeyColumns),
	)
	values := []interface{}{related.ID, o.ID}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, updateQuery)
		fmt.Fprintln(writer, values)
	}
	if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
		return errors.Wrap(err, "failed to update local table")
	}

	o.PeerID = related.ID
	if o.R == nil {
		o.R = &closerPeerR{
			Peer: related,
		}
	} else {
		o.R.Peer = related
	}

	if related.R == nil {
		related.R = &peerR{
			CloserPeers: CloserPeerSlice{o},
		}
	} else {
		related.R.CloserPeers = append(related.R.CloserPeers, o)
	}

	return nil
}

// CloserPeers retrieves all the records using an executor.
func CloserPeers(mods ...qm.QueryMod) closerPeerQuery {
	mods = append(mods, qm.From("\"closer_peers\""))
	return closerPeerQuery{NewQuery(mods...)}
}

// FindCloserPeer retrieves a single record by ID with an executor.
// If selectCols is empty Find will return all columns.
func FindCloserPeer(ctx context.Context, exec boil.ContextExecutor, iD int, selectCols ...string) (*CloserPeer, error) {
	closerPeerObj := &CloserPeer{}

	sel := "*"
	if len(selectCols) > 0 {
		sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
	}
	query := fmt.Sprintf(
		"select %s from \"closer_peers\" where \"id\"=$1", sel,
	)

	q := queries.Raw(query, iD)

	err := q.Bind(ctx, exec, closerPeerObj)
	if err != nil {
		if errors.Cause(err) == sql.ErrNoRows {
			return nil, sql.ErrNoRows
		}
		return nil, errors.Wrap(err, "models: unable to select from closer_peers")
	}

	if err = closerPeerObj.doAfterSelectHooks(ctx, exec); err != nil {
		return closerPeerObj, err
	}

	return closerPeerObj, nil
}

// Insert a single record using an executor.
// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts.
func (o *CloserPeer) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
	if o == nil {
		return errors.New("models: no closer_peers provided for insertion")
	}

	var err error

	if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
		return err
	}

	nzDefaults := queries.NonZeroDefaultSet(closerPeerColumnsWithDefault, o)

	key := makeCacheKey(columns, nzDefaults)
	closerPeerInsertCacheMut.RLock()
	cache, cached := closerPeerInsertCache[key]
	closerPeerInsertCacheMut.RUnlock()

	if !cached {
		wl, returnColumns := columns.InsertColumnSet(
			closerPeerAllColumns,
			closerPeerColumnsWithDefault,
			closerPeerColumnsWithoutDefault,
			nzDefaults,
		)

		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, wl)
		if err != nil {
			return err
		}
		cache.retMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, returnColumns)
		if err != nil {
			return err
		}
		if len(wl) != 0 {
			cache.query = fmt.Sprintf("INSERT INTO \"closer_peers\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
		} else {
			cache.query = "INSERT INTO \"closer_peers\" %sDEFAULT VALUES%s"
		}

		var queryOutput, queryReturning string

		if len(cache.retMapping) != 0 {
			queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\""))
		}

		cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
	}

	value := reflect.Indirect(reflect.ValueOf(o))
	vals := queries.ValuesFromMapping(value, cache.valueMapping)

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, vals)
	}

	if len(cache.retMapping) != 0 {
		err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
	} else {
		_, err = exec.ExecContext(ctx, cache.query, vals...)
	}

	if err != nil {
		return errors.Wrap(err, "models: unable to insert into closer_peers")
	}

	if !cached {
		closerPeerInsertCacheMut.Lock()
		closerPeerInsertCache[key] = cache
		closerPeerInsertCacheMut.Unlock()
	}

	return o.doAfterInsertHooks(ctx, exec)
}

// Update uses an executor to update the CloserPeer.
// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates.
// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records.
func (o *CloserPeer) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
	var err error
	if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
		return 0, err
	}
	key := makeCacheKey(columns, nil)
	closerPeerUpdateCacheMut.RLock()
	cache, cached := closerPeerUpdateCache[key]
	closerPeerUpdateCacheMut.RUnlock()

	if !cached {
		wl := columns.UpdateColumnSet(
			closerPeerAllColumns,
			closerPeerPrimaryKeyColumns,
		)

		if !columns.IsWhitelist() {
			wl = strmangle.SetComplement(wl, []string{"created_at"})
		}
		if len(wl) == 0 {
			return 0, errors.New("models: unable to update closer_peers, could not build whitelist")
		}

		cache.query = fmt.Sprintf("UPDATE \"closer_peers\" SET %s WHERE %s",
			strmangle.SetParamNames("\"", "\"", 1, wl),
			strmangle.WhereClause("\"", "\"", len(wl)+1, closerPeerPrimaryKeyColumns),
		)
		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, append(wl, closerPeerPrimaryKeyColumns...))
		if err != nil {
			return 0, err
		}
	}

	values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, values)
	}
	var result sql.Result
	result, err = exec.ExecContext(ctx, cache.query, values...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update closer_peers row")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by update for closer_peers")
	}

	if !cached {
		closerPeerUpdateCacheMut.Lock()
		closerPeerUpdateCache[key] = cache
		closerPeerUpdateCacheMut.Unlock()
	}

	return rowsAff, o.doAfterUpdateHooks(ctx, exec)
}

// UpdateAll updates all rows with the specified column values.
func (q closerPeerQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
	queries.SetUpdate(q.Query, cols)

	result, err := q.Query.ExecContext(ctx, exec)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update all for closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to retrieve rows affected for closer_peers")
	}

	return rowsAff, nil
}

// UpdateAll updates all rows with the specified column values, using an executor.
func (o CloserPeerSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
	ln := int64(len(o))
	if ln == 0 {
		return 0, nil
	}

	if len(cols) == 0 {
		return 0, errors.New("models: update all requires at least one column argument")
	}

	colNames := make([]string, len(cols))
	args := make([]interface{}, len(cols))

	i := 0
	for name, value := range cols {
		colNames[i] = name
		args[i] = value
		i++
	}

	// Append all of the primary key values for each column
	for _, obj := range o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := fmt.Sprintf("UPDATE \"closer_peers\" SET %s WHERE %s",
		strmangle.SetParamNames("\"", "\"", 1, colNames),
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, closerPeerPrimaryKeyColumns, len(o)))

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args...)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to update all in closerPeer slice")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to retrieve rows affected all in update all closerPeer")
	}
	return rowsAff, nil
}

// Upsert attempts an insert using an executor, and does an update or ignore on conflict.
// See boil.Columns documentation for how to properly use updateColumns and insertColumns.
func (o *CloserPeer) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
	if o == nil {
		return errors.New("models: no closer_peers provided for upsert")
	}

	if err := o.doBeforeUpsertHooks(ctx, exec); err != nil {
		return err
	}

	nzDefaults := queries.NonZeroDefaultSet(closerPeerColumnsWithDefault, o)

	// Build cache key in-line uglily - mysql vs psql problems
	buf := strmangle.GetBuffer()
	if updateOnConflict {
		buf.WriteByte('t')
	} else {
		buf.WriteByte('f')
	}
	buf.WriteByte('.')
	for _, c := range conflictColumns {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	buf.WriteString(strconv.Itoa(updateColumns.Kind))
	for _, c := range updateColumns.Cols {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	buf.WriteString(strconv.Itoa(insertColumns.Kind))
	for _, c := range insertColumns.Cols {
		buf.WriteString(c)
	}
	buf.WriteByte('.')
	for _, c := range nzDefaults {
		buf.WriteString(c)
	}
	key := buf.String()
	strmangle.PutBuffer(buf)

	closerPeerUpsertCacheMut.RLock()
	cache, cached := closerPeerUpsertCache[key]
	closerPeerUpsertCacheMut.RUnlock()

	var err error

	if !cached {
		insert, ret := insertColumns.InsertColumnSet(
			closerPeerAllColumns,
			closerPeerColumnsWithDefault,
			closerPeerColumnsWithoutDefault,
			nzDefaults,
		)
		update := updateColumns.UpdateColumnSet(
			closerPeerAllColumns,
			closerPeerPrimaryKeyColumns,
		)

		if updateOnConflict && len(update) == 0 {
			return errors.New("models: unable to upsert closer_peers, could not build update column list")
		}

		conflict := conflictColumns
		if len(conflict) == 0 {
			conflict = make([]string, len(closerPeerPrimaryKeyColumns))
			copy(conflict, closerPeerPrimaryKeyColumns)
		}
		cache.query = buildUpsertQueryPostgres(dialect, "\"closer_peers\"", updateOnConflict, ret, update, conflict, insert)

		cache.valueMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, insert)
		if err != nil {
			return err
		}
		if len(ret) != 0 {
			cache.retMapping, err = queries.BindMapping(closerPeerType, closerPeerMapping, ret)
			if err != nil {
				return err
			}
		}
	}

	value := reflect.Indirect(reflect.ValueOf(o))
	vals := queries.ValuesFromMapping(value, cache.valueMapping)
	var returns []interface{}
	if len(cache.retMapping) != 0 {
		returns = queries.PtrsFromMapping(value, cache.retMapping)
	}

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, cache.query)
		fmt.Fprintln(writer, vals)
	}
	if len(cache.retMapping) != 0 {
		err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...)
		if err == sql.ErrNoRows {
			err = nil // Postgres doesn't return anything when there's no update
		}
	} else {
		_, err = exec.ExecContext(ctx, cache.query, vals...)
	}
	if err != nil {
		return errors.Wrap(err, "models: unable to upsert closer_peers")
	}

	if !cached {
		closerPeerUpsertCacheMut.Lock()
		closerPeerUpsertCache[key] = cache
		closerPeerUpsertCacheMut.Unlock()
	}

	return o.doAfterUpsertHooks(ctx, exec)
}

// Delete deletes a single CloserPeer record with an executor.
// Delete will match against the primary key column to find the record to delete.
func (o *CloserPeer) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if o == nil {
		return 0, errors.New("models: no CloserPeer provided for delete")
	}

	if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
		return 0, err
	}

	args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), closerPeerPrimaryKeyMapping)
	sql := "DELETE FROM \"closer_peers\" WHERE \"id\"=$1"

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args...)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete from closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by delete for closer_peers")
	}

	if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
		return 0, err
	}

	return rowsAff, nil
}

// DeleteAll deletes all matching rows.
func (q closerPeerQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if q.Query == nil {
		return 0, errors.New("models: no closerPeerQuery provided for delete all")
	}

	queries.SetDelete(q.Query)

	result, err := q.Query.ExecContext(ctx, exec)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete all from closer_peers")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for closer_peers")
	}

	return rowsAff, nil
}

// DeleteAll deletes all rows in the slice, using an executor.
func (o CloserPeerSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
	if len(o) == 0 {
		return 0, nil
	}

	if len(closerPeerBeforeDeleteHooks) != 0 {
		for _, obj := range o {
			if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
				return 0, err
			}
		}
	}

	var args []interface{}
	for _, obj := range o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := "DELETE FROM \"closer_peers\" WHERE " +
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, closerPeerPrimaryKeyColumns, len(o))

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, args)
	}
	result, err := exec.ExecContext(ctx, sql, args...)
	if err != nil {
		return 0, errors.Wrap(err, "models: unable to delete all from closerPeer slice")
	}

	rowsAff, err := result.RowsAffected()
	if err != nil {
		return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for closer_peers")
	}

	if len(closerPeerAfterDeleteHooks) != 0 {
		for _, obj := range o {
			if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
				return 0, err
			}
		}
	}

	return rowsAff, nil
}

// Reload refetches the object from the database
// using the primary keys with an executor.
func (o *CloserPeer) Reload(ctx context.Context, exec boil.ContextExecutor) error {
	ret, err := FindCloserPeer(ctx, exec, o.ID)
	if err != nil {
		return err
	}

	*o = *ret
	return nil
}

// ReloadAll refetches every row with matching primary key column values
// and overwrites the original object slice with the newly updated slice.
func (o *CloserPeerSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
	if o == nil || len(*o) == 0 {
		return nil
	}

	slice := CloserPeerSlice{}
	var args []interface{}
	for _, obj := range *o {
		pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), closerPeerPrimaryKeyMapping)
		args = append(args, pkeyArgs...)
	}

	sql := "SELECT \"closer_peers\".* FROM \"closer_peers\" WHERE " +
		strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, closerPeerPrimaryKeyColumns, len(*o))

	q := queries.Raw(sql, args...)

	err := q.Bind(ctx, exec, &slice)
	if err != nil {
		return errors.Wrap(err, "models: unable to reload all in CloserPeerSlice")
	}

	*o = slice

	return nil
}

// CloserPeerExists checks if the CloserPeer row exists.
func CloserPeerExists(ctx context.Context, exec boil.ContextExecutor, iD int) (bool, error) {
	var exists bool
	sql := "select exists(select 1 from \"closer_peers\" where \"id\"=$1 limit 1)"

	if boil.IsDebug(ctx) {
		writer := boil.DebugWriterFrom(ctx)
		fmt.Fprintln(writer, sql)
		fmt.Fprintln(writer, iD)
	}
	row := exec.QueryRowContext(ctx, sql, iD)

	err := row.Scan(&exists)
	if err != nil {
		return false, errors.Wrap(err, "models: unable to check if closer_peers exists")
	}

	return exists, nil
}
