package ent

import (
	"context"
	"fmt"

	"github.com/blushft/strana/modules/sink/reporter/store/ent/device"
	"github.com/blushft/strana/modules/sink/reporter/store/ent/event"
	"github.com/blushft/strana/modules/sink/reporter/store/ent/predicate"
	"github.com/facebook/ent/dialect/sql"
	"github.com/facebook/ent/dialect/sql/sqlgraph"
	"github.com/facebook/ent/schema/field"
	"github.com/google/uuid"
)

type DeviceUpdate struct {
	config
	hooks      []Hook
	mutation   *DeviceMutation
	predicates []predicate.Device
}

func (du *DeviceUpdate) Where(ps ...predicate.Device) *DeviceUpdate {
	du.predicates = append(du.predicates, ps...)
	return du
}

func (du *DeviceUpdate) SetManufacturer(s string) *DeviceUpdate {
	du.mutation.SetManufacturer(s)
	return du
}

func (du *DeviceUpdate) SetNillableManufacturer(s *string) *DeviceUpdate {
	if s != nil {
		du.SetManufacturer(*s)
	}
	return du
}

func (du *DeviceUpdate) ClearManufacturer() *DeviceUpdate {
	du.mutation.ClearManufacturer()
	return du
}

func (du *DeviceUpdate) SetModel(s string) *DeviceUpdate {
	du.mutation.SetModel(s)
	return du
}

func (du *DeviceUpdate) SetNillableModel(s *string) *DeviceUpdate {
	if s != nil {
		du.SetModel(*s)
	}
	return du
}

func (du *DeviceUpdate) ClearModel() *DeviceUpdate {
	du.mutation.ClearModel()
	return du
}

func (du *DeviceUpdate) SetName(s string) *DeviceUpdate {
	du.mutation.SetName(s)
	return du
}

func (du *DeviceUpdate) SetNillableName(s *string) *DeviceUpdate {
	if s != nil {
		du.SetName(*s)
	}
	return du
}

func (du *DeviceUpdate) ClearName() *DeviceUpdate {
	du.mutation.ClearName()
	return du
}

func (du *DeviceUpdate) SetType(s string) *DeviceUpdate {
	du.mutation.SetType(s)
	return du
}

func (du *DeviceUpdate) SetNillableType(s *string) *DeviceUpdate {
	if s != nil {
		du.SetType(*s)
	}
	return du
}

func (du *DeviceUpdate) ClearType() *DeviceUpdate {
	du.mutation.ClearType()
	return du
}

func (du *DeviceUpdate) SetVersion(s string) *DeviceUpdate {
	du.mutation.SetVersion(s)
	return du
}

func (du *DeviceUpdate) SetNillableVersion(s *string) *DeviceUpdate {
	if s != nil {
		du.SetVersion(*s)
	}
	return du
}

func (du *DeviceUpdate) ClearVersion() *DeviceUpdate {
	du.mutation.ClearVersion()
	return du
}

func (du *DeviceUpdate) SetMobile(b bool) *DeviceUpdate {
	du.mutation.SetMobile(b)
	return du
}

func (du *DeviceUpdate) SetNillableMobile(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetMobile(*b)
	}
	return du
}

func (du *DeviceUpdate) ClearMobile() *DeviceUpdate {
	du.mutation.ClearMobile()
	return du
}

func (du *DeviceUpdate) SetTablet(b bool) *DeviceUpdate {
	du.mutation.SetTablet(b)
	return du
}

func (du *DeviceUpdate) SetNillableTablet(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetTablet(*b)
	}
	return du
}

func (du *DeviceUpdate) ClearTablet() *DeviceUpdate {
	du.mutation.ClearTablet()
	return du
}

func (du *DeviceUpdate) SetDesktop(b bool) *DeviceUpdate {
	du.mutation.SetDesktop(b)
	return du
}

func (du *DeviceUpdate) SetNillableDesktop(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetDesktop(*b)
	}
	return du
}

func (du *DeviceUpdate) ClearDesktop() *DeviceUpdate {
	du.mutation.ClearDesktop()
	return du
}

func (du *DeviceUpdate) SetProperties(m map[string]interface{}) *DeviceUpdate {
	du.mutation.SetProperties(m)
	return du
}

func (du *DeviceUpdate) ClearProperties() *DeviceUpdate {
	du.mutation.ClearProperties()
	return du
}

func (du *DeviceUpdate) AddEventIDs(ids ...uuid.UUID) *DeviceUpdate {
	du.mutation.AddEventIDs(ids...)
	return du
}

func (du *DeviceUpdate) AddEvents(e ...*Event) *DeviceUpdate {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return du.AddEventIDs(ids...)
}

