Fixed foreign-key (mariadb) errors.

When using MariaDB v10.5+ Foreign-Key errors were popping up because of
some changes in that version. To mitigate this on MariaDB and other
MySQL forks those errors are now catched, and instead of a replace_into
an update will happen. I have tested this as thorough as possible with
MariaDB 10.5, 10.4, 10.3 and the default MySQL on Ubuntu Focal. And
tested it again using sqlite, all seems to be ok on all tables.

resolves #1081. resolves #1065, resolves #1050
This commit is contained in:
BlackDex
2020-09-22 12:13:02 +02:00
parent 2f3e18caa9
commit 978be0b4a9
8 changed files with 170 additions and 45 deletions

View File

@ -194,14 +194,25 @@ impl Cipher {
pub fn save(&mut self, conn: &DbConn) -> EmptyResult {
self.update_users_revision(conn);
self.updated_at = Utc::now().naive_utc();
db_run! { conn:
db_run! { conn:
sqlite, mysql {
diesel::replace_into(ciphers::table)
match diesel::replace_into(ciphers::table)
.values(CipherDb::to_db(self))
.execute(conn)
.map_res("Error saving cipher")
}
{
Ok(_) => Ok(()),
// Record already exists and causes a Foreign Key Violation because replace_into() wants to delete the record first.
Err(diesel::result::Error::DatabaseError(diesel::result::DatabaseErrorKind::ForeignKeyViolation, _)) => {
diesel::update(ciphers::table)
.filter(ciphers::uuid.eq(&self.uuid))
.set(CipherDb::to_db(self))
.execute(conn)
.map_res("Error saving cipher")
}
Err(e) => Err(e.into()),
}.map_res("Error saving cipher")
}
postgresql {
let value = CipherDb::to_db(self);
diesel::insert_into(ciphers::table)