Cleanup merge

This commit is contained in:
Matthew Kilgore
2025-07-27 17:37:56 -04:00
parent de1491133b
commit 64907bbb3a
10 changed files with 601 additions and 76 deletions

View File

@@ -11,7 +11,7 @@ import (
"entgo.io/ent/dialect/sql"
"github.com/google/uuid"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/item"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/entity"
)
// Attachment is the model entity for the Attachment schema.
@@ -37,24 +37,19 @@ type Attachment struct {
// The values are being populated by the AttachmentQuery when eager-loading is set.
Edges AttachmentEdges `json:"edges"`
attachment_thumbnail *uuid.UUID
item_attachments *uuid.UUID
entity_attachments *uuid.UUID
selectValues sql.SelectValues
Edges AttachmentEdges `json:"edges"`
entity_attachments *uuid.UUID
selectValues sql.SelectValues
}
// AttachmentEdges holds the relations/edges for other nodes in the graph.
type AttachmentEdges struct {
// Entity holds the value of the entity edge.
Entity *Entity `json:"entity,omitempty"`
// Item holds the value of the item edge.
Item *Item `json:"item,omitempty"`
// Thumbnail holds the value of the thumbnail edge.
Thumbnail *Attachment `json:"thumbnail,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
loadedTypes [2]bool
}
// EntityOrErr returns the Entity value or an error if the edge
@@ -86,7 +81,7 @@ func (*Attachment) scanValues(columns []string) ([]any, error) {
switch columns[i] {
case attachment.FieldPrimary:
values[i] = new(sql.NullBool)
case attachment.FieldType, attachment.FieldTitle, attachment.FieldPath:
case attachment.FieldType, attachment.FieldTitle, attachment.FieldPath, attachment.FieldMimeType:
values[i] = new(sql.NullString)
case attachment.FieldCreatedAt, attachment.FieldUpdatedAt:
values[i] = new(sql.NullTime)
@@ -94,8 +89,7 @@ func (*Attachment) scanValues(columns []string) ([]any, error) {
values[i] = new(uuid.UUID)
case attachment.ForeignKeys[0]: // attachment_thumbnail
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
case attachment.ForeignKeys[1]: // item_attachments
case attachment.ForeignKeys[0]: // entity_attachments
case attachment.ForeignKeys[1]: // entity_attachments
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
default:
values[i] = new(sql.UnknownType)
@@ -169,7 +163,6 @@ func (a *Attachment) assignValues(columns []string, values []any) error {
}
case attachment.ForeignKeys[1]:
if value, ok := values[i].(*sql.NullScanner); !ok {
return fmt.Errorf("unexpected type %T for field item_attachments", values[i])
return fmt.Errorf("unexpected type %T for field entity_attachments", values[i])
} else if value.Valid {
a.entity_attachments = new(uuid.UUID)

View File

@@ -28,8 +28,12 @@ const (
FieldTitle = "title"
// FieldPath holds the string denoting the path field in the database.
FieldPath = "path"
// FieldMimeType holds the string denoting the mime_type field in the database.
FieldMimeType = "mime_type"
// EdgeEntity holds the string denoting the entity edge name in mutations.
EdgeEntity = "entity"
// EdgeThumbnail holds the string denoting the thumbnail edge name in mutations.
EdgeThumbnail = "thumbnail"
// Table holds the table name of the attachment in the database.
Table = "attachments"
// EntityTable is the table that holds the entity relation/edge.
@@ -39,6 +43,10 @@ const (
EntityInverseTable = "entities"
// EntityColumn is the table column denoting the entity relation/edge.
EntityColumn = "entity_attachments"
// ThumbnailTable is the table that holds the thumbnail relation/edge.
ThumbnailTable = "attachments"
// ThumbnailColumn is the table column denoting the thumbnail relation/edge.
ThumbnailColumn = "attachment_thumbnail"
)
// Columns holds all SQL columns for attachment fields.
@@ -50,11 +58,13 @@ var Columns = []string{
FieldPrimary,
FieldTitle,
FieldPath,
FieldMimeType,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "attachments"
// table and are not defined as standalone fields in the schema.
var ForeignKeys = []string{
"attachment_thumbnail",
"entity_attachments",
}
@@ -86,6 +96,8 @@ var (
DefaultTitle string
// DefaultPath holds the default value on creation for the "path" field.
DefaultPath string
// DefaultMimeType holds the default value on creation for the "mime_type" field.
DefaultMimeType string
// DefaultID holds the default value on creation for the "id" field.
DefaultID func() uuid.UUID
)
@@ -103,6 +115,7 @@ const (
TypeWarranty Type = "warranty"
TypeAttachment Type = "attachment"
TypeReceipt Type = "receipt"
TypeThumbnail Type = "thumbnail"
)
func (_type Type) String() string {
@@ -112,7 +125,7 @@ func (_type Type) String() string {
// TypeValidator is a validator for the "type" field enum values. It is called by the builders before save.
func TypeValidator(_type Type) error {
switch _type {
case TypePhoto, TypeManual, TypeWarranty, TypeAttachment, TypeReceipt:
case TypePhoto, TypeManual, TypeWarranty, TypeAttachment, TypeReceipt, TypeThumbnail:
return nil
default:
return fmt.Errorf("attachment: invalid enum value for type field: %q", _type)
@@ -157,12 +170,24 @@ func ByPath(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldPath, opts...).ToFunc()
}
// ByMimeType orders the results by the mime_type field.
func ByMimeType(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldMimeType, opts...).ToFunc()
}
// ByEntityField orders the results by entity field.
func ByEntityField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newEntityStep(), sql.OrderByField(field, opts...))
}
}
// ByThumbnailField orders the results by thumbnail field.
func ByThumbnailField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newThumbnailStep(), sql.OrderByField(field, opts...))
}
}
func newEntityStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
@@ -170,3 +195,10 @@ func newEntityStep() *sqlgraph.Step {
sqlgraph.Edge(sqlgraph.M2O, true, EntityTable, EntityColumn),
)
}
func newThumbnailStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(Table, FieldID),
sqlgraph.Edge(sqlgraph.O2O, false, ThumbnailTable, ThumbnailColumn),
)
}

View File

@@ -81,6 +81,11 @@ func Path(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldEQ(FieldPath, v))
}
// MimeType applies equality check predicate on the "mime_type" field. It's identical to MimeTypeEQ.
func MimeType(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldEQ(FieldMimeType, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Attachment {
return predicate.Attachment(sql.FieldEQ(FieldCreatedAt, v))
@@ -321,6 +326,71 @@ func PathContainsFold(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldContainsFold(FieldPath, v))
}
// MimeTypeEQ applies the EQ predicate on the "mime_type" field.
func MimeTypeEQ(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldEQ(FieldMimeType, v))
}
// MimeTypeNEQ applies the NEQ predicate on the "mime_type" field.
func MimeTypeNEQ(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldNEQ(FieldMimeType, v))
}
// MimeTypeIn applies the In predicate on the "mime_type" field.
func MimeTypeIn(vs ...string) predicate.Attachment {
return predicate.Attachment(sql.FieldIn(FieldMimeType, vs...))
}
// MimeTypeNotIn applies the NotIn predicate on the "mime_type" field.
func MimeTypeNotIn(vs ...string) predicate.Attachment {
return predicate.Attachment(sql.FieldNotIn(FieldMimeType, vs...))
}
// MimeTypeGT applies the GT predicate on the "mime_type" field.
func MimeTypeGT(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldGT(FieldMimeType, v))
}
// MimeTypeGTE applies the GTE predicate on the "mime_type" field.
func MimeTypeGTE(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldGTE(FieldMimeType, v))
}
// MimeTypeLT applies the LT predicate on the "mime_type" field.
func MimeTypeLT(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldLT(FieldMimeType, v))
}
// MimeTypeLTE applies the LTE predicate on the "mime_type" field.
func MimeTypeLTE(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldLTE(FieldMimeType, v))
}
// MimeTypeContains applies the Contains predicate on the "mime_type" field.
func MimeTypeContains(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldContains(FieldMimeType, v))
}
// MimeTypeHasPrefix applies the HasPrefix predicate on the "mime_type" field.
func MimeTypeHasPrefix(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldHasPrefix(FieldMimeType, v))
}
// MimeTypeHasSuffix applies the HasSuffix predicate on the "mime_type" field.
func MimeTypeHasSuffix(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldHasSuffix(FieldMimeType, v))
}
// MimeTypeEqualFold applies the EqualFold predicate on the "mime_type" field.
func MimeTypeEqualFold(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldEqualFold(FieldMimeType, v))
}
// MimeTypeContainsFold applies the ContainsFold predicate on the "mime_type" field.
func MimeTypeContainsFold(v string) predicate.Attachment {
return predicate.Attachment(sql.FieldContainsFold(FieldMimeType, v))
}
// HasEntity applies the HasEdge predicate on the "entity" edge.
func HasEntity() predicate.Attachment {
return predicate.Attachment(func(s *sql.Selector) {
@@ -344,6 +414,29 @@ func HasEntityWith(preds ...predicate.Entity) predicate.Attachment {
})
}
// HasThumbnail applies the HasEdge predicate on the "thumbnail" edge.
func HasThumbnail() predicate.Attachment {
return predicate.Attachment(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.O2O, false, ThumbnailTable, ThumbnailColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasThumbnailWith applies the HasEdge predicate on the "thumbnail" edge with a given conditions (other predicates).
func HasThumbnailWith(preds ...predicate.Attachment) predicate.Attachment {
return predicate.Attachment(func(s *sql.Selector) {
step := newThumbnailStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Attachment) predicate.Attachment {
return predicate.Attachment(sql.AndPredicates(predicates...))

View File

@@ -106,6 +106,20 @@ func (ac *AttachmentCreate) SetNillablePath(s *string) *AttachmentCreate {
return ac
}
// SetMimeType sets the "mime_type" field.
func (ac *AttachmentCreate) SetMimeType(s string) *AttachmentCreate {
ac.mutation.SetMimeType(s)
return ac
}
// SetNillableMimeType sets the "mime_type" field if the given value is not nil.
func (ac *AttachmentCreate) SetNillableMimeType(s *string) *AttachmentCreate {
if s != nil {
ac.SetMimeType(*s)
}
return ac
}
// SetID sets the "id" field.
func (ac *AttachmentCreate) SetID(u uuid.UUID) *AttachmentCreate {
ac.mutation.SetID(u)
@@ -126,11 +140,38 @@ func (ac *AttachmentCreate) SetEntityID(id uuid.UUID) *AttachmentCreate {
return ac
}
// SetNillableEntityID sets the "entity" edge to the Entity entity by ID if the given value is not nil.
func (ac *AttachmentCreate) SetNillableEntityID(id *uuid.UUID) *AttachmentCreate {
if id != nil {
ac = ac.SetEntityID(*id)
}
return ac
}
// SetEntity sets the "entity" edge to the Entity entity.
func (ac *AttachmentCreate) SetEntity(e *Entity) *AttachmentCreate {
return ac.SetEntityID(e.ID)
}
// SetThumbnailID sets the "thumbnail" edge to the Attachment entity by ID.
func (ac *AttachmentCreate) SetThumbnailID(id uuid.UUID) *AttachmentCreate {
ac.mutation.SetThumbnailID(id)
return ac
}
// SetNillableThumbnailID sets the "thumbnail" edge to the Attachment entity by ID if the given value is not nil.
func (ac *AttachmentCreate) SetNillableThumbnailID(id *uuid.UUID) *AttachmentCreate {
if id != nil {
ac = ac.SetThumbnailID(*id)
}
return ac
}
// SetThumbnail sets the "thumbnail" edge to the Attachment entity.
func (ac *AttachmentCreate) SetThumbnail(a *Attachment) *AttachmentCreate {
return ac.SetThumbnailID(a.ID)
}
// Mutation returns the AttachmentMutation object of the builder.
func (ac *AttachmentCreate) Mutation() *AttachmentMutation {
return ac.mutation
@@ -190,6 +231,10 @@ func (ac *AttachmentCreate) defaults() {
v := attachment.DefaultPath
ac.mutation.SetPath(v)
}
if _, ok := ac.mutation.MimeType(); !ok {
v := attachment.DefaultMimeType
ac.mutation.SetMimeType(v)
}
if _, ok := ac.mutation.ID(); !ok {
v := attachment.DefaultID()
ac.mutation.SetID(v)
@@ -221,8 +266,8 @@ func (ac *AttachmentCreate) check() error {
if _, ok := ac.mutation.Path(); !ok {
return &ValidationError{Name: "path", err: errors.New(`ent: missing required field "Attachment.path"`)}
}
if len(ac.mutation.EntityIDs()) == 0 {
return &ValidationError{Name: "entity", err: errors.New(`ent: missing required edge "Attachment.entity"`)}
if _, ok := ac.mutation.MimeType(); !ok {
return &ValidationError{Name: "mime_type", err: errors.New(`ent: missing required field "Attachment.mime_type"`)}
}
return nil
}
@@ -283,6 +328,10 @@ func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
_spec.SetField(attachment.FieldPath, field.TypeString, value)
_node.Path = value
}
if value, ok := ac.mutation.MimeType(); ok {
_spec.SetField(attachment.FieldMimeType, field.TypeString, value)
_node.MimeType = value
}
if nodes := ac.mutation.EntityIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
@@ -300,6 +349,23 @@ func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
_node.entity_attachments = &nodes[0]
_spec.Edges = append(_spec.Edges, edge)
}
if nodes := ac.mutation.ThumbnailIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: attachment.ThumbnailTable,
Columns: []string{attachment.ThumbnailColumn},
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_node.attachment_thumbnail = &nodes[0]
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}

View File

@@ -20,12 +20,13 @@ import (
// AttachmentQuery is the builder for querying Attachment entities.
type AttachmentQuery struct {
config
ctx *QueryContext
order []attachment.OrderOption
inters []Interceptor
predicates []predicate.Attachment
withEntity *EntityQuery
withFKs bool
ctx *QueryContext
order []attachment.OrderOption
inters []Interceptor
predicates []predicate.Attachment
withEntity *EntityQuery
withThumbnail *AttachmentQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
@@ -84,6 +85,28 @@ func (aq *AttachmentQuery) QueryEntity() *EntityQuery {
return query
}
// QueryThumbnail chains the current query on the "thumbnail" edge.
func (aq *AttachmentQuery) QueryThumbnail() *AttachmentQuery {
query := (&AttachmentClient{config: aq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := aq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := aq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(attachment.Table, attachment.FieldID, selector),
sqlgraph.To(attachment.Table, attachment.FieldID),
sqlgraph.Edge(sqlgraph.O2O, false, attachment.ThumbnailTable, attachment.ThumbnailColumn),
)
fromU = sqlgraph.SetNeighbors(aq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first Attachment entity from the query.
// Returns a *NotFoundError when no Attachment was found.
func (aq *AttachmentQuery) First(ctx context.Context) (*Attachment, error) {
@@ -271,12 +294,13 @@ func (aq *AttachmentQuery) Clone() *AttachmentQuery {
return nil
}
return &AttachmentQuery{
config: aq.config,
ctx: aq.ctx.Clone(),
order: append([]attachment.OrderOption{}, aq.order...),
inters: append([]Interceptor{}, aq.inters...),
predicates: append([]predicate.Attachment{}, aq.predicates...),
withEntity: aq.withEntity.Clone(),
config: aq.config,
ctx: aq.ctx.Clone(),
order: append([]attachment.OrderOption{}, aq.order...),
inters: append([]Interceptor{}, aq.inters...),
predicates: append([]predicate.Attachment{}, aq.predicates...),
withEntity: aq.withEntity.Clone(),
withThumbnail: aq.withThumbnail.Clone(),
// clone intermediate query.
sql: aq.sql.Clone(),
path: aq.path,
@@ -294,6 +318,17 @@ func (aq *AttachmentQuery) WithEntity(opts ...func(*EntityQuery)) *AttachmentQue
return aq
}
// WithThumbnail tells the query-builder to eager-load the nodes that are connected to
// the "thumbnail" edge. The optional arguments are used to configure the query builder of the edge.
func (aq *AttachmentQuery) WithThumbnail(opts ...func(*AttachmentQuery)) *AttachmentQuery {
query := (&AttachmentClient{config: aq.config}).Query()
for _, opt := range opts {
opt(query)
}
aq.withThumbnail = query
return aq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
@@ -373,11 +408,12 @@ func (aq *AttachmentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*A
nodes = []*Attachment{}
withFKs = aq.withFKs
_spec = aq.querySpec()
loadedTypes = [1]bool{
loadedTypes = [2]bool{
aq.withEntity != nil,
aq.withThumbnail != nil,
}
)
if aq.withEntity != nil {
if aq.withEntity != nil || aq.withThumbnail != nil {
withFKs = true
}
if withFKs {
@@ -407,6 +443,12 @@ func (aq *AttachmentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*A
return nil, err
}
}
if query := aq.withThumbnail; query != nil {
if err := aq.loadThumbnail(ctx, query, nodes, nil,
func(n *Attachment, e *Attachment) { n.Edges.Thumbnail = e }); err != nil {
return nil, err
}
}
return nodes, nil
}
@@ -442,6 +484,38 @@ func (aq *AttachmentQuery) loadEntity(ctx context.Context, query *EntityQuery, n
}
return nil
}
func (aq *AttachmentQuery) loadThumbnail(ctx context.Context, query *AttachmentQuery, nodes []*Attachment, init func(*Attachment), assign func(*Attachment, *Attachment)) error {
ids := make([]uuid.UUID, 0, len(nodes))
nodeids := make(map[uuid.UUID][]*Attachment)
for i := range nodes {
if nodes[i].attachment_thumbnail == nil {
continue
}
fk := *nodes[i].attachment_thumbnail
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(attachment.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "attachment_thumbnail" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (aq *AttachmentQuery) sqlCount(ctx context.Context) (int, error) {
_spec := aq.querySpec()

View File

@@ -92,17 +92,58 @@ func (au *AttachmentUpdate) SetNillablePath(s *string) *AttachmentUpdate {
return au
}
// SetMimeType sets the "mime_type" field.
func (au *AttachmentUpdate) SetMimeType(s string) *AttachmentUpdate {
au.mutation.SetMimeType(s)
return au
}
// SetNillableMimeType sets the "mime_type" field if the given value is not nil.
func (au *AttachmentUpdate) SetNillableMimeType(s *string) *AttachmentUpdate {
if s != nil {
au.SetMimeType(*s)
}
return au
}
// SetEntityID sets the "entity" edge to the Entity entity by ID.
func (au *AttachmentUpdate) SetEntityID(id uuid.UUID) *AttachmentUpdate {
au.mutation.SetEntityID(id)
return au
}
// SetNillableEntityID sets the "entity" edge to the Entity entity by ID if the given value is not nil.
func (au *AttachmentUpdate) SetNillableEntityID(id *uuid.UUID) *AttachmentUpdate {
if id != nil {
au = au.SetEntityID(*id)
}
return au
}
// SetEntity sets the "entity" edge to the Entity entity.
func (au *AttachmentUpdate) SetEntity(e *Entity) *AttachmentUpdate {
return au.SetEntityID(e.ID)
}
// SetThumbnailID sets the "thumbnail" edge to the Attachment entity by ID.
func (au *AttachmentUpdate) SetThumbnailID(id uuid.UUID) *AttachmentUpdate {
au.mutation.SetThumbnailID(id)
return au
}
// SetNillableThumbnailID sets the "thumbnail" edge to the Attachment entity by ID if the given value is not nil.
func (au *AttachmentUpdate) SetNillableThumbnailID(id *uuid.UUID) *AttachmentUpdate {
if id != nil {
au = au.SetThumbnailID(*id)
}
return au
}
// SetThumbnail sets the "thumbnail" edge to the Attachment entity.
func (au *AttachmentUpdate) SetThumbnail(a *Attachment) *AttachmentUpdate {
return au.SetThumbnailID(a.ID)
}
// Mutation returns the AttachmentMutation object of the builder.
func (au *AttachmentUpdate) Mutation() *AttachmentMutation {
return au.mutation
@@ -114,6 +155,12 @@ func (au *AttachmentUpdate) ClearEntity() *AttachmentUpdate {
return au
}
// ClearThumbnail clears the "thumbnail" edge to the Attachment entity.
func (au *AttachmentUpdate) ClearThumbnail() *AttachmentUpdate {
au.mutation.ClearThumbnail()
return au
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (au *AttachmentUpdate) Save(ctx context.Context) (int, error) {
au.defaults()
@@ -157,9 +204,6 @@ func (au *AttachmentUpdate) check() error {
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
}
}
if au.mutation.EntityCleared() && len(au.mutation.EntityIDs()) > 0 {
return errors.New(`ent: clearing a required unique edge "Attachment.entity"`)
}
return nil
}
@@ -190,6 +234,9 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
if value, ok := au.mutation.Path(); ok {
_spec.SetField(attachment.FieldPath, field.TypeString, value)
}
if value, ok := au.mutation.MimeType(); ok {
_spec.SetField(attachment.FieldMimeType, field.TypeString, value)
}
if au.mutation.EntityCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
@@ -219,6 +266,35 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if au.mutation.ThumbnailCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: attachment.ThumbnailTable,
Columns: []string{attachment.ThumbnailColumn},
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := au.mutation.ThumbnailIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: attachment.ThumbnailTable,
Columns: []string{attachment.ThumbnailColumn},
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
},
}
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, au.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{attachment.Label}
@@ -301,17 +377,58 @@ func (auo *AttachmentUpdateOne) SetNillablePath(s *string) *AttachmentUpdateOne
return auo
}
// SetMimeType sets the "mime_type" field.
func (auo *AttachmentUpdateOne) SetMimeType(s string) *AttachmentUpdateOne {
auo.mutation.SetMimeType(s)
return auo
}
// SetNillableMimeType sets the "mime_type" field if the given value is not nil.
func (auo *AttachmentUpdateOne) SetNillableMimeType(s *string) *AttachmentUpdateOne {
if s != nil {
auo.SetMimeType(*s)
}
return auo
}
// SetEntityID sets the "entity" edge to the Entity entity by ID.
func (auo *AttachmentUpdateOne) SetEntityID(id uuid.UUID) *AttachmentUpdateOne {
auo.mutation.SetEntityID(id)
return auo
}
// SetNillableEntityID sets the "entity" edge to the Entity entity by ID if the given value is not nil.
func (auo *AttachmentUpdateOne) SetNillableEntityID(id *uuid.UUID) *AttachmentUpdateOne {
if id != nil {
auo = auo.SetEntityID(*id)
}
return auo
}
// SetEntity sets the "entity" edge to the Entity entity.
func (auo *AttachmentUpdateOne) SetEntity(e *Entity) *AttachmentUpdateOne {
return auo.SetEntityID(e.ID)
}
// SetThumbnailID sets the "thumbnail" edge to the Attachment entity by ID.
func (auo *AttachmentUpdateOne) SetThumbnailID(id uuid.UUID) *AttachmentUpdateOne {
auo.mutation.SetThumbnailID(id)
return auo
}
// SetNillableThumbnailID sets the "thumbnail" edge to the Attachment entity by ID if the given value is not nil.
func (auo *AttachmentUpdateOne) SetNillableThumbnailID(id *uuid.UUID) *AttachmentUpdateOne {
if id != nil {
auo = auo.SetThumbnailID(*id)
}
return auo
}
// SetThumbnail sets the "thumbnail" edge to the Attachment entity.
func (auo *AttachmentUpdateOne) SetThumbnail(a *Attachment) *AttachmentUpdateOne {
return auo.SetThumbnailID(a.ID)
}
// Mutation returns the AttachmentMutation object of the builder.
func (auo *AttachmentUpdateOne) Mutation() *AttachmentMutation {
return auo.mutation
@@ -323,6 +440,12 @@ func (auo *AttachmentUpdateOne) ClearEntity() *AttachmentUpdateOne {
return auo
}
// ClearThumbnail clears the "thumbnail" edge to the Attachment entity.
func (auo *AttachmentUpdateOne) ClearThumbnail() *AttachmentUpdateOne {
auo.mutation.ClearThumbnail()
return auo
}
// Where appends a list predicates to the AttachmentUpdate builder.
func (auo *AttachmentUpdateOne) Where(ps ...predicate.Attachment) *AttachmentUpdateOne {
auo.mutation.Where(ps...)
@@ -379,9 +502,6 @@ func (auo *AttachmentUpdateOne) check() error {
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Attachment.type": %w`, err)}
}
}
if auo.mutation.EntityCleared() && len(auo.mutation.EntityIDs()) > 0 {
return errors.New(`ent: clearing a required unique edge "Attachment.entity"`)
}
return nil
}
@@ -429,6 +549,9 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
if value, ok := auo.mutation.Path(); ok {
_spec.SetField(attachment.FieldPath, field.TypeString, value)
}
if value, ok := auo.mutation.MimeType(); ok {
_spec.SetField(attachment.FieldMimeType, field.TypeString, value)
}
if auo.mutation.EntityCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
@@ -458,6 +581,35 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if auo.mutation.ThumbnailCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: attachment.ThumbnailTable,
Columns: []string{attachment.ThumbnailColumn},
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := auo.mutation.ThumbnailIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: attachment.ThumbnailTable,
Columns: []string{attachment.ThumbnailColumn},
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Attachment{config: auo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues

View File

@@ -13,11 +13,13 @@ var (
{Name: "id", Type: field.TypeUUID},
{Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime},
{Name: "type", Type: field.TypeEnum, Enums: []string{"photo", "manual", "warranty", "attachment", "receipt"}, Default: "attachment"},
{Name: "type", Type: field.TypeEnum, Enums: []string{"photo", "manual", "warranty", "attachment", "receipt", "thumbnail"}, Default: "attachment"},
{Name: "primary", Type: field.TypeBool, Default: false},
{Name: "title", Type: field.TypeString, Default: ""},
{Name: "path", Type: field.TypeString, Default: ""},
{Name: "entity_attachments", Type: field.TypeUUID},
{Name: "mime_type", Type: field.TypeString, Default: "application/octet-stream"},
{Name: "attachment_thumbnail", Type: field.TypeUUID, Unique: true, Nullable: true},
{Name: "entity_attachments", Type: field.TypeUUID, Nullable: true},
}
// AttachmentsTable holds the schema information for the "attachments" table.
AttachmentsTable = &schema.Table{
@@ -25,9 +27,15 @@ var (
Columns: AttachmentsColumns,
PrimaryKey: []*schema.Column{AttachmentsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "attachments_attachments_thumbnail",
Columns: []*schema.Column{AttachmentsColumns[8]},
RefColumns: []*schema.Column{AttachmentsColumns[0]},
OnDelete: schema.SetNull,
},
{
Symbol: "attachments_entities_attachments",
Columns: []*schema.Column{AttachmentsColumns[7]},
Columns: []*schema.Column{AttachmentsColumns[9]},
RefColumns: []*schema.Column{EntitiesColumns[0]},
OnDelete: schema.Cascade,
},
@@ -458,7 +466,8 @@ var (
)
func init() {
AttachmentsTable.ForeignKeys[0].RefTable = EntitiesTable
AttachmentsTable.ForeignKeys[0].RefTable = AttachmentsTable
AttachmentsTable.ForeignKeys[1].RefTable = EntitiesTable
AuthRolesTable.ForeignKeys[0].RefTable = AuthTokensTable
AuthTokensTable.ForeignKeys[0].RefTable = UsersTable
EntitiesTable.ForeignKeys[0].RefTable = EntitiesTable

View File

@@ -53,21 +53,24 @@ const (
// AttachmentMutation represents an operation that mutates the Attachment nodes in the graph.
type AttachmentMutation struct {
config
op Op
typ string
id *uuid.UUID
created_at *time.Time
updated_at *time.Time
_type *attachment.Type
primary *bool
title *string
_path *string
clearedFields map[string]struct{}
entity *uuid.UUID
clearedentity bool
done bool
oldValue func(context.Context) (*Attachment, error)
predicates []predicate.Attachment
op Op
typ string
id *uuid.UUID
created_at *time.Time
updated_at *time.Time
_type *attachment.Type
primary *bool
title *string
_path *string
mime_type *string
clearedFields map[string]struct{}
entity *uuid.UUID
clearedentity bool
thumbnail *uuid.UUID
clearedthumbnail bool
done bool
oldValue func(context.Context) (*Attachment, error)
predicates []predicate.Attachment
}
var _ ent.Mutation = (*AttachmentMutation)(nil)
@@ -390,6 +393,42 @@ func (m *AttachmentMutation) ResetPath() {
m._path = nil
}
// SetMimeType sets the "mime_type" field.
func (m *AttachmentMutation) SetMimeType(s string) {
m.mime_type = &s
}
// MimeType returns the value of the "mime_type" field in the mutation.
func (m *AttachmentMutation) MimeType() (r string, exists bool) {
v := m.mime_type
if v == nil {
return
}
return *v, true
}
// OldMimeType returns the old "mime_type" field's value of the Attachment entity.
// If the Attachment object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AttachmentMutation) OldMimeType(ctx context.Context) (v string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldMimeType is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldMimeType requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldMimeType: %w", err)
}
return oldValue.MimeType, nil
}
// ResetMimeType resets all changes to the "mime_type" field.
func (m *AttachmentMutation) ResetMimeType() {
m.mime_type = nil
}
// SetEntityID sets the "entity" edge to the Entity entity by id.
func (m *AttachmentMutation) SetEntityID(id uuid.UUID) {
m.entity = &id
@@ -429,6 +468,45 @@ func (m *AttachmentMutation) ResetEntity() {
m.clearedentity = false
}
// SetThumbnailID sets the "thumbnail" edge to the Attachment entity by id.
func (m *AttachmentMutation) SetThumbnailID(id uuid.UUID) {
m.thumbnail = &id
}
// ClearThumbnail clears the "thumbnail" edge to the Attachment entity.
func (m *AttachmentMutation) ClearThumbnail() {
m.clearedthumbnail = true
}
// ThumbnailCleared reports if the "thumbnail" edge to the Attachment entity was cleared.
func (m *AttachmentMutation) ThumbnailCleared() bool {
return m.clearedthumbnail
}
// ThumbnailID returns the "thumbnail" edge ID in the mutation.
func (m *AttachmentMutation) ThumbnailID() (id uuid.UUID, exists bool) {
if m.thumbnail != nil {
return *m.thumbnail, true
}
return
}
// ThumbnailIDs returns the "thumbnail" edge IDs in the mutation.
// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
// ThumbnailID instead. It exists only for internal usage by the builders.
func (m *AttachmentMutation) ThumbnailIDs() (ids []uuid.UUID) {
if id := m.thumbnail; id != nil {
ids = append(ids, *id)
}
return
}
// ResetThumbnail resets all changes to the "thumbnail" edge.
func (m *AttachmentMutation) ResetThumbnail() {
m.thumbnail = nil
m.clearedthumbnail = false
}
// Where appends a list predicates to the AttachmentMutation builder.
func (m *AttachmentMutation) Where(ps ...predicate.Attachment) {
m.predicates = append(m.predicates, ps...)
@@ -463,7 +541,7 @@ func (m *AttachmentMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *AttachmentMutation) Fields() []string {
fields := make([]string, 0, 6)
fields := make([]string, 0, 7)
if m.created_at != nil {
fields = append(fields, attachment.FieldCreatedAt)
}
@@ -482,6 +560,9 @@ func (m *AttachmentMutation) Fields() []string {
if m._path != nil {
fields = append(fields, attachment.FieldPath)
}
if m.mime_type != nil {
fields = append(fields, attachment.FieldMimeType)
}
return fields
}
@@ -502,6 +583,8 @@ func (m *AttachmentMutation) Field(name string) (ent.Value, bool) {
return m.Title()
case attachment.FieldPath:
return m.Path()
case attachment.FieldMimeType:
return m.MimeType()
}
return nil, false
}
@@ -523,6 +606,8 @@ func (m *AttachmentMutation) OldField(ctx context.Context, name string) (ent.Val
return m.OldTitle(ctx)
case attachment.FieldPath:
return m.OldPath(ctx)
case attachment.FieldMimeType:
return m.OldMimeType(ctx)
}
return nil, fmt.Errorf("unknown Attachment field %s", name)
}
@@ -574,6 +659,13 @@ func (m *AttachmentMutation) SetField(name string, value ent.Value) error {
}
m.SetPath(v)
return nil
case attachment.FieldMimeType:
v, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetMimeType(v)
return nil
}
return fmt.Errorf("unknown Attachment field %s", name)
}
@@ -641,16 +733,22 @@ func (m *AttachmentMutation) ResetField(name string) error {
case attachment.FieldPath:
m.ResetPath()
return nil
case attachment.FieldMimeType:
m.ResetMimeType()
return nil
}
return fmt.Errorf("unknown Attachment field %s", name)
}
// AddedEdges returns all edge names that were set/added in this mutation.
func (m *AttachmentMutation) AddedEdges() []string {
edges := make([]string, 0, 1)
edges := make([]string, 0, 2)
if m.entity != nil {
edges = append(edges, attachment.EdgeEntity)
}
if m.thumbnail != nil {
edges = append(edges, attachment.EdgeThumbnail)
}
return edges
}
@@ -662,13 +760,17 @@ func (m *AttachmentMutation) AddedIDs(name string) []ent.Value {
if id := m.entity; id != nil {
return []ent.Value{*id}
}
case attachment.EdgeThumbnail:
if id := m.thumbnail; id != nil {
return []ent.Value{*id}
}
}
return nil
}
// RemovedEdges returns all edge names that were removed in this mutation.
func (m *AttachmentMutation) RemovedEdges() []string {
edges := make([]string, 0, 1)
edges := make([]string, 0, 2)
return edges
}
@@ -680,10 +782,13 @@ func (m *AttachmentMutation) RemovedIDs(name string) []ent.Value {
// ClearedEdges returns all edge names that were cleared in this mutation.
func (m *AttachmentMutation) ClearedEdges() []string {
edges := make([]string, 0, 1)
edges := make([]string, 0, 2)
if m.clearedentity {
edges = append(edges, attachment.EdgeEntity)
}
if m.clearedthumbnail {
edges = append(edges, attachment.EdgeThumbnail)
}
return edges
}
@@ -693,6 +798,8 @@ func (m *AttachmentMutation) EdgeCleared(name string) bool {
switch name {
case attachment.EdgeEntity:
return m.clearedentity
case attachment.EdgeThumbnail:
return m.clearedthumbnail
}
return false
}
@@ -704,6 +811,9 @@ func (m *AttachmentMutation) ClearEdge(name string) error {
case attachment.EdgeEntity:
m.ClearEntity()
return nil
case attachment.EdgeThumbnail:
m.ClearThumbnail()
return nil
}
return fmt.Errorf("unknown Attachment unique edge %s", name)
}
@@ -715,6 +825,9 @@ func (m *AttachmentMutation) ResetEdge(name string) error {
case attachment.EdgeEntity:
m.ResetEntity()
return nil
case attachment.EdgeThumbnail:
m.ResetThumbnail()
return nil
}
return fmt.Errorf("unknown Attachment edge %s", name)
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/gen2brain/jpegxl"
"github.com/gen2brain/webp"
"github.com/rs/zerolog/log"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/entity"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/group"
"github.com/sysadminsmedia/homebox/backend/internal/sys/config"
"github.com/sysadminsmedia/homebox/backend/pkgs/utils"
@@ -27,7 +28,6 @@ import (
"github.com/google/uuid"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/item"
"gocloud.dev/blob"
_ "gocloud.dev/blob/azureblob"
@@ -267,9 +267,9 @@ func (r *AttachmentRepo) Get(ctx context.Context, gid uuid.UUID, id uuid.UUID) (
return r.db.Attachment.
Query().
Where(attachment.ID(id),
attachment.HasThumbnailWith(attachment.HasItemWith(item.HasGroupWith(group.ID(gid)))),
attachment.HasThumbnailWith(attachment.HasEntityWith(entity.HasGroupWith(group.ID(gid)))),
).
WithItem().
WithEntity().
WithThumbnail().
Only(ctx)
} else {
@@ -277,9 +277,9 @@ func (r *AttachmentRepo) Get(ctx context.Context, gid uuid.UUID, id uuid.UUID) (
return r.db.Attachment.
Query().
Where(attachment.ID(id),
attachment.HasItemWith(item.HasGroupWith(group.ID(gid))),
attachment.HasEntityWith(entity.HasGroupWith(group.ID(gid))),
).
WithItem().
WithEntity().
WithThumbnail().
Only(ctx)
}
@@ -290,7 +290,7 @@ func (r *AttachmentRepo) Update(ctx context.Context, gid uuid.UUID, id uuid.UUID
_, err := r.db.Attachment.Query().
Where(
attachment.ID(id),
attachment.HasItemWith(item.HasGroupWith(group.ID(gid))),
attachment.HasEntityWith(entity.HasGroupWith(group.ID(gid))),
).
Only(ctx)
if err != nil {
@@ -324,7 +324,7 @@ func (r *AttachmentRepo) Update(ctx context.Context, gid uuid.UUID, id uuid.UUID
if typ == attachment.TypePhoto && data.Primary {
err = r.db.Attachment.Update().
Where(
attachment.HasItemWith(item.ID(attachmentItem.ID)),
attachment.HasEntityWith(entity.ID(attachmentItem.ID)),
attachment.IDNEQ(updatedAttachment.ID),
attachment.TypeEQ(attachment.TypePhoto),
).
@@ -343,7 +343,7 @@ func (r *AttachmentRepo) Delete(ctx context.Context, gid uuid.UUID, itemId uuid.
doc, err := r.db.Attachment.Query().
Where(
attachment.ID(id),
attachment.HasItemWith(item.HasGroupWith(group.ID(gid))),
attachment.HasEntityWith(entity.HasGroupWith(group.ID(gid))),
).
Only(ctx)
if err != nil {
@@ -404,7 +404,7 @@ func (r *AttachmentRepo) Rename(ctx context.Context, gid uuid.UUID, id uuid.UUID
_, err := r.db.Attachment.Query().
Where(
attachment.ID(id),
attachment.HasItemWith(item.HasGroupWith(group.ID(gid))),
attachment.HasEntityWith(entity.HasGroupWith(group.ID(gid))),
).
Only(ctx)
if err != nil {
@@ -680,7 +680,7 @@ func (r *AttachmentRepo) CreateThumbnail(ctx context.Context, groupId, attachmen
func (r *AttachmentRepo) CreateMissingThumbnails(ctx context.Context, groupId uuid.UUID) (int, error) {
attachments, err := r.db.Attachment.Query().
Where(
attachment.HasItemWith(item.HasGroupWith(group.ID(groupId))),
attachment.HasEntityWith(entity.HasGroupWith(group.ID(groupId))),
attachment.TypeNEQ("thumbnail"),
).
All(ctx)

View File

@@ -366,20 +366,13 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite
// For queries without accents, the traditional search is more efficient.
qb.Where(
entity.Or(
// Regular case-insensitive search (fastest)
entity.NameContainsFold(q.Search),
entity.DescriptionContainsFold(q.Search),
entity.SerialNumberContainsFold(q.Search),
entity.ModelNumberContainsFold(q.Search),
entity.ManufacturerContainsFold(q.Search),
entity.NotesContainsFold(q.Search),
item.Or(
// Regular case-insensitive search (fastest)
item.NameContainsFold(q.Search),
item.DescriptionContainsFold(q.Search),
item.SerialNumberContainsFold(q.Search),
item.ModelNumberContainsFold(q.Search),
item.ManufacturerContainsFold(q.Search),
item.NotesContainsFold(q.Search),
// Accent-insensitive search using custom predicates
ent.ItemNameAccentInsensitiveContains(q.Search),
ent.ItemDescriptionAccentInsensitiveContains(q.Search),