func (du *DeviceUpdate) Mutation() *DeviceMutation {
	return du.mutation
}

func (du *DeviceUpdate) RemoveEventIDs(ids ...uuid.UUID) *DeviceUpdate {
	du.mutation.RemoveEventIDs(ids...)
	return du
}

func (du *DeviceUpdate) RemoveEvents(e ...*Event) *DeviceUpdate {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return du.RemoveEventIDs(ids...)
}

func (du *DeviceUpdate) Save(ctx context.Context) (int, error) {

	var (
		err      error
		affected int
	)
	if len(du.hooks) == 0 {
		affected, err = du.sqlSave(ctx)
	} else {
		var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
			mutation, ok := m.(*DeviceMutation)
			if !ok {
				return nil, fmt.Errorf("unexpected mutation type %T", m)
			}
			du.mutation = mutation
			affected, err = du.sqlSave(ctx)
			mutation.done = true
			return affected, err
		})
		for i := len(du.hooks) - 1; i >= 0; i-- {
			mut = du.hooks[i](mut)
		}
		if _, err := mut.Mutate(ctx, du.mutation); err != nil {
			return 0, err
		}
	}
	return affected, err
}

func (du *DeviceUpdate) SaveX(ctx context.Context) int {
	affected, err := du.Save(ctx)
	if err != nil {
		panic(err)
	}
	return affected
}

func (du *DeviceUpdate) Exec(ctx context.Context) error {
	_, err := du.Save(ctx)
	return err
}

func (du *DeviceUpdate) ExecX(ctx context.Context) {
	if err := du.Exec(ctx); err != nil {
		panic(err)
	}
}

func (du *DeviceUpdate) sqlSave(ctx context.Context) (n int, err error) {
	_spec := &sqlgraph.UpdateSpec{
		Node: &sqlgraph.NodeSpec{
			Table:   device.Table,
			Columns: device.Columns,
			ID: &sqlgraph.FieldSpec{
				Type:   field.TypeString,
				Column: device.FieldID,
			},
		},
	}
	if ps := du.predicates; len(ps) > 0 {
		_spec.Predicate = func(selector *sql.Selector) {
			for i := range ps {
				ps[i](selector)
			}
		}
	}
	if value, ok := du.mutation.Manufacturer(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldManufacturer,
		})
	}
	if du.mutation.ManufacturerCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldManufacturer,
		})
	}
	if value, ok := du.mutation.Model(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldModel,
		})
	}
	if du.mutation.ModelCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldModel,
		})
	}
	if value, ok := du.mutation.Name(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldName,
		})
	}
	if du.mutation.NameCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldName,
		})
	}
	if value, ok := du.mutation.GetType(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldType,
		})
	}
	if du.mutation.TypeCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldType,
		})
	}
	if value, ok := du.mutation.Version(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldVersion,
		})
	}
	if du.mutation.VersionCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldVersion,
		})
	}
	if value, ok := du.mutation.Mobile(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldMobile,
		})
	}
	if du.mutation.MobileCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldMobile,
		})
	}
	if value, ok := du.mutation.Tablet(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldTablet,
		})
	}
	if du.mutation.TabletCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldTablet,
		})
	}
	if value, ok := du.mutation.Desktop(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldDesktop,
		})
	}
	if du.mutation.DesktopCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldDesktop,
		})
	}
	if value, ok := du.mutation.Properties(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Value:  value,
			Column: device.FieldProperties,
		})
	}
	if du.mutation.PropertiesCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Column: device.FieldProperties,
		})
	}
	if nodes := du.mutation.RemovedEventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
	}
	if nodes := du.mutation.EventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Add = append(_spec.Edges.Add, edge)
	}
	if n, err = sqlgraph.UpdateNodes(ctx, du.driver, _spec); err != nil {
		if _, ok := err.(*sqlgraph.NotFoundError); ok {
			err = &NotFoundError{device.Label}
		} else if cerr, ok := isSQLConstraintError(err); ok {
			err = cerr
		}
		return 0, err
	}
	return n, nil
}

type DeviceUpdateOne struct {
	config
	hooks    []Hook
	mutation *DeviceMutation
}

