mirror of
https://github.com/docker/docs.git
synced 2026-10-31 10:34:26 +03:00
reworking the insert check for TUF metadata in the database
Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
@@ -39,12 +39,12 @@ func NewMySQLStorage(db *sql.DB) *MySQLStorage {
|
||||
// UpdateCurrent updates multiple TUF records in a single transaction.
|
||||
// Always insert a new row. The unique constraint will ensure there is only ever
|
||||
func (db *MySQLStorage) UpdateCurrent(gun, update MetaUpdate) error {
|
||||
insertStmt := "INSERT INTO `tuf_files` (`gun`, `role`, `version`, `data`) VALUES (?,?,?,?) ;"
|
||||
insertStmt := "INSERT INTO `tuf_files` (`gun`, `role`, `version`, `data`) VALUES (?,?,?,?) WHERE (SELECT count(*) FROM `tuf_files` WHERE `gun`=? AND `role`=? AND `version`>=?) = 0;"
|
||||
|
||||
// attempt to insert. Due to race conditions with the check this could fail.
|
||||
// That's OK, we're doing first write wins. The client will be messaged it
|
||||
// needs to rebase.
|
||||
_, err := db.Exec(insertStmt, gun, update.Role, update.Version, update.Data)
|
||||
_, err := db.Exec(insertStmt, gun, update.Role, update.Version, update.Data, gun, update.Role, update.Version)
|
||||
if err != nil {
|
||||
if err, ok := err.(*mysql.MySQLError); ok {
|
||||
if err.Number == 1022 { // duplicate key error
|
||||
@@ -60,14 +60,14 @@ func (db *MySQLStorage) UpdateCurrent(gun, update MetaUpdate) error {
|
||||
|
||||
// UpdateMany atomically updates many TUF records in a single transaction
|
||||
func (db *MySQLStorage) UpdateMany(gun string, updates []MetaUpdate) error {
|
||||
insertStmt := "INSERT INTO `tuf_files` (`gun`, `role`, `version`, `data`) VALUES (?,?,?,?) ;"
|
||||
insertStmt := "INSERT INTO `tuf_files` (`gun`, `role`, `version`, `data`) VALUES (?,?,?,?) WHERE (SELECT count(*) FROM `tuf_files` WHERE `gun`=? AND `role`=? AND `version`>=?) = 0;"
|
||||
|
||||
tx, err := db.Begin()
|
||||
for _, u := range updates {
|
||||
// attempt to insert. Due to race conditions with the check this could fail.
|
||||
// That's OK, we're doing first write wins. The client will be messaged it
|
||||
// needs to rebase.
|
||||
_, err = tx.Exec(insertStmt, gun, u.Role, u.Version, u.Data)
|
||||
_, err = tx.Exec(insertStmt, gun, u.Role, u.Version, u.Data, u.Role, u.Version)
|
||||
if err != nil {
|
||||
// need to check error type for duplicate key exception
|
||||
// and return ErrOldVersion if duplicate
|
||||
|
||||
Reference in New Issue
Block a user