diff options
Diffstat (limited to 'internal/db')
| -rw-r--r-- | internal/db/bundb/media.go | 86 | ||||
| -rw-r--r-- | internal/db/bundb/status.go | 22 | ||||
| -rw-r--r-- | internal/db/media.go | 11 | 
3 files changed, 91 insertions, 28 deletions
| diff --git a/internal/db/bundb/media.go b/internal/db/bundb/media.go index 6975df85f..8f6985bad 100644 --- a/internal/db/bundb/media.go +++ b/internal/db/bundb/media.go @@ -34,39 +34,69 @@ type mediaDB struct {  	state *state.State  } -func (m *mediaDB) newMediaQ(i *gtsmodel.MediaAttachment) *bun.SelectQuery { -	return m.conn. -		NewSelect(). -		Model(i) -} -  func (m *mediaDB) GetAttachmentByID(ctx context.Context, id string) (*gtsmodel.MediaAttachment, db.Error) {  	return m.getAttachment(  		ctx,  		"ID",  		func(attachment *gtsmodel.MediaAttachment) error { -			return m.newMediaQ(attachment).Where("? = ?", bun.Ident("media_attachment.id"), id).Scan(ctx) +			return m.conn.NewSelect(). +				Model(attachment). +				Where("? = ?", bun.Ident("media_attachment.id"), id). +				Scan(ctx)  		},  		id,  	)  } -func (m *mediaDB) getAttachments(ctx context.Context, ids []string) ([]*gtsmodel.MediaAttachment, db.Error) { -	attachments := make([]*gtsmodel.MediaAttachment, 0, len(ids)) +func (m *mediaDB) getAttachment(ctx context.Context, lookup string, dbQuery func(*gtsmodel.MediaAttachment) error, keyParts ...any) (*gtsmodel.MediaAttachment, db.Error) { +	return m.state.Caches.GTS.Media().Load(lookup, func() (*gtsmodel.MediaAttachment, error) { +		var attachment gtsmodel.MediaAttachment -	for _, id := range ids { -		// Attempt fetch from DB -		attachment, err := m.GetAttachmentByID(ctx, id) -		if err != nil { -			log.Errorf(ctx, "error getting attachment %q: %v", id, err) -			continue +		// Not cached! Perform database query +		if err := dbQuery(&attachment); err != nil { +			return nil, m.conn.ProcessError(err)  		} -		// Append attachment -		attachments = append(attachments, attachment) +		return &attachment, nil +	}, keyParts...) +} + +func (m *mediaDB) PutAttachment(ctx context.Context, media *gtsmodel.MediaAttachment) error { +	return m.state.Caches.GTS.Media().Store(media, func() error { +		_, err := m.conn.NewInsert().Model(media).Exec(ctx) +		return m.conn.ProcessError(err) +	}) +} + +func (m *mediaDB) UpdateAttachment(ctx context.Context, media *gtsmodel.MediaAttachment, columns ...string) error { +	media.UpdatedAt = time.Now() +	if len(columns) > 0 { +		// If we're updating by column, ensure "updated_at" is included. +		columns = append(columns, "updated_at")  	} -	return attachments, nil +	return m.state.Caches.GTS.Media().Store(media, func() error { +		_, err := m.conn.NewUpdate(). +			Model(media). +			Where("? = ?", bun.Ident("media_attachment.id"), media.ID). +			Column(columns...). +			Exec(ctx) +		return m.conn.ProcessError(err) +	}) +} + +func (m *mediaDB) DeleteAttachment(ctx context.Context, id string) error { +	// Attempt to delete from database. +	if _, err := m.conn.NewDelete(). +		TableExpr("? AS ?", bun.Ident("media_attachments"), bun.Ident("media_attachment")). +		Where("? = ?", bun.Ident("media_attachment.id"), id). +		Exec(ctx); err != nil { +		return m.conn.ProcessError(err) +	} + +	// Invalidate this media item from the cache. +	m.state.Caches.GTS.Media().Invalidate("ID", id) +	return nil  }  func (m *mediaDB) GetRemoteOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, db.Error) { @@ -183,14 +213,20 @@ func (m *mediaDB) CountLocalUnattachedOlderThan(ctx context.Context, olderThan t  	return count, nil  } -func (m *mediaDB) getAttachment(ctx context.Context, lookup string, dbQuery func(*gtsmodel.MediaAttachment) error, keyParts ...any) (*gtsmodel.MediaAttachment, db.Error) { -	// Fetch attachment from database -	// todo: cache this lookup -	attachment := new(gtsmodel.MediaAttachment) +func (m *mediaDB) getAttachments(ctx context.Context, ids []string) ([]*gtsmodel.MediaAttachment, db.Error) { +	attachments := make([]*gtsmodel.MediaAttachment, 0, len(ids)) -	if err := dbQuery(attachment); err != nil { -		return nil, m.conn.ProcessError(err) +	for _, id := range ids { +		// Attempt fetch from DB +		attachment, err := m.GetAttachmentByID(ctx, id) +		if err != nil { +			log.Errorf(ctx, "error getting attachment %q: %v", id, err) +			continue +		} + +		// Append attachment +		attachments = append(attachments, attachment)  	} -	return attachment, nil +	return attachments, nil  } diff --git a/internal/db/bundb/status.go b/internal/db/bundb/status.go index 72e44068d..3bbf67657 100644 --- a/internal/db/bundb/status.go +++ b/internal/db/bundb/status.go @@ -188,7 +188,7 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g  }  func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Error { -	return s.state.Caches.GTS.Status().Store(status, func() error { +	err := s.state.Caches.GTS.Status().Store(status, func() error {  		// It is safe to run this database transaction within cache.Store  		// as the cache does not attempt a mutex lock until AFTER hook.  		// @@ -248,6 +248,17 @@ func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Er  			return err  		})  	}) +	if err != nil { +		// already processed +		return err +	} + +	for _, id := range status.AttachmentIDs { +		// Clear updated media attachment IDs from cache +		s.state.Caches.GTS.Media().Invalidate("ID", id) +	} + +	return nil  }  func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status, columns ...string) db.Error { @@ -317,11 +328,18 @@ func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status, co  			Exec(ctx)  		return err  	}); err != nil { +		// already processed  		return err  	} -	// Drop any old value from cache by this ID +	for _, id := range status.AttachmentIDs { +		// Clear updated media attachment IDs from cache +		s.state.Caches.GTS.Media().Invalidate("ID", id) +	} + +	// Drop any old status value from cache by this ID  	s.state.Caches.GTS.Status().Invalidate("ID", status.ID) +  	return nil  } diff --git a/internal/db/media.go b/internal/db/media.go index 3756bd58f..131d0ab08 100644 --- a/internal/db/media.go +++ b/internal/db/media.go @@ -27,9 +27,18 @@ import (  // Media contains functions related to creating/getting/removing media attachments.  type Media interface { -	// GetAttachmentByID gets a single attachment by its ID +	// GetAttachmentByID gets a single attachment by its ID.  	GetAttachmentByID(ctx context.Context, id string) (*gtsmodel.MediaAttachment, Error) +	// PutAttachment inserts the given attachment into the database. +	PutAttachment(ctx context.Context, media *gtsmodel.MediaAttachment) error + +	// UpdateAttachment will update the given attachment in the database. +	UpdateAttachment(ctx context.Context, media *gtsmodel.MediaAttachment, columns ...string) error + +	// DeleteAttachment deletes the attachment with given ID from the database. +	DeleteAttachment(ctx context.Context, id string) error +  	// GetRemoteOlderThan gets limit n remote media attachments (including avatars and headers) older than the given  	// olderThan time. These will be returned in order of attachment.created_at descending (newest to oldest in other words).  	// | 