func (duo *DeviceUpdateOne) SetManufacturer(s string) *DeviceUpdateOne {
	duo.mutation.SetManufacturer(s)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableManufacturer(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetManufacturer(*s)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearManufacturer() *DeviceUpdateOne {
	duo.mutation.ClearManufacturer()
	return duo
}

func (duo *DeviceUpdateOne) SetModel(s string) *DeviceUpdateOne {
	duo.mutation.SetModel(s)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableModel(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetModel(*s)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearModel() *DeviceUpdateOne {
	duo.mutation.ClearModel()
	return duo
}

func (duo *DeviceUpdateOne) SetName(s string) *DeviceUpdateOne {
	duo.mutation.SetName(s)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableName(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetName(*s)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearName() *DeviceUpdateOne {
	duo.mutation.ClearName()
	return duo
}

func (duo *DeviceUpdateOne) SetType(s string) *DeviceUpdateOne {
	duo.mutation.SetType(s)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableType(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetType(*s)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearType() *DeviceUpdateOne {
	duo.mutation.ClearType()
	return duo
}

func (duo *DeviceUpdateOne) SetVersion(s string) *DeviceUpdateOne {
	duo.mutation.SetVersion(s)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableVersion(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetVersion(*s)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearVersion() *DeviceUpdateOne {
	duo.mutation.ClearVersion()
	return duo
}

func (duo *DeviceUpdateOne) SetMobile(b bool) *DeviceUpdateOne {
	duo.mutation.SetMobile(b)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableMobile(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetMobile(*b)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearMobile() *DeviceUpdateOne {
	duo.mutation.ClearMobile()
	return duo
}

func (duo *DeviceUpdateOne) SetTablet(b bool) *DeviceUpdateOne {
	duo.mutation.SetTablet(b)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableTablet(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetTablet(*b)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearTablet() *DeviceUpdateOne {
	duo.mutation.ClearTablet()
	return duo
}

func (duo *DeviceUpdateOne) SetDesktop(b bool) *DeviceUpdateOne {
	duo.mutation.SetDesktop(b)
	return duo
}

func (duo *DeviceUpdateOne) SetNillableDesktop(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetDesktop(*b)
	}
	return duo
}

func (duo *DeviceUpdateOne) ClearDesktop() *DeviceUpdateOne {
	duo.mutation.ClearDesktop()
	return duo
}

func (duo *DeviceUpdateOne) SetProperties(m map[string]interface{}) *DeviceUpdateOne {
	duo.mutation.SetProperties(m)
	return duo
}

func (duo *DeviceUpdateOne) ClearProperties() *DeviceUpdateOne {
	duo.mutation.ClearProperties()
	return duo
}

func (duo *DeviceUpdateOne) AddEventIDs(ids ...uuid.UUID) *DeviceUpdateOne {
	duo.mutation.AddEventIDs(ids...)
	return duo
}

func (duo *DeviceUpdateOne) AddEvents(e ...*Event) *DeviceUpdateOne {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return duo.AddEventIDs(ids...)
}

func (duo *DeviceUpdateOne) Mutation() *DeviceMutation {
	return duo.mutation
}

func (duo *DeviceUpdateOne) RemoveEventIDs(ids ...uuid.UUID) *DeviceUpdateOne {
	duo.mutation.RemoveEventIDs(ids...)
	return duo
}

func (duo *DeviceUpdateOne) RemoveEvents(e ...*Event) *DeviceUpdateOne {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return duo.RemoveEventIDs(ids...)
}

func (duo *DeviceUpdateOne) Save(ctx context.Context) (*Device, error) {

	var (
		err  error
		node *Device
	)
	if len(duo.hooks) == 0 {
		node, err = duo.sqlSave(ctx)
	} else {
		var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
			mutation, ok := m.(*DeviceMutation)
			if !ok {
				return nil, fmt.Errorf("unexpected mutation type %T", m)
			}
			duo.mutation = mutation
			node, err = duo.sqlSave(ctx)
			mutation.done = true
			return node, err
		})
		for i := len(duo.hooks) - 1; i >= 0; i-- {
			mut = duo.hooks[i](mut)
		}
		if _, err := mut.Mutate(ctx, duo.mutation); err != nil {
			return nil, err
		}
	}
	return node, err
}

func (duo *DeviceUpdateOne) SaveX(ctx context.Context) *Device {
	d, err := duo.Save(ctx)
	if err != nil {
		panic(err)
	}
	return d
}

func (duo *DeviceUpdateOne) Exec(ctx context.Context) error {
	_, err := duo.Save(ctx)
	return err
}

func (duo *DeviceUpdateOne) ExecX(ctx context.Context) {
	if err := duo.Exec(ctx); err != nil {
		panic(err)
	}
}

func (duo *DeviceUpdateOne) sqlSave(ctx context.Context) (d *Device, err error) {
	_spec := &sqlgraph.UpdateSpec{
		Node: &sqlgraph.NodeSpec{
			Table:   device.Table,
			Columns: device.Columns,
			ID: &sqlgraph.FieldSpec{
				Type:   field.TypeString,
				Column: device.FieldID,
			},
		},
	}
	id, ok := duo.mutation.ID()
	if !ok {
		return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Device.ID for update")}
	}
	_spec.Node.ID.Value = id
	if value, ok := duo.mutation.Manufacturer(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldManufacturer,
		})
	}
	if duo.mutation.ManufacturerCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldManufacturer,
		})
	}
	if value, ok := duo.mutation.Model(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldModel,
		})
	}
	if duo.mutation.ModelCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldModel,
		})
	}
	if value, ok := duo.mutation.Name(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldName,
		})
	}
	if duo.mutation.NameCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldName,
		})
	}
	if value, ok := duo.mutation.GetType(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldType,
		})
	}
	if duo.mutation.TypeCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldType,
		})
	}
	if value, ok := duo.mutation.Version(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldVersion,
		})
	}
	if duo.mutation.VersionCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldVersion,
		})
	}
	if value, ok := duo.mutation.Mobile(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldMobile,
		})
	}
	if duo.mutation.MobileCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldMobile,
		})
	}
	if value, ok := duo.mutation.Tablet(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldTablet,
		})
	}
	if duo.mutation.TabletCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldTablet,
		})
	}
	if value, ok := duo.mutation.Desktop(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldDesktop,
		})
	}
	if duo.mutation.DesktopCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldDesktop,
		})
	}
	if value, ok := duo.mutation.Properties(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Value:  value,
			Column: device.FieldProperties,
		})
	}
	if duo.mutation.PropertiesCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Column: device.FieldProperties,
		})
	}
	if nodes := duo.mutation.RemovedEventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
	}
	if nodes := duo.mutation.EventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Add = append(_spec.Edges.Add, edge)
	}
	d = &Device{config: duo.config}
	_spec.Assign = d.assignValues
	_spec.ScanValues = d.scanValues()
	if err = sqlgraph.UpdateNode(ctx, duo.driver, _spec); err != nil {
		if _, ok := err.(*sqlgraph.NotFoundError); ok {
			err = &NotFoundError{device.Label}
		} else if cerr, ok := isSQLConstraintError(err); ok {
			err = cerr
		}
		return nil, err
	}
	return d, nil
}
// Code generated by entc, DO NOT EDIT.

