mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 18:11:09 +00:00
use newtypes for all ids
This commit is contained in:
parent
7d8954ecd1
commit
639ca1704f
14 changed files with 102 additions and 54 deletions
|
@ -1,2 +1 @@
|
||||||
ALTER TABLE conflict DROP CONSTRAINT conflict_creator_id_fkey;
|
select 1;
|
||||||
ALTER TABLE conflict ADD CONSTRAINT conflict_creator_id_fkey FOREIGN KEY (creator_id) REFERENCES local_user(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
|
|
@ -7,7 +7,13 @@ use crate::{
|
||||||
error::MyResult,
|
error::MyResult,
|
||||||
federation::objects::edits_collection::DbEditCollection,
|
federation::objects::edits_collection::DbEditCollection,
|
||||||
},
|
},
|
||||||
common::{ArticleView, DbArticle, DbEdit, EditVersion},
|
common::{
|
||||||
|
newtypes::{ArticleId, InstanceId},
|
||||||
|
ArticleView,
|
||||||
|
DbArticle,
|
||||||
|
DbEdit,
|
||||||
|
EditVersion,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId};
|
use activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId};
|
||||||
use diesel::{
|
use diesel::{
|
||||||
|
@ -29,7 +35,7 @@ pub struct DbArticleForm {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub ap_id: ObjectId<DbArticle>,
|
pub ap_id: ObjectId<DbArticle>,
|
||||||
pub instance_id: i32,
|
pub instance_id: InstanceId,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub protected: bool,
|
pub protected: bool,
|
||||||
}
|
}
|
||||||
|
@ -59,26 +65,26 @@ impl DbArticle {
|
||||||
.get_result(conn.deref_mut())?)
|
.get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_text(id: i32, text: &str, data: &IbisData) -> MyResult<Self> {
|
pub fn update_text(id: ArticleId, text: &str, data: &IbisData) -> MyResult<Self> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
Ok(diesel::update(article::dsl::article.find(id))
|
Ok(diesel::update(article::dsl::article.find(id))
|
||||||
.set(article::dsl::text.eq(text))
|
.set(article::dsl::text.eq(text))
|
||||||
.get_result::<Self>(conn.deref_mut())?)
|
.get_result::<Self>(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_protected(id: i32, locked: bool, data: &IbisData) -> MyResult<Self> {
|
pub fn update_protected(id: ArticleId, locked: bool, data: &IbisData) -> MyResult<Self> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
Ok(diesel::update(article::dsl::article.find(id))
|
Ok(diesel::update(article::dsl::article.find(id))
|
||||||
.set(article::dsl::protected.eq(locked))
|
.set(article::dsl::protected.eq(locked))
|
||||||
.get_result::<Self>(conn.deref_mut())?)
|
.get_result::<Self>(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(id: i32, data: &IbisData) -> MyResult<Self> {
|
pub fn read(id: ArticleId, data: &IbisData) -> MyResult<Self> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
Ok(article::table.find(id).get_result(conn.deref_mut())?)
|
Ok(article::table.find(id).get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_view(id: i32, data: &IbisData) -> MyResult<ArticleView> {
|
pub fn read_view(id: ArticleId, data: &IbisData) -> MyResult<ArticleView> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
let article: DbArticle = { article::table.find(id).get_result(conn.deref_mut())? };
|
let article: DbArticle = { article::table.find(id).get_result(conn.deref_mut())? };
|
||||||
let latest_version = article.latest_edit_version(data)?;
|
let latest_version = article.latest_edit_version(data)?;
|
||||||
|
@ -139,7 +145,7 @@ impl DbArticle {
|
||||||
/// TODO: Should get rid of only_local param and rely on instance_id
|
/// TODO: Should get rid of only_local param and rely on instance_id
|
||||||
pub fn read_all(
|
pub fn read_all(
|
||||||
only_local: Option<bool>,
|
only_local: Option<bool>,
|
||||||
instance_id: Option<i32>,
|
instance_id: Option<InstanceId>,
|
||||||
data: &IbisData,
|
data: &IbisData,
|
||||||
) -> MyResult<Vec<Self>> {
|
) -> MyResult<Vec<Self>> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
|
|
|
@ -5,9 +5,15 @@ use crate::{
|
||||||
federation::activities::submit_article_update,
|
federation::activities::submit_article_update,
|
||||||
utils::generate_article_version,
|
utils::generate_article_version,
|
||||||
},
|
},
|
||||||
common::{ApiConflict, DbArticle, DbEdit, DbPerson, EditVersion},
|
common::{
|
||||||
|
newtypes::{ArticleId, ConflictId, PersonId},
|
||||||
|
ApiConflict,
|
||||||
|
DbArticle,
|
||||||
|
DbEdit,
|
||||||
|
DbPerson,
|
||||||
|
EditVersion,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use crate::common::newtypes::PersonId;
|
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use diesel::{
|
use diesel::{
|
||||||
delete,
|
delete,
|
||||||
|
@ -29,12 +35,12 @@ use std::ops::DerefMut;
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Queryable, Selectable, Identifiable)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Queryable, Selectable, Identifiable)]
|
||||||
#[diesel(table_name = conflict, check_for_backend(diesel::pg::Pg), belongs_to(DbArticle, foreign_key = article_id))]
|
#[diesel(table_name = conflict, check_for_backend(diesel::pg::Pg), belongs_to(DbArticle, foreign_key = article_id))]
|
||||||
pub struct DbConflict {
|
pub struct DbConflict {
|
||||||
pub id: i32,
|
pub id: ConflictId,
|
||||||
pub hash: EditVersion,
|
pub hash: EditVersion,
|
||||||
pub diff: String,
|
pub diff: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
pub creator_id: PersonId,
|
pub creator_id: PersonId,
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
pub previous_version_id: EditVersion,
|
pub previous_version_id: EditVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +51,7 @@ pub struct DbConflictForm {
|
||||||
pub diff: String,
|
pub diff: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
pub creator_id: PersonId,
|
pub creator_id: PersonId,
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
pub previous_version_id: EditVersion,
|
pub previous_version_id: EditVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +71,7 @@ impl DbConflict {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a merge conflict after it is resolved.
|
/// Delete a merge conflict after it is resolved.
|
||||||
pub fn delete(id: i32, data: &IbisData) -> MyResult<Self> {
|
pub fn delete(id: ConflictId, data: &IbisData) -> MyResult<Self> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
Ok(delete(conflict::table.find(id)).get_result(conn.deref_mut())?)
|
Ok(delete(conflict::table.find(id)).get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,19 @@ use crate::{
|
||||||
error::MyResult,
|
error::MyResult,
|
||||||
IbisData,
|
IbisData,
|
||||||
},
|
},
|
||||||
common::{DbArticle, DbEdit, EditVersion, EditView},
|
common::{
|
||||||
|
newtypes::{ArticleId, PersonId},
|
||||||
|
DbArticle,
|
||||||
|
DbEdit,
|
||||||
|
EditVersion,
|
||||||
|
EditView,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use activitypub_federation::fetch::object_id::ObjectId;
|
use activitypub_federation::fetch::object_id::ObjectId;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use diesel::{insert_into, AsChangeset, ExpressionMethods, Insertable, QueryDsl, RunQueryDsl};
|
use diesel::{insert_into, AsChangeset, ExpressionMethods, Insertable, QueryDsl, RunQueryDsl};
|
||||||
use diffy::create_patch;
|
use diffy::create_patch;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use crate::common::newtypes::PersonId;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Insertable, AsChangeset)]
|
#[derive(Debug, Clone, Insertable, AsChangeset)]
|
||||||
#[diesel(table_name = edit, check_for_backend(diesel::pg::Pg))]
|
#[diesel(table_name = edit, check_for_backend(diesel::pg::Pg))]
|
||||||
|
@ -21,7 +26,7 @@ pub struct DbEditForm {
|
||||||
pub ap_id: ObjectId<DbEdit>,
|
pub ap_id: ObjectId<DbEdit>,
|
||||||
pub diff: String,
|
pub diff: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
pub previous_version_id: EditVersion,
|
pub previous_version_id: EditVersion,
|
||||||
pub created: DateTime<Utc>,
|
pub created: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
instance_collection::DbInstanceCollection,
|
instance_collection::DbInstanceCollection,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
common::{DbInstance, DbPerson, InstanceView},
|
common::{newtypes::InstanceId, DbInstance, DbPerson, InstanceView},
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
||||||
|
@ -54,7 +54,7 @@ impl DbInstance {
|
||||||
.get_result(conn.deref_mut())?)
|
.get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(id: i32, data: &IbisData) -> MyResult<Self> {
|
pub fn read(id: InstanceId, data: &IbisData) -> MyResult<Self> {
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
Ok(instance::table.find(id).get_result(conn.deref_mut())?)
|
Ok(instance::table.find(id).get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ impl DbInstance {
|
||||||
.get_result(conn.deref_mut())?)
|
.get_result(conn.deref_mut())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_view(id: Option<i32>, data: &Data<IbisData>) -> MyResult<InstanceView> {
|
pub fn read_view(id: Option<InstanceId>, data: &Data<IbisData>) -> MyResult<InstanceView> {
|
||||||
let instance = match id {
|
let instance = match id {
|
||||||
Some(id) => DbInstance::read(id, data),
|
Some(id) => DbInstance::read(id, data),
|
||||||
None => DbInstance::read_local_instance(data),
|
None => DbInstance::read_local_instance(data),
|
||||||
|
@ -113,7 +113,7 @@ impl DbInstance {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_followers(id_: i32, data: &IbisData) -> MyResult<Vec<DbPerson>> {
|
pub fn read_followers(id_: InstanceId, data: &IbisData) -> MyResult<Vec<DbPerson>> {
|
||||||
use crate::backend::database::schema::person;
|
use crate::backend::database::schema::person;
|
||||||
use instance_follow::dsl::{follower_id, instance_id};
|
use instance_follow::dsl::{follower_id, instance_id};
|
||||||
let mut conn = data.db_pool.get()?;
|
let mut conn = data.db_pool.get()?;
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
error::MyResult,
|
error::MyResult,
|
||||||
},
|
},
|
||||||
common::{
|
common::{
|
||||||
|
newtypes::PersonId,
|
||||||
utils::http_protocol_str,
|
utils::http_protocol_str,
|
||||||
DbInstance,
|
DbInstance,
|
||||||
DbLocalUser,
|
DbLocalUser,
|
||||||
|
@ -14,7 +15,6 @@ use crate::{
|
||||||
LocalUserView,
|
LocalUserView,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::common::newtypes::PersonId;
|
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
|
|
|
@ -7,11 +7,16 @@ use crate::{
|
||||||
update_remote_article::UpdateRemoteArticle,
|
update_remote_article::UpdateRemoteArticle,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
common::{DbArticle, DbEdit, DbInstance, EditVersion},
|
common::{
|
||||||
|
newtypes::{EditId, PersonId},
|
||||||
|
DbArticle,
|
||||||
|
DbEdit,
|
||||||
|
DbInstance,
|
||||||
|
EditVersion,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use crate::common::newtypes::PersonId;
|
|
||||||
|
|
||||||
pub mod accept;
|
pub mod accept;
|
||||||
pub mod create_article;
|
pub mod create_article;
|
||||||
|
@ -43,7 +48,7 @@ pub async fn submit_article_update(
|
||||||
} else {
|
} else {
|
||||||
// dont insert edit into db, might be invalid in case of conflict
|
// dont insert edit into db, might be invalid in case of conflict
|
||||||
let edit = DbEdit {
|
let edit = DbEdit {
|
||||||
id: -1,
|
id: EditId(-1),
|
||||||
creator_id,
|
creator_id,
|
||||||
hash: form.hash,
|
hash: form.hash,
|
||||||
ap_id: form.ap_id,
|
ap_id: form.ap_id,
|
||||||
|
|
|
@ -46,7 +46,11 @@ pub fn generate_article_version(edits: &Vec<EditView>, version: &EditVersion) ->
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::common::{newtypes::PersonId, DbEdit, DbPerson};
|
use crate::common::{
|
||||||
|
newtypes::{ArticleId, EditId, PersonId},
|
||||||
|
DbEdit,
|
||||||
|
DbPerson,
|
||||||
|
};
|
||||||
use activitypub_federation::fetch::object_id::ObjectId;
|
use activitypub_federation::fetch::object_id::ObjectId;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use diffy::create_patch;
|
use diffy::create_patch;
|
||||||
|
@ -56,13 +60,13 @@ mod test {
|
||||||
let diff = create_patch(a, b).to_string();
|
let diff = create_patch(a, b).to_string();
|
||||||
Ok(EditView {
|
Ok(EditView {
|
||||||
edit: DbEdit {
|
edit: DbEdit {
|
||||||
id: 0,
|
id: EditId(0),
|
||||||
creator_id: PersonId(0),
|
creator_id: PersonId(0),
|
||||||
hash: EditVersion::new(&diff),
|
hash: EditVersion::new(&diff),
|
||||||
ap_id: ObjectId::parse("http://example.com")?,
|
ap_id: ObjectId::parse("http://example.com")?,
|
||||||
diff,
|
diff,
|
||||||
summary: String::new(),
|
summary: String::new(),
|
||||||
article_id: 0,
|
article_id: ArticleId(0),
|
||||||
previous_version_id: Default::default(),
|
previous_version_id: Default::default(),
|
||||||
created: Utc::now(),
|
created: Utc::now(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,7 +3,7 @@ pub mod utils;
|
||||||
pub mod validation;
|
pub mod validation;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use newtypes::PersonId;
|
use newtypes::{ArticleId, ConflictId, EditId, InstanceId, PersonId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -26,13 +26,13 @@ pub const MAIN_PAGE_NAME: &str = "Main_Page";
|
||||||
pub struct GetArticleForm {
|
pub struct GetArticleForm {
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
pub domain: Option<String>,
|
pub domain: Option<String>,
|
||||||
pub id: Option<i32>,
|
pub id: Option<ArticleId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone)]
|
||||||
pub struct ListArticlesForm {
|
pub struct ListArticlesForm {
|
||||||
pub only_local: Option<bool>,
|
pub only_local: Option<bool>,
|
||||||
pub instance_id: Option<i32>,
|
pub instance_id: Option<InstanceId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
@ -48,14 +48,14 @@ pub struct ArticleView {
|
||||||
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
||||||
#[cfg_attr(feature = "ssr", diesel(table_name = article, check_for_backend(diesel::pg::Pg), belongs_to(DbInstance, foreign_key = instance_id)))]
|
#[cfg_attr(feature = "ssr", diesel(table_name = article, check_for_backend(diesel::pg::Pg), belongs_to(DbInstance, foreign_key = instance_id)))]
|
||||||
pub struct DbArticle {
|
pub struct DbArticle {
|
||||||
pub id: i32,
|
pub id: ArticleId,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
pub ap_id: ObjectId<DbArticle>,
|
pub ap_id: ObjectId<DbArticle>,
|
||||||
#[cfg(not(feature = "ssr"))]
|
#[cfg(not(feature = "ssr"))]
|
||||||
pub ap_id: String,
|
pub ap_id: String,
|
||||||
pub instance_id: i32,
|
pub instance_id: InstanceId,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub protected: bool,
|
pub protected: bool,
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ pub struct DbArticle {
|
||||||
pub struct DbEdit {
|
pub struct DbEdit {
|
||||||
// TODO: we could use hash as primary key, but that gives errors on forking because
|
// TODO: we could use hash as primary key, but that gives errors on forking because
|
||||||
// the same edit is used for multiple articles
|
// the same edit is used for multiple articles
|
||||||
pub id: i32,
|
pub id: EditId,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub creator_id: PersonId,
|
pub creator_id: PersonId,
|
||||||
/// UUID built from sha224 hash of diff
|
/// UUID built from sha224 hash of diff
|
||||||
|
@ -78,7 +78,7 @@ pub struct DbEdit {
|
||||||
pub ap_id: String,
|
pub ap_id: String,
|
||||||
pub diff: String,
|
pub diff: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
/// First edit of an article always has `EditVersion::default()` here
|
/// First edit of an article always has `EditVersion::default()` here
|
||||||
pub previous_version_id: EditVersion,
|
pub previous_version_id: EditVersion,
|
||||||
pub created: DateTime<Utc>,
|
pub created: DateTime<Utc>,
|
||||||
|
@ -145,10 +145,10 @@ pub struct LocalUserView {
|
||||||
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
||||||
#[cfg_attr(feature = "ssr", diesel(table_name = local_user, check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "ssr", diesel(table_name = local_user, check_for_backend(diesel::pg::Pg)))]
|
||||||
pub struct DbLocalUser {
|
pub struct DbLocalUser {
|
||||||
pub id: i32,
|
pub id: InstanceId,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub password_encrypted: String,
|
pub password_encrypted: String,
|
||||||
pub person_id: i32,
|
pub person_id: PersonId,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ pub struct CreateArticleForm {
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct EditArticleForm {
|
pub struct EditArticleForm {
|
||||||
/// Id of the article to edit
|
/// Id of the article to edit
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
/// Full, new text of the article. A diff against `previous_version` is generated on the backend
|
/// Full, new text of the article. A diff against `previous_version` is generated on the backend
|
||||||
/// side to handle conflicts.
|
/// side to handle conflicts.
|
||||||
pub new_text: String,
|
pub new_text: String,
|
||||||
|
@ -199,29 +199,29 @@ pub struct EditArticleForm {
|
||||||
/// [ApiConflict.previous_version]
|
/// [ApiConflict.previous_version]
|
||||||
pub previous_version_id: EditVersion,
|
pub previous_version_id: EditVersion,
|
||||||
/// If you are resolving a conflict, pass the id to delete conflict from the database
|
/// If you are resolving a conflict, pass the id to delete conflict from the database
|
||||||
pub resolve_conflict_id: Option<i32>,
|
pub resolve_conflict_id: Option<ConflictId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct ProtectArticleForm {
|
pub struct ProtectArticleForm {
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
pub protected: bool,
|
pub protected: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct ForkArticleForm {
|
pub struct ForkArticleForm {
|
||||||
pub article_id: i32,
|
pub article_id: ArticleId,
|
||||||
pub new_title: String,
|
pub new_title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct GetInstance {
|
pub struct GetInstance {
|
||||||
pub id: Option<i32>,
|
pub id: Option<InstanceId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct FollowInstance {
|
pub struct FollowInstance {
|
||||||
pub id: i32,
|
pub id: InstanceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone)]
|
||||||
|
@ -236,7 +236,7 @@ pub struct ResolveObject {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct ApiConflict {
|
pub struct ApiConflict {
|
||||||
pub id: i32,
|
pub id: ConflictId,
|
||||||
pub hash: EditVersion,
|
pub hash: EditVersion,
|
||||||
pub three_way_merge: String,
|
pub three_way_merge: String,
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
|
@ -248,7 +248,7 @@ pub struct ApiConflict {
|
||||||
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Identifiable))]
|
||||||
#[cfg_attr(feature = "ssr", diesel(table_name = instance, check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "ssr", diesel(table_name = instance, check_for_backend(diesel::pg::Pg)))]
|
||||||
pub struct DbInstance {
|
pub struct DbInstance {
|
||||||
pub id: i32,
|
pub id: InstanceId,
|
||||||
pub domain: String,
|
pub domain: String,
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
pub ap_id: ObjectId<DbInstance>,
|
pub ap_id: ObjectId<DbInstance>,
|
||||||
|
|
23
src/common/newtypes.rs
Normal file
23
src/common/newtypes.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
use diesel_derive_newtype::DieselNewType;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(DieselNewType))]
|
||||||
|
pub struct PersonId(pub i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(DieselNewType))]
|
||||||
|
pub struct ArticleId(pub i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(DieselNewType))]
|
||||||
|
pub struct EditId(pub i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(DieselNewType))]
|
||||||
|
pub struct InstanceId(pub i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(DieselNewType))]
|
||||||
|
pub struct ConflictId(pub i32);
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{DbInstance, FollowInstance},
|
common::{newtypes::InstanceId, DbInstance, FollowInstance},
|
||||||
frontend::app::GlobalState,
|
frontend::app::GlobalState,
|
||||||
};
|
};
|
||||||
use leptos::{component, *};
|
use leptos::{component, *};
|
||||||
|
@ -7,7 +7,7 @@ use leptos::{component, *};
|
||||||
#[component]
|
#[component]
|
||||||
pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView {
|
pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView {
|
||||||
let global_state = use_context::<RwSignal<GlobalState>>().unwrap();
|
let global_state = use_context::<RwSignal<GlobalState>>().unwrap();
|
||||||
let follow_action = create_action(move |instance_id: &i32| {
|
let follow_action = create_action(move |instance_id: &InstanceId| {
|
||||||
let instance_id = *instance_id;
|
let instance_id = *instance_id;
|
||||||
async move {
|
async move {
|
||||||
let form = FollowInstance { id: instance_id };
|
let form = FollowInstance { id: instance_id };
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{ForkArticleForm, ProtectArticleForm},
|
common::{newtypes::ArticleId, ForkArticleForm, ProtectArticleForm},
|
||||||
frontend::{
|
frontend::{
|
||||||
app::GlobalState,
|
app::GlobalState,
|
||||||
article_link,
|
article_link,
|
||||||
|
@ -18,7 +18,7 @@ pub fn ArticleActions() -> impl IntoView {
|
||||||
let (new_title, set_new_title) = create_signal(String::new());
|
let (new_title, set_new_title) = create_signal(String::new());
|
||||||
let (fork_response, set_fork_response) = create_signal(Option::<DbArticle>::None);
|
let (fork_response, set_fork_response) = create_signal(Option::<DbArticle>::None);
|
||||||
let (error, set_error) = create_signal(None::<String>);
|
let (error, set_error) = create_signal(None::<String>);
|
||||||
let fork_action = create_action(move |(article_id, new_title): &(i32, String)| {
|
let fork_action = create_action(move |(article_id, new_title): &(ArticleId, String)| {
|
||||||
let params = ForkArticleForm {
|
let params = ForkArticleForm {
|
||||||
article_id: *article_id,
|
article_id: *article_id,
|
||||||
new_title: new_title.to_string(),
|
new_title: new_title.to_string(),
|
||||||
|
@ -34,7 +34,7 @@ pub fn ArticleActions() -> impl IntoView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let protect_action = create_action(move |(id, protected): &(i32, bool)| {
|
let protect_action = create_action(move |(id, protected): &(ArticleId, bool)| {
|
||||||
let params = ProtectArticleForm {
|
let params = ProtectArticleForm {
|
||||||
article_id: *id,
|
article_id: *id,
|
||||||
protected: !protected,
|
protected: !protected,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{ApiConflict, ArticleView, EditArticleForm},
|
common::{newtypes::ConflictId, ApiConflict, ArticleView, EditArticleForm},
|
||||||
frontend::{
|
frontend::{
|
||||||
app::GlobalState,
|
app::GlobalState,
|
||||||
components::{
|
components::{
|
||||||
|
@ -32,7 +32,7 @@ pub fn EditArticle() -> impl IntoView {
|
||||||
let conflict_id = move || use_params_map().get_untracked().get("conflict_id").cloned();
|
let conflict_id = move || use_params_map().get_untracked().get("conflict_id").cloned();
|
||||||
if let Some(conflict_id) = conflict_id() {
|
if let Some(conflict_id) = conflict_id() {
|
||||||
create_action(move |conflict_id: &String| {
|
create_action(move |conflict_id: &String| {
|
||||||
let conflict_id: i32 = conflict_id.parse().unwrap();
|
let conflict_id = ConflictId(conflict_id.parse().unwrap());
|
||||||
async move {
|
async move {
|
||||||
let conflict = GlobalState::api_client()
|
let conflict = GlobalState::api_client()
|
||||||
.get_conflicts()
|
.get_conflicts()
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub fn Conflicts() -> impl IntoView {
|
||||||
let link = format!(
|
let link = format!(
|
||||||
"{}/edit/{}",
|
"{}/edit/{}",
|
||||||
article_link(&c.article),
|
article_link(&c.article),
|
||||||
c.id,
|
c.id.0,
|
||||||
);
|
);
|
||||||
view! {
|
view! {
|
||||||
<li>
|
<li>
|
||||||
|
|
Loading…
Reference in a new issue