fix: mariadb compatibility

Partially reverting #1717
According to MySQL docs (even in latest MySQL 9.4) FOR SHARE and LOCK IN
SHARE MODE are equivalent. MariaDB implements the latter only. The
additional options mentioned in the docs are not used here.

Closes #1753
This commit is contained in:
Fritz Elfert 2025-10-21 09:35:40 +02:00
parent 594f1de822
commit b1ca7b32de
No known key found for this signature in database
GPG Key ID: E91ACCEBA1586922
2 changed files with 35 additions and 1 deletions

View File

@ -3,11 +3,44 @@ use std::{fmt::Debug, marker::PhantomData};
use diesel::{
backend::Backend,
insertable::CanInsertInSingleQuery,
mysql::Mysql,
query_builder::{AstPass, InsertStatement, QueryFragment, QueryId},
query_dsl::methods::LockingDsl,
result::QueryResult,
Expression, QuerySource, RunQueryDsl,
};
/// Emit MySQL <= 5.7's `LOCK IN SHARE MODE`
///
/// MySQL 8 supports `FOR SHARE` as an alias (which diesel natively supports)
/// This is required for MariaDB which does not provide that alias.
pub trait LockInShareModeDsl {
type Output;
fn lock_in_share_mode(self) -> Self::Output;
}
impl<T> LockInShareModeDsl for T
where
T: LockingDsl<LockInShareMode>,
{
type Output = <T as LockingDsl<LockInShareMode>>::Output;
fn lock_in_share_mode(self) -> Self::Output {
self.with_lock(LockInShareMode)
}
}
#[derive(Debug, Clone, Copy, QueryId)]
pub struct LockInShareMode;
impl QueryFragment<Mysql> for LockInShareMode {
fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Mysql>) -> QueryResult<()> {
out.push_sql(" LOCK IN SHARE MODE");
Ok(())
}
}
#[allow(dead_code)] // Not really dead, Rust can't see it.
#[derive(Debug, Clone)]
pub struct OnDuplicateKeyUpdate<T, U, Op, Ret, DB, X>(

View File

@ -19,6 +19,7 @@ use syncstorage_settings::{Quota, DEFAULT_MAX_TOTAL_RECORDS};
use super::{
batch,
diesel_ext::LockInShareModeDsl,
pool::{CollectionCache, Conn},
schema::{bso, collections, user_collections},
DbError, DbResult,
@ -133,7 +134,7 @@ impl MysqlDb {
.select(user_collections::modified)
.filter(user_collections::user_id.eq(user_id))
.filter(user_collections::collection_id.eq(collection_id))
.for_share()
.lock_in_share_mode()
.first(&mut self.conn)
.await
.optional()?;