package ent

import (
	"context"
	"fmt"

	"github.com/blushft/strana/modules/sink/reporter/store/ent/device"
	"github.com/blushft/strana/modules/sink/reporter/store/ent/event"
	"github.com/blushft/strana/modules/sink/reporter/store/ent/predicate"
	"github.com/facebook/ent/dialect/sql"
	"github.com/facebook/ent/dialect/sql/sqlgraph"
	"github.com/facebook/ent/schema/field"
	"github.com/google/uuid"
)

// DeviceUpdate is the builder for updating Device entities.
type DeviceUpdate struct {
	config
	hooks      []Hook
	mutation   *DeviceMutation
	predicates []predicate.Device
}

// Where adds a new predicate for the builder.
func (du *DeviceUpdate) Where(ps ...predicate.Device) *DeviceUpdate {
	du.predicates = append(du.predicates, ps...)
	return du
}

// SetManufacturer sets the manufacturer field.
func (du *DeviceUpdate) SetManufacturer(s string) *DeviceUpdate {
	du.mutation.SetManufacturer(s)
	return du
}

// SetNillableManufacturer sets the manufacturer field if the given value is not nil.
func (du *DeviceUpdate) SetNillableManufacturer(s *string) *DeviceUpdate {
	if s != nil {
		du.SetManufacturer(*s)
	}
	return du
}

// ClearManufacturer clears the value of manufacturer.
func (du *DeviceUpdate) ClearManufacturer() *DeviceUpdate {
	du.mutation.ClearManufacturer()
	return du
}

// SetModel sets the model field.
func (du *DeviceUpdate) SetModel(s string) *DeviceUpdate {
	du.mutation.SetModel(s)
	return du
}

// SetNillableModel sets the model field if the given value is not nil.
func (du *DeviceUpdate) SetNillableModel(s *string) *DeviceUpdate {
	if s != nil {
		du.SetModel(*s)
	}
	return du
}

// ClearModel clears the value of model.
func (du *DeviceUpdate) ClearModel() *DeviceUpdate {
	du.mutation.ClearModel()
	return du
}

// SetName sets the name field.
func (du *DeviceUpdate) SetName(s string) *DeviceUpdate {
	du.mutation.SetName(s)
	return du
}

// SetNillableName sets the name field if the given value is not nil.
func (du *DeviceUpdate) SetNillableName(s *string) *DeviceUpdate {
	if s != nil {
		du.SetName(*s)
	}
	return du
}

