pragma.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #![allow(clippy::upper_case_acronyms)]
  2. use crate::sqlite::errors::{Error, Result};
  3. use diesel::{
  4. expression::SqlLiteral,
  5. query_dsl::load_dsl::LoadQuery,
  6. sql_types::{Integer, Text},
  7. SqliteConnection,
  8. };
  9. use crate::sqlite::conn_ext::ConnectionExtension;
  10. use std::{
  11. convert::{TryFrom, TryInto},
  12. fmt,
  13. str::FromStr,
  14. };
  15. pub trait PragmaExtension: ConnectionExtension {
  16. fn pragma<D: std::fmt::Display>(&self, key: &str, val: D, schema: Option<&str>) -> Result<()> {
  17. let query = match schema {
  18. Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
  19. None => format!("PRAGMA {} = '{}'", key, val),
  20. };
  21. tracing::trace!("SQLITE {}", query);
  22. self.exec(&query)?;
  23. Ok(())
  24. }
  25. fn pragma_ret<ST, T, D: std::fmt::Display>(
  26. &self,
  27. key: &str,
  28. val: D,
  29. schema: Option<&str>,
  30. ) -> Result<T>
  31. where
  32. SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
  33. {
  34. let query = match schema {
  35. Some(schema) => format!("PRAGMA {}.{} = '{}'", schema, key, val),
  36. None => format!("PRAGMA {} = '{}'", key, val),
  37. };
  38. tracing::trace!("SQLITE {}", query);
  39. self.query::<ST, T>(&query)
  40. }
  41. fn pragma_get<ST, T>(&self, key: &str, schema: Option<&str>) -> Result<T>
  42. where
  43. SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
  44. {
  45. let query = match schema {
  46. Some(schema) => format!("PRAGMA {}.{}", schema, key),
  47. None => format!("PRAGMA {}", key),
  48. };
  49. tracing::trace!("SQLITE {}", query);
  50. self.query::<ST, T>(&query)
  51. }
  52. fn pragma_set_busy_timeout(&self, timeout_ms: i32) -> Result<i32> {
  53. self.pragma_ret::<Integer, i32, i32>("busy_timeout", timeout_ms, None)
  54. }
  55. fn pragma_get_busy_timeout(&self) -> Result<i32> {
  56. self.pragma_get::<Integer, i32>("busy_timeout", None)
  57. }
  58. fn pragma_set_journal_mode(&self, mode: SQLiteJournalMode, schema: Option<&str>) -> Result<i32> {
  59. self.pragma_ret::<Integer, i32, SQLiteJournalMode>("journal_mode", mode, schema)
  60. }
  61. fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result<SQLiteJournalMode> {
  62. self
  63. .pragma_get::<Text, String>("journal_mode", schema)?
  64. .parse()
  65. }
  66. fn pragma_set_synchronous(
  67. &self,
  68. synchronous: SQLiteSynchronous,
  69. schema: Option<&str>,
  70. ) -> Result<()> {
  71. self.pragma("synchronous", synchronous as u8, schema)
  72. }
  73. fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result<SQLiteSynchronous> {
  74. self
  75. .pragma_get::<Integer, i32>("synchronous", schema)?
  76. .try_into()
  77. }
  78. }
  79. impl PragmaExtension for SqliteConnection {}
  80. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  81. pub enum SQLiteJournalMode {
  82. DELETE,
  83. TRUNCATE,
  84. PERSIST,
  85. MEMORY,
  86. WAL,
  87. OFF,
  88. }
  89. impl fmt::Display for SQLiteJournalMode {
  90. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  91. write!(
  92. f,
  93. "{}",
  94. match self {
  95. Self::DELETE => "DELETE",
  96. Self::TRUNCATE => "TRUNCATE",
  97. Self::PERSIST => "PERSIST",
  98. Self::MEMORY => "MEMORY",
  99. Self::WAL => "WAL",
  100. Self::OFF => "OFF",
  101. }
  102. )
  103. }
  104. }
  105. impl FromStr for SQLiteJournalMode {
  106. type Err = Error;
  107. fn from_str(s: &str) -> Result<Self> {
  108. match s.to_uppercase().as_ref() {
  109. "DELETE" => Ok(Self::DELETE),
  110. "TRUNCATE" => Ok(Self::TRUNCATE),
  111. "PERSIST" => Ok(Self::PERSIST),
  112. "MEMORY" => Ok(Self::MEMORY),
  113. "WAL" => Ok(Self::WAL),
  114. "OFF" => Ok(Self::OFF),
  115. _ => Err(format!("Unknown value {} for JournalMode", s).into()),
  116. }
  117. }
  118. }
  119. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  120. pub enum SQLiteSynchronous {
  121. EXTRA = 3,
  122. FULL = 2,
  123. NORMAL = 1,
  124. OFF = 0,
  125. }
  126. impl fmt::Display for SQLiteSynchronous {
  127. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  128. write!(
  129. f,
  130. "{}",
  131. match self {
  132. Self::OFF => "OFF",
  133. Self::NORMAL => "NORMAL",
  134. Self::FULL => "FULL",
  135. Self::EXTRA => "EXTRA",
  136. }
  137. )
  138. }
  139. }
  140. impl TryFrom<i32> for SQLiteSynchronous {
  141. type Error = Error;
  142. fn try_from(v: i32) -> Result<Self> {
  143. match v {
  144. 0 => Ok(Self::OFF),
  145. 1 => Ok(Self::NORMAL),
  146. 2 => Ok(Self::FULL),
  147. 3 => Ok(Self::EXTRA),
  148. _ => Err(format!("Unknown value {} for Synchronous", v).into()),
  149. }
  150. }
  151. }
  152. impl FromStr for SQLiteSynchronous {
  153. type Err = Error;
  154. fn from_str(s: &str) -> Result<Self> {
  155. match s.to_uppercase().as_ref() {
  156. "0" | "OFF" => Ok(Self::OFF),
  157. "1" | "NORMAL" => Ok(Self::NORMAL),
  158. "2" | "FULL" => Ok(Self::FULL),
  159. "3" | "EXTRA" => Ok(Self::EXTRA),
  160. _ => Err(format!("Unknown value {} for Synchronous", s).into()),
  161. }
  162. }
  163. }