浏览代码

feat: return rows and fields

appflowy 3 年之前
父节点
当前提交
11ceb96f65
共有 23 个文件被更改,包括 915 次插入155 次删除
  1. 2 2
      frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart
  2. 11 9
      frontend/app_flowy/lib/workspace/application/grid/grid_service.dart
  3. 2 2
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart
  4. 132 4
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart
  5. 24 2
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart
  6. 1 0
      frontend/rust-lib/Cargo.lock
  7. 2 0
      frontend/rust-lib/flowy-folder/build.rs
  8. 1 1
      frontend/rust-lib/flowy-grid/Cargo.toml
  9. 2 0
      frontend/rust-lib/flowy-grid/build.rs
  10. 10 7
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  11. 2 2
      frontend/rust-lib/flowy-grid/src/event_map.rs
  12. 2 10
      frontend/rust-lib/flowy-grid/src/manager.rs
  13. 7 7
      frontend/rust-lib/flowy-grid/src/services/cell_data.rs
  14. 93 4
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  15. 41 41
      frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs
  16. 1 3
      frontend/rust-lib/flowy-grid/src/services/mod.rs
  17. 20 22
      frontend/rust-lib/flowy-grid/src/services/stringify.rs
  18. 2 0
      frontend/rust-lib/flowy-net/build.rs
  19. 2 0
      frontend/rust-lib/flowy-user/build.rs
  20. 5 1
      shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs
  21. 58 3
      shared-lib/flowy-grid-data-model/src/entities/grid.rs
  22. 486 34
      shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs
  23. 9 1
      shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto

+ 2 - 2
frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart

