Schema: add follows, blocks, split lib.rs
This commit is contained in:
parent
b8c6c4e13a
commit
c9d988bdd2
84
schema/src/account.rs
Normal file
84
schema/src/account.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use crate::keys::{Created, DatetimeKey, TaggedKey, Updated, UuidKey};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{
|
||||
view::{map::Mappings, CollectionViewSchema},
|
||||
Collection, ReduceResult, View, ViewMapResult,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "accounts",
|
||||
views = [AccountsByUsername, AccountsByEmail],
|
||||
primary_key = TaggedKey<UuidKey, Account>,
|
||||
natural_id = |account: &Account| Some(account.id)
|
||||
)]
|
||||
pub struct Account {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
username: String,
|
||||
emails: Vec<String>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Account, key = String, value = usize, name = "accounts-by-username")]
|
||||
pub struct AccountsByUsername;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Account, key = String, value = usize, name = "accounts-by-email")]
|
||||
pub struct AccountsByEmail;
|
||||
|
||||
impl CollectionViewSchema for AccountsByUsername {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.username, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for AccountsByEmail {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.emails.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
for email in document.contents.emails {
|
||||
mappings.extend(document.header.emit_key_and_value(email, 1)?);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
96
schema/src/block.rs
Normal file
96
schema/src/block.rs
Normal file
|
@ -0,0 +1,96 @@
|
|||
use crate::{
|
||||
keys::{CompoundKey, Created, DatetimeKey, KeyExt, TaggedKey, Updated, UuidKey},
|
||||
profile::Profile,
|
||||
};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{view::CollectionViewSchema, Collection, ReduceResult, View, ViewMapResult},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "blocks",
|
||||
views = [BlocksByAccount, BlockersByAccount],
|
||||
primary_key = TaggedKey<UuidKey, Block>,
|
||||
natural_id = |block: &Block| Some(block.id)
|
||||
)]
|
||||
pub struct Block {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
target_profile: TaggedKey<UuidKey, Profile>,
|
||||
actor_profile: TaggedKey<UuidKey, Profile>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
pub type AccountBlocksKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Updated>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
pub type AccountBlockersKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Updated>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Block, key = AccountBlocksKey, value = usize, name = "blocks-by-account")]
|
||||
pub struct BlocksByAccount;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Block, key = AccountBlockersKey, value = usize, name = "blockers-by-account")]
|
||||
pub struct BlockersByAccount;
|
||||
|
||||
impl CollectionViewSchema for BlockersByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.target_profile
|
||||
.compound(document.contents.updated_at)
|
||||
.compound(document.contents.actor_profile),
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for BlocksByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.actor_profile
|
||||
.compound(document.contents.updated_at)
|
||||
.compound(document.contents.target_profile),
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
187
schema/src/follow.rs
Normal file
187
schema/src/follow.rs
Normal file
|
@ -0,0 +1,187 @@
|
|||
use crate::{
|
||||
keys::{CompoundKey, Created, DatetimeKey, KeyExt, TaggedKey, Updated, UuidKey},
|
||||
profile::Profile,
|
||||
};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{
|
||||
view::{map::Mappings, CollectionViewSchema},
|
||||
Collection, ReduceResult, View, ViewMapResult,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "follows",
|
||||
views = [FollowsByAccount, FollowersByAccount, InboundFollowRequestsByAccount, OutboundFollowRequestsByAccount],
|
||||
primary_key = TaggedKey<UuidKey, Follow>,
|
||||
natural_id = |follow: &Follow| Some(follow.id)
|
||||
)]
|
||||
pub struct Follow {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
confirmed: bool,
|
||||
|
||||
target_profile: TaggedKey<UuidKey, Profile>,
|
||||
actor_profile: TaggedKey<UuidKey, Profile>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
pub type AccountFollowsKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Updated>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
pub type AccountFollowersKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Updated>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
pub type AccountInboundFollowRequestsKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Created>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
pub type AccountOutboundFollowRequestsKey = CompoundKey<
|
||||
CompoundKey<TaggedKey<UuidKey, Profile>, TaggedKey<DatetimeKey, Created>>,
|
||||
TaggedKey<UuidKey, Profile>,
|
||||
>;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Follow, key = AccountFollowsKey, value = usize, name = "follows-by-account")]
|
||||
pub struct FollowsByAccount;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Follow, key = AccountFollowersKey, value = usize, name = "followers-by-account")]
|
||||
pub struct FollowersByAccount;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Follow, key = AccountInboundFollowRequestsKey, value = usize, name = "inbound-follow-requests-by-account")]
|
||||
pub struct InboundFollowRequestsByAccount;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Follow, key = AccountOutboundFollowRequestsKey, value = usize, name = "outbound-follow-requests-by-account")]
|
||||
pub struct OutboundFollowRequestsByAccount;
|
||||
|
||||
impl CollectionViewSchema for FollowersByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.confirmed {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.target_profile
|
||||
.compound(document.contents.updated_at)
|
||||
.compound(document.contents.actor_profile),
|
||||
1,
|
||||
)
|
||||
} else {
|
||||
Ok(Mappings::none())
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for FollowsByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.confirmed {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.actor_profile
|
||||
.compound(document.contents.updated_at)
|
||||
.compound(document.contents.target_profile),
|
||||
1,
|
||||
)
|
||||
} else {
|
||||
Ok(Mappings::none())
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for InboundFollowRequestsByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.confirmed {
|
||||
Ok(Mappings::none())
|
||||
} else {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.target_profile
|
||||
.compound(document.contents.created_at)
|
||||
.compound(document.contents.actor_profile),
|
||||
1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for OutboundFollowRequestsByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.confirmed {
|
||||
Ok(Mappings::none())
|
||||
} else {
|
||||
document.header.emit_key_and_value(
|
||||
document
|
||||
.contents
|
||||
.actor_profile
|
||||
.compound(document.contents.created_at)
|
||||
.compound(document.contents.target_profile),
|
||||
1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
|
@ -1,468 +1,35 @@
|
|||
pub mod account;
|
||||
pub mod block;
|
||||
pub mod follow;
|
||||
pub mod keys;
|
||||
pub mod media;
|
||||
pub mod post;
|
||||
pub mod profile;
|
||||
pub mod report;
|
||||
pub mod tag;
|
||||
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{
|
||||
view::{map::Mappings, CollectionViewSchema},
|
||||
Collection, ReduceResult, Schema, View, ViewMapResult,
|
||||
},
|
||||
};
|
||||
use keys::{Created, DatetimeKey, KeyExt, ProfileKind, ReportState, TaggedKey, Updated, UuidKey};
|
||||
use account::Account;
|
||||
use block::Block;
|
||||
use bonsaidb::core::schema::Schema;
|
||||
use follow::Follow;
|
||||
use media::Media;
|
||||
use post::Post;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use profile::Profile;
|
||||
use report::Report;
|
||||
use tag::Tag;
|
||||
|
||||
#[derive(Debug, Schema)]
|
||||
#[schema(
|
||||
name = "SiteSchema",
|
||||
collections = [
|
||||
Account,
|
||||
Profile,
|
||||
Block,
|
||||
Follow,
|
||||
Media,
|
||||
Post,
|
||||
Tag,
|
||||
Profile,
|
||||
Report,
|
||||
Tag,
|
||||
]
|
||||
)]
|
||||
pub struct SiteSchema;
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "accounts",
|
||||
views = [AccountsByUsername, AccountsByEmail],
|
||||
primary_key = TaggedKey<UuidKey, Account>,
|
||||
natural_id = |account: &Account| Some(account.id)
|
||||
)]
|
||||
pub struct Account {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
username: String,
|
||||
emails: Vec<String>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "profiles",
|
||||
views = [ProfilesByHandle, RemoteProfilesByDomain, LocalProfilesById, ProfilesByCollaborator, ProfilesByKind],
|
||||
primary_key = TaggedKey<UuidKey, Profile>,
|
||||
natural_id = |profile: &Profile| Some(profile.id)
|
||||
)]
|
||||
pub struct Profile {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
kind: ProfileKind,
|
||||
|
||||
handle: String,
|
||||
domain: Option<String>,
|
||||
full_url: Option<String>,
|
||||
|
||||
name: Option<String>,
|
||||
description: Option<String>,
|
||||
|
||||
local_account: Option<TaggedKey<UuidKey, Account>>,
|
||||
collaborators: Vec<TaggedKey<UuidKey, Profile>>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum MediaState {
|
||||
Uploading {
|
||||
upload_id: String,
|
||||
},
|
||||
Finished {
|
||||
filename: String,
|
||||
delete_token: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "media",
|
||||
views = [],
|
||||
primary_key = TaggedKey<UuidKey, Media>,
|
||||
natural_id = |media: &Media| Some(media.id)
|
||||
)]
|
||||
pub struct Media {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
state: MediaState,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "tags",
|
||||
views = [TagsByName],
|
||||
primary_key = TaggedKey<UuidKey, Tag>,
|
||||
natural_id = |tag: &Tag| Some(tag.id)
|
||||
)]
|
||||
pub struct Tag {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
name: String,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "reports",
|
||||
views = [ReportsByPost, ReportsByState, ReportsByAccount],
|
||||
primary_key = TaggedKey<UuidKey, Report>,
|
||||
natural_id = |report: &Report| Some(report.id)
|
||||
)]
|
||||
pub struct Report {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
message: Option<String>,
|
||||
moderation_note: Option<String>,
|
||||
|
||||
post: TaggedKey<UuidKey, Post>,
|
||||
|
||||
state: ReportState,
|
||||
|
||||
handled_by: Option<TaggedKey<UuidKey, Account>>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Account, key = String, value = usize, name = "by-username")]
|
||||
pub struct AccountsByUsername;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Account, key = String, value = usize, name = "by-email")]
|
||||
pub struct AccountsByEmail;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = String, value = usize, name = "by-handle")]
|
||||
pub struct ProfilesByHandle;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = Option<String>, value = usize, name = "by-remote-domain")]
|
||||
pub struct RemoteProfilesByDomain;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = Option<TaggedKey<UuidKey, Account>>, value = usize, name = "by-local-id")]
|
||||
pub struct LocalProfilesById;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = TaggedKey<UuidKey, Profile>, value = usize, name = "by-collaborator")]
|
||||
pub struct ProfilesByCollaborator;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = ProfileKind, value = usize, name = "by-kind")]
|
||||
pub struct ProfilesByKind;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Tag, key = String, value = usize, name = "by-name")]
|
||||
pub struct TagsByName;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = TaggedKey<UuidKey, Post>, value = usize, name = "by-name")]
|
||||
pub struct ReportsByPost;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = ReportState, value = usize, name = "by-state")]
|
||||
pub struct ReportsByState;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = Option<TaggedKey<UuidKey, Account>>, value = usize, name = "by-account")]
|
||||
pub struct ReportsByAccount;
|
||||
|
||||
impl CollectionViewSchema for AccountsByUsername {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.username, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for AccountsByEmail {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.emails.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
for email in document.contents.emails {
|
||||
mappings.extend(document.header.emit_key_and_value(email, 1)?);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ProfilesByHandle {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
if document.contents.handle.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
const MAX_SEARCH_LEN: usize = 16;
|
||||
|
||||
// enable searching for profiles by handle lol
|
||||
// turns 'asonix' into 'a', 'as', 'aso', 'ason', 'asoni', 'asonix'
|
||||
// cap search characters
|
||||
for i in 1..=document.contents.handle.len().min(MAX_SEARCH_LEN) {
|
||||
mappings.extend(
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handle[..i].to_owned(), 1)?,
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure we index the full handle if longer than max characters as well
|
||||
if document.contents.handle.len() > MAX_SEARCH_LEN {
|
||||
mappings.extend(
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handle, 1)?,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for RemoteProfilesByDomain {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.domain, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for LocalProfilesById {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.local_account, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ProfilesByCollaborator {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.collaborators.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
let mut mappings = Vec::new();
|
||||
for collaborator in document.contents.collaborators {
|
||||
mappings.extend(document.header.emit_key_and_value(collaborator, 1)?);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ProfilesByKind {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.kind, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for TagsByName {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.name, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ReportsByPost {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.post, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ReportsByState {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.state, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ReportsByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handled_by, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
id: UuidKey::generate().tag(),
|
||||
name,
|
||||
created_at: DatetimeKey::now().tag(),
|
||||
updated_at: DatetimeKey::now().tag(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
|
31
schema/src/media.rs
Normal file
31
schema/src/media.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use crate::keys::{Created, DatetimeKey, TaggedKey, Updated, UuidKey};
|
||||
use bonsaidb::core::schema::Collection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum MediaState {
|
||||
Uploading {
|
||||
upload_id: String,
|
||||
},
|
||||
Finished {
|
||||
filename: String,
|
||||
delete_token: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "media",
|
||||
views = [],
|
||||
primary_key = TaggedKey<UuidKey, Media>,
|
||||
natural_id = |media: &Media| Some(media.id)
|
||||
)]
|
||||
pub struct Media {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
state: MediaState,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
|
@ -72,43 +72,43 @@ pub type AuthorPostKindUnpublishedKey = CompoundKey<
|
|||
>;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = PostKind, value = usize, name = "by-kind")]
|
||||
#[view(collection = Post, key = PostKind, value = usize, name = "posts-by-kind")]
|
||||
pub struct PostsByKind;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = PostKindPublishedKey, value = usize, name = "by-kind-and-published")]
|
||||
#[view(collection = Post, key = PostKindPublishedKey, value = usize, name = "posts-by-kind-and-published")]
|
||||
pub struct PublishedPostsByKind;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Profile>, value = usize, name = "by-author")]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Profile>, value = usize, name = "posts-by-author")]
|
||||
pub struct PostsByAuthor;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = AuthorPublishedKey, value = usize, name = "by-author-and-published")]
|
||||
#[view(collection = Post, key = AuthorPublishedKey, value = usize, name = "posts-by-author-and-published")]
|
||||
pub struct PublishedPostsByAuthor;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = AuthorPostKindPublishedKey, value = usize, name = "by-author-and-published")]
|
||||
#[view(collection = Post, key = AuthorPostKindPublishedKey, value = usize, name = "posts-by-author-kind-and-published")]
|
||||
pub struct PublishedPostsByAuthorAndKind;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = AuthorUnpublishedKey, value = usize, name = "by-author-and-unpublished")]
|
||||
#[view(collection = Post, key = AuthorUnpublishedKey, value = usize, name = "posts-by-author-and-unpublished")]
|
||||
pub struct UnpublishedPostsByAuthor;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = AuthorPostKindUnpublishedKey, value = usize, name = "by-author-and-unpublished")]
|
||||
#[view(collection = Post, key = AuthorPostKindUnpublishedKey, value = usize, name = "posts-by-author-kind-and-unpublished")]
|
||||
pub struct UnpublishedPostsByAuthorAndKind;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Tag>, value = usize, name = "by-tag")]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Tag>, value = usize, name = "posts-by-tag")]
|
||||
pub struct PostsByTag;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Profile>, value = usize, name = "by-mention")]
|
||||
#[view(collection = Post, key = TaggedKey<UuidKey, Profile>, value = usize, name = "posts-by-mention")]
|
||||
pub struct PostsByMention;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Post, key = Option<TaggedKey<UuidKey, Post>>, value = usize, name = "by-parent")]
|
||||
#[view(collection = Post, key = Option<TaggedKey<UuidKey, Post>>, value = usize, name = "posts-by-parent")]
|
||||
pub struct PostsByParent;
|
||||
|
||||
impl CollectionViewSchema for PostsByKind {
|
||||
|
|
196
schema/src/profile.rs
Normal file
196
schema/src/profile.rs
Normal file
|
@ -0,0 +1,196 @@
|
|||
use crate::{
|
||||
account::Account,
|
||||
keys::{Created, DatetimeKey, ProfileKind, TaggedKey, Updated, UuidKey},
|
||||
};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{
|
||||
view::{map::Mappings, CollectionViewSchema},
|
||||
Collection, ReduceResult, View, ViewMapResult,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "profiles",
|
||||
views = [ProfilesByHandle, RemoteProfilesByDomain, LocalProfilesById, ProfilesByCollaborator, ProfilesByKind],
|
||||
primary_key = TaggedKey<UuidKey, Profile>,
|
||||
natural_id = |profile: &Profile| Some(profile.id)
|
||||
)]
|
||||
pub struct Profile {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
kind: ProfileKind,
|
||||
|
||||
handle: String,
|
||||
domain: Option<String>,
|
||||
full_url: Option<String>,
|
||||
|
||||
name: Option<String>,
|
||||
description: Option<String>,
|
||||
|
||||
local_account: Option<TaggedKey<UuidKey, Account>>,
|
||||
collaborators: Vec<TaggedKey<UuidKey, Profile>>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = String, value = usize, name = "profiles-by-handle")]
|
||||
pub struct ProfilesByHandle;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = Option<String>, value = usize, name = "profiles-by-remote-domain")]
|
||||
pub struct RemoteProfilesByDomain;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = Option<TaggedKey<UuidKey, Account>>, value = usize, name = "profiles-by-local-id")]
|
||||
pub struct LocalProfilesById;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = TaggedKey<UuidKey, Profile>, value = usize, name = "profiles-by-collaborator")]
|
||||
pub struct ProfilesByCollaborator;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Profile, key = ProfileKind, value = usize, name = "profiles-by-kind")]
|
||||
pub struct ProfilesByKind;
|
||||
|
||||
impl CollectionViewSchema for ProfilesByHandle {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
let mut mappings = Vec::new();
|
||||
|
||||
if document.contents.handle.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
const MAX_SEARCH_LEN: usize = 16;
|
||||
|
||||
// enable searching for profiles by handle lol
|
||||
// turns 'asonix' into 'asonix', 'sonix', 'onix', 'nix', 'ix', 'x'
|
||||
// cap search characters
|
||||
for i in 0..document.contents.handle.len().min(MAX_SEARCH_LEN) {
|
||||
mappings.extend(
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handle[i..].to_owned(), 1)?,
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure we index the full handle if longer than max characters as well
|
||||
if document.contents.handle.len() >= MAX_SEARCH_LEN {
|
||||
mappings.extend(
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handle, 1)?,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for RemoteProfilesByDomain {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.domain, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for LocalProfilesById {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.local_account, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ProfilesByCollaborator {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
if document.contents.collaborators.is_empty() {
|
||||
return Ok(Mappings::none());
|
||||
}
|
||||
|
||||
let mut mappings = Vec::new();
|
||||
for collaborator in document.contents.collaborators {
|
||||
mappings.extend(document.header.emit_key_and_value(collaborator, 1)?);
|
||||
}
|
||||
|
||||
Ok(Mappings::List(mappings))
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ProfilesByKind {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.kind, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
108
schema/src/report.rs
Normal file
108
schema/src/report.rs
Normal file
|
@ -0,0 +1,108 @@
|
|||
use crate::{
|
||||
account::Account,
|
||||
keys::{Created, DatetimeKey, ReportState, TaggedKey, Updated, UuidKey},
|
||||
post::Post,
|
||||
};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{view::CollectionViewSchema, Collection, ReduceResult, View, ViewMapResult},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "reports",
|
||||
views = [ReportsByPost, ReportsByState, ReportsByAccount],
|
||||
primary_key = TaggedKey<UuidKey, Report>,
|
||||
natural_id = |report: &Report| Some(report.id)
|
||||
)]
|
||||
pub struct Report {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
message: Option<String>,
|
||||
moderation_note: Option<String>,
|
||||
|
||||
post: TaggedKey<UuidKey, Post>,
|
||||
|
||||
state: ReportState,
|
||||
|
||||
handled_by: Option<TaggedKey<UuidKey, Account>>,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = TaggedKey<UuidKey, Post>, value = usize, name = "reports-by-name")]
|
||||
pub struct ReportsByPost;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = ReportState, value = usize, name = "reports-by-state")]
|
||||
pub struct ReportsByState;
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Report, key = Option<TaggedKey<UuidKey, Account>>, value = usize, name = "reports-by-account")]
|
||||
pub struct ReportsByAccount;
|
||||
|
||||
impl CollectionViewSchema for ReportsByPost {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.post, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ReportsByState {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.state, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl CollectionViewSchema for ReportsByAccount {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.handled_by, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
62
schema/src/tag.rs
Normal file
62
schema/src/tag.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use crate::keys::{Created, DatetimeKey, KeyExt, TaggedKey, Updated, UuidKey};
|
||||
use bonsaidb::core::{
|
||||
document::{CollectionDocument, Emit},
|
||||
schema::{view::CollectionViewSchema, Collection, ReduceResult, View, ViewMapResult},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Collection, Debug, Deserialize, Serialize)]
|
||||
#[collection(
|
||||
name = "tags",
|
||||
views = [TagsByName],
|
||||
primary_key = TaggedKey<UuidKey, Tag>,
|
||||
natural_id = |tag: &Tag| Some(tag.id)
|
||||
)]
|
||||
pub struct Tag {
|
||||
id: TaggedKey<UuidKey, Self>,
|
||||
|
||||
name: String,
|
||||
|
||||
created_at: TaggedKey<DatetimeKey, Created>,
|
||||
updated_at: TaggedKey<DatetimeKey, Updated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, View)]
|
||||
#[view(collection = Tag, key = String, value = usize, name = "tags-by-name")]
|
||||
pub struct TagsByName;
|
||||
|
||||
impl CollectionViewSchema for TagsByName {
|
||||
type View = Self;
|
||||
|
||||
fn map(
|
||||
&self,
|
||||
document: CollectionDocument<<Self::View as View>::Collection>,
|
||||
) -> ViewMapResult<Self::View> {
|
||||
document
|
||||
.header
|
||||
.emit_key_and_value(document.contents.name, 1)
|
||||
}
|
||||
|
||||
fn reduce(
|
||||
&self,
|
||||
mappings: &[bonsaidb::core::schema::ViewMappedValue<Self::View>],
|
||||
_rereduce: bool,
|
||||
) -> ReduceResult<Self::View> {
|
||||
Ok(mappings.iter().map(|m| m.value).sum())
|
||||
}
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
id: UuidKey::generate().tag(),
|
||||
name,
|
||||
created_at: DatetimeKey::now().tag(),
|
||||
updated_at: DatetimeKey::now().tag(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue