func mergeValues(store *storage.Storage, tx *storage.Tx, sourceValueNames []string, destValueName string) (error, warnings) { destValue, err := store.ValueByName(tx, destValueName) if err != nil { return fmt.Errorf("could not retrieve value '%v': %v", destValueName, err), nil } if destValue == nil { return fmt.Errorf("no such value '%v'", destValueName), nil } warnings := make(warnings, 0, 10) for _, sourceValueName := range sourceValueNames { if sourceValueName == destValueName { warnings = append(warnings, fmt.Sprintf("cannot merge value '%v' into itself", sourceValueName)) continue } sourceValue, err := store.ValueByName(tx, sourceValueName) if err != nil { return fmt.Errorf("could not retrieve value '%v': %v", sourceValueName, err), warnings } if sourceValue == nil { warnings = append(warnings, fmt.Sprintf("no such value '%v'", sourceValueName)) continue } log.Infof(2, "finding files tagged with value '%v'.", sourceValueName) fileTags, err := store.FileTagsByValueId(tx, sourceValue.Id) if err != nil { return fmt.Errorf("could not retrieve files for value '%v': %v", sourceValueName, err), warnings } log.Infof(2, "applying value '%v' to these files.", destValueName) for _, fileTag := range fileTags { if _, err = store.AddFileTag(tx, fileTag.FileId, fileTag.TagId, destValue.Id); err != nil { return fmt.Errorf("could not apply value '%v' to file #%v: %v", destValueName, fileTag.FileId, err), warnings } } log.Infof(2, "deleting value '%v'.", sourceValueName) if err = store.DeleteValue(tx, sourceValue.Id); err != nil { return fmt.Errorf("could not delete value '%v': %v", sourceValueName, err), warnings } } return nil, warnings }
func tagPath(store *storage.Storage, tx *storage.Tx, path string, pairs []entities.TagIdValueIdPair, explicit, recursive, force bool, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg string, reportDuplicates bool) error { absPath, err := filepath.Abs(path) if err != nil { return fmt.Errorf("%v: could not get absolute path: %v", path, err) } stat, err := os.Stat(path) if err != nil { switch { case os.IsNotExist(err), os.IsPermission(err): if !force { return err } else { stat = emptyStat{} } default: return err } } log.Infof(2, "%v: checking if file exists in database", path) file, err := store.FileByPath(tx, absPath) if err != nil { return fmt.Errorf("%v: could not retrieve file: %v", path, err) } if file == nil { log.Infof(2, "%v: creating fingerprint", path) fp, err := fingerprint.Create(path, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg) if err != nil { if !force || !(os.IsNotExist(err) || os.IsPermission(err)) { return fmt.Errorf("%v: could not create fingerprint: %v", path, err) } } if fp != fingerprint.Empty && reportDuplicates { log.Infof(2, "%v: checking for duplicates", path) count, err := store.FileCountByFingerprint(tx, fp) if err != nil { return fmt.Errorf("%v: could not identify duplicates: %v", path, err) } if count != 0 { log.Warnf("'%v' is a duplicate", path) } } log.Infof(2, "%v: adding file", path) file, err = store.AddFile(tx, path, fp, stat.ModTime(), int64(stat.Size()), stat.IsDir()) if err != nil { return fmt.Errorf("%v: could not add file to database: %v", path, err) } } if !explicit { pairs, err = removeAlreadyAppliedTagValuePairs(store, tx, pairs, file) if err != nil { return fmt.Errorf("%v: could not remove applied tags: %v", path, err) } } log.Infof(2, "%v: applying tags.", path) for _, pair := range pairs { if _, err = store.AddFileTag(tx, file.Id, pair.TagId, pair.ValueId); err != nil { return fmt.Errorf("%v: could not apply tags: %v", file.Path(), err) } } if recursive && stat.IsDir() { if err = tagRecursively(store, tx, path, pairs, explicit, force, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg, reportDuplicates); err != nil { return err } } return nil }