// ClearName clears the value of name.
func (du *DeviceUpdate) ClearName() *DeviceUpdate {
	du.mutation.ClearName()
	return du
}

// SetType sets the type field.
func (du *DeviceUpdate) SetType(s string) *DeviceUpdate {
	du.mutation.SetType(s)
	return du
}

// SetNillableType sets the type field if the given value is not nil.
func (du *DeviceUpdate) SetNillableType(s *string) *DeviceUpdate {
	if s != nil {
		du.SetType(*s)
	}
	return du
}

// ClearType clears the value of type.
func (du *DeviceUpdate) ClearType() *DeviceUpdate {
	du.mutation.ClearType()
	return du
}

// SetVersion sets the version field.
func (du *DeviceUpdate) SetVersion(s string) *DeviceUpdate {
	du.mutation.SetVersion(s)
	return du
}

// SetNillableVersion sets the version field if the given value is not nil.
func (du *DeviceUpdate) SetNillableVersion(s *string) *DeviceUpdate {
	if s != nil {
		du.SetVersion(*s)
	}
	return du
}

// ClearVersion clears the value of version.
func (du *DeviceUpdate) ClearVersion() *DeviceUpdate {
	du.mutation.ClearVersion()
	return du
}

// SetMobile sets the mobile field.
func (du *DeviceUpdate) SetMobile(b bool) *DeviceUpdate {
	du.mutation.SetMobile(b)
	return du
}

// SetNillableMobile sets the mobile field if the given value is not nil.
func (du *DeviceUpdate) SetNillableMobile(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetMobile(*b)
	}
	return du
}

// ClearMobile clears the value of mobile.
func (du *DeviceUpdate) ClearMobile() *DeviceUpdate {
	du.mutation.ClearMobile()
	return du
}

// SetTablet sets the tablet field.
func (du *DeviceUpdate) SetTablet(b bool) *DeviceUpdate {
	du.mutation.SetTablet(b)
	return du
}

// SetNillableTablet sets the tablet field if the given value is not nil.
func (du *DeviceUpdate) SetNillableTablet(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetTablet(*b)
	}
	return du
}

// ClearTablet clears the value of tablet.
func (du *DeviceUpdate) ClearTablet() *DeviceUpdate {
	du.mutation.ClearTablet()
	return du
}

// SetDesktop sets the desktop field.
func (du *DeviceUpdate) SetDesktop(b bool) *DeviceUpdate {
	du.mutation.SetDesktop(b)
	return du
}

// SetNillableDesktop sets the desktop field if the given value is not nil.
func (du *DeviceUpdate) SetNillableDesktop(b *bool) *DeviceUpdate {
	if b != nil {
		du.SetDesktop(*b)
	}
	return du
}

// ClearDesktop clears the value of desktop.
func (du *DeviceUpdate) ClearDesktop() *DeviceUpdate {
	du.mutation.ClearDesktop()
	return du
}

// SetProperties sets the properties field.
func (du *DeviceUpdate) SetProperties(m map[string]interface{}) *DeviceUpdate {
	du.mutation.SetProperties(m)
	return du
}

// ClearProperties clears the value of properties.
func (du *DeviceUpdate) ClearProperties() *DeviceUpdate {
	du.mutation.ClearProperties()
	return du
}

// AddEventIDs adds the events edge to Event by ids.
func (du *DeviceUpdate) AddEventIDs(ids ...uuid.UUID) *DeviceUpdate {
	du.mutation.AddEventIDs(ids...)
	return du
}

// AddEvents adds the events edges to Event.
func (du *DeviceUpdate) AddEvents(e ...*Event) *DeviceUpdate {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return du.AddEventIDs(ids...)
}

// Mutation returns the DeviceMutation object of the builder.
func (du *DeviceUpdate) Mutation() *DeviceMutation {
	return du.mutation
}

// RemoveEventIDs removes the events edge to Event by ids.
func (du *DeviceUpdate) RemoveEventIDs(ids ...uuid.UUID) *DeviceUpdate {
	du.mutation.RemoveEventIDs(ids...)
	return du
}

// RemoveEvents removes events edges to Event.
func (du *DeviceUpdate) RemoveEvents(e ...*Event) *DeviceUpdate {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return du.RemoveEventIDs(ids...)
}

// Save executes the query and returns the number of rows/vertices matched by this operation.
func (du *DeviceUpdate) Save(ctx context.Context) (int, error) {

	var (
		err      error
		affected int
	)
	if len(du.hooks) == 0 {
		affected, err = du.sqlSave(ctx)
	} else {
		var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
			mutation, ok := m.(*DeviceMutation)
			if !ok {
				return nil, fmt.Errorf("unexpected mutation type %T", m)
			}
			du.mutation = mutation
			affected, err = du.sqlSave(ctx)
			mutation.done = true
			return affected, err
		})
		for i := len(du.hooks) - 1; i >= 0; i-- {
			mut = du.hooks[i](mut)
		}
		if _, err := mut.Mutate(ctx, du.mutation); err != nil {
			return 0, err
		}
	}
	return affected, err
}

