123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 |
- use crate::entities::*;
- use crate::manager::DatabaseManager;
- use crate::services::cell::{FromCellString, ToCellChangesetString, TypeCellData};
- use crate::services::field::{
- default_type_option_builder_from_type, select_type_option_from_field_rev,
- type_option_builder_from_json_str, DateCellChangeset, DateChangesetPB, SelectOptionCellChangeset,
- SelectOptionCellChangesetPB, SelectOptionCellChangesetParams, SelectOptionCellDataPB,
- SelectOptionChangeset, SelectOptionChangesetPB, SelectOptionIds, SelectOptionPB,
- };
- use crate::services::row::make_row_from_row_rev;
- use database_model::FieldRevision;
- use flowy_error::{ErrorCode, FlowyError, FlowyResult};
- use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult};
- use std::sync::Arc;
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_database_data_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<DatabasePB, FlowyError> {
- let database_id: DatabaseViewIdPB = data.into_inner();
- let editor = manager.open_database(database_id.as_ref()).await?;
- let database = editor.get_database(database_id.as_ref()).await?;
- data_result(database)
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_database_setting_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<DatabaseViewSettingPB, FlowyError> {
- let database_id: DatabaseViewIdPB = data.into_inner();
- let editor = manager.open_database(database_id).await?;
- let database_setting = editor.get_setting().await?;
- data_result(database_setting)
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn update_database_setting_handler(
- data: AFPluginData<DatabaseSettingChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: DatabaseSettingChangesetParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- if let Some(insert_params) = params.insert_group {
- editor.insert_group(insert_params).await?;
- }
- if let Some(delete_params) = params.delete_group {
- editor.delete_group(delete_params).await?;
- }
- if let Some(alter_filter) = params.insert_filter {
- editor.create_or_update_filter(alter_filter).await?;
- }
- if let Some(delete_filter) = params.delete_filter {
- editor.delete_filter(delete_filter).await?;
- }
- if let Some(alter_sort) = params.alert_sort {
- let _ = editor.create_or_update_sort(alter_sort).await?;
- }
- if let Some(delete_sort) = params.delete_sort {
- editor.delete_sort(delete_sort).await?;
- }
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_all_filters_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RepeatedFilterPB, FlowyError> {
- let database_id: DatabaseViewIdPB = data.into_inner();
- let editor = manager.open_database(database_id).await?;
- let filters = RepeatedFilterPB {
- items: editor.get_all_filters().await?,
- };
- data_result(filters)
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_all_sorts_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RepeatedSortPB, FlowyError> {
- let database_id: DatabaseViewIdPB = data.into_inner();
- let editor = manager.open_database(database_id.as_ref()).await?;
- let sorts = RepeatedSortPB {
- items: editor.get_all_sorts(database_id.as_ref()).await?,
- };
- data_result(sorts)
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn delete_all_sorts_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let database_id: DatabaseViewIdPB = data.into_inner();
- let editor = manager.open_database(database_id.as_ref()).await?;
- editor.delete_all_sorts(database_id.as_ref()).await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_fields_handler(
- data: AFPluginData<GetFieldPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RepeatedFieldPB, FlowyError> {
- let params: GetFieldParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- let field_revs = editor.get_field_revs(params.field_ids).await?;
- let repeated_field: RepeatedFieldPB = field_revs
- .into_iter()
- .map(FieldPB::from)
- .collect::<Vec<_>>()
- .into();
- data_result(repeated_field)
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn update_field_handler(
- data: AFPluginData<FieldChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let changeset: FieldChangesetParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(&changeset.database_id).await?;
- editor.update_field(changeset).await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn update_field_type_option_handler(
- data: AFPluginData<TypeOptionChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: TypeOptionChangesetParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- let old_field_rev = editor.get_field_rev(¶ms.field_id).await;
- editor
- .update_field_type_option(¶ms.field_id, params.type_option_data, old_field_rev)
- .await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn delete_field_handler(
- data: AFPluginData<DeleteFieldPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: FieldIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.delete_field(¶ms.field_id).await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn switch_to_field_handler(
- data: AFPluginData<UpdateFieldTypePayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: EditFieldParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- let old_field_rev = editor.get_field_rev(¶ms.field_id).await;
- editor
- .switch_to_field_type(¶ms.field_id, ¶ms.field_type)
- .await?;
- // Get the field_rev with field_id, if it doesn't exist, we create the default FieldRevision from the FieldType.
- let new_field_rev = editor
- .get_field_rev(¶ms.field_id)
- .await
- .unwrap_or(Arc::new(editor.next_field_rev(¶ms.field_type).await?));
- // Update the type-option data after the field type has been changed
- let type_option_data = get_type_option_data(&new_field_rev, ¶ms.field_type).await?;
- editor
- .update_field_type_option(&new_field_rev.id, type_option_data, old_field_rev)
- .await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn duplicate_field_handler(
- data: AFPluginData<DuplicateFieldPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: FieldIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.duplicate_field(¶ms.field_id).await?;
- Ok(())
- }
- /// Return the FieldTypeOptionData if the Field exists otherwise return record not found error.
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_field_type_option_data_handler(
- data: AFPluginData<TypeOptionPathPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<TypeOptionPB, FlowyError> {
- let params: TypeOptionPathParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- match editor.get_field_rev(¶ms.field_id).await {
- None => Err(FlowyError::record_not_found()),
- Some(field_rev) => {
- let field_type = field_rev.ty.into();
- let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
- let data = TypeOptionPB {
- view_id: params.view_id,
- field: field_rev.into(),
- type_option_data,
- };
- data_result(data)
- },
- }
- }
- /// Create FieldMeta and save it. Return the FieldTypeOptionData.
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn create_field_type_option_data_handler(
- data: AFPluginData<CreateFieldPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<TypeOptionPB, FlowyError> {
- let params: CreateFieldParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- let field_rev = editor
- .create_new_field_rev_with_type_option(¶ms.field_type, params.type_option_data)
- .await?;
- let field_type: FieldType = field_rev.ty.into();
- let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
- data_result(TypeOptionPB {
- view_id: params.view_id,
- field: field_rev.into(),
- type_option_data,
- })
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn move_field_handler(
- data: AFPluginData<MoveFieldPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: MoveFieldParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.move_field(params).await?;
- Ok(())
- }
- /// The [FieldRevision] contains multiple data, each of them belongs to a specific FieldType.
- async fn get_type_option_data(
- field_rev: &FieldRevision,
- field_type: &FieldType,
- ) -> FlowyResult<Vec<u8>> {
- let s = field_rev
- .get_type_option_str(field_type)
- .map(|value| value.to_owned())
- .unwrap_or_else(|| {
- default_type_option_builder_from_type(field_type)
- .serializer()
- .json_str()
- });
- let field_type: FieldType = field_rev.ty.into();
- let builder = type_option_builder_from_json_str(&s, &field_type);
- let type_option_data = builder.serializer().protobuf_bytes().to_vec();
- Ok(type_option_data)
- }
- // #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn get_row_handler(
- data: AFPluginData<RowIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<OptionalRowPB, FlowyError> {
- let params: RowIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- let row = editor
- .get_row_rev(¶ms.row_id)
- .await?
- .map(make_row_from_row_rev);
- data_result(OptionalRowPB { row })
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn delete_row_handler(
- data: AFPluginData<RowIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: RowIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.delete_row(¶ms.row_id).await?;
- Ok(())
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn duplicate_row_handler(
- data: AFPluginData<RowIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: RowIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.duplicate_row(¶ms.row_id).await?;
- Ok(())
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn move_row_handler(
- data: AFPluginData<MoveRowPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: MoveRowParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.view_id).await?;
- editor.move_row(params).await?;
- Ok(())
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn create_table_row_handler(
- data: AFPluginData<CreateRowPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RowPB, FlowyError> {
- let params: CreateRowParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
- let row = editor.create_row(params).await?;
- data_result(row)
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn get_cell_handler(
- data: AFPluginData<CellIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<CellPB, FlowyError> {
- let params: CellIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.database_id).await?;
- match editor.get_cell(¶ms).await {
- None => data_result(CellPB::empty(¶ms.field_id, ¶ms.row_id)),
- Some(cell) => data_result(cell),
- }
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn update_cell_handler(
- data: AFPluginData<CellChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let changeset: CellChangesetPB = data.into_inner();
- let editor = manager.get_database_editor(&changeset.database_id).await?;
- editor
- .update_cell_with_changeset(
- &changeset.row_id,
- &changeset.field_id,
- changeset.type_cell_data,
- )
- .await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn new_select_option_handler(
- data: AFPluginData<CreateSelectOptionPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<SelectOptionPB, FlowyError> {
- let params: CreateSelectOptionParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.database_id).await?;
- match editor.get_field_rev(¶ms.field_id).await {
- None => Err(ErrorCode::InvalidData.into()),
- Some(field_rev) => {
- let type_option = select_type_option_from_field_rev(&field_rev)?;
- let select_option = type_option.create_option(¶ms.option_name);
- data_result(select_option)
- },
- }
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn update_select_option_handler(
- data: AFPluginData<SelectOptionChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let changeset: SelectOptionChangeset = data.into_inner().try_into()?;
- let editor = manager
- .get_database_editor(&changeset.cell_path.database_id)
- .await?;
- let field_id = changeset.cell_path.field_id.clone();
- let (tx, rx) = tokio::sync::oneshot::channel();
- editor
- .modify_field_rev(&field_id, |field_rev| {
- let mut type_option = select_type_option_from_field_rev(field_rev)?;
- let mut cell_changeset_str = None;
- let mut is_changed = None;
- for option in changeset.insert_options {
- cell_changeset_str = Some(
- SelectOptionCellChangeset::from_insert_option_id(&option.id).to_cell_changeset_str(),
- );
- type_option.insert_option(option);
- is_changed = Some(());
- }
- for option in changeset.update_options {
- type_option.insert_option(option);
- is_changed = Some(());
- }
- for option in changeset.delete_options {
- cell_changeset_str = Some(
- SelectOptionCellChangeset::from_delete_option_id(&option.id).to_cell_changeset_str(),
- );
- type_option.delete_option(option);
- is_changed = Some(());
- }
- if is_changed.is_some() {
- field_rev.insert_type_option(&*type_option);
- }
- let _ = tx.send(cell_changeset_str);
- Ok(is_changed)
- })
- .await?;
- if let Ok(Some(cell_changeset_str)) = rx.await {
- match editor
- .update_cell_with_changeset(
- &changeset.cell_path.row_id,
- &changeset.cell_path.field_id,
- cell_changeset_str,
- )
- .await
- {
- Ok(_) => {},
- Err(e) => tracing::error!("{}", e),
- }
- }
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip(data, manager), err)]
- pub(crate) async fn get_select_option_handler(
- data: AFPluginData<CellIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<SelectOptionCellDataPB, FlowyError> {
- let params: CellIdParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(¶ms.database_id).await?;
- match editor.get_field_rev(¶ms.field_id).await {
- None => {
- tracing::error!(
- "Can't find the select option field with id: {}",
- params.field_id
- );
- data_result(SelectOptionCellDataPB::default())
- },
- Some(field_rev) => {
- //
- let cell_rev = editor
- .get_cell_rev(¶ms.row_id, ¶ms.field_id)
- .await?;
- let type_option = select_type_option_from_field_rev(&field_rev)?;
- let type_cell_data: TypeCellData = match cell_rev {
- None => TypeCellData {
- cell_str: "".to_string(),
- field_type: field_rev.ty.into(),
- },
- Some(cell_rev) => cell_rev.try_into()?,
- };
- let ids = SelectOptionIds::from_cell_str(&type_cell_data.cell_str)?;
- let selected_options = type_option.get_selected_options(ids);
- data_result(selected_options)
- },
- }
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn update_select_option_cell_handler(
- data: AFPluginData<SelectOptionCellChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?;
- let editor = manager
- .get_database_editor(¶ms.cell_identifier.database_id)
- .await?;
- let changeset = SelectOptionCellChangeset {
- insert_option_ids: params.insert_option_ids,
- delete_option_ids: params.delete_option_ids,
- };
- editor
- .update_cell_with_changeset(
- ¶ms.cell_identifier.row_id,
- ¶ms.cell_identifier.field_id,
- changeset,
- )
- .await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn update_date_cell_handler(
- data: AFPluginData<DateChangesetPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> Result<(), FlowyError> {
- let data = data.into_inner();
- let cell_path: CellIdParams = data.cell_path.try_into()?;
- let cell_changeset = DateCellChangeset {
- date: data.date,
- time: data.time,
- is_utc: data.is_utc,
- };
- let editor = manager.get_database_editor(&cell_path.database_id).await?;
- editor
- .update_cell(cell_path.row_id, cell_path.field_id, cell_changeset)
- .await?;
- Ok(())
- }
- #[tracing::instrument(level = "trace", skip_all, err)]
- pub(crate) async fn get_groups_handler(
- data: AFPluginData<DatabaseViewIdPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RepeatedGroupPB, FlowyError> {
- let params: DatabaseViewIdPB = data.into_inner();
- let editor = manager.get_database_editor(¶ms.value).await?;
- let group = editor.load_groups().await?;
- data_result(group)
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn create_board_card_handler(
- data: AFPluginData<CreateBoardCardPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> DataResult<RowPB, FlowyError> {
- let params: CreateRowParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
- let row = editor.create_row(params).await?;
- data_result(row)
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn move_group_handler(
- data: AFPluginData<MoveGroupPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> FlowyResult<()> {
- let params: MoveGroupParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
- editor.move_group(params).await?;
- Ok(())
- }
- #[tracing::instrument(level = "debug", skip(data, manager), err)]
- pub(crate) async fn move_group_row_handler(
- data: AFPluginData<MoveGroupRowPayloadPB>,
- manager: AFPluginState<Arc<DatabaseManager>>,
- ) -> FlowyResult<()> {
- let params: MoveGroupRowParams = data.into_inner().try_into()?;
- let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
- editor.move_group_row(params).await?;
- Ok(())
- }
|