dialect.rs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. //! The SQL dialect seam: the one place the SQLite/PostgreSQL divergence lives.
  2. //!
  3. //! Resolved once at construction from the pool's connection URL (no query), so
  4. //! the write paths read a plain enum instead of re-probing the backend. A third
  5. //! backend becomes a new variant here, not edits across every `impl`.
  6. use sqlx::{Any, Pool};
  7. /// Which SQL backend a [`SqlStore`](crate::SqlStore) is talking to.
  8. #[derive(Clone, Copy, Debug, PartialEq, Eq)]
  9. pub(crate) enum Dialect {
  10. /// PostgreSQL: supports `SELECT ... FOR UPDATE` row locking.
  11. Postgres,
  12. /// SQLite: no `FOR UPDATE`; it serializes writers itself.
  13. Sqlite,
  14. }
  15. impl Dialect {
  16. /// Resolve the dialect from the pool's connection URL scheme. Synchronous
  17. /// and issues no query. Anything that is not `sqlite` is treated as
  18. /// PostgreSQL, matching the prior runtime probe (which classified any
  19. /// non-SQLite backend as Postgres).
  20. pub(crate) fn from_pool(pool: &Pool<Any>) -> Self {
  21. match pool.connect_options().database_url.scheme() {
  22. "sqlite" => Self::Sqlite,
  23. _ => Self::Postgres,
  24. }
  25. }
  26. /// Row-locking clause appended to a `SELECT` that takes a pessimistic lock:
  27. /// ` FOR UPDATE` on Postgres, empty on SQLite (which has no such clause and
  28. /// serializes writers itself).
  29. pub(crate) fn lock_clause(self) -> &'static str {
  30. match self {
  31. Self::Postgres => " FOR UPDATE",
  32. Self::Sqlite => "",
  33. }
  34. }
  35. }