pragma.rs 4.8 KB

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