feat: return rows and fields

This commit is contained in:
appflowy 2022-03-05 17:52:25 +08:00
parent 8029f1035d
commit 11ceb96f65
23 changed files with 915 additions and 155 deletions

View File

@ -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!);

View File

@ -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}) { Future<Either<RepeatedRow, FlowyError>> getRows({required String gridId, required RepeatedRowOrder rowOrders}) {
return GridEventGetRows(rowOrders).send(); final payload = QueryRowPayload.create()
..gridId = gridId
..rowOrders = rowOrders;
return GridEventGetRows(payload).send();
} }
Future<Either<RepeatedField, FlowyError>> getFields({required RepeatedFieldOrder fieldOrders}) { Future<Either<RepeatedField, FlowyError>> getFields(
return GridEventGetFields(fieldOrders).send(); {required String gridId, required RepeatedFieldOrder fieldOrders}) {
final payload = QueryFieldPayload.create()
..gridId = gridId
..fieldOrders = fieldOrders;
return GridEventGetFields(payload).send();
} }
} }

View File

@ -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() {

View File

@ -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);
}

View File

@ -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=');

View File

@ -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",

View File

@ -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);
} }

View File

@ -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]

View File

@ -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);
} }

View File

@ -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 payload: QueryRowPayload = data.into_inner();
let repeated_row = manager.get_rows(row_orders).await; 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 payload: QueryFieldPayload = data.into_inner();
let repeated_field = manager.get_fields(field_orders).await; 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)
} }

View File

@ -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")]

View File

@ -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")),

View File

@ -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,

View File

@ -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( let grid_pad = rev_manager.load::<GridPadBuilder, GridRevisionCompact>(cloud).await?;
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;

View File

@ -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 { impl<T: TryInto<Bytes, Error = ::protobuf::ProtobufError> + GridIdentifiable> std::convert::From<T> for KeyValue {
fn from(row: RawRow) -> Self { fn from(value: T) -> Self {
let key = row.id.clone(); let key = value.id().to_string();
let bytes: Bytes = row.try_into().unwrap(); 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; // impl std::convert::TryInto<RawRow> for KeyValue {
fn try_into(self) -> Result<RawRow, Self::Error> { // type Error = FlowyError;
let bytes = Bytes::from(self.value); //
RawRow::try_from(bytes) // fn try_into(self) -> Result<RawRow, Self::Error> {
.map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e))) // 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(); // impl std::convert::TryInto<Field> for KeyValue {
let bytes: Bytes = field.try_into().unwrap(); // type Error = FlowyError;
let value = bytes.to_vec(); //
KeyValue { key, value } // 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<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)))
}
}

View File

@ -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 mod stringify;
pub use stringify::*;

View File

@ -3,8 +3,7 @@ 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 { pub fn stringify_serialize(field: &Field, s: &str) -> Result<AnyData, FlowyError> {
fn serialize(field: &Field, s: &str) -> Result<AnyData, FlowyError> {
match field.field_type { match field.field_type {
FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s), FieldType::RichText => RichTextDescription::from(field).str_to_any_data(s),
FieldType::Number => NumberDescription::from(field).str_to_any_data(s), FieldType::Number => NumberDescription::from(field).str_to_any_data(s),
@ -15,8 +14,8 @@ pub trait AnyDataSerde {
} }
} }
fn deserialize(data: &AnyData, field: &Field) -> Result<String, FlowyError> { pub(crate) fn stringify_deserialize(data: AnyData, field: &Field) -> Result<String, FlowyError> {
let _ = check_type_id(data, field)?; let _ = check_type_id(&data, field)?;
let s = match field.field_type { let s = match field.field_type {
FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data), FieldType::RichText => RichTextDescription::from(field).stringify_any_data(data),
FieldType::Number => NumberDescription::from(field).stringify_any_data(data), FieldType::Number => NumberDescription::from(field).stringify_any_data(data),
@ -27,4 +26,3 @@ pub trait AnyDataSerde {
}; };
Ok(s) Ok(s)
} }
}

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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<()>>,

View File

@ -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,
}

View File

@ -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 { pub fn get_data(&self) -> &AnyData {
&self.data 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) { pub fn set_data(&mut self, v: AnyData) {
self.data = v; 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 { pub fn mut_data(&mut self) -> &mut AnyData {
&mut self.data 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 { pub fn take_data(&mut self) -> AnyData {
::std::mem::replace(&mut self.data, ::std::string::String::new()) 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() { if let Some(ref v) = self.data.as_ref() {
my_size += ::protobuf::rt::string_size(4, &self.data); 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() { if let Some(ref v) = self.data.as_ref() {
os.write_string(4, &self.data)?; 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(\ ld_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\
\tR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ \x0b2\x08.AnyDataR\x04data\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\
\x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ \x01\x20\x03(\x0b2\x04.RowR\x05items\"\xa0\x01\n\x03Row\x12\x0e\n\x02id\
R\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellByF\ \x18\x01\x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\
ieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03ke\ \x0b2\x17.Row.CellByFieldIdEntryR\rcellByFieldId\x1aG\n\x12CellByFieldId\
y\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\ Entry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\
\x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\x02id\x18\x01\x20\ \x02\x20\x01(\x0b2\x05.CellR\x05value:\x028\x01\"K\n\x04Cell\x12\x0e\n\
\x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\ \x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08field_id\x18\x02\x20\x01(\
\x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\rCellChangeset\x12\ \tR\x07fieldId\x12\x18\n\x07content\x18\x03\x20\x01(\tR\x07content\"e\n\
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\ \rCellChangeset\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\x06r\
\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\ ow_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01\
\x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11CreateGridPayload\ (\tR\x07fieldId\x12\x12\n\x04data\x18\x04\x20\x01(\tR\x04data\"'\n\x11Cr\
\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\ eateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\
\n\x05value\x18\x01\x20\x01(\tR\x05value*d\n\tFieldType\x12\x0c\n\x08Ric\ \x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"d\n\x11Query\
hText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\ FieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\
\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\ \x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldO\
\n\x08Checkbox\x10\x05b\x06proto3\ 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;

View File

@ -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;