func isReadErr(q *gorm.DB, row TUFFile) error { if q.RecordNotFound() { return ErrNotFound{} } else if q.Error != nil { return q.Error } return nil }
func returnRead(q *gorm.DB, row TUFFile) ([]byte, error) { if q.RecordNotFound() { return nil, ErrNotFound{} } else if q.Error != nil { return nil, q.Error } return row.Data, nil }
// UpdateMany atomically updates many TUF records in a single transaction func (db *SQLStorage) UpdateMany(gun string, updates []MetaUpdate) error { tx, rb, err := db.getTransaction() if err != nil { return err } var ( query *gorm.DB added = make(map[uint]bool) ) if err := func() error { for _, update := range updates { // This looks like the same logic as UpdateCurrent, but if we just // called, version ordering in the updates list must be enforced // (you cannot insert the version 2 before version 1). And we do // not care about monotonic ordering in the updates. query = db.Where("gun = ? and role = ? and version >= ?", gun, update.Role, update.Version).First(&TUFFile{}) if !query.RecordNotFound() { return ErrOldVersion{} } var row TUFFile checksum := sha256.Sum256(update.Data) hexChecksum := hex.EncodeToString(checksum[:]) query = tx.Where(map[string]interface{}{ "gun": gun, "role": update.Role, "version": update.Version, }).Attrs("data", update.Data).Attrs("sha256", hexChecksum).FirstOrCreate(&row) if query.Error != nil { return translateOldVersionError(query.Error) } // it's previously been added, which means it's a duplicate entry // in the same transaction if _, ok := added[row.ID]; ok { return ErrOldVersion{} } if update.Role == data.CanonicalTimestampRole { if err := db.writeChangefeed(tx, gun, update.Version, hexChecksum); err != nil { return err } } added[row.ID] = true } return nil }(); err != nil { return rb(err) } return tx.Commit().Error }
// UpdateMany atomically updates many TUF records in a single transaction func (db *SQLStorage) UpdateMany(gun string, updates []MetaUpdate) error { tx := db.Begin() if tx.Error != nil { return tx.Error } rollback := func(err error) error { if rxErr := tx.Rollback().Error; rxErr != nil { logrus.Error("Failed on Tx rollback with error: ", rxErr.Error()) return rxErr } return err } var ( query *gorm.DB added = make(map[uint]bool) ) for _, update := range updates { // This looks like the same logic as UpdateCurrent, but if we just // called, version ordering in the updates list must be enforced // (you cannot insert the version 2 before version 1). And we do // not care about monotonic ordering in the updates. query = db.Where("gun = ? and role = ? and version >= ?", gun, update.Role, update.Version).First(&TUFFile{}) if !query.RecordNotFound() { return rollback(&ErrOldVersion{}) } var row TUFFile checksum := sha256.Sum256(update.Data) hexChecksum := hex.EncodeToString(checksum[:]) query = tx.Where(map[string]interface{}{ "gun": gun, "role": update.Role, "version": update.Version, }).Attrs("data", update.Data).Attrs("sha256", hexChecksum).FirstOrCreate(&row) if query.Error != nil { return rollback(translateOldVersionError(query.Error)) } // it's previously been added, which means it's a duplicate entry // in the same transaction if _, ok := added[row.ID]; ok { return rollback(&ErrOldVersion{}) } added[row.ID] = true } return tx.Commit().Error }
// UpdateFullName updates the cached full name of the tag func (u *Tag) UpdateFullName(db *gorm.DB) (err error) { var ( repo = &Repo{} org = &Org{} registry = &Registry{} handle *gorm.DB ) if handle = db.First(repo, u.RepoID); handle.RecordNotFound() { return fmt.Errorf("Failed to find parent repo") } if handle = db.First(org, repo.OrgID); handle.RecordNotFound() { return fmt.Errorf("Failed to find parent org") } if handle = db.First(registry, org.RegistryID); handle.RecordNotFound() { return fmt.Errorf("Failed to find parent registry") } u.FullName = fmt.Sprintf( "%s/%s/%s:%s", registry.PlainHost, org.Name, repo.Name, u.Name, ) return nil }