|
| 1 | +--- syncstorage-mysql/src/diesel_ext.rs 2025-09-23 16:12:34 |
| 2 | ++++ syncstorage-mysql/src/diesel_ext.rs.new 2025-11-18 08:04:47 |
| 3 | +@@ -3,11 +3,44 @@ |
| 4 | + use diesel::{ |
| 5 | + backend::Backend, |
| 6 | + insertable::CanInsertInSingleQuery, |
| 7 | ++ mysql::Mysql, |
| 8 | + query_builder::{AstPass, InsertStatement, QueryFragment, QueryId}, |
| 9 | ++ query_dsl::methods::LockingDsl, |
| 10 | + result::QueryResult, |
| 11 | + Expression, QuerySource, RunQueryDsl, |
| 12 | + }; |
| 13 | + |
| 14 | ++/// Emit MySQL <= 5.7's `LOCK IN SHARE MODE` |
| 15 | ++/// |
| 16 | ++/// MySQL 8 supports `FOR SHARE` as an alias (which diesel natively supports) |
| 17 | ++/// This is required for MariaDB which does not provide that alias. |
| 18 | ++pub trait LockInShareModeDsl { |
| 19 | ++ type Output; |
| 20 | ++ |
| 21 | ++ fn lock_in_share_mode(self) -> Self::Output; |
| 22 | ++} |
| 23 | ++ |
| 24 | ++impl<T> LockInShareModeDsl for T |
| 25 | ++where |
| 26 | ++ T: LockingDsl<LockInShareMode>, |
| 27 | ++{ |
| 28 | ++ type Output = <T as LockingDsl<LockInShareMode>>::Output; |
| 29 | ++ |
| 30 | ++ fn lock_in_share_mode(self) -> Self::Output { |
| 31 | ++ self.with_lock(LockInShareMode) |
| 32 | ++ } |
| 33 | ++} |
| 34 | ++ |
| 35 | ++#[derive(Debug, Clone, Copy, QueryId)] |
| 36 | ++pub struct LockInShareMode; |
| 37 | ++ |
| 38 | ++impl QueryFragment<Mysql> for LockInShareMode { |
| 39 | ++ fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Mysql>) -> QueryResult<()> { |
| 40 | ++ out.push_sql(" LOCK IN SHARE MODE"); |
| 41 | ++ Ok(()) |
| 42 | ++ } |
| 43 | ++} |
| 44 | ++ |
| 45 | + #[allow(dead_code)] // Not really dead, Rust can't see it. |
| 46 | + #[derive(Debug, Clone)] |
| 47 | + pub struct OnDuplicateKeyUpdate<T, U, Op, Ret, DB, X>( |
| 48 | +--- syncstorage-mysql/src/models.rs 2025-09-23 16:12:34 |
| 49 | ++++ syncstorage-mysql/src/models.rs.new 2025-11-18 08:07:49 |
| 50 | +@@ -26,6 +26,7 @@ |
| 51 | + use super::{ |
| 52 | + batch, |
| 53 | + error::DbError, |
| 54 | ++ diesel_ext::LockInShareModeDsl, |
| 55 | + pool::CollectionCache, |
| 56 | + schema::{bso, collections, user_collections}, |
| 57 | + DbResult, |
| 58 | +@@ -178,7 +179,7 @@ |
| 59 | + .select(user_collections::modified) |
| 60 | + .filter(user_collections::user_id.eq(user_id)) |
| 61 | + .filter(user_collections::collection_id.eq(collection_id)) |
| 62 | +- .for_share() |
| 63 | ++ .lock_in_share_mode() |
| 64 | + .first(&mut *self.conn.write()?) |
| 65 | + .optional()?; |
| 66 | + if let Some(modified) = modified { |
0 commit comments