Support setting file fingerprints (#4376)

* Support setting file fingerprints
* Disallow modifying managed hashes
This commit is contained in:
WithoutPants
2023-12-22 14:07:10 +11:00
committed by GitHub
parent a1bd7cf817
commit afda6decf2
7 changed files with 156 additions and 0 deletions

View File

@@ -86,6 +86,20 @@ func (_m *FileReaderWriter) Destroy(ctx context.Context, id models.FileID) error
return r0
}
// DestroyFingerprints provides a mock function with given fields: ctx, fileID, types
func (_m *FileReaderWriter) DestroyFingerprints(ctx context.Context, fileID models.FileID, types []string) error {
ret := _m.Called(ctx, fileID, types)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, models.FileID, []string) error); ok {
r0 = rf(ctx, fileID, types)
} else {
r0 = ret.Error(0)
}
return r0
}
// Find provides a mock function with given fields: ctx, id
func (_m *FileReaderWriter) Find(ctx context.Context, id ...models.FileID) ([]models.File, error) {
_va := make([]interface{}, len(id))
@@ -298,6 +312,20 @@ func (_m *FileReaderWriter) IsPrimary(ctx context.Context, fileID models.FileID)
return r0, r1
}
// ModifyFingerprints provides a mock function with given fields: ctx, fileID, fingerprints
func (_m *FileReaderWriter) ModifyFingerprints(ctx context.Context, fileID models.FileID, fingerprints []models.Fingerprint) error {
ret := _m.Called(ctx, fileID, fingerprints)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, models.FileID, []models.Fingerprint) error); ok {
r0 = rf(ctx, fileID, fingerprints)
} else {
r0 = ret.Error(0)
}
return r0
}
// Query provides a mock function with given fields: ctx, options
func (_m *FileReaderWriter) Query(ctx context.Context, options models.FileQueryOptions) (*models.FileQueryResult, error) {
ret := _m.Called(ctx, options)

View File

@@ -72,11 +72,17 @@ type FileReader interface {
IsPrimary(ctx context.Context, fileID FileID) (bool, error)
}
type FileFingerprintWriter interface {
ModifyFingerprints(ctx context.Context, fileID FileID, fingerprints []Fingerprint) error
DestroyFingerprints(ctx context.Context, fileID FileID, types []string) error
}
// FileWriter provides all methods to modify files.
type FileWriter interface {
FileCreator
FileUpdater
FileDestroyer
FileFingerprintWriter
UpdateCaptions(ctx context.Context, fileID FileID, captions []*VideoCaption) error
}

View File

@@ -361,6 +361,15 @@ func (qb *FileStore) Update(ctx context.Context, f models.File) error {
return nil
}
// ModifyFingerprints updates existing fingerprints and adds new ones.
func (qb *FileStore) ModifyFingerprints(ctx context.Context, fileID models.FileID, fingerprints []models.Fingerprint) error {
return FingerprintReaderWriter.upsertJoins(ctx, fileID, fingerprints)
}
func (qb *FileStore) DestroyFingerprints(ctx context.Context, fileID models.FileID, types []string) error {
return FingerprintReaderWriter.destroyJoins(ctx, fileID, types)
}
func (qb *FileStore) Destroy(ctx context.Context, id models.FileID) error {
return qb.tableMgr.destroyExisting(ctx, []int{int(id)})
}

View File

@@ -68,6 +68,25 @@ func (qb *fingerprintQueryBuilder) insertJoins(ctx context.Context, fileID model
return nil
}
func (qb *fingerprintQueryBuilder) upsertJoins(ctx context.Context, fileID models.FileID, f []models.Fingerprint) error {
types := make([]string, len(f))
for i, ff := range f {
types[i] = ff.Type
}
if err := qb.destroyJoins(ctx, fileID, types); err != nil {
return err
}
for _, ff := range f {
if err := qb.insert(ctx, fileID, ff); err != nil {
return err
}
}
return nil
}
func (qb *fingerprintQueryBuilder) replaceJoins(ctx context.Context, fileID models.FileID, f []models.Fingerprint) error {
if err := qb.destroy(ctx, []int{int(fileID)}); err != nil {
return err
@@ -76,6 +95,21 @@ func (qb *fingerprintQueryBuilder) replaceJoins(ctx context.Context, fileID mode
return qb.insertJoins(ctx, fileID, f)
}
func (qb *fingerprintQueryBuilder) destroyJoins(ctx context.Context, fileID models.FileID, types []string) error {
table := qb.table()
q := dialect.Delete(table).Where(
table.Col(fileIDColumn).Eq(fileID),
table.Col("type").In(types),
)
_, err := exec(ctx, q)
if err != nil {
return fmt.Errorf("deleting from %s: %w", table.GetTable(), err)
}
return nil
}
func (qb *fingerprintQueryBuilder) table() exp.IdentifierExpression {
return qb.tableMgr.table
}