// SaveX is like Save, but panics if an error occurs.
func (du *DeviceUpdate) SaveX(ctx context.Context) int {
	affected, err := du.Save(ctx)
	if err != nil {
		panic(err)
	}
	return affected
}

// Exec executes the query.
func (du *DeviceUpdate) Exec(ctx context.Context) error {
	_, err := du.Save(ctx)
	return err
}

// ExecX is like Exec, but panics if an error occurs.
func (du *DeviceUpdate) ExecX(ctx context.Context) {
	if err := du.Exec(ctx); err != nil {
		panic(err)
	}
}

func (du *DeviceUpdate) sqlSave(ctx context.Context) (n int, err error) {
	_spec := &sqlgraph.UpdateSpec{
		Node: &sqlgraph.NodeSpec{
			Table:   device.Table,
			Columns: device.Columns,
			ID: &sqlgraph.FieldSpec{
				Type:   field.TypeString,
				Column: device.FieldID,
			},
		},
	}
	if ps := du.predicates; len(ps) > 0 {
		_spec.Predicate = func(selector *sql.Selector) {
			for i := range ps {
				ps[i](selector)
			}
		}
	}
	if value, ok := du.mutation.Manufacturer(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldManufacturer,
		})
	}
	if du.mutation.ManufacturerCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldManufacturer,
		})
	}
	if value, ok := du.mutation.Model(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldModel,
		})
	}
	if du.mutation.ModelCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldModel,
		})
	}
	if value, ok := du.mutation.Name(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldName,
		})
	}
	if du.mutation.NameCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldName,
		})
	}
	if value, ok := du.mutation.GetType(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldType,
		})
	}
	if du.mutation.TypeCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldType,
		})
	}
	if value, ok := du.mutation.Version(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldVersion,
		})
	}
	if du.mutation.VersionCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldVersion,
		})
	}
	if value, ok := du.mutation.Mobile(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldMobile,
		})
	}
	if du.mutation.MobileCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldMobile,
		})
	}
	if value, ok := du.mutation.Tablet(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldTablet,
		})
	}
	if du.mutation.TabletCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldTablet,
		})
	}
	if value, ok := du.mutation.Desktop(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldDesktop,
		})
	}
	if du.mutation.DesktopCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldDesktop,
		})
	}
	if value, ok := du.mutation.Properties(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Value:  value,
			Column: device.FieldProperties,
		})
	}
	if du.mutation.PropertiesCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Column: device.FieldProperties,
		})
	}
	if nodes := du.mutation.RemovedEventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
	}
	if nodes := du.mutation.EventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Add = append(_spec.Edges.Add, edge)
	}
	if n, err = sqlgraph.UpdateNodes(ctx, du.driver, _spec); err != nil {
		if _, ok := err.(*sqlgraph.NotFoundError); ok {
			err = &NotFoundError{device.Label}
		} else if cerr, ok := isSQLConstraintError(err); ok {
			err = cerr
		}
		return 0, err
	}
	return n, nil
}

// DeviceUpdateOne is the builder for updating a single Device entity.
type DeviceUpdateOne struct {
	config
	hooks    []Hook
	mutation *DeviceMutation
}

// SetManufacturer sets the manufacturer field.
func (duo *DeviceUpdateOne) SetManufacturer(s string) *DeviceUpdateOne {
	duo.mutation.SetManufacturer(s)
	return duo
}

// SetNillableManufacturer sets the manufacturer field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableManufacturer(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetManufacturer(*s)
	}
	return duo
}

// ClearManufacturer clears the value of manufacturer.
func (duo *DeviceUpdateOne) ClearManufacturer() *DeviceUpdateOne {
	duo.mutation.ClearManufacturer()
	return duo
}

// SetModel sets the model field.
func (duo *DeviceUpdateOne) SetModel(s string) *DeviceUpdateOne {
	duo.mutation.SetModel(s)
	return duo
}

// SetNillableModel sets the model field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableModel(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetModel(*s)
	}
	return duo
}

// ClearModel clears the value of model.
func (duo *DeviceUpdateOne) ClearModel() *DeviceUpdateOne {
	duo.mutation.ClearModel()
	return duo
}

// SetName sets the name field.
func (duo *DeviceUpdateOne) SetName(s string) *DeviceUpdateOne {
	duo.mutation.SetName(s)
	return duo
}

