query.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use crate::DB;
  2. pub mod condition;
  3. #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
  4. pub struct ID { id: i64 }
  5. impl rusqlite::ToSql for ID {
  6. fn to_sql(&self) -> Result<rusqlite::types::ToSqlOutput<'_>, rusqlite::Error> {
  7. self.id.to_sql()
  8. }
  9. }
  10. #[derive(Debug)]
  11. pub struct WithID<T: crate::model::Entity> {
  12. wrap: T,
  13. id: ID,
  14. }
  15. impl<T: crate::model::Entity> WithID<T> {
  16. fn wrap(what: T, raw_id: i64) -> Self {
  17. Self {
  18. wrap: what,
  19. id: ID { id: raw_id }
  20. }
  21. }
  22. }
  23. impl<T: crate::model::Entity> WithID<T> {
  24. pub fn id(&self) -> ID {
  25. self.id
  26. }
  27. }
  28. impl<T: crate::model::Entity> AsRef<T> for WithID<T> {
  29. fn as_ref(&self) -> &T {
  30. &self.wrap
  31. }
  32. }
  33. impl<T: crate::model::Entity> std::ops::Deref for WithID<T> {
  34. type Target = T;
  35. fn deref(&self) -> &Self::Target {
  36. &self.wrap
  37. }
  38. }
  39. impl<T: crate::model::Entity> std::ops::DerefMut for WithID<T> {
  40. fn deref_mut(&mut self) -> &mut Self::Target {
  41. &mut self.wrap
  42. }
  43. }
  44. /// Search for an entity by a property
  45. pub fn get_one_by<T: crate::model::Entity<Column = C>, C: crate::model::EntityColumns<Entity = T>, V: rusqlite::ToSql>(
  46. db: &DB,
  47. c: C,
  48. val: V,
  49. ) -> Option<WithID<T>> {
  50. let table_name = <T as crate::model::Entity>::table_name();
  51. let column_name = <T as crate::model::Entity>::name(c);
  52. let mut prepared = db
  53. .conn
  54. .prepare(&format!(
  55. "SELECT rowid, tbl.* FROM {} tbl WHERE {} = ?1",
  56. table_name, column_name
  57. ))
  58. .ok()?;
  59. let result = prepared.query_row([&val], |row| {
  60. let mut deser = crate::model::load::RowDeserializer::from_row(row);
  61. Ok(WithID::wrap(
  62. T::deserialize(&mut deser).expect("deserialization works"),
  63. row.get(0).expect("can get rowid"),
  64. ))
  65. });
  66. result.ok()
  67. }
  68. /// Search for all entities matching a property
  69. pub fn get_all_by<T: crate::model::Entity<Column = C>, C: crate::model::EntityColumns<Entity = T>, V: rusqlite::ToSql>(
  70. db: &DB,
  71. c: C,
  72. val: V) -> Option<Vec<WithID<T>>> {
  73. let table_name = <T as crate::model::Entity>::table_name();
  74. let column_name = <T as crate::model::Entity>::name(c);
  75. let mut prepared = db
  76. .conn
  77. .prepare(&format!(
  78. "SELECT rowid, tbl.* FROM {} tbl WHERE {} = ?1",
  79. table_name, column_name
  80. ))
  81. .ok()?;
  82. let rows = prepared.query_map([&val], |row| {
  83. let mut deser = crate::model::load::RowDeserializer::from_row(row);
  84. Ok(WithID::wrap(
  85. T::deserialize(&mut deser)?,
  86. row.get(0).expect("can get rowid"),
  87. ))
  88. }).ok()?;
  89. Some(rows.map(|x| x.unwrap()).collect())
  90. }
  91. /// Search for an entity by ID
  92. pub fn get_one_by_id<T: crate::model::Entity>(
  93. db: &DB,
  94. id: ID
  95. ) -> Option<WithID<T>> {
  96. let table_name = <T as crate::model::Entity>::table_name();
  97. let mut prepared = db
  98. .conn
  99. .prepare(&format!(
  100. "SELECT rowid, tbl.* FROM {} tbl WHERE rowid = ?1",
  101. table_name
  102. ))
  103. .ok()?;
  104. let result = prepared.query_row([&id], |row| {
  105. let mut deser = crate::model::load::RowDeserializer::from_row(row);
  106. Ok(WithID::wrap(
  107. T::deserialize(&mut deser).expect("deserialization works"),
  108. row.get(0).expect("can get rowid"),
  109. ))
  110. });
  111. result.ok()
  112. }
  113. /// Add an entity to its table
  114. pub fn add<T: crate::model::Entity + serde::Serialize>(db: &DB, m: &T) -> Option<ID> {
  115. let row = crate::model::store::serialize_as_row(m);
  116. let placeholders = (0..<T as crate::model::Entity>::column_count())
  117. .map(|n| format!("?{}", n + 1))
  118. .collect::<Vec<_>>()
  119. .join(",");
  120. let res = db.conn.prepare(&format!(
  121. "INSERT INTO {} VALUES ({})",
  122. <T as crate::model::Entity>::table_name(),
  123. placeholders
  124. ));
  125. let mut prepared = res.ok()?;
  126. // make sure we bound enough things
  127. assert_eq!(row.len(), <T as crate::model::Entity>::column_count());
  128. let id = prepared.insert(rusqlite::params_from_iter(row)).ok()?;
  129. Some(ID {id})
  130. }