@@ -56,7 +56,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
 
 
   Future<void> _loadFields(Emitter<GridState> emit) async {
   Future<void> _loadFields(Emitter<GridState> emit) async {
     if (_grid != null) {
     if (_grid != null) {
-      final result = await service.getFields(fieldOrders: _grid!.fieldOrders);
+      final result = await service.getFields(gridId: _grid!.id, fieldOrders: _grid!.fieldOrders);
       result.fold(
       result.fold(
         (fields) {
         (fields) {
           _fields = fields.items;
           _fields = fields.items;
@@ -70,7 +70,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
 
 
   Future<void> _loadGridInfo(Emitter<GridState> emit) async {
   Future<void> _loadGridInfo(Emitter<GridState> emit) async {
     if (_grid != null && _fields != null) {
     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) {
       result.fold((repeatedRow) {
         final rows = repeatedRow.items;
         final rows = repeatedRow.items;
         final gridInfo = GridInfo(rows: rows, fields: _fields!);
         final gridInfo = GridInfo(rows: rows, fields: _fields!);

+ 11 - 9
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';
 import 'package:dartz/dartz.dart';
 
 
 class GridService {
 class GridService {
-  Future<Either<Grid, FlowyError>> createGrid({required String name}) {
-    final payload = CreateGridPayload()..name = name;
-    return GridEventCreateGrid(payload).send();
-  }
-
   Future<Either<Grid, FlowyError>> openGrid({required String gridId}) {
   Future<Either<Grid, FlowyError>> openGrid({required String gridId}) {
     final payload = GridId(value: gridId);
     final payload = GridId(value: gridId);
     return GridEventOpenGrid(payload).send();
     return GridEventOpenGrid(payload).send();
@@ -18,11 +13,18 @@ class GridService {
     return GridEventCreateRow(GridId(value: gridId)).send();
     return GridEventCreateRow(GridId(value: gridId)).send();
   }
   }
 
 
-  Future<Either<RepeatedRow, FlowyError>> getRows({required RepeatedRowOrder rowOrders}) {
-    return GridEventGetRows(rowOrders).send();
+  Future<Either<RepeatedRow, FlowyError>> getRows({required String gridId, required RepeatedRowOrder rowOrders}) {
+    final payload = QueryRowPayload.create()
+      ..gridId = gridId
+      ..rowOrders = rowOrders;
+    return GridEventGetRows(payload).send();
   }
   }
 
 
-  Future<Either<RepeatedField, FlowyError>> getFields({required RepeatedFieldOrder fieldOrders}) {
-    return GridEventGetFields(fieldOrders).send();
+  Future<Either<RepeatedField, FlowyError>> getFields(
+      {required String gridId, required RepeatedFieldOrder fieldOrders}) {
+    final payload = QueryFieldPayload.create()
+      ..gridId = gridId
+      ..fieldOrders = fieldOrders;
+    return GridEventGetFields(payload).send();
   }
   }
 }
 }

+ 2 - 2
frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart

@@ -19,7 +19,7 @@ class GridEventOpenGrid {
 }
 }
 
 
 class GridEventGetRows {
 class GridEventGetRows {
-     RepeatedRowOrder request;
+     QueryRowPayload request;
      GridEventGetRows(this.request);
      GridEventGetRows(this.request);
 
 
     Future<Either<RepeatedRow, FlowyError>> send() {
     Future<Either<RepeatedRow, FlowyError>> send() {
@@ -36,7 +36,7 @@ class GridEventGetRows {
 }
 }
 
 
 class GridEventGetFields {
 class GridEventGetFields {
-     RepeatedFieldOrder request;
+     QueryFieldPayload request;
      GridEventGetFields(this.request);
      GridEventGetFields(this.request);
 
 
     Future<Either<RepeatedField, FlowyError>> send() {
     Future<Either<RepeatedField, FlowyError>> send() {

+ 132 - 4
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(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
-    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
+    ..aOM<AnyData>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create)
     ..hasRequiredFields = false
     ..hasRequiredFields = false
   ;
   ;
 
 
@@ -628,7 +628,7 @@ class RawCell extends $pb.GeneratedMessage {
     $core.String? id,
     $core.String? id,
     $core.String? rowId,
     $core.String? rowId,
     $core.String? fieldId,
     $core.String? fieldId,
-    $core.String? data,
+    AnyData? data,
   }) {
   }) {
     final _result = create();
     final _result = create();
     if (id != null) {
     if (id != null) {
@@ -694,13 +694,15 @@ class RawCell extends $pb.GeneratedMessage {
   void clearFieldId() => clearField(3);
   void clearFieldId() => clearField(3);
 
 
   @$pb.TagNumber(4)
   @$pb.TagNumber(4)
-  $core.String get data => $_getSZ(3);
+  AnyData get data => $_getN(3);
   @$pb.TagNumber(4)
   @$pb.TagNumber(4)
-  set data($core.String v) { $_setString(3, v); }
+  set data(AnyData v) { setField(4, v); }
   @$pb.TagNumber(4)
   @$pb.TagNumber(4)
   $core.bool hasData() => $_has(3);
   $core.bool hasData() => $_has(3);
   @$pb.TagNumber(4)
   @$pb.TagNumber(4)
   void clearData() => clearField(4);
   void clearData() => clearField(4);
+  @$pb.TagNumber(4)
+  AnyData ensureData() => $_ensure(3);
 }
 }
 
 
 class RepeatedRow extends $pb.GeneratedMessage {
 class RepeatedRow extends $pb.GeneratedMessage {
@@ -1057,3 +1059,129 @@ class GridId extends $pb.GeneratedMessage {
   void clearValue() => clearField(1);
   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<RepeatedFieldOrder>(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<QueryFieldPayload> createRepeated() => $pb.PbList<QueryFieldPayload>();
+  @$core.pragma('dart2js:noInline')
+  static QueryFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<QueryFieldPayload>(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<RepeatedRowOrder>(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<QueryRowPayload> createRepeated() => $pb.PbList<QueryRowPayload>();
+  @$core.pragma('dart2js:noInline')
+  static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<QueryRowPayload>(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);
+}
+

+ 24 - 2
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': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
     const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
     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': '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`.
 /// 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')
 @$core.Deprecated('Use repeatedRowDescriptor instead')
 const RepeatedRow$json = const {
 const RepeatedRow$json = const {
   '1': 'RepeatedRow',
   '1': 'RepeatedRow',
@@ -228,3 +228,25 @@ const GridId$json = const {
 
 
 /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`.
 /// Descriptor for `GridId`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List gridIdDescriptor = $convert.base64Decode('CgZHcmlkSWQSFAoFdmFsdWUYASABKAlSBXZhbHVl');
 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=');

+ 1 - 0
frontend/rust-lib/Cargo.lock

@@ -1067,6 +1067,7 @@ dependencies = [
  "lib-sqlite",
  "lib-sqlite",
  "parking_lot",
  "parking_lot",
  "protobuf",
  "protobuf",
+ "rayon",
  "rust_decimal",
  "rust_decimal",
  "rusty-money",
  "rusty-money",
  "strum",
  "strum",

+ 2 - 0
frontend/rust-lib/flowy-folder/build.rs

@@ -3,5 +3,7 @@ use lib_infra::code_gen;
 fn main() {
 fn main() {
     let crate_name = env!("CARGO_PKG_NAME");
     let crate_name = env!("CARGO_PKG_NAME");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+
+    #[cfg(feature = "dart")]
     code_gen::dart_event::gen(crate_name);
     code_gen::dart_event::gen(crate_name);
 }
 }

+ 1 - 1
frontend/rust-lib/flowy-grid/Cargo.toml

@@ -31,7 +31,7 @@ bytes = { version = "1.0" }
 diesel = {version = "1.4.8", features = ["sqlite"]}
 diesel = {version = "1.4.8", features = ["sqlite"]}
 dashmap = "4.0"
 dashmap = "4.0"
 tokio = {version = "1", features = ["sync"]}
 tokio = {version = "1", features = ["sync"]}
-
+rayon = "1.5"
 parking_lot = "0.11"
 parking_lot = "0.11"
 
 
 [build-dependencies]
 [build-dependencies]

+ 2 - 0
frontend/rust-lib/flowy-grid/build.rs

@@ -3,5 +3,7 @@ use lib_infra::code_gen;
 fn main() {
 fn main() {
     let crate_name = env!("CARGO_PKG_NAME");
     let crate_name = env!("CARGO_PKG_NAME");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+
+    #[cfg(feature = "dart")]
     code_gen::dart_event::gen(crate_name);
     code_gen::dart_event::gen(crate_name);
 }
 }

+ 10 - 7
frontend/rust-lib/flowy-grid/src/event_handler.rs

@@ -1,7 +1,8 @@
 use crate::manager::GridManager;
 use crate::manager::GridManager;
 use flowy_error::FlowyError;
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{
 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 lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
 use std::sync::Arc;
 use std::sync::Arc;
@@ -19,21 +20,23 @@ pub(crate) async fn open_grid_handler(
 
 
 #[tracing::instrument(skip(data, manager), err)]
 #[tracing::instrument(skip(data, manager), err)]
 pub(crate) async fn get_rows_handler(
 pub(crate) async fn get_rows_handler(
-    data: Data<RepeatedRowOrder>,
+    data: Data<QueryRowPayload>,
     manager: AppData<Arc<GridManager>>,
     manager: AppData<Arc<GridManager>>,
 ) -> DataResult<RepeatedRow, FlowyError> {
 ) -> DataResult<RepeatedRow, FlowyError> {
-    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)
     data_result(repeated_row)
 }
 }
 
 
 #[tracing::instrument(skip(data, manager), err)]
 #[tracing::instrument(skip(data, manager), err)]
 pub(crate) async fn get_fields_handler(
 pub(crate) async fn get_fields_handler(
-    data: Data<RepeatedFieldOrder>,
+    data: Data<QueryFieldPayload>,
     manager: AppData<Arc<GridManager>>,
     manager: AppData<Arc<GridManager>>,
 ) -> DataResult<RepeatedField, FlowyError> {
 ) -> DataResult<RepeatedField, FlowyError> {
-    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)
     data_result(repeated_field)
 }
 }
 
 

+ 2 - 2
frontend/rust-lib/flowy-grid/src/event_map.rs

@@ -22,10 +22,10 @@ pub enum GridEvent {
     #[event(input = "GridId", output = "Grid")]
     #[event(input = "GridId", output = "Grid")]
     OpenGrid = 0,
     OpenGrid = 0,
 
 
-    #[event(input = "RepeatedRowOrder", output = "RepeatedRow")]
+    #[event(input = "QueryRowPayload", output = "RepeatedRow")]
     GetRows = 1,
     GetRows = 1,
 
 
-    #[event(input = "RepeatedFieldOrder", output = "RepeatedField")]
+    #[event(input = "QueryFieldPayload", output = "RepeatedField")]
     GetFields = 2,
     GetFields = 2,
 
 
     #[event(input = "GridId")]
     #[event(input = "GridId")]

+ 2 - 10
frontend/rust-lib/flowy-grid/src/manager.rs

@@ -1,11 +1,11 @@
 use crate::services::grid_editor::ClientGridEditor;
 use crate::services::grid_editor::ClientGridEditor;
-use crate::services::kv_persistence::GridKVPersistence;
+use crate::services::kv_persistence::{GridKVPersistence, KVTransaction};
 use dashmap::DashMap;
 use dashmap::DashMap;
 use flowy_collaboration::client_grid::{make_grid_delta, make_grid_revisions};
 use flowy_collaboration::client_grid::{make_grid_delta, make_grid_revisions};
 use flowy_collaboration::entities::revision::RepeatedRevision;
 use flowy_collaboration::entities::revision::RepeatedRevision;
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::{
 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 flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket};
 use lib_sqlite::ConnectionPool;
 use lib_sqlite::ConnectionPool;
@@ -93,14 +93,6 @@ impl GridManager {
         Ok(())
         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<Arc<ClientGridEditor>> {
     pub fn get_grid_editor(&self, grid_id: &str) -> FlowyResult<Arc<ClientGridEditor>> {
         match self.grid_editors.get(grid_id) {
         match self.grid_editors.get(grid_id) {
             None => Err(FlowyError::internal().context("Should call open_grid function first")),
             None => Err(FlowyError::internal().context("Should call open_grid function first")),

+ 7 - 7
frontend/rust-lib/flowy-grid/src/services/cell_data.rs

@@ -17,7 +17,7 @@ use strum::IntoEnumIterator;
 use strum_macros::EnumIter;
 use strum_macros::EnumIter;
 
 
 pub trait StringifyAnyData {
 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<AnyData, FlowyError>;
     fn str_to_any_data(&self, s: &str) -> Result<AnyData, FlowyError>;
 }
 }
 
 
@@ -33,7 +33,7 @@ pub struct RichTextDescription {
 impl_any_data!(RichTextDescription, FieldType::RichText);
 impl_any_data!(RichTextDescription, FieldType::RichText);
 
 
 impl StringifyAnyData for RichTextDescription {
 impl StringifyAnyData for RichTextDescription {
-    fn stringify_any_data(&self, data: &AnyData) -> String {
+    fn stringify_any_data(&self, data: AnyData) -> String {
         data.to_string()
         data.to_string()
     }
     }
 
 
@@ -57,7 +57,7 @@ pub struct CheckboxDescription {
 impl_any_data!(CheckboxDescription, FieldType::Checkbox);
 impl_any_data!(CheckboxDescription, FieldType::Checkbox);
 
 
 impl StringifyAnyData for CheckboxDescription {
 impl StringifyAnyData for CheckboxDescription {
-    fn stringify_any_data(&self, data: &AnyData) -> String {
+    fn stringify_any_data(&self, data: AnyData) -> String {
         data.to_string()
         data.to_string()
     }
     }
 
 
@@ -133,7 +133,7 @@ impl DisplayCell for DateDescription {
 }
 }
 
 
 impl StringifyAnyData 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()) {
         match String::from_utf8(data.value.clone()) {
             Ok(s) => match s.parse::<i64>() {
             Ok(s) => match s.parse::<i64>() {
                 Ok(timestamp) => {
                 Ok(timestamp) => {
@@ -257,7 +257,7 @@ pub struct SingleSelect {
 impl_any_data!(SingleSelect, FieldType::SingleSelect);
 impl_any_data!(SingleSelect, FieldType::SingleSelect);
 
 
 impl StringifyAnyData for SingleSelect {
 impl StringifyAnyData for SingleSelect {
-    fn stringify_any_data(&self, data: &AnyData) -> String {
+    fn stringify_any_data(&self, data: AnyData) -> String {
         data.to_string()
         data.to_string()
     }
     }
 
 
@@ -283,7 +283,7 @@ pub struct MultiSelect {
 }
 }
 impl_any_data!(MultiSelect, FieldType::MultiSelect);
 impl_any_data!(MultiSelect, FieldType::MultiSelect);
 impl StringifyAnyData for MultiSelect {
 impl StringifyAnyData for MultiSelect {
-    fn stringify_any_data(&self, data: &AnyData) -> String {
+    fn stringify_any_data(&self, data: AnyData) -> String {
         data.to_string()
         data.to_string()
     }
     }
 
 
@@ -388,7 +388,7 @@ impl DisplayCell for NumberDescription {
 }
 }
 
 
 impl StringifyAnyData 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()) {
         match String::from_utf8(data.value.clone()) {
             Ok(s) => match self.money_from_str(&s) {
             Ok(s) => match self.money_from_str(&s) {
                 Some(money_str) => money_str,
                 Some(money_str) => money_str,

+ 93 - 4
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -1,10 +1,15 @@
 use crate::manager::GridUser;
 use crate::manager::GridUser;
 use crate::services::kv_persistence::{GridKVPersistence, KVTransaction};
 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::client_grid::{GridChange, GridPad};
 use flowy_collaboration::entities::revision::Revision;
 use flowy_collaboration::entities::revision::Revision;
 use flowy_collaboration::util::make_delta_from_revisions;
 use flowy_collaboration::util::make_delta_from_revisions;
 use flowy_error::{FlowyError, FlowyResult};
 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::{
 use flowy_sync::{
     RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence,
     RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder, RevisionPersistence,
     RevisionWebSocket, RevisionWebSocketManager,
     RevisionWebSocket, RevisionWebSocketManager,
@@ -13,6 +18,8 @@ use lib_infra::future::FutureResult;
 use lib_infra::uuid;
 use lib_infra::uuid;
 use lib_ot::core::PlainTextAttributes;
 use lib_ot::core::PlainTextAttributes;
 use lib_sqlite::ConnectionPool;
 use lib_sqlite::ConnectionPool;
+use rayon::iter::{IntoParallelIterator, ParallelIterator};
+use std::collections::HashMap;
 use std::sync::Arc;
 use std::sync::Arc;
 use tokio::sync::RwLock;
 use tokio::sync::RwLock;
 
 
@@ -22,6 +29,8 @@ pub struct ClientGridEditor {
     grid_pad: Arc<RwLock<GridPad>>,
     grid_pad: Arc<RwLock<GridPad>>,
     rev_manager: Arc<RevisionManager>,
     rev_manager: Arc<RevisionManager>,
     kv_persistence: Arc<GridKVPersistence>,
     kv_persistence: Arc<GridKVPersistence>,
+
+    field_map: DashMap<String, Field>,
 }
 }
 
 
 impl ClientGridEditor {
 impl ClientGridEditor {
@@ -33,16 +42,19 @@ impl ClientGridEditor {
     ) -> FlowyResult<Arc<Self>> {
     ) -> FlowyResult<Arc<Self>> {
         let token = user.token()?;
         let token = user.token()?;
         let cloud = Arc::new(GridRevisionCloudService { token });
         let cloud = Arc::new(GridRevisionCloudService { token });
-        let grid_pad = Arc::new(RwLock::new(
-            rev_manager.load::<GridPadBuilder, GridRevisionCompact>(cloud).await?,
-        ));
+        let grid_pad = rev_manager.load::<GridPadBuilder, GridRevisionCompact>(cloud).await?;
+
         let rev_manager = Arc::new(rev_manager);
         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 {
         Ok(Arc::new(Self {
             grid_id: grid_id.to_owned(),
             grid_id: grid_id.to_owned(),
             user,
             user,
             grid_pad,
             grid_pad,
             rev_manager,
             rev_manager,
             kv_persistence,
             kv_persistence,
+            field_map,
         }))
         }))
     }
     }
 
 
@@ -80,6 +92,65 @@ impl ClientGridEditor {
         Ok(())
         Ok(())
     }
     }
 
 
+    pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult<RepeatedRow> {
+        let ids = row_orders
+            .items
+            .into_iter()
+            .map(|row_order| row_order.row_id)
+            .collect::<Vec<_>>();
+        let raw_rows: Vec<RawRow> = 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::<HashMap<String, Cell>>();
+                row
+            })
+            .collect::<Vec<Row>>();
+
+        Ok(rows.into())
+    }
+
+    pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult<RepeatedField> {
+        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::<Vec<Field>>();
+        Ok(fields.into())
+    }
+
     pub async fn grid_data(&self) -> Grid {
     pub async fn grid_data(&self) -> Grid {
         self.grid_pad.read().await.grid_data()
         self.grid_pad.read().await.grid_data()
     }
     }
@@ -119,6 +190,24 @@ impl ClientGridEditor {
     }
     }
 }
 }
 
 
+async fn load_all_fields(
+    grid_pad: &GridPad,
+    kv_persistence: &Arc<GridKVPersistence>,
+) -> FlowyResult<DashMap<String, Field>> {
+    let field_ids = grid_pad
+        .field_orders()
+        .iter()
+        .map(|field_order| field_order.field_id.clone())
+        .collect::<Vec<_>>();
+
+    let fields = kv_persistence.batch_get::<Field>(field_ids)?;
+    let map = DashMap::new();
+    for field in fields {
+        map.insert(field.id.clone(), field);
+    }
+    Ok(map)
+}
+
 struct GridPadBuilder();
 struct GridPadBuilder();
 impl RevisionObjectBuilder for GridPadBuilder {
 impl RevisionObjectBuilder for GridPadBuilder {
     type Output = GridPad;
     type Output = GridPad;

+ 41 - 41
frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs

@@ -6,7 +6,7 @@ use flowy_database::{
     schema::{kv_table, kv_table::dsl},
     schema::{kv_table, kv_table::dsl},
 };
 };
 use flowy_error::{FlowyError, FlowyResult};
 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_infra::future::{BoxResultFuture, FutureResult};
 use lib_sqlite::{ConnectionManager, ConnectionPool};
 use lib_sqlite::{ConnectionManager, ConnectionPool};
 use std::sync::Arc;
 use std::sync::Arc;
@@ -20,11 +20,12 @@ pub struct KeyValue {
 }
 }
 
 
 pub trait KVTransaction {
 pub trait KVTransaction {
-    fn get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, key: &str) -> FlowyResult<Option<T>>;
+    fn get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(&self, key: &str) -> FlowyResult<Option<T>>;
     fn set<T: Into<KeyValue>>(&self, value: T) -> FlowyResult<()>;
     fn set<T: Into<KeyValue>>(&self, value: T) -> FlowyResult<()>;
     fn remove(&self, key: &str) -> FlowyResult<()>;
     fn remove(&self, key: &str) -> FlowyResult<()>;
 
 
-    fn batch_get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, keys: Vec<String>) -> FlowyResult<Vec<T>>;
+    fn batch_get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(&self, keys: Vec<String>)
+        -> FlowyResult<Vec<T>>;
     fn batch_set<T: Into<KeyValue>>(&self, values: Vec<T>) -> FlowyResult<()>;
     fn batch_set<T: Into<KeyValue>>(&self, values: Vec<T>) -> FlowyResult<()>;
     fn batch_remove(&self, keys: Vec<String>) -> FlowyResult<()>;
     fn batch_remove(&self, keys: Vec<String>) -> FlowyResult<()>;
 }
 }
@@ -51,7 +52,7 @@ impl GridKVPersistence {
 }
 }
 
 
 impl KVTransaction for GridKVPersistence {
 impl KVTransaction for GridKVPersistence {
-    fn get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, key: &str) -> FlowyResult<Option<T>> {
+    fn get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(&self, key: &str) -> FlowyResult<Option<T>> {
         self.begin_transaction(|transaction| transaction.get(key))
         self.begin_transaction(|transaction| transaction.get(key))
     }
     }
 
 
@@ -63,7 +64,10 @@ impl KVTransaction for GridKVPersistence {
         self.begin_transaction(|transaction| transaction.remove(key))
         self.begin_transaction(|transaction| transaction.remove(key))
     }
     }
 
 
-    fn batch_get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, keys: Vec<String>) -> FlowyResult<Vec<T>> {
+    fn batch_get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(
+        &self,
+        keys: Vec<String>,
+    ) -> FlowyResult<Vec<T>> {
         self.begin_transaction(|transaction| transaction.batch_get(keys))
         self.begin_transaction(|transaction| transaction.batch_get(keys))
     }
     }
 
 
@@ -81,11 +85,11 @@ pub struct SqliteTransaction<'a> {
 }
 }
 
 
 impl<'a> KVTransaction for SqliteTransaction<'a> {
 impl<'a> KVTransaction for SqliteTransaction<'a> {
-    fn get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, key: &str) -> FlowyResult<Option<T>> {
+    fn get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(&self, key: &str) -> FlowyResult<Option<T>> {
         let item = dsl::kv_table
         let item = dsl::kv_table
             .filter(kv_table::key.eq(key))
             .filter(kv_table::key.eq(key))
             .first::<KeyValue>(self.conn)?;
             .first::<KeyValue>(self.conn)?;
-        let value: T = item.try_into()?;
+        let value = T::try_from(Bytes::from(item.value)).unwrap();
         Ok(Some(value))
         Ok(Some(value))
     }
     }
 
 
@@ -101,13 +105,16 @@ impl<'a> KVTransaction for SqliteTransaction<'a> {
         Ok(())
         Ok(())
     }
     }
 
 
-    fn batch_get<T: TryFrom<KeyValue, Error = FlowyError>>(&self, keys: Vec<String>) -> FlowyResult<Vec<T>> {
+    fn batch_get<T: TryFrom<Bytes, Error = ::protobuf::ProtobufError>>(
+        &self,
+        keys: Vec<String>,
+    ) -> FlowyResult<Vec<T>> {
         let items = dsl::kv_table
         let items = dsl::kv_table
             .filter(kv_table::key.eq_any(&keys))
             .filter(kv_table::key.eq_any(&keys))
             .load::<KeyValue>(self.conn)?;
             .load::<KeyValue>(self.conn)?;
         let mut values = vec![];
         let mut values = vec![];
         for item in items {
         for item in items {
-            let value: T = item.try_into()?;
+            let value = T::try_from(Bytes::from(item.value)).unwrap();
             values.push(value);
             values.push(value);
         }
         }
         Ok(values)
         Ok(values)
@@ -128,40 +135,33 @@ impl<'a> KVTransaction for SqliteTransaction<'a> {
     }
     }
 }
 }
 
 
-impl std::convert::From<RawRow> for KeyValue {
-    fn from(row: RawRow) -> Self {
-        let key = row.id.clone();
-        let bytes: Bytes = row.try_into().unwrap();
+impl<T: TryInto<Bytes, Error = ::protobuf::ProtobufError> + GridIdentifiable> std::convert::From<T> 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();
         let value = bytes.to_vec();
         KeyValue { key, value }
         KeyValue { key, value }
     }
     }
 }
 }
 
 
-impl std::convert::TryInto<RawRow> for KeyValue {
-    type Error = FlowyError;
-
-    fn try_into(self) -> Result<RawRow, Self::Error> {
-        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<Field> 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<Field> for KeyValue {
-    type Error = FlowyError;
-
-    fn try_into(self) -> Result<Field, Self::Error> {
-        let bytes = Bytes::from(self.value);
-        Field::try_from(bytes)
-            .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e)))
-    }
-}
+//
+// impl std::convert::TryInto<RawRow> for KeyValue {
+
+//     type Error = FlowyError;
+//
+//     fn try_into(self) -> Result<RawRow, Self::Error> {
+//         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<Field> for KeyValue {
+//     type Error = FlowyError;
+//
+//     fn try_into(self) -> Result<Field, Self::Error> {
+//         let bytes = Bytes::from(self.value);
+//         Field::try_from(bytes)
+//             .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e)))
+//     }
+// }

+ 1 - 3
frontend/rust-lib/flowy-grid/src/services/mod.rs

@@ -1,8 +1,6 @@
-mod stringify;
 mod util;
 mod util;
 
 
 pub mod cell_data;
 pub mod cell_data;
 pub mod grid_editor;
 pub mod grid_editor;
 pub mod kv_persistence;
 pub mod kv_persistence;
-
-pub use stringify::*;
+pub mod stringify;

+ 20 - 22
frontend/rust-lib/flowy-grid/src/services/stringify.rs

@@ -3,28 +3,26 @@ use crate::services::util::*;
 use flowy_error::FlowyError;
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{AnyData, Field, FieldType};
 use flowy_grid_data_model::entities::{AnyData, Field, FieldType};
 
 
-pub trait AnyDataSerde {
-    fn serialize(field: &Field, s: &str) -> Result<AnyData, FlowyError> {
-        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 fn stringify_serialize(field: &Field, s: &str) -> Result<AnyData, FlowyError> {
+    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<String, FlowyError> {
-        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(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result<String, FlowyError> {
+    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)
 }
 }

+ 2 - 0
frontend/rust-lib/flowy-net/build.rs

@@ -3,5 +3,7 @@ use lib_infra::code_gen;
 fn main() {
 fn main() {
     let crate_name = env!("CARGO_PKG_NAME");
     let crate_name = env!("CARGO_PKG_NAME");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+
+    #[cfg(feature = "dart")]
     code_gen::dart_event::gen(crate_name);
     code_gen::dart_event::gen(crate_name);
 }
 }

+ 2 - 0
frontend/rust-lib/flowy-user/build.rs

@@ -3,5 +3,7 @@ use lib_infra::code_gen;
 fn main() {
 fn main() {
     let crate_name = env!("CARGO_PKG_NAME");
     let crate_name = env!("CARGO_PKG_NAME");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
     code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+
+    #[cfg(feature = "dart")]
     code_gen::dart_event::gen(crate_name);
     code_gen::dart_event::gen(crate_name);
 }
 }

+ 5 - 1
shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs

@@ -1,7 +1,7 @@
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
 use crate::util::{cal_diff, make_delta_from_revisions};
 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_infra::uuid;
 use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use lib_ot::core::{FlowyStr, OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use std::sync::Arc;
 use std::sync::Arc;
@@ -86,6 +86,10 @@ impl GridPad {
         grid_ref.clone()
         grid_ref.clone()
     }
     }
 
 
+    pub fn field_orders(&self) -> &RepeatedFieldOrder {
+        &self.grid.field_orders
+    }
+
     pub fn modify_grid<F>(&mut self, f: F) -> CollaborateResult<Option<GridChange>>
     pub fn modify_grid<F>(&mut self, f: F) -> CollaborateResult<Option<GridChange>>
     where
     where
         F: FnOnce(&mut Grid) -> CollaborateResult<Option<()>>,
         F: FnOnce(&mut Grid) -> CollaborateResult<Option<()>>,

+ 58 - 3
shared-lib/flowy-grid-data-model/src/entities/grid.rs

@@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
 use std::collections::HashMap;
 use strum_macros::{Display, EnumIter, EnumString};
 use strum_macros::{Display, EnumIter, EnumString};
 
 
+pub trait GridIdentifiable {
+    fn id(&self) -> &str;
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
 pub struct Grid {
 pub struct Grid {
     #[pb(index = 1)]
     #[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 {
 pub struct Field {
     #[pb(index = 1)]
     #[pb(index = 1)]
     pub id: String,
     pub id: String,
@@ -86,6 +90,12 @@ pub struct Field {
     pub type_options: AnyData,
     pub type_options: AnyData,
 }
 }
 
 
+impl GridIdentifiable for Field {
+    fn id(&self) -> &str {
+        &self.id
+    }
+}
+
 #[derive(Debug, Default, ProtoBuf)]
 #[derive(Debug, Default, ProtoBuf)]
 pub struct RepeatedField {
 pub struct RepeatedField {
     #[pb(index = 1)]
     #[pb(index = 1)]
@@ -104,6 +114,12 @@ impl std::ops::DerefMut for RepeatedField {
     }
     }
 }
 }
 
 
+impl std::convert::From<Vec<Field>> for RepeatedField {
+    fn from(items: Vec<Field>) -> Self {
+        Self { items }
+    }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)]
 #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)]
 pub enum FieldType {
 pub enum FieldType {
     RichText = 0,
     RichText = 0,
@@ -140,7 +156,7 @@ impl FieldType {
     }
     }
 }
 }
 
 
-#[derive(Debug, Default, ProtoBuf)]
+#[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct AnyData {
 pub struct AnyData {
     #[pb(index = 1)]
     #[pb(index = 1)]
     pub type_id: String,
     pub type_id: String,
@@ -231,6 +247,12 @@ pub struct RawRow {
     pub cell_by_field_id: HashMap<String, RawCell>,
     pub cell_by_field_id: HashMap<String, RawCell>,
 }
 }
 
 
+impl GridIdentifiable for RawRow {
+    fn id(&self) -> &str {
+        &self.id
+    }
+}
+
 #[derive(Debug, Default, ProtoBuf)]
 #[derive(Debug, Default, ProtoBuf)]
 pub struct RawCell {
 pub struct RawCell {
     #[pb(index = 1)]
     #[pb(index = 1)]
@@ -243,7 +265,7 @@ pub struct RawCell {
     pub field_id: String,
     pub field_id: String,
 
 
     #[pb(index = 4)]
     #[pb(index = 4)]
-    pub data: String,
+    pub data: AnyData,
 }
 }
 
 
 #[derive(Debug, Default, ProtoBuf)]
 #[derive(Debug, Default, ProtoBuf)]
@@ -265,6 +287,12 @@ impl std::ops::DerefMut for RepeatedRow {
     }
     }
 }
 }
 
 
+impl std::convert::From<Vec<Row>> for RepeatedRow {
+    fn from(items: Vec<Row>) -> Self {
+        Self { items }
+    }
+}
+
 #[derive(Debug, Default, ProtoBuf)]
 #[derive(Debug, Default, ProtoBuf)]
 pub struct Row {
 pub struct Row {
     #[pb(index = 1)]
     #[pb(index = 1)]
@@ -274,6 +302,15 @@ pub struct Row {
     pub cell_by_field_id: HashMap<String, Cell>,
     pub cell_by_field_id: HashMap<String, Cell>,
 }
 }
 
 
+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)]
 #[derive(Debug, Default, ProtoBuf)]
 pub struct Cell {
 pub struct Cell {
     #[pb(index = 1)]
     #[pb(index = 1)]
@@ -318,3 +355,21 @@ impl AsRef<str> for GridId {
         &self.value
         &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,
+}

+ 486 - 34
shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs

@@ -2070,7 +2070,7 @@ pub struct RawCell {
     pub id: ::std::string::String,
     pub id: ::std::string::String,
     pub row_id: ::std::string::String,
     pub row_id: ::std::string::String,
     pub field_id: ::std::string::String,
     pub field_id: ::std::string::String,
-    pub data: ::std::string::String,
+    pub data: ::protobuf::SingularPtrField<AnyData>,
     // special fields
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
     pub cached_size: ::protobuf::CachedSize,
@@ -2165,35 +2165,47 @@ impl RawCell {
         ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
         ::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(|| <AnyData as ::protobuf::Message>::default_instance())
     }
     }
     pub fn clear_data(&mut self) {
     pub fn clear_data(&mut self) {
         self.data.clear();
         self.data.clear();
     }
     }
 
 
+    pub fn has_data(&self) -> bool {
+        self.data.is_some()
+    }
+
     // Param is passed by value, moved
     // 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.
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
     // 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
     // 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 {
 impl ::protobuf::Message for RawCell {
     fn is_initialized(&self) -> bool {
     fn is_initialized(&self) -> bool {
+        for v in &self.data {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
         true
         true
     }
     }
 
 
@@ -2211,7 +2223,7 @@ impl ::protobuf::Message for RawCell {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
                 },
                 },
                 4 => {
                 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())?;
                     ::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() {
         if !self.field_id.is_empty() {
             my_size += ::protobuf::rt::string_size(3, &self.field_id);
             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());
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         self.cached_size.set(my_size);
@@ -2252,8 +2265,10 @@ impl ::protobuf::Message for RawCell {
         if !self.field_id.is_empty() {
         if !self.field_id.is_empty() {
             os.write_string(3, &self.field_id)?;
             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())?;
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
         ::std::result::Result::Ok(())
@@ -2308,7 +2323,7 @@ impl ::protobuf::Message for RawCell {
                 |m: &RawCell| { &m.field_id },
                 |m: &RawCell| { &m.field_id },
                 |m: &mut RawCell| { &mut 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<AnyData>>(
                 "data",
                 "data",
                 |m: &RawCell| { &m.data },
                 |m: &RawCell| { &m.data },
                 |m: &mut RawCell| { &mut 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<RepeatedFieldOrder>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a QueryFieldPayload {
+    fn default() -> &'a QueryFieldPayload {
+        <QueryFieldPayload as ::protobuf::Message>::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(|| <RepeatedFieldOrder as ::protobuf::Message>::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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        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<RepeatedFieldOrder>>(
+                "field_orders",
+                |m: &QueryFieldPayload| { &m.field_orders },
+                |m: &mut QueryFieldPayload| { &mut m.field_orders },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<QueryFieldPayload>(
+                "QueryFieldPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static QueryFieldPayload {
+        static instance: ::protobuf::rt::LazyV2<QueryFieldPayload> = ::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<RepeatedRowOrder>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a QueryRowPayload {
+    fn default() -> &'a QueryRowPayload {
+        <QueryRowPayload as ::protobuf::Message>::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(|| <RepeatedRowOrder as ::protobuf::Message>::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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        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<RepeatedRowOrder>>(
+                "row_orders",
+                |m: &QueryRowPayload| { &m.row_orders },
+                |m: &mut QueryRowPayload| { &mut m.row_orders },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<QueryRowPayload>(
+                "QueryRowPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static QueryRowPayload {
+        static instance: ::protobuf::rt::LazyV2<QueryRowPayload> = ::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)]
 #[derive(Clone,PartialEq,Eq,Debug,Hash)]
 pub enum FieldType {
 pub enum FieldType {
     RichText = 0,
     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\
     \x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1a.RawRow.CellByFieldIdEntry\
     R\rcellByFieldId\x1aJ\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\
     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\
     \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\
     \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;
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 9 - 1
shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto

@@ -45,7 +45,7 @@ message RawCell {
     string id = 1;
     string id = 1;
     string row_id = 2;
     string row_id = 2;
     string field_id = 3;
     string field_id = 3;
-    string data = 4;
+    AnyData data = 4;
 }
 }
 message RepeatedRow {
 message RepeatedRow {
     repeated Row items = 1;
     repeated Row items = 1;
@@ -71,6 +71,14 @@ message CreateGridPayload {
 message GridId {
 message GridId {
     string value = 1;
     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 {
 enum FieldType {
     RichText = 0;
     RichText = 0;
     Number = 1;
     Number = 1;