skynet_api 0.6.5

API for Skynet plugin.
Documentation
use std::collections::HashMap;

use crate::{HyUuid, entity::settings, request::Condition};
use anyhow::Result;
use base64::{Engine, prelude::BASE64_STANDARD};
use sea_orm::{
    ActiveModelTrait, ColumnTrait, ConnectionTrait, DatabaseTransaction, EntityTrait,
    IntoActiveModel, PaginatorTrait, QueryFilter, Set,
};
use skynet_macro::default_viewer;

pub struct SettingViewer;

#[default_viewer(settings)]
impl SettingViewer {
    pub async fn get_all<C>(db: &C) -> Result<HashMap<String, String>>
    where
        C: ConnectionTrait,
    {
        Ok(settings::Entity::find()
            .all(db)
            .await?
            .into_iter()
            .map(|x| (x.name, x.value))
            .collect())
    }

    pub async fn get<C>(db: &C, name: &str) -> Result<Option<String>>
    where
        C: ConnectionTrait,
    {
        Self::find_by_name(db, name)
            .await
            .map(|x| x.map(|x| x.value))
    }

    pub async fn get_or_init(db: &DatabaseTransaction, name: &str, value: &str) -> Result<String> {
        Self::find_or_init(db, name, value).await.map(|x| x.value)
    }

    pub async fn find_or_init(
        db: &DatabaseTransaction,
        name: &str,
        value: &str,
    ) -> Result<settings::Model> {
        match Self::find_by_name(db, name).await? {
            Some(x) => Ok(x),
            None => Ok(settings::ActiveModel {
                name: Set(name.to_owned()),
                value: Set(value.to_owned()),
                ..Default::default()
            }
            .insert(db)
            .await?),
        }
    }

    pub async fn find_by_name<C>(db: &C, name: &str) -> Result<Option<settings::Model>>
    where
        C: ConnectionTrait,
    {
        settings::Entity::find()
            .filter(settings::Column::Name.eq(name))
            .one(db)
            .await
            .map_err(Into::into)
    }

    pub async fn set(db: &DatabaseTransaction, name: &str, value: &str) -> Result<()> {
        if let Some(x) = Self::find_by_name(db, name).await? {
            if x.value != value {
                let mut x = x.into_active_model();
                x.value = Set(value.to_owned());
                x.save(db).await?;
            }
        } else {
            settings::ActiveModel {
                name: Set(name.to_owned()),
                value: Set(value.to_owned()),
                ..Default::default()
            }
            .insert(db)
            .await?;
        }
        Ok(())
    }

    pub async fn get_base64<C>(db: &C, name: &str) -> Result<Option<Vec<u8>>>
    where
        C: ConnectionTrait,
    {
        let v = Self::get(db, name).await?;
        if let Some(x) = v {
            Ok(Some(BASE64_STANDARD.decode(x)?))
        } else {
            Ok(None)
        }
    }

    pub async fn set_base64(db: &DatabaseTransaction, name: &str, value: &[u8]) -> Result<()> {
        Self::set(db, name, &BASE64_STANDARD.encode(value)).await
    }

    pub async fn delete<C>(db: &C, name: &str) -> Result<bool>
    where
        C: ConnectionTrait,
    {
        let rows = settings::Entity::delete_many()
            .filter(settings::Column::Name.eq(name))
            .exec(db)
            .await
            .map(|x| x.rows_affected)?;
        Ok(rows == 1)
    }
}