// SetNillableName sets the name field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableName(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetName(*s)
	}
	return duo
}

// ClearName clears the value of name.
func (duo *DeviceUpdateOne) ClearName() *DeviceUpdateOne {
	duo.mutation.ClearName()
	return duo
}

// SetType sets the type field.
func (duo *DeviceUpdateOne) SetType(s string) *DeviceUpdateOne {
	duo.mutation.SetType(s)
	return duo
}

// SetNillableType sets the type field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableType(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetType(*s)
	}
	return duo
}

// ClearType clears the value of type.
func (duo *DeviceUpdateOne) ClearType() *DeviceUpdateOne {
	duo.mutation.ClearType()
	return duo
}

// SetVersion sets the version field.
func (duo *DeviceUpdateOne) SetVersion(s string) *DeviceUpdateOne {
	duo.mutation.SetVersion(s)
	return duo
}

// SetNillableVersion sets the version field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableVersion(s *string) *DeviceUpdateOne {
	if s != nil {
		duo.SetVersion(*s)
	}
	return duo
}

// ClearVersion clears the value of version.
func (duo *DeviceUpdateOne) ClearVersion() *DeviceUpdateOne {
	duo.mutation.ClearVersion()
	return duo
}

// SetMobile sets the mobile field.
func (duo *DeviceUpdateOne) SetMobile(b bool) *DeviceUpdateOne {
	duo.mutation.SetMobile(b)
	return duo
}

// SetNillableMobile sets the mobile field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableMobile(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetMobile(*b)
	}
	return duo
}

// ClearMobile clears the value of mobile.
func (duo *DeviceUpdateOne) ClearMobile() *DeviceUpdateOne {
	duo.mutation.ClearMobile()
	return duo
}

// SetTablet sets the tablet field.
func (duo *DeviceUpdateOne) SetTablet(b bool) *DeviceUpdateOne {
	duo.mutation.SetTablet(b)
	return duo
}

// SetNillableTablet sets the tablet field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableTablet(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetTablet(*b)
	}
	return duo
}

// ClearTablet clears the value of tablet.
func (duo *DeviceUpdateOne) ClearTablet() *DeviceUpdateOne {
	duo.mutation.ClearTablet()
	return duo
}

// SetDesktop sets the desktop field.
func (duo *DeviceUpdateOne) SetDesktop(b bool) *DeviceUpdateOne {
	duo.mutation.SetDesktop(b)
	return duo
}

// SetNillableDesktop sets the desktop field if the given value is not nil.
func (duo *DeviceUpdateOne) SetNillableDesktop(b *bool) *DeviceUpdateOne {
	if b != nil {
		duo.SetDesktop(*b)
	}
	return duo
}

// ClearDesktop clears the value of desktop.
func (duo *DeviceUpdateOne) ClearDesktop() *DeviceUpdateOne {
	duo.mutation.ClearDesktop()
	return duo
}

// SetProperties sets the properties field.
func (duo *DeviceUpdateOne) SetProperties(m map[string]interface{}) *DeviceUpdateOne {
	duo.mutation.SetProperties(m)
	return duo
}

// ClearProperties clears the value of properties.
func (duo *DeviceUpdateOne) ClearProperties() *DeviceUpdateOne {
	duo.mutation.ClearProperties()
	return duo
}

// AddEventIDs adds the events edge to Event by ids.
func (duo *DeviceUpdateOne) AddEventIDs(ids ...uuid.UUID) *DeviceUpdateOne {
	duo.mutation.AddEventIDs(ids...)
	return duo
}

// AddEvents adds the events edges to Event.
func (duo *DeviceUpdateOne) AddEvents(e ...*Event) *DeviceUpdateOne {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return duo.AddEventIDs(ids...)
}

// Mutation returns the DeviceMutation object of the builder.
func (duo *DeviceUpdateOne) Mutation() *DeviceMutation {
	return duo.mutation
}

// RemoveEventIDs removes the events edge to Event by ids.
func (duo *DeviceUpdateOne) RemoveEventIDs(ids ...uuid.UUID) *DeviceUpdateOne {
	duo.mutation.RemoveEventIDs(ids...)
	return duo
}

// RemoveEvents removes events edges to Event.
func (duo *DeviceUpdateOne) RemoveEvents(e ...*Event) *DeviceUpdateOne {
	ids := make([]uuid.UUID, len(e))
	for i := range e {
		ids[i] = e[i].ID
	}
	return duo.RemoveEventIDs(ids...)
}

