diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index 40b145b8a4..f858113fcc 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -56,7 +56,7 @@ class GridBloc extends Bloc { Future _loadFields(Emitter emit) async { if (_grid != null) { - final result = await service.getFields(fieldOrders: _grid!.fieldOrders); + final result = await service.getFields(gridId: _grid!.id, fieldOrders: _grid!.fieldOrders); result.fold( (fields) { _fields = fields.items; @@ -70,7 +70,7 @@ class GridBloc extends Bloc { Future _loadGridInfo(Emitter emit) async { if (_grid != null && _fields != null) { - final result = await service.getRows(rowOrders: _grid!.rowOrders); + final result = await service.getRows(gridId: _grid!.id, rowOrders: _grid!.rowOrders); result.fold((repeatedRow) { final rows = repeatedRow.items; final gridInfo = GridInfo(rows: rows, fields: _fields!); diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index e725f7ac84..5f0cda7813 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -4,11 +4,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:dartz/dartz.dart'; class GridService { - Future> createGrid({required String name}) { - final payload = CreateGridPayload()..name = name; - return GridEventCreateGrid(payload).send(); - } - Future> openGrid({required String gridId}) { final payload = GridId(value: gridId); return GridEventOpenGrid(payload).send(); @@ -18,11 +13,18 @@ class GridService { return GridEventCreateRow(GridId(value: gridId)).send(); } - Future> getRows({required RepeatedRowOrder rowOrders}) { - return GridEventGetRows(rowOrders).send(); + Future> getRows({required String gridId, required RepeatedRowOrder rowOrders}) { + final payload = QueryRowPayload.create() + ..gridId = gridId + ..rowOrders = rowOrders; + return GridEventGetRows(payload).send(); } - Future> getFields({required RepeatedFieldOrder fieldOrders}) { - return GridEventGetFields(fieldOrders).send(); + Future> getFields( + {required String gridId, required RepeatedFieldOrder fieldOrders}) { + final payload = QueryFieldPayload.create() + ..gridId = gridId + ..fieldOrders = fieldOrders; + return GridEventGetFields(payload).send(); } } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 52a51cd026..d7543eb486 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -19,7 +19,7 @@ class GridEventOpenGrid { } class GridEventGetRows { - RepeatedRowOrder request; + QueryRowPayload request; GridEventGetRows(this.request); Future> send() { @@ -36,7 +36,7 @@ class GridEventGetRows { } class GridEventGetFields { - RepeatedFieldOrder request; + QueryFieldPayload request; GridEventGetFields(this.request); Future> send() { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 54139582fe..102be7fb09 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -619,7 +619,7 @@ class RawCell extends $pb.GeneratedMessage { ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') + ..aOM(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create) ..hasRequiredFields = false ; @@ -628,7 +628,7 @@ class RawCell extends $pb.GeneratedMessage { $core.String? id, $core.String? rowId, $core.String? fieldId, - $core.String? data, + AnyData? data, }) { final _result = create(); if (id != null) { @@ -694,13 +694,15 @@ class RawCell extends $pb.GeneratedMessage { void clearFieldId() => clearField(3); @$pb.TagNumber(4) - $core.String get data => $_getSZ(3); + AnyData get data => $_getN(3); @$pb.TagNumber(4) - set data($core.String v) { $_setString(3, v); } + set data(AnyData v) { setField(4, v); } @$pb.TagNumber(4) $core.bool hasData() => $_has(3); @$pb.TagNumber(4) void clearData() => clearField(4); + @$pb.TagNumber(4) + AnyData ensureData() => $_ensure(3); } class RepeatedRow extends $pb.GeneratedMessage { @@ -1057,3 +1059,129 @@ class GridId extends $pb.GeneratedMessage { void clearValue() => clearField(1); } +class QueryFieldPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryFieldPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create) + ..hasRequiredFields = false + ; + + QueryFieldPayload._() : super(); + factory QueryFieldPayload({ + $core.String? gridId, + RepeatedFieldOrder? fieldOrders, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldOrders != null) { + _result.fieldOrders = fieldOrders; + } + return _result; + } + factory QueryFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryFieldPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + QueryFieldPayload clone() => QueryFieldPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + QueryFieldPayload copyWith(void Function(QueryFieldPayload) updates) => super.copyWith((message) => updates(message as QueryFieldPayload)) as QueryFieldPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static QueryFieldPayload create() => QueryFieldPayload._(); + QueryFieldPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static QueryFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryFieldPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + RepeatedFieldOrder get fieldOrders => $_getN(1); + @$pb.TagNumber(2) + set fieldOrders(RepeatedFieldOrder v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasFieldOrders() => $_has(1); + @$pb.TagNumber(2) + void clearFieldOrders() => clearField(2); + @$pb.TagNumber(2) + RepeatedFieldOrder ensureFieldOrders() => $_ensure(1); +} + +class QueryRowPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create) + ..hasRequiredFields = false + ; + + QueryRowPayload._() : super(); + factory QueryRowPayload({ + $core.String? gridId, + RepeatedRowOrder? rowOrders, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (rowOrders != null) { + _result.rowOrders = rowOrders; + } + return _result; + } + factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory QueryRowPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static QueryRowPayload create() => QueryRowPayload._(); + QueryRowPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static QueryRowPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + RepeatedRowOrder get rowOrders => $_getN(1); + @$pb.TagNumber(2) + set rowOrders(RepeatedRowOrder v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasRowOrders() => $_has(1); + @$pb.TagNumber(2) + void clearRowOrders() => clearField(2); + @$pb.TagNumber(2) + RepeatedRowOrder ensureRowOrders() => $_ensure(1); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 23f606194a..9a97445271 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -145,12 +145,12 @@ const RawCell$json = const { const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'data', '3': 4, '4': 1, '5': 9, '10': 'data'}, + const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'}, ], }; /// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE='); +final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRh'); @$core.Deprecated('Use repeatedRowDescriptor instead') const RepeatedRow$json = const { '1': 'RepeatedRow', @@ -228,3 +228,25 @@ const GridId$json = const { /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl'); +@$core.Deprecated('Use queryFieldPayloadDescriptor instead') +const QueryFieldPayload$json = const { + '1': 'QueryFieldPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'}, + ], +}; + +/// Descriptor for `QueryFieldPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryFieldPayloadDescriptor = $convert.base64Decode('ChFRdWVyeUZpZWxkUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSNgoMZmllbGRfb3JkZXJzGAIgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycw=='); +@$core.Deprecated('Use queryRowPayloadDescriptor instead') +const QueryRowPayload$json = const { + '1': 'QueryRowPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'row_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'}, + ], +}; + +/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjAKCnJvd19vcmRlcnMYAiABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM='); diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 1a8fce9353..1ce0e1b649 100755 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1067,6 +1067,7 @@ dependencies = [ "lib-sqlite", "parking_lot", "protobuf", + "rayon", "rust_decimal", "rusty-money", "strum", diff --git a/frontend/rust-lib/flowy-folder/build.rs b/frontend/rust-lib/flowy-folder/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-folder/build.rs +++ b/frontend/rust-lib/flowy-folder/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-grid/Cargo.toml b/frontend/rust-lib/flowy-grid/Cargo.toml index 331dd03b9e..95a5899f5e 100644 --- a/frontend/rust-lib/flowy-grid/Cargo.toml +++ b/frontend/rust-lib/flowy-grid/Cargo.toml @@ -31,7 +31,7 @@ bytes = { version = "1.0" } diesel = {version = "1.4.8", features = ["sqlite"]} dashmap = "4.0" tokio = {version = "1", features = ["sync"]} - +rayon = "1.5" parking_lot = "0.11" [build-dependencies] diff --git a/frontend/rust-lib/flowy-grid/build.rs b/frontend/rust-lib/flowy-grid/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-grid/build.rs +++ b/frontend/rust-lib/flowy-grid/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index e1201408d4..f8efe9f413 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,8 @@ use crate::manager::GridManager; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ - CreateGridPayload, Grid, GridId, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, + CreateGridPayload, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedFieldOrder, + RepeatedRow, RepeatedRowOrder, }; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::sync::Arc; @@ -19,21 +20,23 @@ pub(crate) async fn open_grid_handler( #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_rows_handler( - data: Data, + data: Data, manager: AppData>, ) -> DataResult { - let row_orders: RepeatedRowOrder = data.into_inner(); - let repeated_row = manager.get_rows(row_orders).await; + let payload: QueryRowPayload = data.into_inner(); + let editor = manager.get_grid_editor(&payload.grid_id)?; + let repeated_row = editor.get_rows(payload.row_orders).await?; data_result(repeated_row) } #[tracing::instrument(skip(data, manager), err)] pub(crate) async fn get_fields_handler( - data: Data, + data: Data, manager: AppData>, ) -> DataResult { - let field_orders: RepeatedFieldOrder = data.into_inner(); - let repeated_field = manager.get_fields(field_orders).await; + let payload: QueryFieldPayload = data.into_inner(); + let editor = manager.get_grid_editor(&payload.grid_id)?; + let repeated_field = editor.get_fields(payload.field_orders).await?; data_result(repeated_field) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index bd52c9f0f4..a5f6c7fe47 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -22,10 +22,10 @@ pub enum GridEvent { #[event(input = "GridId", output = "Grid")] OpenGrid = 0, - #[event(input = "RepeatedRowOrder", output = "RepeatedRow")] + #[event(input = "QueryRowPayload", output = "RepeatedRow")] GetRows = 1, - #[event(input = "RepeatedFieldOrder", output = "RepeatedField")] + #[event(input = "QueryFieldPayload", output = "RepeatedField")] GetFields = 2, #[event(input = "GridId")] diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 694ead2d55..ad521cfe59 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -1,11 +1,11 @@ use crate::services::grid_editor::ClientGridEditor; -use crate::services::kv_persistence::GridKVPersistence; +use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; use dashmap::DashMap; use flowy_collaboration::client_grid::{make_grid_delta, make_grid_revisions}; use flowy_collaboration::entities::revision::RepeatedRevision; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, RowOrder, + Field, FieldOrder, Grid, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowOrder, }; use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use lib_sqlite::ConnectionPool; @@ -93,14 +93,6 @@ impl GridManager { Ok(()) } - pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> RepeatedRow { - todo!() - } - - pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> RepeatedField { - todo!() - } - pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult> { match self.grid_editors.get(grid_id) { None => Err(FlowyError::internal().context("Should call open_grid function first")), diff --git a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs index c44c320468..afa278fcd3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell_data.rs @@ -17,7 +17,7 @@ use strum::IntoEnumIterator; use strum_macros::EnumIter; pub trait StringifyAnyData { - fn stringify_any_data(&self, data: &AnyData) -> String; + fn stringify_any_data(&self, data: AnyData) -> String; fn str_to_any_data(&self, s: &str) -> Result; } @@ -33,7 +33,7 @@ pub struct RichTextDescription { impl_any_data!(RichTextDescription, FieldType::RichText); impl StringifyAnyData for RichTextDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -57,7 +57,7 @@ pub struct CheckboxDescription { impl_any_data!(CheckboxDescription, FieldType::Checkbox); impl StringifyAnyData for CheckboxDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -133,7 +133,7 @@ impl DisplayCell for DateDescription { } impl StringifyAnyData for DateDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { match String::from_utf8(data.value.clone()) { Ok(s) => match s.parse::() { Ok(timestamp) => { @@ -257,7 +257,7 @@ pub struct SingleSelect { impl_any_data!(SingleSelect, FieldType::SingleSelect); impl StringifyAnyData for SingleSelect { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -283,7 +283,7 @@ pub struct MultiSelect { } impl_any_data!(MultiSelect, FieldType::MultiSelect); impl StringifyAnyData for MultiSelect { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { data.to_string() } @@ -388,7 +388,7 @@ impl DisplayCell for NumberDescription { } impl StringifyAnyData for NumberDescription { - fn stringify_any_data(&self, data: &AnyData) -> String { + fn stringify_any_data(&self, data: AnyData) -> String { match String::from_utf8(data.value.clone()) { Ok(s) => match self.money_from_str(&s) { Some(money_str) => money_str, diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 4a60254ca0..4e692df48c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,10 +1,15 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; +use crate::services::stringify::stringify_deserialize; +use dashmap::mapref::one::Ref; +use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, Grid, GridId, RawRow}; +use flowy_grid_data_model::entities::{ + Cell, Field, Grid, GridId, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, +}; use flowy_sync::{ RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence, RevisionWebSocket, RevisionWebSocketManager, @@ -13,6 +18,8 @@ use lib_infra::future::FutureResult; use lib_infra::uuid; use lib_ot::core::PlainTextAttributes; use lib_sqlite::ConnectionPool; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -22,6 +29,8 @@ pub struct ClientGridEditor { grid_pad: Arc>, rev_manager: Arc, kv_persistence: Arc, + + field_map: DashMap, } impl ClientGridEditor { @@ -33,16 +42,19 @@ impl ClientGridEditor { ) -> FlowyResult> { let token = user.token()?; let cloud = Arc::new(GridRevisionCloudService { token }); - let grid_pad = Arc::new(RwLock::new( - rev_manager.load::(cloud).await?, - )); + let grid_pad = rev_manager.load::(cloud).await?; + let rev_manager = Arc::new(rev_manager); + let field_map = load_all_fields(&grid_pad, &kv_persistence).await?; + let grid_pad = Arc::new(RwLock::new(grid_pad)); + Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, grid_pad, rev_manager, kv_persistence, + field_map, })) } @@ -80,6 +92,65 @@ impl ClientGridEditor { Ok(()) } + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult { + let ids = row_orders + .items + .into_iter() + .map(|row_order| row_order.row_id) + .collect::>(); + let raw_rows: Vec = self.kv_persistence.batch_get(ids)?; + + let make_cell = |field_id: String, raw_cell: RawCell| { + let some_field = self.field_map.get(&field_id); + if some_field.is_none() { + tracing::error!("Can't find the field with {}", field_id); + return None; + } + + let field = some_field.unwrap(); + match stringify_deserialize(raw_cell.data, field.value()) { + Ok(content) => { + let cell = Cell { + id: raw_cell.id, + field_id: field_id.clone(), + content, + }; + Some((field_id, cell)) + } + Err(_) => None, + } + }; + + let rows = raw_rows + .into_par_iter() + .map(|raw_row| { + let mut row = Row::new(&raw_row.id); + row.cell_by_field_id = raw_row + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) + .collect::>(); + row + }) + .collect::>(); + + Ok(rows.into()) + } + + pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult { + let fields = field_orders + .iter() + .flat_map(|field_order| match self.field_map.get(&field_order.field_id) { + None => { + tracing::error!("Can't find the field with {}", field_order.field_id); + None + } + Some(field) => Some(field.value().clone()), + }) + .collect::>(); + Ok(fields.into()) + } + pub async fn grid_data(&self) -> Grid { self.grid_pad.read().await.grid_data() } @@ -119,6 +190,24 @@ impl ClientGridEditor { } } +async fn load_all_fields( + grid_pad: &GridPad, + kv_persistence: &Arc, +) -> FlowyResult> { + let field_ids = grid_pad + .field_orders() + .iter() + .map(|field_order| field_order.field_id.clone()) + .collect::>(); + + let fields = kv_persistence.batch_get::(field_ids)?; + let map = DashMap::new(); + for field in fields { + map.insert(field.id.clone(), field); + } + Ok(map) +} + struct GridPadBuilder(); impl RevisionObjectBuilder for GridPadBuilder { type Output = GridPad; diff --git a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs index 3538af16f9..db3bdfdd7b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs +++ b/frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs @@ -6,7 +6,7 @@ use flowy_database::{ schema::{kv_table, kv_table::dsl}, }; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{Field, RawRow}; +use flowy_grid_data_model::entities::{Field, GridIdentifiable, RawRow}; use lib_infra::future::{BoxResultFuture, FutureResult}; use lib_sqlite::{ConnectionManager, ConnectionPool}; use std::sync::Arc; @@ -20,11 +20,12 @@ pub struct KeyValue { } pub trait KVTransaction { - fn get>(&self, key: &str) -> FlowyResult>; + fn get>(&self, key: &str) -> FlowyResult>; fn set>(&self, value: T) -> FlowyResult<()>; fn remove(&self, key: &str) -> FlowyResult<()>; - fn batch_get>(&self, keys: Vec) -> FlowyResult>; + fn batch_get>(&self, keys: Vec) + -> FlowyResult>; fn batch_set>(&self, values: Vec) -> FlowyResult<()>; fn batch_remove(&self, keys: Vec) -> FlowyResult<()>; } @@ -51,7 +52,7 @@ impl GridKVPersistence { } impl KVTransaction for GridKVPersistence { - fn get>(&self, key: &str) -> FlowyResult> { + fn get>(&self, key: &str) -> FlowyResult> { self.begin_transaction(|transaction| transaction.get(key)) } @@ -63,7 +64,10 @@ impl KVTransaction for GridKVPersistence { self.begin_transaction(|transaction| transaction.remove(key)) } - fn batch_get>(&self, keys: Vec) -> FlowyResult> { + fn batch_get>( + &self, + keys: Vec, + ) -> FlowyResult> { self.begin_transaction(|transaction| transaction.batch_get(keys)) } @@ -81,11 +85,11 @@ pub struct SqliteTransaction<'a> { } impl<'a> KVTransaction for SqliteTransaction<'a> { - fn get>(&self, key: &str) -> FlowyResult> { + fn get>(&self, key: &str) -> FlowyResult> { let item = dsl::kv_table .filter(kv_table::key.eq(key)) .first::(self.conn)?; - let value: T = item.try_into()?; + let value = T::try_from(Bytes::from(item.value)).unwrap(); Ok(Some(value)) } @@ -101,13 +105,16 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { Ok(()) } - fn batch_get>(&self, keys: Vec) -> FlowyResult> { + fn batch_get>( + &self, + keys: Vec, + ) -> FlowyResult> { let items = dsl::kv_table .filter(kv_table::key.eq_any(&keys)) .load::(self.conn)?; let mut values = vec![]; for item in items { - let value: T = item.try_into()?; + let value = T::try_from(Bytes::from(item.value)).unwrap(); values.push(value); } Ok(values) @@ -128,40 +135,33 @@ impl<'a> KVTransaction for SqliteTransaction<'a> { } } -impl std::convert::From for KeyValue { - fn from(row: RawRow) -> Self { - let key = row.id.clone(); - let bytes: Bytes = row.try_into().unwrap(); +impl + GridIdentifiable> std::convert::From for KeyValue { + fn from(value: T) -> Self { + let key = value.id().to_string(); + let bytes: Bytes = value.try_into().unwrap(); let value = bytes.to_vec(); KeyValue { key, value } } } -impl std::convert::TryInto for KeyValue { - type Error = FlowyError; +// +// impl std::convert::TryInto for KeyValue { - fn try_into(self) -> Result { - let bytes = Bytes::from(self.value); - RawRow::try_from(bytes) - .map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e))) - } -} - -impl std::convert::From for KeyValue { - fn from(field: Field) -> Self { - let key = field.id.clone(); - let bytes: Bytes = field.try_into().unwrap(); - let value = bytes.to_vec(); - KeyValue { key, value } - } -} - -impl std::convert::TryInto for KeyValue { - type Error = FlowyError; - - fn try_into(self) -> Result { - let bytes = Bytes::from(self.value); - Field::try_from(bytes) - .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) - } -} +// type Error = FlowyError; +// +// fn try_into(self) -> Result { +// let bytes = Bytes::from(self.value); +// RawRow::try_from(bytes) +// .map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e))) +// } +// } +// +// impl std::convert::TryInto for KeyValue { +// type Error = FlowyError; +// +// fn try_into(self) -> Result { +// let bytes = Bytes::from(self.value); +// Field::try_from(bytes) +// .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e))) +// } +// } diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index f62472a0e8..dc96f8af5b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -1,8 +1,6 @@ -mod stringify; mod util; pub mod cell_data; pub mod grid_editor; pub mod kv_persistence; - -pub use stringify::*; +pub mod stringify; diff --git a/frontend/rust-lib/flowy-grid/src/services/stringify.rs b/frontend/rust-lib/flowy-grid/src/services/stringify.rs index 299b7e8c96..3eab8f91a5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/stringify.rs @@ -3,28 +3,26 @@ use crate::services::util::*; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; -pub trait AnyDataSerde { - fn serialize(field: &Field, s: &str) -> Result { - match field.field_type { - FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s), - FieldType::Number => NumberDescription::from(field).str_to_any_data(s), - FieldType::DateTime => DateDescription::from(field).str_to_any_data(s), - FieldType::SingleSelect => SingleSelect::from(field).str_to_any_data(s), - FieldType::MultiSelect => MultiSelect::from(field).str_to_any_data(s), - FieldType::Checkbox => CheckboxDescription::from(field).str_to_any_data(s), - } - } - - fn deserialize(data: &AnyData, field: &Field) -> Result { - let _ = check_type_id(data, field)?; - let s = match field.field_type { - FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data), - FieldType::Number => NumberDescription::from(field).stringify_any_data(data), - FieldType::DateTime => DateDescription::from(field).stringify_any_data(data), - FieldType::SingleSelect => SingleSelect::from(field).stringify_any_data(data), - FieldType::MultiSelect => MultiSelect::from(field).stringify_any_data(data), - FieldType::Checkbox => CheckboxDescription::from(field).stringify_any_data(data), - }; - Ok(s) +pub fn stringify_serialize(field: &Field, s: &str) -> Result { + match field.field_type { + FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s), + FieldType::Number => NumberDescription::from(field).str_to_any_data(s), + FieldType::DateTime => DateDescription::from(field).str_to_any_data(s), + FieldType::SingleSelect => SingleSelect::from(field).str_to_any_data(s), + FieldType::MultiSelect => MultiSelect::from(field).str_to_any_data(s), + FieldType::Checkbox => CheckboxDescription::from(field).str_to_any_data(s), } } + +pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result { + let _ = check_type_id(&data, field)?; + let s = match field.field_type { + FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data), + FieldType::Number => NumberDescription::from(field).stringify_any_data(data), + FieldType::DateTime => DateDescription::from(field).stringify_any_data(data), + FieldType::SingleSelect => SingleSelect::from(field).stringify_any_data(data), + FieldType::MultiSelect => MultiSelect::from(field).stringify_any_data(data), + FieldType::Checkbox => CheckboxDescription::from(field).stringify_any_data(data), + }; + Ok(s) +} diff --git a/frontend/rust-lib/flowy-net/build.rs b/frontend/rust-lib/flowy-net/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-net/build.rs +++ b/frontend/rust-lib/flowy-net/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/frontend/rust-lib/flowy-user/build.rs b/frontend/rust-lib/flowy-user/build.rs index 4ab7b9e23d..4d4d3b13da 100644 --- a/frontend/rust-lib/flowy-user/build.rs +++ b/frontend/rust-lib/flowy-user/build.rs @@ -3,5 +3,7 @@ use lib_infra::code_gen; fn main() { let crate_name = env!("CARGO_PKG_NAME"); code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto"); + + #[cfg(feature = "dart")] code_gen::dart_event::gen(crate_name); } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 4cc10614d7..4db744fc08 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -1,7 +1,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; -use flowy_grid_data_model::entities::{CellChangeset, Field, FieldOrder, Grid, RawRow, RowOrder}; +use flowy_grid_data_model::entities::{CellChangeset, Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder}; use lib_infra::uuid; use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use std::sync::Arc; @@ -86,6 +86,10 @@ impl GridPad { grid_ref.clone() } + pub fn field_orders(&self) -> &RepeatedFieldOrder { + &self.grid.field_orders + } + pub fn modify_grid(&mut self, f: F) -> CollaborateResult> where F: FnOnce(&mut Grid) -> CollaborateResult>, diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 6d070e6893..926ca1e750 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use strum_macros::{Display, EnumIter, EnumString}; +pub trait GridIdentifiable { + fn id(&self) -> &str; +} + #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)] pub struct Grid { #[pb(index = 1)] @@ -62,7 +66,7 @@ impl std::ops::DerefMut for RepeatedFieldOrder { } } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct Field { #[pb(index = 1)] pub id: String, @@ -86,6 +90,12 @@ pub struct Field { pub type_options: AnyData, } +impl GridIdentifiable for Field { + fn id(&self) -> &str { + &self.id + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[pb(index = 1)] @@ -104,6 +114,12 @@ impl std::ops::DerefMut for RepeatedField { } } +impl std::convert::From> for RepeatedField { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)] pub enum FieldType { RichText = 0, @@ -140,7 +156,7 @@ impl FieldType { } } -#[derive(Debug, Default, ProtoBuf)] +#[derive(Debug, Clone, Default, ProtoBuf)] pub struct AnyData { #[pb(index = 1)] pub type_id: String, @@ -231,6 +247,12 @@ pub struct RawRow { pub cell_by_field_id: HashMap, } +impl GridIdentifiable for RawRow { + fn id(&self) -> &str { + &self.id + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RawCell { #[pb(index = 1)] @@ -243,7 +265,7 @@ pub struct RawCell { pub field_id: String, #[pb(index = 4)] - pub data: String, + pub data: AnyData, } #[derive(Debug, Default, ProtoBuf)] @@ -265,6 +287,12 @@ impl std::ops::DerefMut for RepeatedRow { } } +impl std::convert::From> for RepeatedRow { + fn from(items: Vec) -> Self { + Self { items } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] @@ -274,6 +302,15 @@ pub struct Row { pub cell_by_field_id: HashMap, } +impl Row { + pub fn new(row_id: &str) -> Self { + Self { + id: row_id.to_owned(), + cell_by_field_id: HashMap::new(), + } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] @@ -318,3 +355,21 @@ impl AsRef for GridId { &self.value } } + +#[derive(ProtoBuf, Default)] +pub struct QueryFieldPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_orders: RepeatedFieldOrder, +} + +#[derive(ProtoBuf, Default)] +pub struct QueryRowPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub row_orders: RepeatedRowOrder, +} diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 1339098bea..f64dde24e6 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -2070,7 +2070,7 @@ pub struct RawCell { pub id: ::std::string::String, pub row_id: ::std::string::String, pub field_id: ::std::string::String, - pub data: ::std::string::String, + pub data: ::protobuf::SingularPtrField, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -2165,35 +2165,47 @@ impl RawCell { ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) } - // string data = 4; + // .AnyData data = 4; - pub fn get_data(&self) -> &str { - &self.data + pub fn get_data(&self) -> &AnyData { + self.data.as_ref().unwrap_or_else(|| ::default_instance()) } pub fn clear_data(&mut self) { self.data.clear(); } + pub fn has_data(&self) -> bool { + self.data.is_some() + } + // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::string::String) { - self.data = v; + pub fn set_data(&mut self, v: AnyData) { + self.data = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::string::String { - &mut self.data + pub fn mut_data(&mut self) -> &mut AnyData { + if self.data.is_none() { + self.data.set_default(); + } + self.data.as_mut().unwrap() } // Take field - pub fn take_data(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.data, ::std::string::String::new()) + pub fn take_data(&mut self) -> AnyData { + self.data.take().unwrap_or_else(|| AnyData::new()) } } impl ::protobuf::Message for RawCell { fn is_initialized(&self) -> bool { + for v in &self.data { + if !v.is_initialized() { + return false; + } + }; true } @@ -2211,7 +2223,7 @@ impl ::protobuf::Message for RawCell { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; }, 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -2234,8 +2246,9 @@ impl ::protobuf::Message for RawCell { if !self.field_id.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.field_id); } - if !self.data.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.data); + if let Some(ref v) = self.data.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -2252,8 +2265,10 @@ impl ::protobuf::Message for RawCell { if !self.field_id.is_empty() { os.write_string(3, &self.field_id)?; } - if !self.data.is_empty() { - os.write_string(4, &self.data)?; + if let Some(ref v) = self.data.as_ref() { + os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -2308,7 +2323,7 @@ impl ::protobuf::Message for RawCell { |m: &RawCell| { &m.field_id }, |m: &mut RawCell| { &mut m.field_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "data", |m: &RawCell| { &m.data }, |m: &mut RawCell| { &mut m.data }, @@ -3557,6 +3572,438 @@ impl ::protobuf::reflect::ProtobufValue for GridId { } } +#[derive(PartialEq,Clone,Default)] +pub struct QueryFieldPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_orders: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a QueryFieldPayload { + fn default() -> &'a QueryFieldPayload { + ::default_instance() + } +} + +impl QueryFieldPayload { + pub fn new() -> QueryFieldPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // .RepeatedFieldOrder field_orders = 2; + + + pub fn get_field_orders(&self) -> &RepeatedFieldOrder { + self.field_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_field_orders(&mut self) { + self.field_orders.clear(); + } + + pub fn has_field_orders(&self) -> bool { + self.field_orders.is_some() + } + + // Param is passed by value, moved + pub fn set_field_orders(&mut self, v: RepeatedFieldOrder) { + self.field_orders = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_orders(&mut self) -> &mut RepeatedFieldOrder { + if self.field_orders.is_none() { + self.field_orders.set_default(); + } + self.field_orders.as_mut().unwrap() + } + + // Take field + pub fn take_field_orders(&mut self) -> RepeatedFieldOrder { + self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new()) + } +} + +impl ::protobuf::Message for QueryFieldPayload { + fn is_initialized(&self) -> bool { + for v in &self.field_orders { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_orders)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let Some(ref v) = self.field_orders.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.field_orders.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> QueryFieldPayload { + QueryFieldPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &QueryFieldPayload| { &m.grid_id }, + |m: &mut QueryFieldPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_orders", + |m: &QueryFieldPayload| { &m.field_orders }, + |m: &mut QueryFieldPayload| { &mut m.field_orders }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryFieldPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static QueryFieldPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryFieldPayload::new) + } +} + +impl ::protobuf::Clear for QueryFieldPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_orders.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for QueryFieldPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct QueryRowPayload { + // message fields + pub grid_id: ::std::string::String, + pub row_orders: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a QueryRowPayload { + fn default() -> &'a QueryRowPayload { + ::default_instance() + } +} + +impl QueryRowPayload { + pub fn new() -> QueryRowPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // .RepeatedRowOrder row_orders = 2; + + + pub fn get_row_orders(&self) -> &RepeatedRowOrder { + self.row_orders.as_ref().unwrap_or_else(|| ::default_instance()) + } + pub fn clear_row_orders(&mut self) { + self.row_orders.clear(); + } + + pub fn has_row_orders(&self) -> bool { + self.row_orders.is_some() + } + + // Param is passed by value, moved + pub fn set_row_orders(&mut self, v: RepeatedRowOrder) { + self.row_orders = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_orders(&mut self) -> &mut RepeatedRowOrder { + if self.row_orders.is_none() { + self.row_orders.set_default(); + } + self.row_orders.as_mut().unwrap() + } + + // Take field + pub fn take_row_orders(&mut self) -> RepeatedRowOrder { + self.row_orders.take().unwrap_or_else(|| RepeatedRowOrder::new()) + } +} + +impl ::protobuf::Message for QueryRowPayload { + fn is_initialized(&self) -> bool { + for v in &self.row_orders { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_orders)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if let Some(ref v) = self.row_orders.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if let Some(ref v) = self.row_orders.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> QueryRowPayload { + QueryRowPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "grid_id", + |m: &QueryRowPayload| { &m.grid_id }, + |m: &mut QueryRowPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "row_orders", + |m: &QueryRowPayload| { &m.row_orders }, + |m: &mut QueryRowPayload| { &mut m.row_orders }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "QueryRowPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static QueryRowPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(QueryRowPayload::new) + } +} + +impl ::protobuf::Clear for QueryRowPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.row_orders.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for QueryRowPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum FieldType { RichText = 0, @@ -3643,25 +4090,30 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\ R\rcellByFieldId\x1aJ\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\ \x20\x01(\tR\x03key\x12\x1e\n\x05value\x18\x02\x20\x01(\x0b2\x08.RawCell\ - R\x05value:\x028\x01\"_\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ + R\x05value:\x028\x01\"i\n\x07RawCell\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ \x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08fie\ - ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\x01(\ - \tR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ - \x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ - R\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByF\ - ieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03ke\ - y\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\ - \x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ - \x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\rCellChangeset\x12\ - \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\ - \x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\ - \x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11CreateGridPayload\ - \x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\ - \n\x05value\x18\x01\x20\x01(\tR\x05value*d\n\tFieldType\x12\x0c\n\x08Ric\ - hText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\ - \x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\ - \n\x08Checkbox\x10\x05b\x06proto3\ + ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\ + \x0b2\x08.AnyDataR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\ + \x01\x20\x03(\x0b2\x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\ + \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldId\ + Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\ + \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\ + \x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\ + \tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\ + \rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06r\ + ow_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01\ + (\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11Cr\ + eateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\ + \x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11Query\ + FieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\ + \x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldO\ + rders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\ + \x06gridId\x120\n\nrow_orders\x18\x02\x20\x01(\x0b2\x11.RepeatedRowOrder\ + R\trowOrders*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Numbe\ + r\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\ + \x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\ + proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index ee4210c061..79d6af77e1 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -45,7 +45,7 @@ message RawCell { string id = 1; string row_id = 2; string field_id = 3; - string data = 4; + AnyData data = 4; } message RepeatedRow { repeated Row items = 1; @@ -71,6 +71,14 @@ message CreateGridPayload { message GridId { string value = 1; } +message QueryFieldPayload { + string grid_id = 1; + RepeatedFieldOrder field_orders = 2; +} +message QueryRowPayload { + string grid_id = 1; + RepeatedRowOrder row_orders = 2; +} enum FieldType { RichText = 0; Number = 1;