1
0
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:
David Lawrence
2015-07-10 20:42:47 -07:00
parent 40921a4bed
commit 5bcd3ff52d

View File

@@ -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