app_sql.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. use crate::entities::{
  2. app::{App, ColorStyle, UpdateAppParams},
  3. trash::{Trash, TrashType},
  4. view::RepeatedView,
  5. };
  6. use diesel::sql_types::Binary;
  7. use flowy_database::{
  8. prelude::*,
  9. schema::{app_table, app_table::dsl},
  10. SqliteConnection,
  11. };
  12. use serde::{Deserialize, Serialize, __private::TryFrom};
  13. use std::convert::TryInto;
  14. use crate::{errors::FlowyError, services::persistence::version_1::workspace_sql::WorkspaceTable};
  15. pub struct AppTableSql();
  16. impl AppTableSql {
  17. pub(crate) fn create_app(app: App, conn: &SqliteConnection) -> Result<(), FlowyError> {
  18. let app_table = AppTable::new(app);
  19. match diesel_record_count!(app_table, &app_table.id, conn) {
  20. 0 => diesel_insert_table!(app_table, &app_table, conn),
  21. _ => {
  22. let changeset = AppChangeset::from_table(app_table);
  23. diesel_update_table!(app_table, changeset, conn)
  24. }
  25. }
  26. Ok(())
  27. }
  28. pub(crate) fn update_app(changeset: AppChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
  29. diesel_update_table!(app_table, changeset, conn);
  30. Ok(())
  31. }
  32. pub(crate) fn read_app(app_id: &str, conn: &SqliteConnection) -> Result<AppTable, FlowyError> {
  33. let filter = dsl::app_table.filter(app_table::id.eq(app_id)).into_boxed();
  34. let app_table = filter.first::<AppTable>(conn)?;
  35. Ok(app_table)
  36. }
  37. pub(crate) fn read_workspace_apps(
  38. workspace_id: &str,
  39. conn: &SqliteConnection,
  40. ) -> Result<Vec<AppTable>, FlowyError> {
  41. let app_table = dsl::app_table
  42. .filter(app_table::workspace_id.eq(workspace_id))
  43. .order(app_table::create_time.asc())
  44. .load::<AppTable>(conn)?;
  45. Ok(app_table)
  46. }
  47. pub(crate) fn delete_app(app_id: &str, conn: &SqliteConnection) -> Result<AppTable, FlowyError> {
  48. let app_table = dsl::app_table
  49. .filter(app_table::id.eq(app_id))
  50. .first::<AppTable>(conn)?;
  51. diesel_delete_table!(app_table, app_id, conn);
  52. Ok(app_table)
  53. }
  54. // pub(crate) fn read_views_belong_to_app(
  55. // &self,
  56. // app_id: &str,
  57. // ) -> Result<Vec<ViewTable>, FlowyError> {
  58. // let conn = self.database.db_connection()?;
  59. //
  60. // let views = conn.immediate_transaction::<_, FlowyError, _>(|| {
  61. // let app_table: AppTable = dsl::app_table
  62. // .filter(app_table::id.eq(app_id))
  63. // .first::<AppTable>(&*(conn))?;
  64. // let views =
  65. // ViewTable::belonging_to(&app_table).load::<ViewTable>(&*conn)?;
  66. // Ok(views)
  67. // })?;
  68. //
  69. // Ok(views)
  70. // }
  71. }
  72. #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
  73. #[belongs_to(WorkspaceTable, foreign_key = "workspace_id")]
  74. #[table_name = "app_table"]
  75. pub(crate) struct AppTable {
  76. pub id: String,
  77. pub workspace_id: String, // equal to #[belongs_to(Workspace, foreign_key = "workspace_id")].
  78. pub name: String,
  79. pub desc: String,
  80. pub color_style: ColorStyleCol,
  81. pub last_view_id: Option<String>,
  82. pub modified_time: i64,
  83. pub create_time: i64,
  84. pub version: i64,
  85. pub is_trash: bool,
  86. }
  87. impl AppTable {
  88. pub fn new(app: App) -> Self {
  89. Self {
  90. id: app.id,
  91. workspace_id: app.workspace_id,
  92. name: app.name,
  93. desc: app.desc,
  94. color_style: ColorStyleCol::default(),
  95. last_view_id: None,
  96. modified_time: app.modified_time,
  97. create_time: app.create_time,
  98. version: 0,
  99. is_trash: false,
  100. }
  101. }
  102. }
  103. impl std::convert::From<AppTable> for Trash {
  104. fn from(table: AppTable) -> Self {
  105. Trash {
  106. id: table.id,
  107. name: table.name,
  108. modified_time: table.modified_time,
  109. create_time: table.create_time,
  110. ty: TrashType::TrashApp,
  111. }
  112. }
  113. }
  114. #[derive(Clone, PartialEq, Serialize, Deserialize, Debug, Default, FromSqlRow, AsExpression)]
  115. #[sql_type = "Binary"]
  116. pub(crate) struct ColorStyleCol {
  117. pub(crate) theme_color: String,
  118. }
  119. impl std::convert::From<ColorStyle> for ColorStyleCol {
  120. fn from(s: ColorStyle) -> Self {
  121. Self {
  122. theme_color: s.theme_color,
  123. }
  124. }
  125. }
  126. impl std::convert::TryInto<Vec<u8>> for &ColorStyleCol {
  127. type Error = String;
  128. fn try_into(self) -> Result<Vec<u8>, Self::Error> {
  129. bincode::serialize(self).map_err(|e| format!("{:?}", e))
  130. }
  131. }
  132. impl std::convert::TryFrom<&[u8]> for ColorStyleCol {
  133. type Error = String;
  134. fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
  135. bincode::deserialize(value).map_err(|e| format!("{:?}", e))
  136. }
  137. }
  138. impl_sql_binary_expression!(ColorStyleCol);
  139. #[derive(AsChangeset, Identifiable, Default, Debug)]
  140. #[table_name = "app_table"]
  141. pub struct AppChangeset {
  142. pub id: String,
  143. pub name: Option<String>,
  144. pub desc: Option<String>,
  145. pub is_trash: Option<bool>,
  146. }
  147. impl AppChangeset {
  148. pub(crate) fn new(params: UpdateAppParams) -> Self {
  149. AppChangeset {
  150. id: params.app_id,
  151. name: params.name,
  152. desc: params.desc,
  153. is_trash: params.is_trash,
  154. }
  155. }
  156. pub(crate) fn from_table(table: AppTable) -> Self {
  157. AppChangeset {
  158. id: table.id,
  159. name: Some(table.name),
  160. desc: Some(table.desc),
  161. is_trash: Some(table.is_trash),
  162. }
  163. }
  164. }
  165. impl std::convert::From<AppTable> for App {
  166. fn from(table: AppTable) -> Self {
  167. App {
  168. id: table.id,
  169. workspace_id: table.workspace_id,
  170. name: table.name,
  171. desc: table.desc,
  172. belongings: RepeatedView::default(),
  173. version: table.version,
  174. modified_time: table.modified_time,
  175. create_time: table.create_time,
  176. }
  177. }
  178. }