// Save executes the query and returns the updated entity.
func (duo *DeviceUpdateOne) Save(ctx context.Context) (*Device, error) {

	var (
		err  error
		node *Device
	)
	if len(duo.hooks) == 0 {
		node, err = duo.sqlSave(ctx)
	} else {
		var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
			mutation, ok := m.(*DeviceMutation)
			if !ok {
				return nil, fmt.Errorf("unexpected mutation type %T", m)
			}
			duo.mutation = mutation
			node, err = duo.sqlSave(ctx)
			mutation.done = true
			return node, err
		})
		for i := len(duo.hooks) - 1; i >= 0; i-- {
			mut = duo.hooks[i](mut)
		}
		if _, err := mut.Mutate(ctx, duo.mutation); err != nil {
			return nil, err
		}
	}
	return node, err
}

// SaveX is like Save, but panics if an error occurs.
func (duo *DeviceUpdateOne) SaveX(ctx context.Context) *Device {
	d, err := duo.Save(ctx)
	if err != nil {
		panic(err)
	}
	return d
}

// Exec executes the query on the entity.
func (duo *DeviceUpdateOne) Exec(ctx context.Context) error {
	_, err := duo.Save(ctx)
	return err
}

// ExecX is like Exec, but panics if an error occurs.
func (duo *DeviceUpdateOne) ExecX(ctx context.Context) {
	if err := duo.Exec(ctx); err != nil {
		panic(err)
	}
}

func (duo *DeviceUpdateOne) sqlSave(ctx context.Context) (d *Device, err error) {
	_spec := &sqlgraph.UpdateSpec{
		Node: &sqlgraph.NodeSpec{
			Table:   device.Table,
			Columns: device.Columns,
			ID: &sqlgraph.FieldSpec{
				Type:   field.TypeString,
				Column: device.FieldID,
			},
		},
	}
	id, ok := duo.mutation.ID()
	if !ok {
		return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Device.ID for update")}
	}
	_spec.Node.ID.Value = id
	if value, ok := duo.mutation.Manufacturer(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldManufacturer,
		})
	}
	if duo.mutation.ManufacturerCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldManufacturer,
		})
	}
	if value, ok := duo.mutation.Model(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldModel,
		})
	}
	if duo.mutation.ModelCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldModel,
		})
	}
	if value, ok := duo.mutation.Name(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldName,
		})
	}
	if duo.mutation.NameCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldName,
		})
	}
	if value, ok := duo.mutation.GetType(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldType,
		})
	}
	if duo.mutation.TypeCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldType,
		})
	}
	if value, ok := duo.mutation.Version(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Value:  value,
			Column: device.FieldVersion,
		})
	}
	if duo.mutation.VersionCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeString,
			Column: device.FieldVersion,
		})
	}
	if value, ok := duo.mutation.Mobile(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldMobile,
		})
	}
	if duo.mutation.MobileCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldMobile,
		})
	}
	if value, ok := duo.mutation.Tablet(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldTablet,
		})
	}
	if duo.mutation.TabletCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldTablet,
		})
	}
	if value, ok := duo.mutation.Desktop(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Value:  value,
			Column: device.FieldDesktop,
		})
	}
	if duo.mutation.DesktopCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeBool,
			Column: device.FieldDesktop,
		})
	}
	if value, ok := duo.mutation.Properties(); ok {
		_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Value:  value,
			Column: device.FieldProperties,
		})
	}
	if duo.mutation.PropertiesCleared() {
		_spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{
			Type:   field.TypeJSON,
			Column: device.FieldProperties,
		})
	}
	if nodes := duo.mutation.RemovedEventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
	}
	if nodes := duo.mutation.EventsIDs(); len(nodes) > 0 {
		edge := &sqlgraph.EdgeSpec{
			Rel:     sqlgraph.O2M,
			Inverse: true,
			Table:   device.EventsTable,
			Columns: []string{device.EventsColumn},
			Bidi:    false,
			Target: &sqlgraph.EdgeTarget{
				IDSpec: &sqlgraph.FieldSpec{
					Type:   field.TypeUUID,
					Column: event.FieldID,
				},
			},
		}
		for _, k := range nodes {
			edge.Target.Nodes = append(edge.Target.Nodes, k)
		}
		_spec.Edges.Add = append(_spec.Edges.Add, edge)
	}
	d = &Device{config: duo.config}
	_spec.Assign = d.assignValues
	_spec.ScanValues = d.scanValues()
	if err = sqlgraph.UpdateNode(ctx, duo.driver, _spec); err != nil {
		if _, ok := err.(*sqlgraph.NotFoundError); ok {
			err = &NotFoundError{device.Label}
		} else if cerr, ok := isSQLConstraintError(err); ok {
			err = cerr
		}
		return nil, err
	}
	return d, nil
}
