Feat/database view (#1875)

* chore: rename structs

* chore: add todos

* chore: hidden database id

* refactor: add database folder, prepare to extract the view

* refactor: rename grid-model to datbase-model

* ci: fix warnings
This commit is contained in:
Nathan.fooo 2023-02-21 15:47:51 +08:00 committed by GitHub
parent 346a09b2ae
commit f76d722b4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
160 changed files with 2152 additions and 1947 deletions

View File

@ -74,7 +74,7 @@ jobs:
run: |
mkdir dist
npm install
cargo make --cwd .. build_tauri_backend
cargo make --cwd .. tauri_build
yarn && yarn build
- uses: tauri-apps/tauri-action@v0

View File

@ -45,7 +45,7 @@ class BoardDataController {
BoardDataController({required ViewPB view})
: viewId = view.id,
_listener = BoardListener(view.id),
_databaseFFIService = DatabaseFFIService(databaseId: view.id),
_databaseFFIService = DatabaseFFIService(viewId: view.id),
fieldController = GridFieldController(databaseId: view.id) {
//
_viewCache = DatabaseViewCache(

View File

@ -152,7 +152,7 @@ class GridCellController<T, D> extends Equatable {
_cellDataPersistence = cellDataPersistence,
_fieldNotifier = fieldNotifier,
_fieldService = FieldService(
databaseId: cellId.databaseId,
viewId: cellId.databaseId,
fieldId: cellId.fieldInfo.id,
),
_cacheKey = GridCellCacheKey(

View File

@ -175,7 +175,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
});
final result = await FieldService.updateFieldTypeOption(
databaseId: cellController.databaseId,
viewId: cellController.databaseId,
fieldId: cellController.fieldInfo.id,
typeOptionData: newDateTypeOption.writeToBuffer(),
);

View File

@ -13,7 +13,7 @@ class FieldActionSheetBloc
FieldActionSheetBloc({required GridFieldCellContext fieldCellContext})
: fieldService = FieldService(
databaseId: fieldCellContext.databaseId,
viewId: fieldCellContext.viewId,
fieldId: fieldCellContext.field.id,
),
super(

View File

@ -16,7 +16,7 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
required GridFieldCellContext cellContext,
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
_fieldService = FieldService(
databaseId: cellContext.databaseId, fieldId: cellContext.field.id),
viewId: cellContext.viewId, fieldId: cellContext.field.id),
super(FieldCellState.initial(cellContext)) {
on<FieldCellEvent>(
(event, emit) async {
@ -80,7 +80,7 @@ class FieldCellState with _$FieldCellState {
factory FieldCellState.initial(GridFieldCellContext cellContext) =>
FieldCellState(
databaseId: cellContext.databaseId,
databaseId: cellContext.viewId,
field: cellContext.field,
width: cellContext.field.width.toDouble(),
);

View File

@ -150,9 +150,9 @@ class GridFieldController {
GridFieldController({required this.databaseId})
: _fieldListener = DatabaseFieldsListener(databaseId: databaseId),
_settingListener = DatabaseSettingListener(databaseId: databaseId),
_filterFFIService = FilterFFIService(databaseId: databaseId),
_filterFFIService = FilterFFIService(viewId: databaseId),
_filtersListener = FiltersListener(viewId: databaseId),
_gridFFIService = DatabaseFFIService(databaseId: databaseId),
_gridFFIService = DatabaseFFIService(viewId: databaseId),
_sortFFIService = SortFFIService(viewId: databaseId),
_sortsListener = SortsListener(viewId: databaseId),
_settingFFIService = SettingFFIService(viewId: databaseId) {

View File

@ -49,7 +49,7 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
() => null,
(field) {
final fieldService = FieldService(
databaseId: databaseId,
viewId: databaseId,
fieldId: field.id,
);
fieldService.deleteField();

View File

@ -12,14 +12,14 @@ part 'field_service.freezed.dart';
///
/// You could check out the rust-lib/flowy-database/event_map.rs for more information.
class FieldService {
final String databaseId;
final String viewId;
final String fieldId;
FieldService({required this.databaseId, required this.fieldId});
FieldService({required this.viewId, required this.fieldId});
Future<Either<Unit, FlowyError>> moveField(int fromIndex, int toIndex) {
final payload = MoveFieldPayloadPB.create()
..viewId = databaseId
..viewId = viewId
..fieldId = fieldId
..fromIndex = fromIndex
..toIndex = toIndex;
@ -35,7 +35,7 @@ class FieldService {
double? width,
}) {
var payload = FieldChangesetPB.create()
..databaseId = databaseId
..databaseId = viewId
..fieldId = fieldId;
if (name != null) {
@ -62,12 +62,12 @@ class FieldService {
}
static Future<Either<Unit, FlowyError>> updateFieldTypeOption({
required String databaseId,
required String viewId,
required String fieldId,
required List<int> typeOptionData,
}) {
var payload = TypeOptionChangesetPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldId
..typeOptionData = typeOptionData;
@ -76,7 +76,7 @@ class FieldService {
Future<Either<Unit, FlowyError>> deleteField() {
final payload = DeleteFieldPayloadPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldId;
return DatabaseEventDeleteField(payload).send();
@ -84,7 +84,7 @@ class FieldService {
Future<Either<Unit, FlowyError>> duplicateField() {
final payload = DuplicateFieldPayloadPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldId;
return DatabaseEventDuplicateField(payload).send();
@ -94,7 +94,7 @@ class FieldService {
required FieldType fieldType,
}) {
final payload = TypeOptionPathPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldId
..fieldType = fieldType;
return DatabaseEventGetTypeOption(payload).send().then((result) {
@ -109,7 +109,7 @@ class FieldService {
@freezed
class GridFieldCellContext with _$GridFieldCellContext {
const factory GridFieldCellContext({
required String databaseId,
required String viewId,
required FieldPB field,
}) = _GridFieldCellContext;
}

View File

@ -155,13 +155,13 @@ abstract class TypeOptionFieldDelegate {
}
abstract class IFieldTypeOptionLoader {
String get databaseId;
String get viewId;
Future<Either<TypeOptionPB, FlowyError>> load();
Future<Either<Unit, FlowyError>> switchToField(
String fieldId, FieldType fieldType) {
final payload = UpdateFieldTypePayloadPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldId
..fieldType = fieldType;
@ -174,9 +174,9 @@ class NewFieldTypeOptionLoader extends IFieldTypeOptionLoader {
TypeOptionPB? fieldTypeOption;
@override
final String databaseId;
final String viewId;
NewFieldTypeOptionLoader({
required this.databaseId,
required this.viewId,
});
/// Creates the field type option if the fieldTypeOption is null.
@ -185,14 +185,14 @@ class NewFieldTypeOptionLoader extends IFieldTypeOptionLoader {
Future<Either<TypeOptionPB, FlowyError>> load() {
if (fieldTypeOption != null) {
final payload = TypeOptionPathPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = fieldTypeOption!.field_2.id
..fieldType = fieldTypeOption!.field_2.fieldType;
return DatabaseEventGetTypeOption(payload).send();
} else {
final payload = CreateFieldPayloadPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldType = FieldType.RichText;
return DatabaseEventCreateTypeOption(payload).send().then((result) {
@ -211,18 +211,18 @@ class NewFieldTypeOptionLoader extends IFieldTypeOptionLoader {
/// Uses when editing a existing field
class FieldTypeOptionLoader extends IFieldTypeOptionLoader {
@override
final String databaseId;
final String viewId;
final FieldPB field;
FieldTypeOptionLoader({
required this.databaseId,
required this.viewId,
required this.field,
});
@override
Future<Either<TypeOptionPB, FlowyError>> load() {
final payload = TypeOptionPathPB.create()
..databaseId = databaseId
..viewId = viewId
..fieldId = field.id
..fieldType = field.fieldType;

View File

@ -28,7 +28,7 @@ class TypeOptionDataController {
}) {
if (fieldInfo != null) {
_typeOptiondata = TypeOptionPB.create()
..databaseId = databaseId
..viewId = databaseId
..field_2 = fieldInfo.field;
}
}
@ -66,8 +66,7 @@ class TypeOptionDataController {
_fieldNotifier.value = _typeOptiondata.field_2;
FieldService(databaseId: databaseId, fieldId: field.id)
.updateField(name: name);
FieldService(viewId: databaseId, fieldId: field.id).updateField(name: name);
}
set typeOptionData(List<int> typeOptionData) {
@ -78,7 +77,7 @@ class TypeOptionDataController {
});
FieldService.updateFieldTypeOption(
databaseId: databaseId,
viewId: databaseId,
fieldId: field.id,
typeOptionData: typeOptionData,
);

View File

@ -16,7 +16,7 @@ class CheckboxFilterEditorBloc
final FilterListener _listener;
CheckboxFilterEditorBloc({required this.filterInfo})
: _ffiService = FilterFFIService(databaseId: filterInfo.viewId),
: _ffiService = FilterFFIService(viewId: filterInfo.viewId),
_listener = FilterListener(
viewId: filterInfo.viewId,
filterId: filterInfo.filter.id,

View File

@ -18,7 +18,7 @@ class ChecklistFilterEditorBloc
ChecklistFilterEditorBloc({
required this.filterInfo,
}) : _ffiService = FilterFFIService(databaseId: filterInfo.viewId),
}) : _ffiService = FilterFFIService(viewId: filterInfo.viewId),
// _selectOptionService =
// SelectOptionFFIService(cellId: cellController.cellId)
_listener = FilterListener(

View File

@ -22,7 +22,7 @@ class GridCreateFilterBloc
final GridFieldController fieldController;
void Function(List<FieldInfo>)? _onFieldFn;
GridCreateFilterBloc({required this.viewId, required this.fieldController})
: _ffiService = FilterFFIService(databaseId: viewId),
: _ffiService = FilterFFIService(viewId: viewId),
super(GridCreateFilterState.initial(fieldController.fieldInfos)) {
on<GridCreateFilterEvent>(
(event, emit) async {

View File

@ -15,11 +15,11 @@ import 'package:appflowy_backend/protobuf/flowy-database/util.pb.dart';
import 'package:fixnum/fixnum.dart' as $fixnum;
class FilterFFIService {
final String databaseId;
const FilterFFIService({required this.databaseId});
final String viewId;
const FilterFFIService({required this.viewId});
Future<Either<List<FilterPB>, FlowyError>> getAllFilters() {
final payload = DatabaseIdPB()..value = databaseId;
final payload = DatabaseViewIdPB()..value = viewId;
return DatabaseEventGetAllFilters(payload).send().then((result) {
return result.fold(
@ -171,7 +171,7 @@ class FilterFFIService {
var insertFilterPayload = AlterFilterPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = databaseId
..viewId = viewId
..data = data;
if (filterId != null) {
@ -179,7 +179,7 @@ class FilterFFIService {
}
final payload = DatabaseSettingChangesetPB.create()
..databaseId = databaseId
..viewId = viewId
..alterFilter = insertFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
@ -200,11 +200,11 @@ class FilterFFIService {
final deleteFilterPayload = DeleteFilterPayloadPB.create()
..fieldId = fieldId
..filterId = filterId
..viewId = databaseId
..viewId = viewId
..fieldType = fieldType;
final payload = DatabaseSettingChangesetPB.create()
..databaseId = databaseId
..viewId = viewId
..deleteFilter = deleteFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {

View File

@ -20,7 +20,7 @@ class SelectOptionFilterEditorBloc
SelectOptionFilterEditorBloc({
required this.filterInfo,
required this.delegate,
}) : _ffiService = FilterFFIService(databaseId: filterInfo.viewId),
}) : _ffiService = FilterFFIService(viewId: filterInfo.viewId),
_listener = FilterListener(
viewId: filterInfo.viewId,
filterId: filterInfo.filter.id,

View File

@ -16,7 +16,7 @@ class TextFilterEditorBloc
final FilterListener _listener;
TextFilterEditorBloc({required this.filterInfo})
: _ffiService = FilterFFIService(databaseId: filterInfo.viewId),
: _ffiService = FilterFFIService(viewId: filterInfo.viewId),
_listener = FilterListener(
viewId: filterInfo.viewId,
filterId: filterInfo.filter.id,

View File

@ -32,7 +32,7 @@ class GridController {
GridController({required ViewPB view})
: databaseId = view.id,
_gridFFIService = DatabaseFFIService(databaseId: view.id),
_gridFFIService = DatabaseFFIService(viewId: view.id),
fieldController = GridFieldController(databaseId: view.id) {
_viewCache = DatabaseViewCache(
databaseId: databaseId,

View File

@ -46,7 +46,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
emit(state.copyWith(fields: fields));
final fieldService =
FieldService(databaseId: databaseId, fieldId: value.field.id);
FieldService(viewId: databaseId, fieldId: value.field.id);
final result = await fieldService.moveField(
value.fromIndex,
value.toIndex,

View File

@ -8,20 +8,20 @@ import 'package:appflowy_backend/protobuf/flowy-database/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
class DatabaseFFIService {
final String databaseId;
final String viewId;
DatabaseFFIService({
required this.databaseId,
required this.viewId,
});
Future<Either<DatabasePB, FlowyError>> openGrid() async {
await FolderEventSetLatestView(ViewIdPB(value: databaseId)).send();
await FolderEventSetLatestView(ViewIdPB(value: viewId)).send();
final payload = DatabaseIdPB(value: databaseId);
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetDatabase(payload).send();
}
Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
var payload = CreateRowPayloadPB.create()..databaseId = databaseId;
var payload = CreateRowPayloadPB.create()..viewId = viewId;
startRowId?.fold(() => null, (id) => payload.startRowId = id);
return DatabaseEventCreateRow(payload).send();
}
@ -31,7 +31,7 @@ class DatabaseFFIService {
String? startRowId,
) {
CreateBoardCardPayloadPB payload = CreateBoardCardPayloadPB.create()
..databaseId = databaseId
..viewId = viewId
..groupId = groupId;
if (startRowId != null) {
@ -43,7 +43,7 @@ class DatabaseFFIService {
Future<Either<List<FieldPB>, FlowyError>> getFields(
{List<FieldIdPB>? fieldIds}) {
var payload = GetFieldPayloadPB.create()..databaseId = databaseId;
var payload = GetFieldPayloadPB.create()..viewId = viewId;
if (fieldIds != null) {
payload.fieldIds = RepeatedFieldIdPB(items: fieldIds);
@ -54,12 +54,12 @@ class DatabaseFFIService {
}
Future<Either<Unit, FlowyError>> closeGrid() {
final request = ViewIdPB(value: databaseId);
final request = ViewIdPB(value: viewId);
return FolderEventCloseView(request).send();
}
Future<Either<RepeatedGroupPB, FlowyError>> loadGroups() {
final payload = DatabaseIdPB(value: databaseId);
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetGroup(payload).send();
}
}

View File

@ -214,7 +214,7 @@ class GridRowCache {
Future<void> _loadRow(String rowId) async {
final payload = RowIdPB.create()
..databaseId = databaseId
..viewId = databaseId
..rowId = rowId;
final result = await DatabaseEventGetRow(payload).send();

View File

@ -27,7 +27,7 @@ class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
},
deleteField: (_DeleteField value) {
final fieldService = FieldService(
databaseId: dataController.rowInfo.databaseId,
viewId: dataController.rowInfo.databaseId,
fieldId: value.fieldId,
);
fieldService.deleteField();

View File

@ -14,7 +14,7 @@ class RowFFIService {
Future<Either<RowPB, FlowyError>> createRow(String rowId) {
final payload = CreateRowPayloadPB.create()
..databaseId = databaseId
..viewId = databaseId
..startRowId = rowId;
return DatabaseEventCreateRow(payload).send();
@ -22,7 +22,7 @@ class RowFFIService {
Future<Either<OptionalRowPB, FlowyError>> getRow(String rowId) {
final payload = RowIdPB.create()
..databaseId = databaseId
..viewId = databaseId
..rowId = rowId;
return DatabaseEventGetRow(payload).send();
@ -30,7 +30,7 @@ class RowFFIService {
Future<Either<Unit, FlowyError>> deleteRow(String rowId) {
final payload = RowIdPB.create()
..databaseId = databaseId
..viewId = databaseId
..rowId = rowId;
return DatabaseEventDeleteRow(payload).send();
@ -38,7 +38,7 @@ class RowFFIService {
Future<Either<Unit, FlowyError>> duplicateRow(String rowId) {
final payload = RowIdPB.create()
..databaseId = databaseId
..viewId = databaseId
..rowId = rowId;
return DatabaseEventDuplicateRow(payload).send();

View File

@ -26,7 +26,7 @@ class GridPropertyBloc extends Bloc<GridPropertyEvent, GridPropertyState> {
},
setFieldVisibility: (_SetFieldVisibility value) async {
final fieldService =
FieldService(databaseId: databaseId, fieldId: value.fieldId);
FieldService(viewId: databaseId, fieldId: value.fieldId);
final result =
await fieldService.updateField(visibility: value.visibility);
result.fold(

View File

@ -12,7 +12,7 @@ class SettingFFIService {
const SettingFFIService({required this.viewId});
Future<Either<DatabaseViewSettingPB, FlowyError>> getSetting() {
final payload = DatabaseIdPB.create()..value = viewId;
final payload = DatabaseViewIdPB.create()..value = viewId;
return DatabaseEventGetDatabaseSetting(payload).send();
}
@ -24,7 +24,7 @@ class SettingFFIService {
..fieldId = fieldId
..fieldType = fieldType;
final payload = DatabaseSettingChangesetPB.create()
..databaseId = viewId
..viewId = viewId
..insertGroup = insertGroupPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send();

View File

@ -13,7 +13,7 @@ class SortFFIService {
SortFFIService({required this.viewId});
Future<Either<List<SortPB>, FlowyError>> getAllSorts() {
final payload = DatabaseIdPB()..value = viewId;
final payload = DatabaseViewIdPB()..value = viewId;
return DatabaseEventGetAllSorts(payload).send().then((result) {
return result.fold(
@ -37,7 +37,7 @@ class SortFFIService {
..sortId = sortId;
final payload = DatabaseSettingChangesetPB.create()
..databaseId = viewId
..viewId = viewId
..alterSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
@ -62,7 +62,7 @@ class SortFFIService {
..condition = condition;
final payload = DatabaseSettingChangesetPB.create()
..databaseId = viewId
..viewId = viewId
..alterSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
@ -87,7 +87,7 @@ class SortFFIService {
..fieldType = fieldType;
final payload = DatabaseSettingChangesetPB.create()
..databaseId = viewId
..viewId = viewId
..deleteSort = deleteFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
@ -102,7 +102,7 @@ class SortFFIService {
}
Future<Either<Unit, FlowyError>> deleteAllSorts() {
final payload = DatabaseIdPB(value: viewId);
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventDeleteAllSorts(payload).send().then((result) {
return result.fold(
(l) => left(l),

View File

@ -35,10 +35,10 @@ class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
return SizedBox(
width: 400,
child: FieldEditor(
databaseId: widget.cellContext.databaseId,
databaseId: widget.cellContext.viewId,
fieldName: field.name,
typeOptionLoader: FieldTypeOptionLoader(
databaseId: widget.cellContext.databaseId,
viewId: widget.cellContext.viewId,
field: field,
),
),
@ -206,7 +206,7 @@ extension _FieldActionExtension on FieldAction {
PopoverContainer.of(context).close();
FieldService(
databaseId: fieldInfo.databaseId,
viewId: fieldInfo.viewId,
fieldId: fieldInfo.field.id,
).duplicateField();
@ -218,7 +218,7 @@ extension _FieldActionExtension on FieldAction {
title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
confirm: () {
FieldService(
databaseId: fieldInfo.databaseId,
viewId: fieldInfo.viewId,
fieldId: fieldInfo.field.id,
).deleteField();
},

View File

@ -98,8 +98,8 @@ class _GridHeaderState extends State<_GridHeader> {
builder: (context, state) {
final cells = state.fields
.where((field) => field.visibility)
.map((field) => GridFieldCellContext(
databaseId: widget.viewId, field: field.field))
.map((field) =>
GridFieldCellContext(viewId: widget.viewId, field: field.field))
.map((ctx) =>
GridFieldCell(key: _getKeyById(ctx.field.id), cellContext: ctx))
.toList();
@ -189,7 +189,7 @@ class CreateFieldButton extends StatelessWidget {
popupBuilder: (BuildContext popover) {
return FieldEditor(
databaseId: databaseId,
typeOptionLoader: NewFieldTypeOptionLoader(databaseId: databaseId),
typeOptionLoader: NewFieldTypeOptionLoader(viewId: databaseId),
);
},
);

View File

@ -144,7 +144,7 @@ TypeOptionContext<T> makeTypeOptionContext<T extends GeneratedMessage>({
required FieldInfo fieldInfo,
}) {
final loader =
FieldTypeOptionLoader(databaseId: databaseId, field: fieldInfo.field);
FieldTypeOptionLoader(viewId: databaseId, field: fieldInfo.field);
final dataController = TypeOptionDataController(
databaseId: databaseId,
loader: loader,
@ -176,7 +176,7 @@ TypeOptionContext<T> makeSelectTypeOptionContext<T extends GeneratedMessage>({
required FieldPB fieldPB,
}) {
final loader = FieldTypeOptionLoader(
databaseId: databaseId,
viewId: databaseId,
field: fieldPB,
);
final dataController = TypeOptionDataController(

View File

@ -206,7 +206,7 @@ class _CreateFieldButtonState extends State<_CreateFieldButton> {
popupBuilder: (BuildContext popOverContext) {
return FieldEditor(
databaseId: widget.viewId,
typeOptionLoader: NewFieldTypeOptionLoader(databaseId: widget.viewId),
typeOptionLoader: NewFieldTypeOptionLoader(viewId: widget.viewId),
onDeleted: (fieldId) {
popoverController.close();
@ -300,7 +300,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
fieldName: widget.cellId.fieldInfo.field.name,
isGroupField: widget.cellId.fieldInfo.isGroupField,
typeOptionLoader: FieldTypeOptionLoader(
databaseId: widget.cellId.databaseId,
viewId: widget.cellId.databaseId,
field: widget.cellId.fieldInfo.field,
),
onDeleted: (fieldId) {

View File

@ -139,7 +139,7 @@ class _GridPropertyCellState extends State<_GridPropertyCell> {
databaseId: widget.databaseId,
fieldName: widget.fieldInfo.name,
typeOptionLoader: FieldTypeOptionLoader(
databaseId: widget.databaseId,
viewId: widget.databaseId,
field: widget.fieldInfo.field,
),
);

View File

@ -30,7 +30,7 @@ void main() {
final fieldInfo = context.singleSelectFieldContext();
final loader = FieldTypeOptionLoader(
databaseId: context.gridView.id,
viewId: context.gridView.id,
field: fieldInfo.field,
);

View File

@ -81,10 +81,10 @@ class BoardTestContext {
}) {
IFieldTypeOptionLoader loader;
if (fieldInfo == null) {
loader = NewFieldTypeOptionLoader(databaseId: gridView.id);
loader = NewFieldTypeOptionLoader(viewId: gridView.id);
} else {
loader = FieldTypeOptionLoader(
databaseId: gridView.id, field: fieldInfo.field);
loader =
FieldTypeOptionLoader(viewId: gridView.id, field: fieldInfo.field);
}
final editorBloc = FieldEditorBloc(
@ -144,7 +144,7 @@ class BoardTestContext {
GridFieldCellContext singleSelectFieldCellContext() {
final field = singleSelectFieldContext().field;
return GridFieldCellContext(databaseId: gridView.id, field: field);
return GridFieldCellContext(viewId: gridView.id, field: field);
}
FieldInfo textFieldContext() {

View File

@ -8,7 +8,7 @@ Future<FieldEditorBloc> createEditorBloc(AppFlowyGridTest gridTest) async {
final context = await gridTest.createTestGrid();
final fieldInfo = context.singleSelectFieldContext();
final loader = FieldTypeOptionLoader(
databaseId: context.gridView.id,
viewId: context.gridView.id,
field: fieldInfo.field,
);
@ -78,7 +78,7 @@ Future<FieldEditorBloc> makeEditorBloc(AppFlowyGridTest gridTest) async {
final context = await gridTest.createTestGrid();
final fieldInfo = context.singleSelectFieldContext();
final loader = FieldTypeOptionLoader(
databaseId: context.gridView.id,
viewId: context.gridView.id,
field: fieldInfo.field,
);

View File

@ -15,7 +15,7 @@ void main() {
test('create a text filter)', () async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
await service.insertTextFilter(
fieldId: textField.id,
@ -28,7 +28,7 @@ void main() {
test('delete a text filter)', () async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
await service.insertTextFilter(
fieldId: textField.id,
@ -49,7 +49,7 @@ void main() {
test('filter rows with condition: text is empty', () async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final gridController = GridController(view: context.gridView);
final gridBloc = GridBloc(
view: context.gridView,
@ -70,7 +70,7 @@ void main() {
test('filter rows with condition: text is empty(After edit the row)',
() async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final gridController = GridController(view: context.gridView);
final gridBloc = GridBloc(
view: context.gridView,
@ -97,7 +97,7 @@ void main() {
test('filter rows with condition: text is not empty', () async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
await gridResponseFuture();
await service.insertTextFilter(
@ -111,7 +111,7 @@ void main() {
test('filter rows with condition: checkbox uncheck', () async {
final context = await gridTest.createTestGrid();
final checkboxField = context.checkboxFieldContext();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final gridController = GridController(view: context.gridView);
final gridBloc = GridBloc(
view: context.gridView,
@ -130,7 +130,7 @@ void main() {
test('filter rows with condition: checkbox check', () async {
final context = await gridTest.createTestGrid();
final checkboxField = context.checkboxFieldContext();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final gridController = GridController(view: context.gridView);
final gridBloc = GridBloc(
view: context.gridView,

View File

@ -16,7 +16,7 @@ void main() {
test("create a text filter and then alter the filter's field)", () async {
final context = await gridTest.createTestGrid();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// Create the filter menu bloc
@ -35,7 +35,7 @@ void main() {
// Edit the text field
final loader = FieldTypeOptionLoader(
databaseId: context.gridView.id,
viewId: context.gridView.id,
field: textField.field,
);

View File

@ -19,7 +19,7 @@ void main() {
await gridResponseFuture();
assert(menuBloc.state.creatableFields.length == 3);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
await service.insertTextFilter(
fieldId: textField.id,
@ -36,7 +36,7 @@ void main() {
..add(const GridFilterMenuEvent.initial());
await gridResponseFuture();
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// Create filter

View File

@ -13,7 +13,7 @@ void main() {
test('filter rows by checkbox is check condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final controller = await context.makeCheckboxCellController(0);
controller.saveCellData("Yes");
@ -32,7 +32,7 @@ void main() {
test('filter rows by checkbox is uncheck condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final controller = await context.makeCheckboxCellController(0);
controller.saveCellData("Yes");

View File

@ -14,7 +14,7 @@ void main() {
test('filter rows by text is empty condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// create a new filter
await service.insertTextFilter(
@ -41,7 +41,7 @@ void main() {
test('filter rows by text is not empty condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// create a new filter
await service.insertTextFilter(
@ -66,7 +66,7 @@ void main() {
test('filter rows by text is empty or is not empty condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// create a new filter
await service.insertTextFilter(
@ -102,7 +102,7 @@ void main() {
test('filter rows by text is condition)', () async {
final context = await createTestFilterGrid(gridTest);
final service = FilterFFIService(databaseId: context.gridView.id);
final service = FilterFFIService(viewId: context.gridView.id);
final textField = context.textFieldContext();
// create a new filter
await service.insertTextFilter(

View File

@ -39,10 +39,10 @@ class GridTestContext {
}) {
IFieldTypeOptionLoader loader;
if (fieldInfo == null) {
loader = NewFieldTypeOptionLoader(databaseId: gridView.id);
loader = NewFieldTypeOptionLoader(viewId: gridView.id);
} else {
loader = FieldTypeOptionLoader(
databaseId: gridView.id, field: fieldInfo.field);
loader =
FieldTypeOptionLoader(viewId: gridView.id, field: fieldInfo.field);
}
final editorBloc = FieldEditorBloc(
@ -104,7 +104,7 @@ class GridTestContext {
GridFieldCellContext singleSelectFieldCellContext() {
final field = singleSelectFieldContext().field;
return GridFieldCellContext(databaseId: gridView.id, field: field);
return GridFieldCellContext(viewId: gridView.id, field: field);
}
FieldInfo textFieldContext() {

View File

@ -849,6 +849,18 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "database-model"
version = "0.1.0"
dependencies = [
"bytes",
"indexmap",
"nanoid",
"serde",
"serde_json",
"serde_repr",
]
[[package]]
name = "derivative"
version = "2.2.0"
@ -1132,12 +1144,12 @@ version = "0.1.0"
dependencies = [
"bytes",
"chrono",
"database-model",
"dissimilar",
"document-model",
"flowy-derive",
"flowy-sync",
"folder-model",
"grid-model",
"lib-infra",
"lib-ot",
"parking_lot",
@ -1195,6 +1207,7 @@ name = "flowy-core"
version = "0.1.0"
dependencies = [
"bytes",
"database-model",
"flowy-client-ws",
"flowy-database",
"flowy-document",
@ -1206,7 +1219,6 @@ dependencies = [
"flowy-task",
"flowy-user",
"futures-core",
"grid-model",
"lib-dispatch",
"lib-infra",
"lib-log",
@ -1230,6 +1242,7 @@ dependencies = [
"chrono",
"crossbeam-utils",
"dashmap",
"database-model",
"diesel",
"fancy-regex 0.10.0",
"flowy-client-sync",
@ -1242,7 +1255,6 @@ dependencies = [
"flowy-sqlite",
"flowy-task",
"futures",
"grid-model",
"indexmap",
"lazy_static",
"lib-dispatch",
@ -1960,18 +1972,6 @@ dependencies = [
"system-deps 6.0.3",
]
[[package]]
name = "grid-model"
version = "0.1.0"
dependencies = [
"bytes",
"indexmap",
"nanoid",
"serde",
"serde_json",
"serde_repr",
]
[[package]]
name = "gtk"
version = "0.15.5"

View File

@ -3,7 +3,7 @@ import {
DatabaseEventGetDatabase,
DatabaseEventGetFields,
} from '../../../../services/backend/events/flowy-database/event';
import { DatabaseIdPB } from '../../../../services/backend/models/flowy-database';
import { DatabaseViewIdPB } from '../../../../services/backend/models/flowy-database';
import { CreateRowPayloadPB } from '../../../../services/backend/models/flowy-database/row_entities';
import {
GetFieldPayloadPB,
@ -21,7 +21,7 @@ export class DatabaseBackendService {
}
openDatabase = async () => {
const payload = DatabaseIdPB.fromObject({
const payload = DatabaseViewIdPB.fromObject({
value: this.viewId,
});
return DatabaseEventGetDatabase(payload);
@ -39,7 +39,7 @@ export class DatabaseBackendService {
};
getFields = async (fieldIds?: FieldIdPB[]) => {
const payload = GetFieldPayloadPB.fromObject({ database_id: this.viewId });
const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId });
if (!fieldIds) {
payload.field_ids = RepeatedFieldIdPB.fromObject({ items: fieldIds });

View File

@ -19,7 +19,7 @@ export abstract class TypeOptionParser<T> {
}
export class FieldBackendService {
constructor(public readonly databaseId: string, public readonly fieldId: string) {}
constructor(public readonly viewId: string, public readonly fieldId: string) {}
updateField = (data: {
name?: string;
@ -28,7 +28,7 @@ export class FieldBackendService {
visibility?: boolean;
width?: number;
}) => {
const payload = FieldChangesetPB.fromObject({ database_id: this.databaseId, field_id: this.fieldId });
const payload = FieldChangesetPB.fromObject({ database_id: this.viewId, field_id: this.fieldId });
if (data.name !== undefined) {
payload.name = data.name;
@ -55,7 +55,7 @@ export class FieldBackendService {
updateTypeOption = (typeOptionData: Uint8Array) => {
const payload = TypeOptionChangesetPB.fromObject({
database_id: this.databaseId,
view_id: this.viewId,
field_id: this.fieldId,
type_option_data: typeOptionData,
});
@ -64,20 +64,20 @@ export class FieldBackendService {
};
deleteField = () => {
const payload = DeleteFieldPayloadPB.fromObject({ database_id: this.databaseId, field_id: this.fieldId });
const payload = DeleteFieldPayloadPB.fromObject({ view_id: this.viewId, field_id: this.fieldId });
return DatabaseEventDeleteField(payload);
};
duplicateField = () => {
const payload = DuplicateFieldPayloadPB.fromObject({ database_id: this.databaseId, field_id: this.fieldId });
const payload = DuplicateFieldPayloadPB.fromObject({ view_id: this.viewId, field_id: this.fieldId });
return DatabaseEventDuplicateField(payload);
};
getTypeOptionData = (fieldType: FieldType) => {
const payload = TypeOptionPathPB.fromObject({
database_id: this.databaseId,
view_id: this.viewId,
field_id: this.fieldId,
field_type: fieldType,
});

View File

@ -695,6 +695,18 @@ dependencies = [
"parking_lot 0.12.1",
]
[[package]]
name = "database-model"
version = "0.1.0"
dependencies = [
"bytes",
"indexmap",
"nanoid",
"serde",
"serde_json",
"serde_repr",
]
[[package]]
name = "derivative"
version = "2.2.0"
@ -921,12 +933,12 @@ version = "0.1.0"
dependencies = [
"bytes",
"chrono",
"database-model",
"dissimilar",
"document-model",
"flowy-derive",
"flowy-sync",
"folder-model",
"grid-model",
"lib-infra",
"lib-ot",
"parking_lot 0.12.1",
@ -984,6 +996,7 @@ name = "flowy-core"
version = "0.1.0"
dependencies = [
"bytes",
"database-model",
"flowy-client-ws",
"flowy-database",
"flowy-document",
@ -995,7 +1008,6 @@ dependencies = [
"flowy-task",
"flowy-user",
"futures-core",
"grid-model",
"lib-dispatch",
"lib-infra",
"lib-log",
@ -1019,6 +1031,7 @@ dependencies = [
"chrono",
"crossbeam-utils",
"dashmap",
"database-model",
"diesel",
"fancy-regex 0.10.0",
"flowy-client-sync",
@ -1033,7 +1046,6 @@ dependencies = [
"flowy-task",
"flowy-test",
"futures",
"grid-model",
"indexmap",
"lazy_static",
"lib-dispatch",
@ -1613,18 +1625,6 @@ dependencies = [
"walkdir",
]
[[package]]
name = "grid-model"
version = "0.1.0"
dependencies = [
"bytes",
"indexmap",
"nanoid",
"serde",
"serde_json",
"serde_repr",
]
[[package]]
name = "h2"
version = "0.3.15"

View File

@ -10,7 +10,7 @@ lib-ot = { path = "../../../shared-lib/lib-ot" }
lib-infra = { path = "../../../shared-lib/lib-infra" }
flowy-derive = { path = "../flowy-derive" }
folder-model = { path = "../../../shared-lib/folder-model" }
grid-model = { path = "../../../shared-lib/grid-model" }
database-model = { path = "../../../shared-lib/database-model" }
revision-model = { path = "../../../shared-lib/revision-model" }
document-model = { path = "../../../shared-lib/document-model" }
flowy-sync = { path = "../../../shared-lib/flowy-sync" }

View File

@ -1,26 +1,27 @@
use crate::errors::{SyncError, SyncResult};
use crate::util::cal_diff;
use flowy_sync::util::make_operations_from_revisions;
use grid_model::{
use database_model::{
gen_block_id, gen_row_id, CellRevision, DatabaseBlockRevision, RowChangeset, RowRevision,
};
use flowy_sync::util::make_operations_from_revisions;
use lib_infra::util::md5;
use lib_ot::core::{DeltaBuilder, DeltaOperations, EmptyAttributes, OperationTransform};
use revision_model::Revision;
use std::any::type_name;
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;
pub type GridBlockOperations = DeltaOperations<EmptyAttributes>;
pub type GridBlockOperationsBuilder = DeltaBuilder;
pub type DatabaseBlockOperations = DeltaOperations<EmptyAttributes>;
pub type DatabaseBlockOperationsBuilder = DeltaBuilder;
#[derive(Debug, Clone)]
pub struct GridBlockRevisionPad {
pub struct DatabaseBlockRevisionPad {
block: DatabaseBlockRevision,
operations: GridBlockOperations,
operations: DatabaseBlockOperations,
}
impl std::ops::Deref for GridBlockRevisionPad {
impl std::ops::Deref for DatabaseBlockRevisionPad {
type Target = DatabaseBlockRevision;
fn deref(&self) -> &Self::Target {
@ -28,7 +29,7 @@ impl std::ops::Deref for GridBlockRevisionPad {
}
}
impl GridBlockRevisionPad {
impl DatabaseBlockRevisionPad {
pub fn duplicate_data(&self, duplicated_block_id: &str) -> DatabaseBlockRevision {
let duplicated_rows = self
.block
@ -47,10 +48,14 @@ impl GridBlockRevisionPad {
}
}
pub fn from_operations(operations: GridBlockOperations) -> SyncResult<Self> {
pub fn from_operations(operations: DatabaseBlockOperations) -> SyncResult<Self> {
let s = operations.content()?;
let revision: DatabaseBlockRevision = serde_json::from_str(&s).map_err(|e| {
let msg = format!("Deserialize operations to GridBlockRevision failed: {}", e);
let msg = format!(
"Deserialize operations to {} failed: {}",
type_name::<DatabaseBlockRevision>(),
e
);
tracing::error!("{}", s);
SyncError::internal().context(msg)
})?;
@ -60,8 +65,8 @@ impl GridBlockRevisionPad {
})
}
pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> SyncResult<Self> {
let operations: GridBlockOperations = make_operations_from_revisions(revisions)?;
pub fn from_revisions(revisions: Vec<Revision>) -> SyncResult<Self> {
let operations: DatabaseBlockOperations = make_operations_from_revisions(revisions)?;
Self::from_operations(operations)
}
@ -70,7 +75,7 @@ impl GridBlockRevisionPad {
&mut self,
row: RowRevision,
start_row_id: Option<String>,
) -> SyncResult<Option<GridBlockRevisionChangeset>> {
) -> SyncResult<Option<DatabaseBlockRevisionChangeset>> {
self.modify(|rows| {
if let Some(start_row_id) = start_row_id {
if !start_row_id.is_empty() {
@ -89,7 +94,7 @@ impl GridBlockRevisionPad {
pub fn delete_rows(
&mut self,
row_ids: Vec<Cow<'_, String>>,
) -> SyncResult<Option<GridBlockRevisionChangeset>> {
) -> SyncResult<Option<DatabaseBlockRevisionChangeset>> {
self.modify(|rows| {
rows.retain(|row| !row_ids.contains(&Cow::Borrowed(&row.id)));
Ok(Some(()))
@ -168,7 +173,7 @@ impl GridBlockRevisionPad {
pub fn update_row(
&mut self,
changeset: RowChangeset,
) -> SyncResult<Option<GridBlockRevisionChangeset>> {
) -> SyncResult<Option<DatabaseBlockRevisionChangeset>> {
let row_id = changeset.row_id.clone();
self.modify_row(&row_id, |row| {
let mut is_changed = None;
@ -201,7 +206,7 @@ impl GridBlockRevisionPad {
row_id: &str,
from: usize,
to: usize,
) -> SyncResult<Option<GridBlockRevisionChangeset>> {
) -> SyncResult<Option<DatabaseBlockRevisionChangeset>> {
self.modify(|row_revs| {
if let Some(position) = row_revs.iter().position(|row_rev| row_rev.id == row_id) {
debug_assert_eq!(from, position);
@ -218,7 +223,7 @@ impl GridBlockRevisionPad {
})
}
pub fn modify<F>(&mut self, f: F) -> SyncResult<Option<GridBlockRevisionChangeset>>
pub fn modify<F>(&mut self, f: F) -> SyncResult<Option<DatabaseBlockRevisionChangeset>>
where
F: for<'a> FnOnce(&'a mut Vec<Arc<RowRevision>>) -> SyncResult<Option<()>>,
{
@ -232,11 +237,12 @@ impl GridBlockRevisionPad {
None => Ok(None),
Some(operations) => {
tracing::trace!(
"[GridBlockRevision] Composing operations {}",
"[{}] Composing operations {}",
type_name::<DatabaseBlockRevision>(),
operations.json_str()
);
self.operations = self.operations.compose(&operations)?;
Ok(Some(GridBlockRevisionChangeset {
Ok(Some(DatabaseBlockRevisionChangeset {
operations,
md5: md5(&self.operations.json_bytes()),
}))
@ -246,7 +252,11 @@ impl GridBlockRevisionPad {
}
}
fn modify_row<F>(&mut self, row_id: &str, f: F) -> SyncResult<Option<GridBlockRevisionChangeset>>
fn modify_row<F>(
&mut self,
row_id: &str,
f: F,
) -> SyncResult<Option<DatabaseBlockRevisionChangeset>>
where
F: FnOnce(&mut RowRevision) -> SyncResult<Option<()>>,
{
@ -270,28 +280,30 @@ impl GridBlockRevisionPad {
}
}
pub struct GridBlockRevisionChangeset {
pub operations: GridBlockOperations,
pub struct DatabaseBlockRevisionChangeset {
pub operations: DatabaseBlockOperations,
/// md5: the md5 of the grid after applying the change.
pub md5: String,
}
pub fn make_database_block_operations(block_rev: &DatabaseBlockRevision) -> GridBlockOperations {
pub fn make_database_block_operations(
block_rev: &DatabaseBlockRevision,
) -> DatabaseBlockOperations {
let json = serde_json::to_string(&block_rev).unwrap();
GridBlockOperationsBuilder::new().insert(&json).build()
DatabaseBlockOperationsBuilder::new().insert(&json).build()
}
pub fn make_grid_block_revisions(
pub fn make_database_block_revisions(
_user_id: &str,
grid_block_meta_data: &DatabaseBlockRevision,
database_block_meta_data: &DatabaseBlockRevision,
) -> Vec<Revision> {
let operations = make_database_block_operations(grid_block_meta_data);
let operations = make_database_block_operations(database_block_meta_data);
let bytes = operations.json_bytes();
let revision = Revision::initial_revision(&grid_block_meta_data.block_id, bytes);
let revision = Revision::initial_revision(&database_block_meta_data.block_id, bytes);
vec![revision]
}
impl std::default::Default for GridBlockRevisionPad {
impl std::default::Default for DatabaseBlockRevisionPad {
fn default() -> Self {
let block_revision = DatabaseBlockRevision {
block_id: gen_block_id(),
@ -299,7 +311,7 @@ impl std::default::Default for GridBlockRevisionPad {
};
let operations = make_database_block_operations(&block_revision);
GridBlockRevisionPad {
DatabaseBlockRevisionPad {
block: block_revision,
operations,
}
@ -308,8 +320,8 @@ impl std::default::Default for GridBlockRevisionPad {
#[cfg(test)]
mod tests {
use crate::client_database::{GridBlockOperations, GridBlockRevisionPad};
use grid_model::{RowChangeset, RowRevision};
use crate::client_database::{DatabaseBlockOperations, DatabaseBlockRevisionPad};
use database_model::{RowChangeset, RowRevision};
use std::borrow::Cow;
@ -365,7 +377,7 @@ mod tests {
assert_eq!(*pad.rows[2], row_3);
}
fn test_row_rev(id: &str, pad: &GridBlockRevisionPad) -> RowRevision {
fn test_row_rev(id: &str, pad: &DatabaseBlockRevisionPad) -> RowRevision {
RowRevision {
id: id.to_string(),
block_id: pad.block_id.clone(),
@ -470,9 +482,10 @@ mod tests {
);
}
fn test_pad() -> GridBlockRevisionPad {
fn test_pad() -> DatabaseBlockRevisionPad {
let operations =
GridBlockOperations::from_json(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap();
GridBlockRevisionPad::from_operations(operations).unwrap()
DatabaseBlockOperations::from_json(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#)
.unwrap();
DatabaseBlockRevisionPad::from_operations(operations).unwrap()
}
}

View File

@ -1,6 +1,7 @@
use crate::errors::{SyncError, SyncResult};
use grid_model::{
BuildDatabaseContext, DatabaseBlockRevision, FieldRevision, GridBlockMetaRevision, RowRevision,
use database_model::{
BuildDatabaseContext, DatabaseBlockMetaRevision, DatabaseBlockRevision, FieldRevision,
RowRevision,
};
use std::sync::Arc;
@ -12,7 +13,7 @@ impl std::default::Default for DatabaseBuilder {
fn default() -> Self {
let mut build_context = BuildDatabaseContext::new();
let block_meta = GridBlockMetaRevision::new();
let block_meta = DatabaseBlockMetaRevision::new();
let block_meta_data = DatabaseBlockRevision {
block_id: block_meta.block_id.clone(),
rows: vec![],

View File

@ -1,10 +1,10 @@
use crate::errors::{internal_sync_error, SyncError, SyncResult};
use crate::util::cal_diff;
use flowy_sync::util::make_operations_from_revisions;
use grid_model::{
gen_block_id, gen_grid_id, DatabaseRevision, FieldRevision, FieldTypeRevision,
GridBlockMetaRevision, GridBlockMetaRevisionChangeset,
use database_model::{
gen_block_id, gen_database_id, DatabaseBlockMetaRevision, DatabaseBlockMetaRevisionChangeset,
DatabaseRevision, FieldRevision, FieldTypeRevision,
};
use flowy_sync::util::make_operations_from_revisions;
use lib_infra::util::md5;
use lib_infra::util::move_vec_element;
use lib_ot::core::{DeltaOperationBuilder, DeltaOperations, EmptyAttributes, OperationTransform};
@ -17,7 +17,7 @@ pub type DatabaseOperationsBuilder = DeltaOperationBuilder<EmptyAttributes>;
#[derive(Clone)]
pub struct DatabaseRevisionPad {
grid_rev: Arc<DatabaseRevision>,
database_rev: Arc<DatabaseRevision>,
operations: DatabaseOperations,
}
@ -26,21 +26,22 @@ pub trait JsonDeserializer {
}
impl DatabaseRevisionPad {
pub fn grid_id(&self) -> String {
self.grid_rev.grid_id.clone()
pub fn database_id(&self) -> String {
self.database_rev.database_id.clone()
}
pub async fn duplicate_grid_block_meta(
pub async fn duplicate_database_block_meta(
&self,
) -> (Vec<FieldRevision>, Vec<GridBlockMetaRevision>) {
) -> (Vec<FieldRevision>, Vec<DatabaseBlockMetaRevision>) {
let fields = self
.grid_rev
.database_rev
.fields
.iter()
.map(|field_rev| field_rev.as_ref().clone())
.collect();
let blocks = self
.grid_rev
.database_rev
.blocks
.iter()
.map(|block| {
@ -48,21 +49,21 @@ impl DatabaseRevisionPad {
duplicated_block.block_id = gen_block_id();
duplicated_block
})
.collect::<Vec<GridBlockMetaRevision>>();
.collect::<Vec<DatabaseBlockMetaRevision>>();
(fields, blocks)
}
pub fn from_operations(operations: DatabaseOperations) -> SyncResult<Self> {
let content = operations.content()?;
let grid: DatabaseRevision = serde_json::from_str(&content).map_err(|e| {
let database_rev: DatabaseRevision = serde_json::from_str(&content).map_err(|e| {
let msg = format!("Deserialize operations to grid failed: {}", e);
tracing::error!("{}", msg);
SyncError::internal().context(msg)
})?;
Ok(Self {
grid_rev: Arc::new(grid),
database_rev: Arc::new(database_rev),
operations,
})
}
@ -78,7 +79,7 @@ impl DatabaseRevisionPad {
new_field_rev: FieldRevision,
start_field_id: Option<String>,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
// Check if the field exists or not
if grid_meta
.fields
@ -109,7 +110,7 @@ impl DatabaseRevisionPad {
&mut self,
field_id: &str,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
match grid_meta
.fields
.iter()
@ -133,7 +134,7 @@ impl DatabaseRevisionPad {
field_id: &str,
duplicated_field_id: &str,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
match grid_meta
.fields
.iter()
@ -176,7 +177,7 @@ impl DatabaseRevisionPad {
T: Into<FieldTypeRevision>,
{
let new_field_type = new_field_type.into();
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
match grid_meta
.fields
.iter_mut()
@ -224,7 +225,7 @@ impl DatabaseRevisionPad {
&mut self,
field_rev: Arc<FieldRevision>,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
match grid_meta
.fields
.iter()
@ -246,7 +247,7 @@ impl DatabaseRevisionPad {
from_index: usize,
to_index: usize,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
match move_vec_element(
&mut grid_meta.fields,
|field| field.id == field_id,
@ -263,7 +264,7 @@ impl DatabaseRevisionPad {
pub fn contain_field(&self, field_id: &str) -> bool {
self
.grid_rev
.database_rev
.fields
.iter()
.any(|field| field.id == field_id)
@ -271,7 +272,7 @@ impl DatabaseRevisionPad {
pub fn get_field_rev(&self, field_id: &str) -> Option<(usize, &Arc<FieldRevision>)> {
self
.grid_rev
.database_rev
.fields
.iter()
.enumerate()
@ -283,10 +284,10 @@ impl DatabaseRevisionPad {
field_ids: Option<Vec<String>>,
) -> SyncResult<Vec<Arc<FieldRevision>>> {
match field_ids {
None => Ok(self.grid_rev.fields.clone()),
None => Ok(self.database_rev.fields.clone()),
Some(field_ids) => {
let field_by_field_id = self
.grid_rev
.database_rev
.fields
.iter()
.map(|field| (&field.id, field))
@ -309,9 +310,9 @@ impl DatabaseRevisionPad {
pub fn create_block_meta_rev(
&mut self,
block: GridBlockMetaRevision,
block: DatabaseBlockMetaRevision,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
self.modify_grid(|grid_meta| {
self.modify_database(|grid_meta| {
if grid_meta.blocks.iter().any(|b| b.block_id == block.block_id) {
tracing::warn!("Duplicate grid block");
Ok(None)
@ -333,13 +334,13 @@ impl DatabaseRevisionPad {
})
}
pub fn get_block_meta_revs(&self) -> Vec<Arc<GridBlockMetaRevision>> {
self.grid_rev.blocks.clone()
pub fn get_block_meta_revs(&self) -> Vec<Arc<DatabaseBlockMetaRevision>> {
self.database_rev.blocks.clone()
}
pub fn update_block_rev(
&mut self,
changeset: GridBlockMetaRevisionChangeset,
changeset: DatabaseBlockMetaRevisionChangeset,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
let block_id = changeset.block_id.clone();
self.modify_block(&block_id, |block| {
@ -368,18 +369,18 @@ impl DatabaseRevisionPad {
}
pub fn get_fields(&self) -> &[Arc<FieldRevision>] {
&self.grid_rev.fields
&self.database_rev.fields
}
fn modify_grid<F>(&mut self, f: F) -> SyncResult<Option<DatabaseRevisionChangeset>>
fn modify_database<F>(&mut self, f: F) -> SyncResult<Option<DatabaseRevisionChangeset>>
where
F: FnOnce(&mut DatabaseRevision) -> SyncResult<Option<()>>,
{
let cloned_grid = self.grid_rev.clone();
match f(Arc::make_mut(&mut self.grid_rev))? {
let cloned_database = self.database_rev.clone();
match f(Arc::make_mut(&mut self.database_rev))? {
None => Ok(None),
Some(_) => {
let old = make_database_rev_json_str(&cloned_grid)?;
let old = make_database_rev_json_str(&cloned_database)?;
let new = self.json_str()?;
match cal_diff::<EmptyAttributes>(old, new) {
None => Ok(None),
@ -401,9 +402,9 @@ impl DatabaseRevisionPad {
f: F,
) -> SyncResult<Option<DatabaseRevisionChangeset>>
where
F: FnOnce(&mut GridBlockMetaRevision) -> SyncResult<Option<()>>,
F: FnOnce(&mut DatabaseBlockMetaRevision) -> SyncResult<Option<()>>,
{
self.modify_grid(|grid_rev| {
self.modify_database(|grid_rev| {
match grid_rev
.blocks
.iter()
@ -429,7 +430,7 @@ impl DatabaseRevisionPad {
where
F: FnOnce(&mut FieldRevision) -> SyncResult<Option<()>>,
{
self.modify_grid(|grid_rev| {
self.modify_database(|grid_rev| {
match grid_rev
.fields
.iter()
@ -448,7 +449,7 @@ impl DatabaseRevisionPad {
}
pub fn json_str(&self) -> SyncResult<String> {
make_database_rev_json_str(&self.grid_rev)
make_database_rev_json_str(&self.database_rev)
}
}
@ -472,16 +473,16 @@ pub fn make_database_operations(grid_rev: &DatabaseRevision) -> DatabaseOperatio
pub fn make_database_revisions(_user_id: &str, grid_rev: &DatabaseRevision) -> Vec<Revision> {
let operations = make_database_operations(grid_rev);
let bytes = operations.json_bytes();
let revision = Revision::initial_revision(&grid_rev.grid_id, bytes);
let revision = Revision::initial_revision(&grid_rev.database_id, bytes);
vec![revision]
}
impl std::default::Default for DatabaseRevisionPad {
fn default() -> Self {
let grid = DatabaseRevision::new(&gen_grid_id());
let operations = make_database_operations(&grid);
let database = DatabaseRevision::new(&gen_database_id());
let operations = make_database_operations(&database);
DatabaseRevisionPad {
grid_rev: Arc::new(grid),
database_rev: Arc::new(database),
operations,
}
}

View File

@ -1,10 +1,10 @@
use crate::errors::{internal_sync_error, SyncError, SyncResult};
use crate::util::cal_diff;
use flowy_sync::util::make_operations_from_revisions;
use grid_model::{
use database_model::{
DatabaseViewRevision, FieldRevision, FieldTypeRevision, FilterRevision,
GroupConfigurationRevision, LayoutRevision, SortRevision,
};
use flowy_sync::util::make_operations_from_revisions;
use lib_infra::util::md5;
use lib_ot::core::{DeltaBuilder, DeltaOperations, EmptyAttributes, OperationTransform};
use revision_model::Revision;
@ -14,12 +14,12 @@ pub type GridViewOperations = DeltaOperations<EmptyAttributes>;
pub type GridViewOperationsBuilder = DeltaBuilder;
#[derive(Debug, Clone)]
pub struct GridViewRevisionPad {
pub struct DatabaseViewRevisionPad {
view: Arc<DatabaseViewRevision>,
operations: GridViewOperations,
}
impl std::ops::Deref for GridViewRevisionPad {
impl std::ops::Deref for DatabaseViewRevisionPad {
type Target = DatabaseViewRevision;
fn deref(&self) -> &Self::Target {
@ -27,23 +27,19 @@ impl std::ops::Deref for GridViewRevisionPad {
}
}
impl GridViewRevisionPad {
// For the moment, the view_id is equal to grid_id. The grid_id represents the database id.
impl DatabaseViewRevisionPad {
// For the moment, the view_id is equal to grid_id. The database_id represents the database id.
// A database can be referenced by multiple views.
pub fn new(grid_id: String, view_id: String, layout: LayoutRevision) -> Self {
let view = Arc::new(DatabaseViewRevision::new(grid_id, view_id, layout));
pub fn new(database_id: String, view_id: String, layout: LayoutRevision) -> Self {
let view = Arc::new(DatabaseViewRevision::new(database_id, view_id, layout));
let json = serde_json::to_string(&view).unwrap();
let operations = GridViewOperationsBuilder::new().insert(&json).build();
Self { view, operations }
}
pub fn from_operations(view_id: &str, operations: GridViewOperations) -> SyncResult<Self> {
pub fn from_operations(operations: GridViewOperations) -> SyncResult<Self> {
if operations.is_empty() {
return Ok(GridViewRevisionPad::new(
view_id.to_owned(),
view_id.to_owned(),
LayoutRevision::Grid,
));
return Err(SyncError::record_not_found().context("Unexpected empty operations"));
}
let s = operations.content()?;
let view: DatabaseViewRevision = serde_json::from_str(&s).map_err(|e| {
@ -57,9 +53,9 @@ impl GridViewRevisionPad {
})
}
pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> SyncResult<Self> {
pub fn from_revisions(revisions: Vec<Revision>) -> SyncResult<Self> {
let operations: GridViewOperations = make_operations_from_revisions(revisions)?;
Self::from_operations(view_id, operations)
Self::from_operations(operations)
}
pub fn get_groups_by_field_revs(

View File

@ -1,9 +1,9 @@
mod block_revision_pad;
mod database_builder;
mod database_revision_pad;
mod view_revision_pad;
mod database_view_revision_pad;
pub use block_revision_pad::*;
pub use database_builder::*;
pub use database_revision_pad::*;
pub use view_revision_pad::*;
pub use database_view_revision_pad::*;

View File

@ -12,7 +12,7 @@ flowy-user = { path = "../flowy-user" }
flowy-net = { path = "../flowy-net" }
flowy-folder = { path = "../flowy-folder" }
flowy-database = { path = "../flowy-database" }
grid-model = { path = "../../../shared-lib/grid-model" }
database-model = { path = "../../../shared-lib/database-model" }
user-model = { path = "../../../shared-lib/user-model" }
flowy-client-ws = { path = "../../../shared-lib/flowy-client-ws" }
flowy-sqlite = { path = "../flowy-sqlite", optional = true }

View File

@ -1,6 +1,7 @@
use bytes::Bytes;
use flowy_sqlite::ConnectionPool;
use database_model::BuildDatabaseContext;
use flowy_client_ws::FlowyWebSocketConnect;
use flowy_database::entities::LayoutTypePB;
use flowy_database::manager::{make_database_view_data, DatabaseManager};
@ -19,7 +20,6 @@ use flowy_net::{http_server::folder::FolderHttpCloudService, local_server::Local
use flowy_revision::{RevisionWebSocket, WSStateReceiver};
use flowy_user::services::UserSession;
use futures_core::future::BoxFuture;
use grid_model::BuildDatabaseContext;
use lib_infra::future::{BoxResultFuture, FutureResult};
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
use revision_model::Revision;
@ -36,7 +36,7 @@ impl FolderDepsResolver {
server_config: &ClientServerConfiguration,
ws_conn: &Arc<FlowyWebSocketConnect>,
text_block_manager: &Arc<DocumentManager>,
grid_manager: &Arc<DatabaseManager>,
database_manager: &Arc<DatabaseManager>,
) -> Arc<FolderManager> {
let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone()));
let database: Arc<dyn WorkspaceDatabase> = Arc::new(WorkspaceDatabaseImpl(user_session));
@ -47,7 +47,7 @@ impl FolderDepsResolver {
};
let view_data_processor =
make_view_data_processor(text_block_manager.clone(), grid_manager.clone());
make_view_data_processor(text_block_manager.clone(), database_manager.clone());
let folder_manager = Arc::new(
FolderManager::new(
user.clone(),
@ -74,7 +74,7 @@ impl FolderDepsResolver {
fn make_view_data_processor(
document_manager: Arc<DocumentManager>,
grid_manager: Arc<DatabaseManager>,
database_manager: Arc<DatabaseManager>,
) -> ViewDataProcessorMap {
let mut map: HashMap<ViewDataFormatPB, Arc<dyn ViewDataProcessor + Send + Sync>> = HashMap::new();
@ -86,7 +86,7 @@ fn make_view_data_processor(
map.insert(data_type, document_processor.clone());
});
let grid_data_impl = Arc::new(GridViewDataProcessor(grid_manager));
let grid_data_impl = Arc::new(GridViewDataProcessor(database_manager));
grid_data_impl
.data_types()
.into_iter()
@ -177,7 +177,7 @@ impl ViewDataProcessor for DocumentViewDataProcessor {
debug_assert_eq!(layout, ViewLayoutTypePB::Document);
let view_data = match String::from_utf8(view_data.to_vec()) {
Ok(content) => match make_transaction_from_document_content(&content) {
Ok(transaction) => transaction.to_bytes().unwrap_or(vec![]),
Ok(transaction) => transaction.to_bytes().unwrap_or_else(|_| vec![]),
Err(_) => vec![],
},
Err(_) => vec![],
@ -259,9 +259,9 @@ impl ViewDataProcessor for GridViewDataProcessor {
) -> FutureResult<(), FlowyError> {
let revision = Revision::initial_revision(view_id, delta_data);
let view_id = view_id.to_string();
let grid_manager = self.0.clone();
let database_manager = self.0.clone();
FutureResult::new(async move {
grid_manager
database_manager
.create_database(view_id, vec![revision])
.await?;
Ok(())
@ -269,20 +269,20 @@ impl ViewDataProcessor for GridViewDataProcessor {
}
fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
let grid_manager = self.0.clone();
let database_manager = self.0.clone();
let view_id = view_id.to_string();
FutureResult::new(async move {
grid_manager.close_database(view_id).await?;
database_manager.close_database(view_id).await?;
Ok(())
})
}
fn get_view_data(&self, view: &ViewPB) -> FutureResult<Bytes, FlowyError> {
let grid_manager = self.0.clone();
let database_manager = self.0.clone();
let view_id = view.id.clone();
FutureResult::new(async move {
let editor = grid_manager.open_database(view_id).await?;
let delta_bytes = editor.duplicate_grid().await?;
let editor = database_manager.open_database(view_id).await?;
let delta_bytes = editor.duplicate_database().await?;
Ok(delta_bytes.into())
})
}
@ -308,9 +308,9 @@ impl ViewDataProcessor for GridViewDataProcessor {
let user_id = user_id.to_string();
let view_id = view_id.to_string();
let grid_manager = self.0.clone();
let database_manager = self.0.clone();
FutureResult::new(async move {
make_database_view_data(&user_id, &view_id, layout, grid_manager, build_context).await
make_database_view_data(&user_id, &view_id, layout, database_manager, build_context).await
})
}
@ -323,7 +323,7 @@ impl ViewDataProcessor for GridViewDataProcessor {
) -> FutureResult<Bytes, FlowyError> {
let user_id = user_id.to_string();
let view_id = view_id.to_string();
let grid_manager = self.0.clone();
let database_manager = self.0.clone();
let layout = match layout {
ViewLayoutTypePB::Grid => LayoutTypePB::Grid,
@ -339,7 +339,7 @@ impl ViewDataProcessor for GridViewDataProcessor {
FutureResult::new(async move {
let bytes = Bytes::from(data);
let build_context = BuildDatabaseContext::try_from(bytes)?;
make_database_view_data(&user_id, &view_id, layout, grid_manager, build_context).await
make_database_view_data(&user_id, &view_id, layout, database_manager, build_context).await
})
}

View File

@ -15,7 +15,7 @@ flowy-error = { path = "../flowy-error", features = ["adaptor_database", "adapto
flowy-derive = { path = "../flowy-derive" }
lib-ot = { path = "../../../shared-lib/lib-ot" }
lib-infra = { path = "../../../shared-lib/lib-infra" }
grid-model = { path = "../../../shared-lib/grid-model" }
database-model = { path = "../../../shared-lib/database-model" }
flowy-client-sync = { path = "../flowy-client-sync"}
revision-model = { path = "../../../shared-lib/revision-model" }
flowy-sqlite = { path = "../flowy-sqlite", optional = true }

View File

@ -1,8 +1,8 @@
use crate::entities::parser::NotEmptyStr;
use crate::entities::FieldType;
use database_model::{CellRevision, RowChangeset};
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use grid_model::{CellRevision, RowChangeset};
use std::collections::HashMap;
#[derive(ProtoBuf, Default)]

View File

@ -1,6 +1,6 @@
use database_model::{FieldRevision, FieldTypeRevision};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::{FieldRevision, FieldTypeRevision};
use serde_repr::*;
use std::sync::Arc;
@ -88,7 +88,7 @@ impl std::convert::From<&Arc<FieldRevision>> for FieldIdPB {
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct DatabaseFieldChangesetPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub inserted_fields: Vec<IndexFieldPB>,
@ -103,7 +103,7 @@ pub struct DatabaseFieldChangesetPB {
impl DatabaseFieldChangesetPB {
pub fn insert(database_id: &str, inserted_fields: Vec<IndexFieldPB>) -> Self {
Self {
database_id: database_id.to_owned(),
view_id: database_id.to_owned(),
inserted_fields,
deleted_fields: vec![],
updated_fields: vec![],
@ -112,7 +112,7 @@ impl DatabaseFieldChangesetPB {
pub fn delete(database_id: &str, deleted_fields: Vec<FieldIdPB>) -> Self {
Self {
database_id: database_id.to_string(),
view_id: database_id.to_string(),
inserted_fields: vec![],
deleted_fields,
updated_fields: vec![],
@ -121,7 +121,7 @@ impl DatabaseFieldChangesetPB {
pub fn update(database_id: &str, updated_fields: Vec<FieldPB>) -> Self {
Self {
database_id: database_id.to_string(),
view_id: database_id.to_string(),
inserted_fields: vec![],
deleted_fields: vec![],
updated_fields,
@ -150,7 +150,7 @@ impl IndexFieldPB {
#[derive(Debug, Default, ProtoBuf)]
pub struct CreateFieldPayloadPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_type: FieldType,
@ -161,7 +161,7 @@ pub struct CreateFieldPayloadPB {
#[derive(Clone)]
pub struct CreateFieldParams {
pub database_id: String,
pub view_id: String,
pub field_type: FieldType,
pub type_option_data: Option<Vec<u8>>,
}
@ -170,10 +170,9 @@ impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
Ok(CreateFieldParams {
database_id: database_id.0,
view_id: view_id.0,
field_type: self.field_type,
type_option_data: self.type_option_data,
})
@ -183,7 +182,7 @@ impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
#[derive(Debug, Default, ProtoBuf)]
pub struct UpdateFieldTypePayloadPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_id: String,
@ -196,7 +195,7 @@ pub struct UpdateFieldTypePayloadPB {
}
pub struct EditFieldParams {
pub database_id: String,
pub view_id: String,
pub field_id: String,
pub field_type: FieldType,
}
@ -205,11 +204,10 @@ impl TryInto<EditFieldParams> for UpdateFieldTypePayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<EditFieldParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
Ok(EditFieldParams {
database_id: database_id.0,
view_id: view_id.0,
field_id: field_id.0,
field_type: self.field_type,
})
@ -219,7 +217,7 @@ impl TryInto<EditFieldParams> for UpdateFieldTypePayloadPB {
#[derive(Debug, Default, ProtoBuf)]
pub struct TypeOptionPathPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_id: String,
@ -229,7 +227,7 @@ pub struct TypeOptionPathPB {
}
pub struct TypeOptionPathParams {
pub database_id: String,
pub view_id: String,
pub field_id: String,
pub field_type: FieldType,
}
@ -238,11 +236,10 @@ impl TryInto<TypeOptionPathParams> for TypeOptionPathPB {
type Error = ErrorCode;
fn try_into(self) -> Result<TypeOptionPathParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let database_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
Ok(TypeOptionPathParams {
database_id: database_id.0,
view_id: database_id.0,
field_id: field_id.0,
field_type: self.field_type,
})
@ -252,7 +249,7 @@ impl TryInto<TypeOptionPathParams> for TypeOptionPathPB {
#[derive(Debug, Default, ProtoBuf)]
pub struct TypeOptionPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field: FieldPB,
@ -317,7 +314,7 @@ impl std::convert::From<String> for RepeatedFieldIdPB {
#[derive(ProtoBuf, Default)]
pub struct TypeOptionChangesetPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_id: String,
@ -329,7 +326,7 @@ pub struct TypeOptionChangesetPB {
#[derive(Clone)]
pub struct TypeOptionChangesetParams {
pub database_id: String,
pub view_id: String,
pub field_id: String,
pub type_option_data: Vec<u8>,
}
@ -338,12 +335,11 @@ impl TryInto<TypeOptionChangesetParams> for TypeOptionChangesetPB {
type Error = ErrorCode;
fn try_into(self) -> Result<TypeOptionChangesetParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
Ok(TypeOptionChangesetParams {
database_id: database_id.0,
view_id: view_id.0,
field_id: self.field_id,
type_option_data: self.type_option_data,
})
@ -353,14 +349,14 @@ impl TryInto<TypeOptionChangesetParams> for TypeOptionChangesetPB {
#[derive(ProtoBuf, Default)]
pub struct GetFieldPayloadPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2, one_of)]
pub field_ids: Option<RepeatedFieldIdPB>,
}
pub struct GetFieldParams {
pub database_id: String,
pub view_id: String,
pub field_ids: Option<Vec<String>>,
}
@ -368,8 +364,7 @@ impl TryInto<GetFieldParams> for GetFieldPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<GetFieldParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let field_ids = self.field_ids.map(|repeated| {
repeated
.items
@ -379,7 +374,7 @@ impl TryInto<GetFieldParams> for GetFieldPayloadPB {
});
Ok(GetFieldParams {
database_id: database_id.0,
view_id: view_id.0,
field_ids,
})
}
@ -624,27 +619,26 @@ pub struct DuplicateFieldPayloadPB {
pub field_id: String,
#[pb(index = 2)]
pub database_id: String,
pub view_id: String,
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct GridFieldIdentifierPayloadPB {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub database_id: String,
}
// #[derive(Debug, Clone, Default, ProtoBuf)]
// pub struct GridFieldIdentifierPayloadPB {
// #[pb(index = 1)]
// pub field_id: String,
//
// #[pb(index = 2)]
// pub view_id: String,
// }
impl TryInto<FieldIdParams> for DuplicateFieldPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<FieldIdParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
Ok(FieldIdParams {
database_id: database_id.0,
view_id: view_id.0,
field_id: field_id.0,
})
}
@ -656,18 +650,17 @@ pub struct DeleteFieldPayloadPB {
pub field_id: String,
#[pb(index = 2)]
pub database_id: String,
pub view_id: String,
}
impl TryInto<FieldIdParams> for DeleteFieldPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<FieldIdParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
Ok(FieldIdParams {
database_id: database_id.0,
view_id: view_id.0,
field_id: field_id.0,
})
}
@ -675,5 +668,5 @@ impl TryInto<FieldIdParams> for DeleteFieldPayloadPB {
pub struct FieldIdParams {
pub field_id: String,
pub database_id: String,
pub view_id: String,
}

View File

@ -1,7 +1,7 @@
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct CheckboxFilterPB {

View File

@ -1,7 +1,7 @@
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct ChecklistFilterPB {

View File

@ -1,7 +1,7 @@
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
use serde::{Deserialize, Serialize};
use std::str::FromStr;

View File

@ -1,7 +1,7 @@
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct NumberFilterPB {

View File

@ -1,8 +1,8 @@
use crate::services::field::SelectOptionIds;
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct SelectOptionFilterPB {

View File

@ -1,7 +1,7 @@
use crate::services::filter::FromFilterString;
use database_model::FilterRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::FilterRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct TextFilterPB {

View File

@ -6,9 +6,9 @@ use crate::entities::{
use crate::services::field::SelectOptionIds;
use crate::services::filter::FilterType;
use bytes::Bytes;
use database_model::{FieldRevision, FieldTypeRevision, FilterRevision};
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use grid_model::{FieldRevision, FieldTypeRevision, FilterRevision};
use std::convert::TryInto;
use std::sync::Arc;

View File

@ -23,12 +23,12 @@ pub struct CreateDatabasePayloadPB {
}
#[derive(Clone, ProtoBuf, Default, Debug)]
pub struct DatabaseIdPB {
pub struct DatabaseViewIdPB {
#[pb(index = 1)]
pub value: String,
}
impl AsRef<str> for DatabaseIdPB {
impl AsRef<str> for DatabaseViewIdPB {
fn as_ref(&self) -> &str {
&self.value
}

View File

@ -1,5 +1,5 @@
use database_model::{GroupRevision, SelectOptionGroupConfigurationRevision};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use grid_model::{GroupRevision, SelectOptionGroupConfigurationRevision};
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct UrlGroupConfigurationPB {

View File

@ -1,16 +1,16 @@
use crate::entities::parser::NotEmptyStr;
use crate::entities::{CreateRowParams, FieldType, LayoutTypePB, RowPB};
use crate::services::group::Group;
use database_model::{FieldTypeRevision, GroupConfigurationRevision};
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use grid_model::{FieldTypeRevision, GroupConfigurationRevision};
use std::convert::TryInto;
use std::sync::Arc;
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct CreateBoardCardPayloadPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub group_id: String,
@ -23,8 +23,7 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let group_id = NotEmptyStr::parse(self.group_id).map_err(|_| ErrorCode::GroupIdIsEmpty)?;
let start_row_id = match self.start_row_id {
None => None,
@ -35,7 +34,7 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
),
};
Ok(CreateRowParams {
database_id: database_id.0,
view_id: view_id.0,
start_row_id,
group_id: Some(group_id.0),
layout: LayoutTypePB::Board,

View File

@ -1,8 +1,8 @@
use crate::entities::parser::NotEmptyStr;
use crate::entities::LayoutTypePB;
use database_model::RowRevision;
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use grid_model::RowRevision;
use std::sync::Arc;
/// [RowPB] Describes a row. Has the id of the parent Block. Has the metadata of the row.
@ -136,14 +136,14 @@ pub struct UpdatedRowPB {
#[derive(Debug, Default, Clone, ProtoBuf)]
pub struct RowIdPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub row_id: String,
}
pub struct RowIdParams {
pub database_id: String,
pub view_id: String,
pub row_id: String,
}
@ -151,12 +151,11 @@ impl TryInto<RowIdParams> for RowIdPB {
type Error = ErrorCode;
fn try_into(self) -> Result<RowIdParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
Ok(RowIdParams {
database_id: database_id.0,
view_id: view_id.0,
row_id: row_id.0,
})
}
@ -174,7 +173,7 @@ pub struct BlockRowIdPB {
#[derive(ProtoBuf, Default)]
pub struct CreateRowPayloadPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2, one_of)]
pub start_row_id: Option<String>,
@ -182,7 +181,7 @@ pub struct CreateRowPayloadPB {
#[derive(Default)]
pub struct CreateRowParams {
pub database_id: String,
pub view_id: String,
pub start_row_id: Option<String>,
pub group_id: Option<String>,
pub layout: LayoutTypePB,
@ -192,11 +191,10 @@ impl TryInto<CreateRowParams> for CreateRowPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let database_id =
NotEmptyStr::parse(self.database_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
Ok(CreateRowParams {
database_id: database_id.0,
view_id: view_id.0,
start_row_id: self.start_row_id,
group_id: None,
layout: LayoutTypePB::Grid,

View File

@ -5,9 +5,9 @@ use crate::entities::{
DeleteSortPayloadPB, InsertGroupParams, InsertGroupPayloadPB, RepeatedFilterPB,
RepeatedGroupConfigurationPB, RepeatedSortPB,
};
use database_model::LayoutRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::LayoutRevision;
use std::convert::TryInto;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
@ -85,7 +85,7 @@ impl std::convert::From<LayoutTypePB> for LayoutRevision {
#[derive(Default, ProtoBuf)]
pub struct DatabaseSettingChangesetPB {
#[pb(index = 1)]
pub database_id: String,
pub view_id: String,
#[pb(index = 2)]
pub layout_type: LayoutTypePB,
@ -113,7 +113,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
type Error = ErrorCode;
fn try_into(self) -> Result<DatabaseSettingChangesetParams, Self::Error> {
let database_id = NotEmptyStr::parse(self.database_id)
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::ViewIdInvalid)?
.0;
@ -148,7 +148,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
};
Ok(DatabaseSettingChangesetParams {
database_id,
view_id,
layout_type: self.layout_type.into(),
insert_filter,
delete_filter,
@ -161,7 +161,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
}
pub struct DatabaseSettingChangesetParams {
pub database_id: String,
pub view_id: String,
pub layout_type: LayoutRevision,
pub insert_filter: Option<AlterFilterParams>,
pub delete_filter: Option<DeleteFilterParams>,

View File

@ -3,9 +3,9 @@ use crate::entities::FieldType;
use crate::services::sort::SortType;
use std::sync::Arc;
use database_model::{FieldTypeRevision, SortCondition, SortRevision};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_model::{FieldTypeRevision, SortCondition, SortRevision};
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct SortPB {

View File

@ -8,17 +8,17 @@ use crate::services::field::{
SelectOptionChangeset, SelectOptionChangesetPB, SelectOptionIds, SelectOptionPB,
};
use crate::services::row::make_row_from_row_rev;
use database_model::FieldRevision;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use grid_model::FieldRevision;
use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult};
use std::sync::Arc;
#[tracing::instrument(level = "trace", skip(data, manager), err)]
pub(crate) async fn get_database_data_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<DatabasePB, FlowyError> {
let database_id: DatabaseIdPB = data.into_inner();
let database_id: DatabaseViewIdPB = data.into_inner();
let editor = manager.open_database(database_id.as_ref()).await?;
let database = editor.get_database(database_id.as_ref()).await?;
data_result(database)
@ -26,10 +26,10 @@ pub(crate) async fn get_database_data_handler(
#[tracing::instrument(level = "trace", skip(data, manager), err)]
pub(crate) async fn get_database_setting_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<DatabaseViewSettingPB, FlowyError> {
let database_id: DatabaseIdPB = data.into_inner();
let database_id: DatabaseViewIdPB = data.into_inner();
let editor = manager.open_database(database_id).await?;
let database_setting = editor.get_setting().await?;
data_result(database_setting)
@ -42,7 +42,7 @@ pub(crate) async fn update_database_setting_handler(
) -> Result<(), FlowyError> {
let params: DatabaseSettingChangesetParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
if let Some(insert_params) = params.insert_group {
editor.insert_group(insert_params).await?;
}
@ -70,10 +70,10 @@ pub(crate) async fn update_database_setting_handler(
#[tracing::instrument(level = "trace", skip(data, manager), err)]
pub(crate) async fn get_all_filters_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RepeatedFilterPB, FlowyError> {
let database_id: DatabaseIdPB = data.into_inner();
let database_id: DatabaseViewIdPB = data.into_inner();
let editor = manager.open_database(database_id).await?;
let filters = RepeatedFilterPB {
items: editor.get_all_filters().await?,
@ -83,10 +83,10 @@ pub(crate) async fn get_all_filters_handler(
#[tracing::instrument(level = "trace", skip(data, manager), err)]
pub(crate) async fn get_all_sorts_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RepeatedSortPB, FlowyError> {
let database_id: DatabaseIdPB = data.into_inner();
let database_id: DatabaseViewIdPB = data.into_inner();
let editor = manager.open_database(database_id.as_ref()).await?;
let sorts = RepeatedSortPB {
items: editor.get_all_sorts(database_id.as_ref()).await?,
@ -96,10 +96,10 @@ pub(crate) async fn get_all_sorts_handler(
#[tracing::instrument(level = "trace", skip(data, manager), err)]
pub(crate) async fn delete_all_sorts_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let database_id: DatabaseIdPB = data.into_inner();
let database_id: DatabaseViewIdPB = data.into_inner();
let editor = manager.open_database(database_id.as_ref()).await?;
editor.delete_all_sorts(database_id.as_ref()).await?;
Ok(())
@ -111,7 +111,7 @@ pub(crate) async fn get_fields_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RepeatedFieldPB, FlowyError> {
let params: GetFieldParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
let field_revs = editor.get_field_revs(params.field_ids).await?;
let repeated_field: RepeatedFieldPB = field_revs
.into_iter()
@ -138,15 +138,10 @@ pub(crate) async fn update_field_type_option_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: TypeOptionChangesetParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
let old_field_rev = editor.get_field_rev(&params.field_id).await;
editor
.update_field_type_option(
&params.database_id,
&params.field_id,
params.type_option_data,
old_field_rev,
)
.update_field_type_option(&params.field_id, params.type_option_data, old_field_rev)
.await?;
Ok(())
}
@ -157,7 +152,7 @@ pub(crate) async fn delete_field_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: FieldIdParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
editor.delete_field(&params.field_id).await?;
Ok(())
}
@ -168,7 +163,7 @@ pub(crate) async fn switch_to_field_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: EditFieldParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
let old_field_rev = editor.get_field_rev(&params.field_id).await;
editor
.switch_to_field_type(&params.field_id, &params.field_type)
@ -183,12 +178,7 @@ pub(crate) async fn switch_to_field_handler(
// Update the type-option data after the field type has been changed
let type_option_data = get_type_option_data(&new_field_rev, &params.field_type).await?;
editor
.update_field_type_option(
&params.database_id,
&new_field_rev.id,
type_option_data,
old_field_rev,
)
.update_field_type_option(&new_field_rev.id, type_option_data, old_field_rev)
.await?;
Ok(())
@ -200,7 +190,7 @@ pub(crate) async fn duplicate_field_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: FieldIdParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
editor.duplicate_field(&params.field_id).await?;
Ok(())
}
@ -212,14 +202,14 @@ pub(crate) async fn get_field_type_option_data_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<TypeOptionPB, FlowyError> {
let params: TypeOptionPathParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
match editor.get_field_rev(&params.field_id).await {
None => Err(FlowyError::record_not_found()),
Some(field_rev) => {
let field_type = field_rev.ty.into();
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
let data = TypeOptionPB {
database_id: params.database_id,
view_id: params.view_id,
field: field_rev.into(),
type_option_data,
};
@ -235,7 +225,7 @@ pub(crate) async fn create_field_type_option_data_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<TypeOptionPB, FlowyError> {
let params: CreateFieldParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
let field_rev = editor
.create_new_field_rev_with_type_option(&params.field_type, params.type_option_data)
.await?;
@ -243,7 +233,7 @@ pub(crate) async fn create_field_type_option_data_handler(
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
data_result(TypeOptionPB {
database_id: params.database_id,
view_id: params.view_id,
field: field_rev.into(),
type_option_data,
})
@ -286,7 +276,7 @@ pub(crate) async fn get_row_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<OptionalRowPB, FlowyError> {
let params: RowIdParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
let row = editor
.get_row_rev(&params.row_id)
.await?
@ -301,7 +291,7 @@ pub(crate) async fn delete_row_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: RowIdParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
editor.delete_row(&params.row_id).await?;
Ok(())
}
@ -312,7 +302,7 @@ pub(crate) async fn duplicate_row_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> Result<(), FlowyError> {
let params: RowIdParams = data.into_inner().try_into()?;
let editor = manager.get_database_editor(&params.database_id).await?;
let editor = manager.get_database_editor(&params.view_id).await?;
editor.duplicate_row(&params.row_id).await?;
Ok(())
}
@ -334,9 +324,7 @@ pub(crate) async fn create_table_row_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RowPB, FlowyError> {
let params: CreateRowParams = data.into_inner().try_into()?;
let editor = manager
.get_database_editor(params.database_id.as_ref())
.await?;
let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
let row = editor.create_row(params).await?;
data_result(row)
}
@ -531,10 +519,10 @@ pub(crate) async fn update_date_cell_handler(
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) async fn get_groups_handler(
data: AFPluginData<DatabaseIdPB>,
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RepeatedGroupPB, FlowyError> {
let params: DatabaseIdPB = data.into_inner();
let params: DatabaseViewIdPB = data.into_inner();
let editor = manager.get_database_editor(&params.value).await?;
let group = editor.load_groups().await?;
data_result(group)
@ -546,9 +534,7 @@ pub(crate) async fn create_board_card_handler(
manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RowPB, FlowyError> {
let params: CreateRowParams = data.into_inner().try_into()?;
let editor = manager
.get_database_editor(params.database_id.as_ref())
.await?;
let editor = manager.get_database_editor(params.view_id.as_ref()).await?;
let row = editor.create_row(params).await?;
data_result(row)
}

View File

@ -59,15 +59,15 @@ pub fn init(database_manager: Arc<DatabaseManager>) -> AFPlugin {
pub enum DatabaseEvent {
/// [GetDatabase] event is used to get the [DatabasePB]
///
/// The event handler accepts a [DatabaseIdPB] and returns a [DatabasePB] if there are no errors.
#[event(input = "DatabaseIdPB", output = "DatabasePB")]
/// The event handler accepts a [DatabaseViewIdPB] and returns a [DatabasePB] if there are no errors.
#[event(input = "DatabaseViewIdPB", output = "DatabasePB")]
GetDatabase = 0,
/// [GetDatabaseSetting] event is used to get the database's settings.
///
/// The event handler accepts [DatabaseIdPB] and return [DatabaseViewSettingPB]
/// The event handler accepts [DatabaseViewIdPB] and return [DatabaseViewSettingPB]
/// if there is no errors.
#[event(input = "DatabaseIdPB", output = "DatabaseViewSettingPB")]
#[event(input = "DatabaseViewIdPB", output = "DatabaseViewSettingPB")]
GetDatabaseSetting = 2,
/// [UpdateDatabaseSetting] event is used to update the database's settings.
@ -76,13 +76,13 @@ pub enum DatabaseEvent {
#[event(input = "DatabaseSettingChangesetPB")]
UpdateDatabaseSetting = 3,
#[event(input = "DatabaseIdPB", output = "RepeatedFilterPB")]
#[event(input = "DatabaseViewIdPB", output = "RepeatedFilterPB")]
GetAllFilters = 4,
#[event(input = "DatabaseIdPB", output = "RepeatedSortPB")]
#[event(input = "DatabaseViewIdPB", output = "RepeatedSortPB")]
GetAllSorts = 5,
#[event(input = "DatabaseIdPB")]
#[event(input = "DatabaseViewIdPB")]
DeleteAllSorts = 6,
/// [GetFields] event is used to get the database's settings.
@ -215,7 +215,7 @@ pub enum DatabaseEvent {
#[event(input = "DateChangesetPB")]
UpdateDateCell = 80,
#[event(input = "DatabaseIdPB", output = "RepeatedGroupPB")]
#[event(input = "DatabaseViewIdPB", output = "RepeatedGroupPB")]
GetGroup = 100,
#[event(input = "CreateBoardCardPayloadPB", output = "RowPB")]

View File

@ -1,7 +1,9 @@
use crate::entities::LayoutTypePB;
use crate::services::grid_editor::{
DatabaseRevisionEditor, GridRevisionCloudService, GridRevisionMergeable, GridRevisionSerde,
use crate::services::database::{
make_database_block_rev_manager, DatabaseRevisionCloudService, DatabaseRevisionEditor,
DatabaseRevisionMergeable, DatabaseRevisionSerde,
};
use crate::services::database_view::make_database_view_rev_manager;
use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::persistence::kv::DatabaseKVPersistence;
use crate::services::persistence::migration::DatabaseMigration;
@ -9,8 +11,8 @@ use crate::services::persistence::rev_sqlite::{
SQLiteDatabaseRevisionPersistence, SQLiteDatabaseRevisionSnapshotPersistence,
};
use crate::services::persistence::GridDatabase;
use crate::services::view_editor::make_database_view_rev_manager;
use bytes::Bytes;
use database_model::{BuildDatabaseContext, DatabaseRevision, DatabaseViewRevision};
use flowy_client_sync::client_database::{
make_database_block_operations, make_database_operations, make_grid_view_operations,
};
@ -19,12 +21,10 @@ use flowy_revision::{
RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration, RevisionWebSocket,
};
use flowy_sqlite::ConnectionPool;
use grid_model::{BuildDatabaseContext, DatabaseRevision, DatabaseViewRevision};
use lib_infra::async_trait::async_trait;
use lib_infra::ref_map::{RefCountHashMap, RefCountValue};
use revision_model::Revision;
use crate::services::block_manager::make_database_block_rev_manager;
use flowy_task::TaskDispatcher;
use std::sync::Arc;
use tokio::sync::RwLock;
@ -135,6 +135,7 @@ impl DatabaseManager {
}
// #[tracing::instrument(level = "debug", skip(self), err)]
//TODO(nathan): map the view_id to database_id
pub async fn get_database_editor(
&self,
database_id: &str,
@ -175,11 +176,11 @@ impl DatabaseManager {
) -> Result<Arc<DatabaseRevisionEditor>, FlowyError> {
let user = self.database_user.clone();
let token = user.token()?;
let cloud = Arc::new(GridRevisionCloudService::new(token));
let cloud = Arc::new(DatabaseRevisionCloudService::new(token));
let mut rev_manager = self.make_database_rev_manager(database_id, pool.clone())?;
let database_pad = Arc::new(RwLock::new(
rev_manager
.initialize::<GridRevisionSerde>(Some(cloud))
.initialize::<DatabaseRevisionSerde>(Some(cloud))
.await?,
));
let database_editor = DatabaseRevisionEditor::new(
@ -213,7 +214,7 @@ impl DatabaseManager {
let snapshot_persistence =
SQLiteDatabaseRevisionSnapshotPersistence::new(&snapshot_object_id, pool);
let rev_compress = GridRevisionMergeable();
let rev_compress = DatabaseRevisionMergeable();
let rev_manager = RevisionManager::new(
&user_id,
database_id,
@ -236,7 +237,7 @@ pub async fn make_database_view_data(
field_revs,
block_metas,
blocks,
grid_view_revision_data,
database_view_data: grid_view_revision_data,
} = build_context;
for block_meta_data in &blocks {
@ -249,40 +250,40 @@ pub async fn make_database_view_data(
});
// Create grid's block
let grid_block_delta = make_database_block_operations(block_meta_data);
let block_delta_data = grid_block_delta.json_bytes();
let revision = Revision::initial_revision(block_id, block_delta_data);
let database_block_ops = make_database_block_operations(block_meta_data);
let database_block_bytes = database_block_ops.json_bytes();
let revision = Revision::initial_revision(block_id, database_block_bytes);
database_manager
.create_database_block(&block_id, vec![revision])
.await?;
}
// Will replace the grid_id with the value returned by the gen_grid_id()
let grid_id = view_id.to_owned();
let grid_rev = DatabaseRevision::from_build_context(&grid_id, field_revs, block_metas);
let database_id = view_id.to_owned();
let database_rev = DatabaseRevision::from_build_context(&database_id, field_revs, block_metas);
// Create grid
let grid_rev_delta = make_database_operations(&grid_rev);
let grid_rev_delta_bytes = grid_rev_delta.json_bytes();
let revision = Revision::initial_revision(&grid_id, grid_rev_delta_bytes.clone());
let database_ops = make_database_operations(&database_rev);
let database_bytes = database_ops.json_bytes();
let revision = Revision::initial_revision(&database_id, database_bytes.clone());
database_manager
.create_database(&grid_id, vec![revision])
.create_database(&database_id, vec![revision])
.await?;
// Create grid view
let grid_view = if grid_view_revision_data.is_empty() {
DatabaseViewRevision::new(grid_id, view_id.to_owned(), layout.into())
DatabaseViewRevision::new(database_id, view_id.to_owned(), layout.into())
} else {
DatabaseViewRevision::from_json(grid_view_revision_data)?
};
let grid_view_delta = make_grid_view_operations(&grid_view);
let grid_view_delta_bytes = grid_view_delta.json_bytes();
let revision = Revision::initial_revision(view_id, grid_view_delta_bytes);
let database_view_ops = make_grid_view_operations(&grid_view);
let database_view_bytes = database_view_ops.json_bytes();
let revision = Revision::initial_revision(view_id, database_view_bytes);
database_manager
.create_database_view(view_id, vec![revision])
.await?;
Ok(grid_rev_delta_bytes)
Ok(database_bytes)
}
#[async_trait]

View File

@ -3,8 +3,8 @@ use crate::services::cell::{AtomicCellDataCache, CellProtobufBlob, TypeCellData}
use crate::services::field::*;
use crate::services::group::make_no_status_group;
use database_model::{CellRevision, FieldRevision};
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use grid_model::{CellRevision, FieldRevision};
use std::fmt::Debug;

View File

@ -1,8 +1,8 @@
use crate::entities::FieldType;
use bytes::Bytes;
use database_model::CellRevision;
use flowy_error::{internal_error, FlowyError, FlowyResult};
use grid_model::CellRevision;
use serde::{Deserialize, Serialize};
/// TypeCellData is a generic CellData, you can parse the type_cell_data according to the field_type.

View File

@ -1,6 +1,9 @@
use crate::services::retry::GetRowDataRetryAction;
use crate::services::database::retry::GetRowDataRetryAction;
use bytes::Bytes;
use flowy_client_sync::client_database::{GridBlockRevisionChangeset, GridBlockRevisionPad};
use database_model::{CellRevision, DatabaseBlockRevision, RowChangeset, RowRevision};
use flowy_client_sync::client_database::{
DatabaseBlockRevisionChangeset, DatabaseBlockRevisionPad,
};
use flowy_client_sync::make_operations_from_revisions;
use flowy_error::{FlowyError, FlowyResult};
use flowy_revision::{
@ -8,7 +11,6 @@ use flowy_revision::{
RevisionObjectSerializer,
};
use flowy_sqlite::ConnectionPool;
use grid_model::{CellRevision, DatabaseBlockRevision, RowChangeset, RowRevision};
use lib_infra::future::FutureResult;
use lib_infra::retry::spawn_retry;
use lib_ot::core::EmptyAttributes;
@ -21,7 +23,7 @@ pub struct DatabaseBlockRevisionEditor {
#[allow(dead_code)]
user_id: String,
pub block_id: String,
pad: Arc<RwLock<GridBlockRevisionPad>>,
pad: Arc<RwLock<DatabaseBlockRevisionPad>>,
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
}
@ -32,7 +34,7 @@ impl DatabaseBlockRevisionEditor {
block_id: &str,
mut rev_manager: RevisionManager<Arc<ConnectionPool>>,
) -> FlowyResult<Self> {
let cloud = Arc::new(GridBlockRevisionCloudService {
let cloud = Arc::new(DatabaseBlockRevisionCloudService {
token: token.to_owned(),
});
let block_revision_pad = rev_manager
@ -165,8 +167,8 @@ impl DatabaseBlockRevisionEditor {
async fn modify<F>(&self, f: F) -> FlowyResult<()>
where
F: for<'a> FnOnce(
&'a mut GridBlockRevisionPad,
) -> FlowyResult<Option<GridBlockRevisionChangeset>>,
&'a mut DatabaseBlockRevisionPad,
) -> FlowyResult<Option<DatabaseBlockRevisionChangeset>>,
{
let mut write_guard = self.pad.write().await;
let changeset = f(&mut write_guard)?;
@ -179,8 +181,8 @@ impl DatabaseBlockRevisionEditor {
Ok(())
}
async fn apply_change(&self, change: GridBlockRevisionChangeset) -> FlowyResult<()> {
let GridBlockRevisionChangeset {
async fn apply_change(&self, change: DatabaseBlockRevisionChangeset) -> FlowyResult<()> {
let DatabaseBlockRevisionChangeset {
operations: delta,
md5,
} = change;
@ -190,12 +192,12 @@ impl DatabaseBlockRevisionEditor {
}
}
struct GridBlockRevisionCloudService {
struct DatabaseBlockRevisionCloudService {
#[allow(dead_code)]
token: String,
}
impl RevisionCloudService for GridBlockRevisionCloudService {
impl RevisionCloudService for DatabaseBlockRevisionCloudService {
#[tracing::instrument(level = "trace", skip(self))]
fn fetch_object(
&self,
@ -208,10 +210,13 @@ impl RevisionCloudService for GridBlockRevisionCloudService {
struct DatabaseBlockRevisionSerde();
impl RevisionObjectDeserializer for DatabaseBlockRevisionSerde {
type Output = GridBlockRevisionPad;
type Output = DatabaseBlockRevisionPad;
fn deserialize_revisions(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
let pad = GridBlockRevisionPad::from_revisions(object_id, revisions)?;
fn deserialize_revisions(
_object_id: &str,
revisions: Vec<Revision>,
) -> FlowyResult<Self::Output> {
let pad = DatabaseBlockRevisionPad::from_revisions(revisions)?;
Ok(pad)
}
@ -227,8 +232,8 @@ impl RevisionObjectSerializer for DatabaseBlockRevisionSerde {
}
}
pub struct GridBlockRevisionMergeable();
impl RevisionMergeable for GridBlockRevisionMergeable {
pub struct DatabaseBlockRevisionMergeable();
impl RevisionMergeable for DatabaseBlockRevisionMergeable {
fn combine_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
DatabaseBlockRevisionSerde::combine_revisions(revisions)
}

View File

@ -1,19 +1,19 @@
use crate::entities::{CellChangesetPB, InsertedRowPB, UpdatedRowPB};
use crate::manager::DatabaseUser;
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::block_editor::{DatabaseBlockRevisionEditor, GridBlockRevisionMergeable};
use crate::services::database::{DatabaseBlockRevisionEditor, DatabaseBlockRevisionMergeable};
use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::persistence::rev_sqlite::{
SQLiteDatabaseBlockRevisionPersistence, SQLiteDatabaseRevisionSnapshotPersistence,
};
use crate::services::row::{make_row_from_row_rev, DatabaseBlockRow, DatabaseBlockRowRevision};
use dashmap::DashMap;
use database_model::{
DatabaseBlockMetaRevision, DatabaseBlockMetaRevisionChangeset, RowChangeset, RowRevision,
};
use flowy_error::FlowyResult;
use flowy_revision::{RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration};
use flowy_sqlite::ConnectionPool;
use grid_model::{
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowChangeset, RowRevision,
};
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;
@ -51,7 +51,7 @@ pub(crate) struct DatabaseBlockManager {
impl DatabaseBlockManager {
pub(crate) async fn new(
user: &Arc<dyn DatabaseUser>,
block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
block_meta_revs: Vec<Arc<DatabaseBlockMetaRevision>>,
persistence: Arc<BlockIndexCache>,
event_notifier: broadcast::Sender<DatabaseBlockEvent>,
) -> FlowyResult<Self> {
@ -73,7 +73,7 @@ impl DatabaseBlockManager {
}
// #[tracing::instrument(level = "trace", skip(self))]
pub(crate) async fn get_block_editor(
pub(crate) async fn get_or_create_block_editor(
&self,
block_id: &str,
) -> FlowyResult<Arc<DatabaseBlockRevisionEditor>> {
@ -99,7 +99,7 @@ impl DatabaseBlockManager {
row_id: &str,
) -> FlowyResult<Arc<DatabaseBlockRevisionEditor>> {
let block_id = self.persistence.get_block_id(row_id)?;
self.get_block_editor(&block_id).await
self.get_or_create_block_editor(&block_id).await
}
#[tracing::instrument(level = "trace", skip(self, start_row_id), err)]
@ -110,7 +110,7 @@ impl DatabaseBlockManager {
) -> FlowyResult<i32> {
let block_id = row_rev.block_id.clone();
self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
let editor = self.get_block_editor(&row_rev.block_id).await?;
let editor = self.get_or_create_block_editor(&row_rev.block_id).await?;
let mut row = InsertedRowPB::from(&row_rev);
let (number_of_rows, index) = editor.create_row(row_rev, start_row_id).await?;
@ -125,10 +125,10 @@ impl DatabaseBlockManager {
pub(crate) async fn insert_row(
&self,
rows_by_block_id: HashMap<String, Vec<RowRevision>>,
) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {
) -> FlowyResult<Vec<DatabaseBlockMetaRevisionChangeset>> {
let mut changesets = vec![];
for (block_id, row_revs) in rows_by_block_id {
let editor = self.get_block_editor(&block_id).await?;
let editor = self.get_or_create_block_editor(&block_id).await?;
for row_rev in row_revs {
self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
let mut row = InsertedRowPB::from(&row_rev);
@ -138,7 +138,7 @@ impl DatabaseBlockManager {
row,
});
}
changesets.push(GridBlockMetaRevisionChangeset::from_row_count(
changesets.push(DatabaseBlockMetaRevisionChangeset::from_row_count(
block_id.clone(),
editor.number_of_rows().await,
));
@ -179,7 +179,7 @@ impl DatabaseBlockManager {
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
let row_id = row_id.to_owned();
let block_id = self.persistence.get_block_id(&row_id)?;
let editor = self.get_block_editor(&block_id).await?;
let editor = self.get_or_create_block_editor(&block_id).await?;
match editor.get_row_rev(&row_id).await? {
None => Ok(None),
Some((_, row_rev)) => {
@ -197,17 +197,18 @@ impl DatabaseBlockManager {
pub(crate) async fn delete_rows(
&self,
block_rows: Vec<DatabaseBlockRow>,
) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {
) -> FlowyResult<Vec<DatabaseBlockMetaRevisionChangeset>> {
let mut changesets = vec![];
for block_row in block_rows {
let editor = self.get_block_editor(&block_row.block_id).await?;
let editor = self.get_or_create_block_editor(&block_row.block_id).await?;
let row_ids = block_row
.row_ids
.into_iter()
.map(Cow::Owned)
.collect::<Vec<Cow<String>>>();
let row_count = editor.delete_rows(row_ids).await?;
let changeset = GridBlockMetaRevisionChangeset::from_row_count(block_row.block_id, row_count);
let changeset =
DatabaseBlockMetaRevisionChangeset::from_row_count(block_row.block_id, row_count);
changesets.push(changeset);
}
@ -285,7 +286,7 @@ impl DatabaseBlockManager {
},
Some(block_ids) => {
for block_id in block_ids {
let editor = self.get_block_editor(&block_id).await?;
let editor = self.get_or_create_block_editor(&block_id).await?;
let row_revs = editor.get_row_revs::<&str>(None).await?;
blocks.push(DatabaseBlockRowRevision { block_id, row_revs });
}
@ -304,7 +305,7 @@ impl DatabaseBlockManager {
/// Initialize each block editor
async fn make_block_editors(
user: &Arc<dyn DatabaseUser>,
block_meta_revs: Vec<Arc<GridBlockMetaRevision>>,
block_meta_revs: Vec<Arc<DatabaseBlockMetaRevision>>,
) -> FlowyResult<DashMap<String, Arc<DatabaseBlockRevisionEditor>>> {
let editor_map = DashMap::new();
for block_meta_rev in block_meta_revs {
@ -343,7 +344,7 @@ pub fn make_database_block_rev_manager(
let snapshot_persistence =
SQLiteDatabaseRevisionSnapshotPersistence::new(&snapshot_object_id, pool);
let rev_compress = GridBlockRevisionMergeable();
let rev_compress = DatabaseBlockRevisionMergeable();
let rev_manager = RevisionManager::new(
&user_id,
block_id,

View File

@ -2,26 +2,28 @@ use crate::entities::CellIdParams;
use crate::entities::*;
use crate::manager::DatabaseUser;
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::block_manager::DatabaseBlockManager;
use crate::services::cell::{
apply_cell_data_changeset, get_type_cell_protobuf, stringify_cell_data, AnyTypeCache,
AtomicCellDataCache, CellProtobufBlob, ToCellChangesetString, TypeCellData,
};
use crate::services::database::DatabaseBlockManager;
use crate::services::field::{
default_type_option_builder_from_type, transform_type_option, type_option_builder_from_bytes,
FieldBuilder, RowSingleCellData,
};
use crate::services::database::DatabaseViewEditorDelegateImpl;
use crate::services::database_view::{DatabaseViewChanged, DatabaseViewManager};
use crate::services::filter::FilterType;
use crate::services::grid_editor_trait_impl::GridViewEditorDelegateImpl;
use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::row::{DatabaseBlockRow, DatabaseBlockRowRevision, RowRevisionBuilder};
use crate::services::view_editor::{DatabaseViewChanged, DatabaseViewManager};
use bytes::Bytes;
use database_model::*;
use flowy_client_sync::client_database::{
DatabaseRevisionChangeset, DatabaseRevisionPad, JsonDeserializer,
};
use flowy_client_sync::errors::{SyncError, SyncResult};
use flowy_client_sync::make_operations_from_revisions;
use flowy_error::{FlowyError, FlowyResult};
use flowy_revision::{
RevisionCloudService, RevisionManager, RevisionMergeable, RevisionObjectDeserializer,
@ -29,30 +31,25 @@ use flowy_revision::{
};
use flowy_sqlite::ConnectionPool;
use flowy_task::TaskDispatcher;
use grid_model::*;
use lib_infra::future::{to_fut, FutureResult};
use lib_ot::core::EmptyAttributes;
use revision_model::Revision;
use std::collections::HashMap;
use flowy_client_sync::make_operations_from_revisions;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
pub struct DatabaseRevisionEditor {
pub database_id: String,
#[allow(dead_code)]
user: Arc<dyn DatabaseUser>,
database_pad: Arc<RwLock<DatabaseRevisionPad>>,
view_manager: Arc<DatabaseViewManager>,
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
block_manager: Arc<DatabaseBlockManager>,
database_view_manager: Arc<DatabaseViewManager>,
database_block_manager: Arc<DatabaseBlockManager>,
cell_data_cache: AtomicCellDataCache,
}
impl Drop for DatabaseRevisionEditor {
fn drop(&mut self) {
tracing::trace!("Drop GridRevisionEditor");
tracing::trace!("Drop DatabaseRevisionEditor");
}
}
@ -71,18 +68,18 @@ impl DatabaseRevisionEditor {
// Block manager
let (block_event_tx, block_event_rx) = broadcast::channel(100);
let block_meta_revs = database_pad.read().await.get_block_meta_revs();
let block_manager = Arc::new(
let database_block_manager = Arc::new(
DatabaseBlockManager::new(&user, block_meta_revs, persistence, block_event_tx).await?,
);
let delegate = Arc::new(GridViewEditorDelegateImpl {
let delegate = Arc::new(DatabaseViewEditorDelegateImpl {
pad: database_pad.clone(),
block_manager: block_manager.clone(),
block_manager: database_block_manager.clone(),
task_scheduler,
cell_data_cache: cell_data_cache.clone(),
});
// View manager
let view_manager = Arc::new(
let database_view_manager = Arc::new(
DatabaseViewManager::new(
database_id.to_owned(),
user.clone(),
@ -95,23 +92,22 @@ impl DatabaseRevisionEditor {
let editor = Arc::new(Self {
database_id: database_id.to_owned(),
user,
database_pad,
rev_manager,
block_manager,
view_manager,
database_block_manager,
database_view_manager,
cell_data_cache,
});
Ok(editor)
}
#[tracing::instrument(name = "close grid editor", level = "trace", skip_all)]
#[tracing::instrument(name = "close database editor", level = "trace", skip_all)]
pub async fn close(&self) {
self.block_manager.close().await;
self.database_block_manager.close().await;
self.rev_manager.generate_snapshot().await;
self.rev_manager.close().await;
self.view_manager.close(&self.database_id).await;
self.database_view_manager.close(&self.database_id).await;
}
/// Save the type-option data to disk and send a `DatabaseNotification::DidUpdateField` notification
@ -120,14 +116,12 @@ impl DatabaseRevisionEditor {
/// It will do nothing if the passed-in type_option_data is empty
/// # Arguments
///
/// * `grid_id`: the id of the grid
/// * `field_id`: the id of the field
/// * `type_option_data`: the updated type-option data. The `type-option` data might be empty
/// if there is no type-option config for that field. For example, the `RichTextTypeOptionPB`.
///
pub async fn update_field_type_option(
&self,
_grid_id: &str,
field_id: &str,
type_option_data: Vec<u8>,
old_field_rev: Option<Arc<FieldRevision>>,
@ -139,8 +133,8 @@ impl DatabaseRevisionEditor {
}
let field_rev = result.unwrap();
self
.modify(|grid| {
let changeset = grid.modify_field(field_id, |field| {
.modify(|pad| {
let changeset = pad.modify_field(field_id, |field| {
let deserializer = TypeOptionJsonDeserializer(field_rev.ty.into());
match deserializer.deserialize(type_option_data) {
Ok(json_str) => {
@ -158,10 +152,10 @@ impl DatabaseRevisionEditor {
.await?;
self
.view_manager
.database_view_manager
.did_update_view_field_type_option(field_id, old_field_rev)
.await?;
self.notify_did_update_grid_field(field_id).await?;
self.notify_did_update_database_field(field_id).await?;
Ok(())
}
@ -179,9 +173,9 @@ impl DatabaseRevisionEditor {
pub async fn create_new_field_rev(&self, field_rev: FieldRevision) -> FlowyResult<()> {
let field_id = field_rev.id.clone();
self
.modify(|grid| Ok(grid.create_field_rev(field_rev, None)?))
.modify(|pad| Ok(pad.create_field_rev(field_rev, None)?))
.await?;
self.notify_did_insert_grid_field(&field_id).await?;
self.notify_did_insert_database_field(&field_id).await?;
Ok(())
}
@ -197,9 +191,9 @@ impl DatabaseRevisionEditor {
field_rev.insert_type_option(type_option_builder.serializer());
}
self
.modify(|grid| Ok(grid.create_field_rev(field_rev.clone(), None)?))
.modify(|pad| Ok(pad.create_field_rev(field_rev.clone(), None)?))
.await?;
self.notify_did_insert_grid_field(&field_rev.id).await?;
self.notify_did_insert_database_field(&field_rev.id).await?;
Ok(field_rev)
}
@ -211,8 +205,8 @@ impl DatabaseRevisionEditor {
pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> {
let field_id = params.field_id.clone();
self
.modify(|grid| {
let changeset = grid.modify_field(&params.field_id, |field| {
.modify(|pad| {
let changeset = pad.modify_field(&params.field_id, |field| {
if let Some(name) = params.name {
field.name = name;
}
@ -236,7 +230,7 @@ impl DatabaseRevisionEditor {
Ok(changeset)
})
.await?;
self.notify_did_update_grid_field(&field_id).await?;
self.notify_did_update_database_field(&field_id).await?;
Ok(())
}
@ -247,8 +241,8 @@ impl DatabaseRevisionEditor {
let mut is_changed = false;
let old_field_rev = self.get_field_rev(field_id).await;
self
.modify(|grid| {
let changeset = grid.modify_field(field_id, |field_rev| {
.modify(|pad| {
let changeset = pad.modify_field(field_id, |field_rev| {
f(field_rev).map_err(|e| SyncError::internal().context(e))
})?;
is_changed = changeset.is_some();
@ -258,30 +252,30 @@ impl DatabaseRevisionEditor {
if is_changed {
match self
.view_manager
.database_view_manager
.did_update_view_field_type_option(field_id, old_field_rev)
.await
{
Ok(_) => {},
Err(e) => tracing::error!("View manager update field failed: {:?}", e),
}
self.notify_did_update_grid_field(field_id).await?;
self.notify_did_update_database_field(field_id).await?;
}
Ok(())
}
pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> {
self
.modify(|grid_pad| Ok(grid_pad.delete_field_rev(field_id)?))
.modify(|pad| Ok(pad.delete_field_rev(field_id)?))
.await?;
let field_order = FieldIdPB::from(field_id);
let notified_changeset = DatabaseFieldChangesetPB::delete(&self.database_id, vec![field_order]);
self.notify_did_update_grid(notified_changeset).await?;
self.notify_did_update_database(notified_changeset).await?;
Ok(())
}
pub async fn group_by_field(&self, field_id: &str) -> FlowyResult<()> {
self.view_manager.group_by_field(field_id).await?;
self.database_view_manager.group_by_field(field_id).await?;
Ok(())
}
@ -321,8 +315,8 @@ impl DatabaseRevisionEditor {
};
self
.modify(|grid| {
Ok(grid.switch_to_field(
.modify(|pad| {
Ok(pad.switch_to_field(
field_id,
new_field_type.clone(),
make_default_type_option,
@ -331,7 +325,7 @@ impl DatabaseRevisionEditor {
})
.await?;
self.notify_did_update_grid_field(field_id).await?;
self.notify_did_update_database_field(field_id).await?;
Ok(())
}
@ -339,11 +333,11 @@ impl DatabaseRevisionEditor {
pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> {
let duplicated_field_id = gen_field_id();
self
.modify(|grid| Ok(grid.duplicate_field_rev(field_id, &duplicated_field_id)?))
.modify(|pad| Ok(pad.duplicate_field_rev(field_id, &duplicated_field_id)?))
.await?;
self
.notify_did_insert_grid_field(&duplicated_field_id)
.notify_did_insert_database_field(&duplicated_field_id)
.await?;
Ok(())
}
@ -385,16 +379,19 @@ impl DatabaseRevisionEditor {
Ok(field_revs)
}
pub async fn create_block(&self, block_meta_rev: GridBlockMetaRevision) -> FlowyResult<()> {
pub async fn create_block(&self, block_meta_rev: DatabaseBlockMetaRevision) -> FlowyResult<()> {
self
.modify(|grid_pad| Ok(grid_pad.create_block_meta_rev(block_meta_rev)?))
.modify(|pad| Ok(pad.create_block_meta_rev(block_meta_rev)?))
.await?;
Ok(())
}
pub async fn update_block(&self, changeset: GridBlockMetaRevisionChangeset) -> FlowyResult<()> {
pub async fn update_block(
&self,
changeset: DatabaseBlockMetaRevisionChangeset,
) -> FlowyResult<()> {
self
.modify(|grid_pad| Ok(grid_pad.update_block_rev(changeset)?))
.modify(|pad| Ok(pad.update_block_rev(changeset)?))
.await?;
Ok(())
}
@ -403,7 +400,7 @@ impl DatabaseRevisionEditor {
let mut row_rev = self.create_row_rev().await?;
self
.view_manager
.database_view_manager
.will_create_row(&mut row_rev, &params)
.await;
@ -411,13 +408,16 @@ impl DatabaseRevisionEditor {
.create_row_pb(row_rev, params.start_row_id.clone())
.await?;
self.view_manager.did_create_row(&row_pb, &params).await;
self
.database_view_manager
.did_create_row(&row_pb, &params)
.await;
Ok(row_pb)
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
self.view_manager.move_group(params).await?;
self.database_view_manager.move_group(params).await?;
Ok(())
}
@ -432,7 +432,10 @@ impl DatabaseRevisionEditor {
.or_insert_with(Vec::new)
.push(row_rev);
}
let changesets = self.block_manager.insert_row(rows_by_block_id).await?;
let changesets = self
.database_block_manager
.insert_row(rows_by_block_id)
.await?;
for changeset in changesets {
self.update_block(changeset).await?;
}
@ -442,14 +445,20 @@ impl DatabaseRevisionEditor {
pub async fn update_row(&self, changeset: RowChangeset) -> FlowyResult<()> {
let row_id = changeset.row_id.clone();
let old_row = self.get_row_rev(&row_id).await?;
self.block_manager.update_row(changeset).await?;
self.view_manager.did_update_row(old_row, &row_id).await;
self.database_block_manager.update_row(changeset).await?;
self
.database_view_manager
.did_update_row(old_row, &row_id)
.await;
Ok(())
}
/// Returns all the rows in this block.
pub async fn get_row_pbs(&self, view_id: &str, block_id: &str) -> FlowyResult<Vec<RowPB>> {
let rows = self.view_manager.get_row_revs(view_id, block_id).await?;
let rows = self
.database_view_manager
.get_row_revs(view_id, block_id)
.await?;
let rows = rows
.into_iter()
.map(|row_rev| RowPB::from(&row_rev))
@ -459,10 +468,10 @@ impl DatabaseRevisionEditor {
pub async fn get_all_row_revs(&self, view_id: &str) -> FlowyResult<Vec<Arc<RowRevision>>> {
let mut all_rows = vec![];
let blocks = self.block_manager.get_blocks(None).await?;
let blocks = self.database_block_manager.get_blocks(None).await?;
for block in blocks {
let rows = self
.view_manager
.database_view_manager
.get_row_revs(view_id, &block.block_id)
.await?;
all_rows.extend(rows);
@ -471,17 +480,17 @@ impl DatabaseRevisionEditor {
}
pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
match self.block_manager.get_row_rev(row_id).await? {
match self.database_block_manager.get_row_rev(row_id).await? {
None => Ok(None),
Some((_, row_rev)) => Ok(Some(row_rev)),
}
}
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
let row_rev = self.block_manager.delete_row(row_id).await?;
let row_rev = self.database_block_manager.delete_row(row_id).await?;
tracing::trace!("Did delete row:{:?}", row_rev);
if let Some(row_rev) = row_rev {
self.view_manager.did_delete_row(row_rev).await;
self.database_view_manager.did_delete_row(row_rev).await;
}
Ok(())
}
@ -490,7 +499,10 @@ impl DatabaseRevisionEditor {
&self,
view_id: &str,
) -> FlowyResult<broadcast::Receiver<DatabaseViewChanged>> {
self.view_manager.subscribe_view_changed(view_id).await
self
.database_view_manager
.subscribe_view_changed(view_id)
.await
}
pub async fn duplicate_row(&self, _row_id: &str) -> FlowyResult<()> {
@ -545,7 +557,7 @@ impl DatabaseRevisionEditor {
) -> Option<(FieldType, CellProtobufBlob)> {
let field_rev = self.get_field_rev(&params.field_id).await?;
let (_, row_rev) = self
.block_manager
.database_block_manager
.get_row_rev(&params.row_id)
.await
.ok()??;
@ -562,7 +574,7 @@ impl DatabaseRevisionEditor {
row_id: &str,
field_id: &str,
) -> FlowyResult<Option<CellRevision>> {
match self.block_manager.get_row_rev(row_id).await? {
match self.database_block_manager.get_row_rev(row_id).await? {
None => Ok(None),
Some((_, row_rev)) => {
let cell_rev = row_rev.cells.get(field_id).cloned();
@ -577,7 +589,7 @@ impl DatabaseRevisionEditor {
view_id: &str,
field_id: &str,
) -> FlowyResult<Vec<RowSingleCellData>> {
let view_editor = self.view_manager.get_view_editor(view_id).await?;
let view_editor = self.database_view_manager.get_view_editor(view_id).await?;
view_editor.get_cells_for_field(field_id).await
}
@ -614,8 +626,14 @@ impl DatabaseRevisionEditor {
field_id: field_id.to_owned(),
type_cell_data,
};
self.block_manager.update_cell(cell_changeset).await?;
self.view_manager.did_update_row(old_row_rev, row_id).await;
self
.database_block_manager
.update_cell(cell_changeset)
.await?;
self
.database_view_manager
.did_update_row(old_row_rev, row_id)
.await;
Ok(())
},
}
@ -633,7 +651,7 @@ impl DatabaseRevisionEditor {
.await
}
pub async fn get_block_meta_revs(&self) -> FlowyResult<Vec<Arc<GridBlockMetaRevision>>> {
pub async fn get_block_meta_revs(&self) -> FlowyResult<Vec<Arc<DatabaseBlockMetaRevision>>> {
let block_meta_revs = self.database_pad.read().await.get_block_meta_revs();
Ok(block_meta_revs)
}
@ -653,12 +671,15 @@ impl DatabaseRevisionEditor {
.collect::<Vec<String>>(),
Some(block_ids) => block_ids,
};
let blocks = self.block_manager.get_blocks(Some(block_ids)).await?;
let blocks = self
.database_block_manager
.get_blocks(Some(block_ids))
.await?;
Ok(blocks)
}
pub async fn delete_rows(&self, block_rows: Vec<DatabaseBlockRow>) -> FlowyResult<()> {
let changesets = self.block_manager.delete_rows(block_rows).await?;
let changesets = self.database_block_manager.delete_rows(block_rows).await?;
for changeset in changesets {
self.update_block(changeset).await?;
}
@ -687,13 +708,13 @@ impl DatabaseRevisionEditor {
}
pub async fn get_setting(&self) -> FlowyResult<DatabaseViewSettingPB> {
self.view_manager.get_setting().await
self.database_view_manager.get_setting().await
}
pub async fn get_all_filters(&self) -> FlowyResult<Vec<FilterPB>> {
Ok(
self
.view_manager
.database_view_manager
.get_all_filters()
.await?
.into_iter()
@ -703,23 +724,26 @@ impl DatabaseRevisionEditor {
}
pub async fn get_filters(&self, filter_id: FilterType) -> FlowyResult<Vec<Arc<FilterRevision>>> {
self.view_manager.get_filters(&filter_id).await
self.database_view_manager.get_filters(&filter_id).await
}
pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
self.view_manager.create_or_update_filter(params).await?;
self
.database_view_manager
.create_or_update_filter(params)
.await?;
Ok(())
}
pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
self.view_manager.delete_filter(params).await?;
self.database_view_manager.delete_filter(params).await?;
Ok(())
}
pub async fn get_all_sorts(&self, view_id: &str) -> FlowyResult<Vec<SortPB>> {
Ok(
self
.view_manager
.database_view_manager
.get_all_sorts(view_id)
.await?
.into_iter()
@ -729,25 +753,31 @@ impl DatabaseRevisionEditor {
}
pub async fn delete_all_sorts(&self, view_id: &str) -> FlowyResult<()> {
self.view_manager.delete_all_sorts(view_id).await
self.database_view_manager.delete_all_sorts(view_id).await
}
pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
self.view_manager.delete_sort(params).await?;
self.database_view_manager.delete_sort(params).await?;
Ok(())
}
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
let sort_rev = self.view_manager.create_or_update_sort(params).await?;
let sort_rev = self
.database_view_manager
.create_or_update_sort(params)
.await?;
Ok(sort_rev)
}
pub async fn insert_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
self.view_manager.insert_or_update_group(params).await
self
.database_view_manager
.insert_or_update_group(params)
.await
}
pub async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
self.view_manager.delete_group(params).await
self.database_view_manager.delete_group(params).await
}
pub async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {
@ -757,17 +787,21 @@ impl DatabaseRevisionEditor {
to_row_id,
} = params;
match self.block_manager.get_row_rev(&from_row_id).await? {
match self
.database_block_manager
.get_row_rev(&from_row_id)
.await?
{
None => tracing::warn!("Move row failed, can not find the row:{}", from_row_id),
Some((_, row_rev)) => {
match (
self.block_manager.index_of_row(&from_row_id).await,
self.block_manager.index_of_row(&to_row_id).await,
self.database_block_manager.index_of_row(&from_row_id).await,
self.database_block_manager.index_of_row(&to_row_id).await,
) {
(Some(from_index), Some(to_index)) => {
tracing::trace!("Move row from {} to {}", from_index, to_index);
self
.block_manager
.database_block_manager
.move_row(row_rev.clone(), from_index, to_index)
.await?;
},
@ -787,12 +821,16 @@ impl DatabaseRevisionEditor {
to_row_id,
} = params;
match self.block_manager.get_row_rev(&from_row_id).await? {
match self
.database_block_manager
.get_row_rev(&from_row_id)
.await?
{
None => tracing::warn!("Move row failed, can not find the row:{}", from_row_id),
Some((_, row_rev)) => {
let block_manager = self.block_manager.clone();
let block_manager = self.database_block_manager.clone();
self
.view_manager
.database_view_manager
.move_group_row(row_rev, to_group_id, to_row_id.clone(), |row_changeset| {
to_fut(async move {
tracing::trace!("Row data changed: {:?}", row_changeset);
@ -830,42 +868,40 @@ impl DatabaseRevisionEditor {
} = params;
self
.modify(|grid_pad| {
Ok(grid_pad.move_field(&field_id, from_index as usize, to_index as usize)?)
})
.modify(|pad| Ok(pad.move_field(&field_id, from_index as usize, to_index as usize)?))
.await?;
if let Some((index, field_rev)) = self.database_pad.read().await.get_field_rev(&field_id) {
let delete_field_order = FieldIdPB::from(field_id);
let insert_field = IndexFieldPB::from_field_rev(field_rev, index);
let notified_changeset = DatabaseFieldChangesetPB {
database_id: self.database_id.clone(),
view_id: self.database_id.clone(),
inserted_fields: vec![insert_field],
deleted_fields: vec![delete_field_order],
updated_fields: vec![],
};
self.notify_did_update_grid(notified_changeset).await?;
self.notify_did_update_database(notified_changeset).await?;
}
Ok(())
}
pub async fn duplicate_grid(&self) -> FlowyResult<BuildDatabaseContext> {
let grid_pad = self.database_pad.read().await;
let grid_view_revision_data = self.view_manager.duplicate_database_view().await?;
let original_blocks = grid_pad.get_block_meta_revs();
let (duplicated_fields, duplicated_blocks) = grid_pad.duplicate_grid_block_meta().await;
pub async fn duplicate_database(&self) -> FlowyResult<BuildDatabaseContext> {
let database_pad = self.database_pad.read().await;
let database_view_data = self.database_view_manager.duplicate_database_view().await?;
let original_blocks = database_pad.get_block_meta_revs();
let (duplicated_fields, duplicated_blocks) = database_pad.duplicate_database_block_meta().await;
let mut blocks_meta_data = vec![];
if original_blocks.len() == duplicated_blocks.len() {
for (index, original_block_meta) in original_blocks.iter().enumerate() {
let grid_block_meta_editor = self
.block_manager
.get_block_editor(&original_block_meta.block_id)
let database_block_meta_editor = self
.database_block_manager
.get_or_create_block_editor(&original_block_meta.block_id)
.await?;
let duplicated_block_id = &duplicated_blocks[index].block_id;
tracing::trace!("Duplicate block:{} meta data", duplicated_block_id);
let duplicated_block_meta_data = grid_block_meta_editor
let duplicated_block_meta_data = database_block_meta_editor
.duplicate_block(duplicated_block_id)
.await;
blocks_meta_data.push(duplicated_block_meta_data);
@ -873,19 +909,19 @@ impl DatabaseRevisionEditor {
} else {
debug_assert_eq!(original_blocks.len(), duplicated_blocks.len());
}
drop(grid_pad);
drop(database_pad);
Ok(BuildDatabaseContext {
field_revs: duplicated_fields.into_iter().map(Arc::new).collect(),
block_metas: duplicated_blocks,
blocks: blocks_meta_data,
grid_view_revision_data,
database_view_data,
})
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub async fn load_groups(&self) -> FlowyResult<RepeatedGroupPB> {
self.view_manager.load_groups().await
self.database_view_manager.load_groups().await
}
async fn create_row_rev(&self) -> FlowyResult<RowRevision> {
@ -906,10 +942,13 @@ impl DatabaseRevisionEditor {
let block_id = row_rev.block_id.clone();
// insert the row
let row_count = self.block_manager.create_row(row_rev, start_row_id).await?;
let row_count = self
.database_block_manager
.create_row(row_rev, start_row_id)
.await?;
// update block row count
let changeset = GridBlockMetaRevisionChangeset::from_row_count(block_id, row_count);
let changeset = DatabaseBlockMetaRevisionChangeset::from_row_count(block_id, row_count);
self.update_block(changeset).await?;
Ok(row_pb)
}
@ -938,24 +977,25 @@ impl DatabaseRevisionEditor {
async fn block_id(&self) -> FlowyResult<String> {
match self.database_pad.read().await.get_block_meta_revs().last() {
None => Err(FlowyError::internal().context("There is no grid block in this grid")),
Some(grid_block) => Ok(grid_block.block_id.clone()),
None => Err(FlowyError::internal().context("There is no block in this database")),
Some(database_block) => Ok(database_block.block_id.clone()),
}
}
#[tracing::instrument(level = "trace", skip_all, err)]
async fn notify_did_insert_grid_field(&self, field_id: &str) -> FlowyResult<()> {
async fn notify_did_insert_database_field(&self, field_id: &str) -> FlowyResult<()> {
if let Some((index, field_rev)) = self.database_pad.read().await.get_field_rev(field_id) {
let index_field = IndexFieldPB::from_field_rev(field_rev, index);
//TODO(nathan): broadcast the changeset to views that reference to this database
let notified_changeset =
DatabaseFieldChangesetPB::insert(&self.database_id, vec![index_field]);
self.notify_did_update_grid(notified_changeset).await?;
self.notify_did_update_database(notified_changeset).await?;
}
Ok(())
}
#[tracing::instrument(level = "trace", skip_all, err)]
async fn notify_did_update_grid_field(&self, field_id: &str) -> FlowyResult<()> {
async fn notify_did_update_database_field(&self, field_id: &str) -> FlowyResult<()> {
if let Some((_, field_rev)) = self
.database_pad
.read()
@ -966,7 +1006,7 @@ impl DatabaseRevisionEditor {
let updated_field = FieldPB::from(field_rev);
let notified_changeset =
DatabaseFieldChangesetPB::update(&self.database_id, vec![updated_field.clone()]);
self.notify_did_update_grid(notified_changeset).await?;
self.notify_did_update_database(notified_changeset).await?;
send_notification(field_id, DatabaseNotification::DidUpdateField)
.payload(updated_field)
@ -976,7 +1016,10 @@ impl DatabaseRevisionEditor {
Ok(())
}
async fn notify_did_update_grid(&self, changeset: DatabaseFieldChangesetPB) -> FlowyResult<()> {
async fn notify_did_update_database(
&self,
changeset: DatabaseFieldChangesetPB,
) -> FlowyResult<()> {
send_notification(&self.database_id, DatabaseNotification::DidUpdateFields)
.payload(changeset)
.send();
@ -990,13 +1033,13 @@ impl DatabaseRevisionEditor {
self.rev_manager.clone()
}
pub fn grid_pad(&self) -> Arc<RwLock<DatabaseRevisionPad>> {
pub fn database_pad(&self) -> Arc<RwLock<DatabaseRevisionPad>> {
self.database_pad.clone()
}
}
pub struct GridRevisionSerde();
impl RevisionObjectDeserializer for GridRevisionSerde {
pub struct DatabaseRevisionSerde();
impl RevisionObjectDeserializer for DatabaseRevisionSerde {
type Output = DatabaseRevisionPad;
fn deserialize_revisions(
@ -1011,25 +1054,25 @@ impl RevisionObjectDeserializer for GridRevisionSerde {
None
}
}
impl RevisionObjectSerializer for GridRevisionSerde {
impl RevisionObjectSerializer for DatabaseRevisionSerde {
fn combine_revisions(revisions: Vec<Revision>) -> FlowyResult<Bytes> {
let operations = make_operations_from_revisions::<EmptyAttributes>(revisions)?;
Ok(operations.json_bytes())
}
}
pub struct GridRevisionCloudService {
pub struct DatabaseRevisionCloudService {
#[allow(dead_code)]
token: String,
}
impl GridRevisionCloudService {
impl DatabaseRevisionCloudService {
pub fn new(token: String) -> Self {
Self { token }
}
}
impl RevisionCloudService for GridRevisionCloudService {
impl RevisionCloudService for DatabaseRevisionCloudService {
#[tracing::instrument(level = "trace", skip(self))]
fn fetch_object(
&self,
@ -1040,11 +1083,11 @@ impl RevisionCloudService for GridRevisionCloudService {
}
}
pub struct GridRevisionMergeable();
pub struct DatabaseRevisionMergeable();
impl RevisionMergeable for GridRevisionMergeable {
impl RevisionMergeable for DatabaseRevisionMergeable {
fn combine_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
GridRevisionSerde::combine_revisions(revisions)
DatabaseRevisionSerde::combine_revisions(revisions)
}
}

View File

@ -0,0 +1,10 @@
mod block_editor;
mod block_manager;
mod database_editor;
mod retry;
mod trait_impl;
pub use block_editor::*;
pub use block_manager::*;
pub use database_editor::*;
pub use trait_impl::*;

View File

@ -1,6 +1,6 @@
use flowy_client_sync::client_database::GridBlockRevisionPad;
use database_model::RowRevision;
use flowy_client_sync::client_database::DatabaseBlockRevisionPad;
use flowy_error::FlowyError;
use grid_model::RowRevision;
use lib_infra::retry::Action;
use std::future::Future;
use std::pin::Pin;
@ -9,7 +9,7 @@ use tokio::sync::RwLock;
pub struct GetRowDataRetryAction {
pub row_id: String,
pub pad: Arc<RwLock<GridBlockRevisionPad>>,
pub pad: Arc<RwLock<DatabaseBlockRevisionPad>>,
}
impl Action for GetRowDataRetryAction {

View File

@ -1,25 +1,26 @@
use crate::entities::FieldType;
use crate::services::block_manager::DatabaseBlockManager;
use crate::services::cell::AtomicCellDataCache;
use crate::services::database::DatabaseBlockManager;
use crate::services::database_view::DatabaseViewEditorDelegate;
use crate::services::field::{TypeOptionCellDataHandler, TypeOptionCellExt};
use crate::services::row::DatabaseBlockRowRevision;
use crate::services::view_editor::DatabaseViewEditorDelegate;
use database_model::{FieldRevision, RowRevision};
use flowy_client_sync::client_database::DatabaseRevisionPad;
use flowy_task::TaskDispatcher;
use grid_model::{FieldRevision, RowRevision};
use lib_infra::future::{to_fut, Fut};
use std::any::type_name;
use std::sync::Arc;
use tokio::sync::RwLock;
pub(crate) struct GridViewEditorDelegateImpl {
pub struct DatabaseViewEditorDelegateImpl {
pub(crate) pad: Arc<RwLock<DatabaseRevisionPad>>,
pub(crate) block_manager: Arc<DatabaseBlockManager>,
pub(crate) task_scheduler: Arc<RwLock<TaskDispatcher>>,
pub(crate) cell_data_cache: AtomicCellDataCache,
}
impl DatabaseViewEditorDelegate for GridViewEditorDelegateImpl {
impl DatabaseViewEditorDelegate for DatabaseViewEditorDelegateImpl {
fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> Fut<Vec<Arc<FieldRevision>>> {
let pad = self.pad.clone();
to_fut(async move {
@ -27,7 +28,8 @@ impl DatabaseViewEditorDelegate for GridViewEditorDelegateImpl {
Ok(field_revs) => field_revs,
Err(e) => {
tracing::error!(
"[GridViewRevisionDelegate] get field revisions failed: {}",
"[{}] get field revisions failed: {}",
type_name::<DatabaseViewEditorDelegateImpl>(),
e
);
vec![]

View File

@ -1,7 +1,10 @@
use crate::entities::*;
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::block_manager::DatabaseBlockEvent;
use crate::services::cell::{AtomicCellDataCache, TypeCellData};
use crate::services::database::DatabaseBlockEvent;
use crate::services::database_view::notifier::DatabaseViewChangedNotifier;
use crate::services::database_view::trait_impl::*;
use crate::services::database_view::DatabaseViewChangedReceiverRunner;
use crate::services::field::{RowSingleCellData, TypeOptionCellDataHandler};
use crate::services::filter::{
FilterChangeset, FilterController, FilterTaskHandler, FilterType, UpdatedFilterType,
@ -14,20 +17,17 @@ use crate::services::row::DatabaseBlockRowRevision;
use crate::services::sort::{
DeletedSortType, SortChangeset, SortController, SortTaskHandler, SortType,
};
use crate::services::view_editor::changed_notifier::GridViewChangedNotifier;
use crate::services::view_editor::trait_impl::*;
use crate::services::view_editor::GridViewChangedReceiverRunner;
use database_model::{
gen_database_filter_id, gen_database_sort_id, FieldRevision, FieldTypeRevision, FilterRevision,
LayoutRevision, RowChangeset, RowRevision, SortRevision,
};
use flowy_client_sync::client_database::{
make_grid_view_operations, GridViewRevisionChangeset, GridViewRevisionPad,
make_grid_view_operations, DatabaseViewRevisionPad, GridViewRevisionChangeset,
};
use flowy_error::FlowyResult;
use flowy_revision::RevisionManager;
use flowy_sqlite::ConnectionPool;
use flowy_task::TaskDispatcher;
use grid_model::{
gen_grid_filter_id, gen_grid_sort_id, FieldRevision, FieldTypeRevision, FilterRevision,
LayoutRevision, RowChangeset, RowRevision, SortRevision,
};
use lib_infra::async_trait::async_trait;
use lib_infra::future::Fut;
use lib_infra::ref_map::RefCountValue;
@ -76,13 +76,13 @@ pub trait DatabaseViewEditorDelegate: Send + Sync + 'static {
pub struct DatabaseViewRevisionEditor {
user_id: String,
view_id: String,
pad: Arc<RwLock<GridViewRevisionPad>>,
pad: Arc<RwLock<DatabaseViewRevisionPad>>,
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
group_controller: Arc<RwLock<Box<dyn GroupController>>>,
filter_controller: Arc<FilterController>,
sort_controller: Arc<RwLock<SortController>>,
pub notifier: GridViewChangedNotifier,
pub notifier: DatabaseViewChangedNotifier,
}
impl DatabaseViewRevisionEditor {
@ -96,7 +96,7 @@ impl DatabaseViewRevisionEditor {
mut rev_manager: RevisionManager<Arc<ConnectionPool>>,
) -> FlowyResult<Self> {
let (notifier, _) = broadcast::channel(100);
tokio::spawn(GridViewChangedReceiverRunner(Some(notifier.subscribe())).run());
tokio::spawn(DatabaseViewChangedReceiverRunner(Some(notifier.subscribe())).run());
let cloud = Arc::new(GridViewRevisionCloudService {
token: token.to_owned(),
});
@ -109,8 +109,11 @@ impl DatabaseViewRevisionEditor {
Err(err) => {
// It shouldn't be here, because the snapshot should come to recue.
tracing::error!("Deserialize grid view revisions failed: {}", err);
let view =
GridViewRevisionPad::new(view_id.to_owned(), view_id.to_owned(), LayoutRevision::Grid);
let view = DatabaseViewRevisionPad::new(
view_id.to_owned(),
view_id.to_owned(),
LayoutRevision::Grid,
);
let bytes = make_grid_view_operations(&view).json_bytes();
let reset_revision = Revision::initial_revision(&view_id, bytes);
let _ = rev_manager.reset_object(vec![reset_revision]).await;
@ -460,7 +463,7 @@ impl DatabaseViewRevisionEditor {
let sort_type = SortType::from(&params);
let is_exist = params.sort_id.is_some();
let sort_id = match params.sort_id {
None => gen_grid_sort_id(),
None => gen_database_sort_id(),
Some(sort_id) => sort_id,
};
@ -559,7 +562,7 @@ impl DatabaseViewRevisionEditor {
let filter_type = FilterType::from(&params);
let is_exist = params.filter_id.is_some();
let filter_id = match params.filter_id {
None => gen_grid_filter_id(),
None => gen_database_filter_id(),
Some(filter_id) => filter_id,
};
let filter_rev = FilterRevision {
@ -756,8 +759,9 @@ impl DatabaseViewRevisionEditor {
async fn modify<F>(&self, f: F) -> FlowyResult<()>
where
F:
for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>,
F: for<'a> FnOnce(
&'a mut DatabaseViewRevisionPad,
) -> FlowyResult<Option<GridViewRevisionChangeset>>,
{
let mut write_guard = self.pad.write().await;
match f(&mut write_guard)? {
@ -839,7 +843,7 @@ impl RefCountValue for DatabaseViewRevisionEditor {
async fn new_group_controller(
user_id: String,
view_id: String,
view_rev_pad: Arc<RwLock<GridViewRevisionPad>>,
view_rev_pad: Arc<RwLock<DatabaseViewRevisionPad>>,
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
) -> FlowyResult<Box<dyn GroupController>> {
@ -879,7 +883,7 @@ async fn new_group_controller(
async fn new_group_controller_with_field_rev(
user_id: String,
view_id: String,
view_rev_pad: Arc<RwLock<GridViewRevisionPad>>,
view_rev_pad: Arc<RwLock<DatabaseViewRevisionPad>>,
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
field_rev: Arc<FieldRevision>,
row_revs: Vec<Arc<RowRevision>>,
@ -903,9 +907,9 @@ async fn new_group_controller_with_field_rev(
async fn make_filter_controller(
view_id: &str,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
notifier: GridViewChangedNotifier,
notifier: DatabaseViewChangedNotifier,
cell_data_cache: AtomicCellDataCache,
pad: Arc<RwLock<GridViewRevisionPad>>,
pad: Arc<RwLock<DatabaseViewRevisionPad>>,
) -> Arc<FilterController> {
let field_revs = delegate.get_field_revs(None).await;
let filter_revs = pad.read().await.get_all_filters(&field_revs);
@ -939,9 +943,9 @@ async fn make_filter_controller(
async fn make_sort_controller(
view_id: &str,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
notifier: GridViewChangedNotifier,
notifier: DatabaseViewChangedNotifier,
filter_controller: Arc<FilterController>,
pad: Arc<RwLock<GridViewRevisionPad>>,
pad: Arc<RwLock<DatabaseViewRevisionPad>>,
cell_data_cache: AtomicCellDataCache,
) -> Arc<RwLock<SortController>> {
let handler_id = gen_handler_id();

View File

@ -3,19 +3,19 @@ use crate::entities::{
DeleteGroupParams, DeleteSortParams, InsertGroupParams, MoveGroupParams, RepeatedGroupPB, RowPB,
};
use crate::manager::DatabaseUser;
use crate::services::block_manager::DatabaseBlockEvent;
use crate::services::cell::AtomicCellDataCache;
use crate::services::database::DatabaseBlockEvent;
use crate::services::database_view::notifier::*;
use crate::services::database_view::trait_impl::GridViewRevisionMergeable;
use crate::services::database_view::{DatabaseViewEditorDelegate, DatabaseViewRevisionEditor};
use crate::services::filter::FilterType;
use crate::services::persistence::rev_sqlite::{
SQLiteDatabaseRevisionSnapshotPersistence, SQLiteGridViewRevisionPersistence,
};
use crate::services::view_editor::changed_notifier::*;
use crate::services::view_editor::trait_impl::GridViewRevisionMergeable;
use crate::services::view_editor::{DatabaseViewEditorDelegate, DatabaseViewRevisionEditor};
use database_model::{FieldRevision, FilterRevision, RowChangeset, RowRevision, SortRevision};
use flowy_error::FlowyResult;
use flowy_revision::{RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration};
use flowy_sqlite::ConnectionPool;
use grid_model::{FieldRevision, FilterRevision, RowChangeset, RowRevision, SortRevision};
use lib_infra::future::Fut;
use lib_infra::ref_map::RefCountHashMap;
use std::borrow::Cow;
@ -23,7 +23,7 @@ use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
pub struct DatabaseViewManager {
view_id: String,
database_id: String,
user: Arc<dyn DatabaseUser>,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
view_editors: Arc<RwLock<RefCountHashMap<Arc<DatabaseViewRevisionEditor>>>>,
@ -32,7 +32,7 @@ pub struct DatabaseViewManager {
impl DatabaseViewManager {
pub async fn new(
view_id: String,
database_id: String,
user: Arc<dyn DatabaseUser>,
delegate: Arc<dyn DatabaseViewEditorDelegate>,
cell_data_cache: AtomicCellDataCache,
@ -41,7 +41,7 @@ impl DatabaseViewManager {
let view_editors = Arc::new(RwLock::new(RefCountHashMap::default()));
listen_on_database_block_event(block_event_rx, view_editors.clone());
Ok(Self {
view_id,
database_id,
user,
delegate,
cell_data_cache,
@ -260,7 +260,7 @@ impl DatabaseViewManager {
}
async fn get_default_view_editor(&self) -> FlowyResult<Arc<DatabaseViewRevisionEditor>> {
self.get_view_editor(&self.view_id).await
self.get_view_editor(&self.database_id).await
}
async fn make_view_editor(&self, view_id: &str) -> FlowyResult<DatabaseViewRevisionEditor> {

View File

@ -1,8 +1,8 @@
mod changed_notifier;
mod editor;
mod editor_manager;
mod notifier;
mod trait_impl;
pub use changed_notifier::*;
pub use editor::*;
pub use editor_manager::*;
pub use notifier::*;

View File

@ -13,12 +13,13 @@ pub enum DatabaseViewChanged {
ReorderSingleRowNotification(ReorderSingleRowResult),
}
pub type GridViewChangedNotifier = broadcast::Sender<DatabaseViewChanged>;
pub type DatabaseViewChangedNotifier = broadcast::Sender<DatabaseViewChanged>;
pub(crate) struct GridViewChangedReceiverRunner(
pub(crate) struct DatabaseViewChangedReceiverRunner(
pub(crate) Option<broadcast::Receiver<DatabaseViewChanged>>,
);
impl GridViewChangedReceiverRunner {
impl DatabaseViewChangedReceiverRunner {
pub(crate) async fn run(mut self) {
let mut receiver = self.0.take().expect("Only take once");
let stream = stream! {

View File

@ -1,12 +1,16 @@
use crate::entities::{DatabaseViewSettingPB, LayoutTypePB, ViewLayoutPB};
use crate::services::database_view::{get_cells_for_field, DatabaseViewEditorDelegate};
use crate::services::field::RowSingleCellData;
use crate::services::filter::{FilterController, FilterDelegate, FilterType};
use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter};
use crate::services::row::DatabaseBlockRowRevision;
use crate::services::sort::{SortDelegate, SortType};
use crate::services::view_editor::{get_cells_for_field, DatabaseViewEditorDelegate};
use bytes::Bytes;
use flowy_client_sync::client_database::{GridViewRevisionChangeset, GridViewRevisionPad};
use database_model::{
FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision, RowRevision,
SortRevision,
};
use flowy_client_sync::client_database::{DatabaseViewRevisionPad, GridViewRevisionChangeset};
use flowy_client_sync::make_operations_from_revisions;
use flowy_error::{FlowyError, FlowyResult};
use flowy_revision::{
@ -14,10 +18,6 @@ use flowy_revision::{
RevisionObjectSerializer,
};
use flowy_sqlite::ConnectionPool;
use grid_model::{
FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision, RowRevision,
SortRevision,
};
use lib_infra::future::{to_fut, Fut, FutureResult};
use lib_ot::core::EmptyAttributes;
use revision_model::Revision;
@ -41,10 +41,13 @@ impl RevisionCloudService for GridViewRevisionCloudService {
pub(crate) struct GridViewRevisionSerde();
impl RevisionObjectDeserializer for GridViewRevisionSerde {
type Output = GridViewRevisionPad;
type Output = DatabaseViewRevisionPad;
fn deserialize_revisions(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
let pad = GridViewRevisionPad::from_revisions(object_id, revisions)?;
fn deserialize_revisions(
_object_id: &str,
revisions: Vec<Revision>,
) -> FlowyResult<Self::Output> {
let pad = DatabaseViewRevisionPad::from_revisions(revisions)?;
Ok(pad)
}
@ -68,7 +71,7 @@ impl RevisionMergeable for GridViewRevisionMergeable {
}
pub(crate) struct GroupConfigurationReaderImpl {
pub(crate) pad: Arc<RwLock<GridViewRevisionPad>>,
pub(crate) pad: Arc<RwLock<DatabaseViewRevisionPad>>,
pub(crate) view_editor_delegate: Arc<dyn DatabaseViewEditorDelegate>,
}
@ -96,7 +99,7 @@ impl GroupConfigurationReader for GroupConfigurationReaderImpl {
pub(crate) struct GroupConfigurationWriterImpl {
pub(crate) user_id: String,
pub(crate) rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
pub(crate) view_pad: Arc<RwLock<GridViewRevisionPad>>,
pub(crate) view_pad: Arc<RwLock<DatabaseViewRevisionPad>>,
}
impl GroupConfigurationWriter for GroupConfigurationWriterImpl {
@ -140,7 +143,7 @@ pub(crate) async fn apply_change(
}
pub fn make_grid_setting(
view_pad: &GridViewRevisionPad,
view_pad: &DatabaseViewRevisionPad,
field_revs: &[Arc<FieldRevision>],
) -> DatabaseViewSettingPB {
let layout_type: LayoutTypePB = view_pad.layout.clone().into();
@ -158,7 +161,7 @@ pub fn make_grid_setting(
pub(crate) struct GridViewFilterDelegateImpl {
pub(crate) editor_delegate: Arc<dyn DatabaseViewEditorDelegate>,
pub(crate) view_revision_pad: Arc<RwLock<GridViewRevisionPad>>,
pub(crate) view_revision_pad: Arc<RwLock<DatabaseViewRevisionPad>>,
}
impl FilterDelegate for GridViewFilterDelegateImpl {
@ -198,7 +201,7 @@ impl FilterDelegate for GridViewFilterDelegateImpl {
pub(crate) struct GridViewSortDelegateImpl {
pub(crate) editor_delegate: Arc<dyn DatabaseViewEditorDelegate>,
pub(crate) view_revision_pad: Arc<RwLock<GridViewRevisionPad>>,
pub(crate) view_revision_pad: Arc<RwLock<DatabaseViewRevisionPad>>,
pub(crate) filter_controller: Arc<FilterController>,
}

View File

@ -2,7 +2,7 @@ use crate::entities::{FieldPB, FieldType};
use crate::services::field::{default_type_option_builder_from_type, TypeOptionBuilder};
use grid_model::FieldRevision;
use database_model::FieldRevision;
use indexmap::IndexMap;
pub struct FieldBuilder {

View File

@ -1,7 +1,7 @@
use crate::services::database::DatabaseRevisionEditor;
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
use crate::services::grid_editor::DatabaseRevisionEditor;
use database_model::{TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_error::FlowyResult;
use grid_model::{TypeOptionDataDeserializer, TypeOptionDataSerializer};
use std::sync::Arc;
pub async fn edit_field_type_option<T>(
@ -23,7 +23,7 @@ where
action(&mut type_option);
let bytes = type_option.protobuf_bytes().to_vec();
editor
.update_field_type_option(&editor.database_id, field_id, bytes, old_field_rev)
.update_field_type_option(field_id, bytes, old_field_rev)
.await?;
}

View File

@ -1,7 +1,7 @@
use crate::entities::FieldType;
use crate::services::field::type_options::*;
use bytes::Bytes;
use grid_model::TypeOptionDataSerializer;
use database_model::TypeOptionDataSerializer;
pub trait TypeOptionBuilder {
/// Returns the type of the type-option data

View File

@ -5,7 +5,7 @@ mod tests {
use crate::services::field::type_options::checkbox_type_option::*;
use crate::services::field::FieldBuilder;
use grid_model::FieldRevision;
use database_model::FieldRevision;
#[test]
fn checkout_box_description_test() {

View File

@ -6,9 +6,9 @@ use crate::services::field::{
TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionTransform,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::FlowyResult;
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::str::FromStr;

View File

@ -7,7 +7,7 @@ mod tests {
// use crate::services::field::{DateCellChangeset, DateCellData, DateFormat, DateTypeOptionPB, TimeFormat};
use chrono::format::strftime::StrftimeItems;
use chrono::{FixedOffset, NaiveDateTime};
use grid_model::FieldRevision;
use database_model::FieldRevision;
use strum::IntoEnumIterator;
#[test]

View File

@ -9,9 +9,9 @@ use crate::services::field::{
use bytes::Bytes;
use chrono::format::strftime::StrftimeItems;
use chrono::{NaiveDateTime, Timelike};
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;

View File

@ -5,7 +5,7 @@ mod tests {
use crate::services::field::FieldBuilder;
use crate::services::field::{strip_currency_symbol, NumberFormat, NumberTypeOptionPB};
use grid_model::FieldRevision;
use database_model::FieldRevision;
use strum::IntoEnumIterator;
/// Testing when the input is not a number.

View File

@ -7,10 +7,10 @@ use crate::services::field::{
TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionTransform,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use fancy_regex::Regex;
use flowy_derive::ProtoBuf;
use flowy_error::FlowyResult;
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use lazy_static::lazy_static;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};

View File

@ -7,9 +7,9 @@ use crate::services::field::{
TypeOptionBuilder, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::FlowyResult;
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;

View File

@ -9,9 +9,9 @@ use crate::services::field::{
TypeOptionBuilder, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::FlowyResult;
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use serde::{Deserialize, Serialize};
// Multiple select

View File

@ -11,9 +11,9 @@ use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionTransform,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataSerializer};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{internal_error, ErrorCode, FlowyResult};
use grid_model::{FieldRevision, TypeOptionDataSerializer};
use nanoid::nanoid;
use serde::{Deserialize, Serialize};

View File

@ -11,9 +11,9 @@ use crate::services::field::{
SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::FlowyResult;
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use serde::{Deserialize, Serialize};
// Single select

View File

@ -5,7 +5,7 @@ use crate::services::field::{
SelectTypeOptionSharedAction, SingleSelectTypeOptionPB, TypeOption, CHECK, UNCHECK,
};
use grid_model::TypeOptionDataDeserializer;
use database_model::TypeOptionDataDeserializer;
/// Handles how to transform the cell data when switching between different field types
pub(crate) struct SelectOptionTypeOptionTransformHelper();

View File

@ -9,9 +9,9 @@ use crate::services::field::{
TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionTransform,
};
use bytes::Bytes;
use database_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use grid_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use protobuf::ProtobufError;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;

View File

@ -5,8 +5,8 @@ use crate::services::cell::{
use crate::services::filter::FromFilterString;
use bytes::Bytes;
use database_model::FieldRevision;
use flowy_error::FlowyResult;
use grid_model::FieldRevision;
use protobuf::ProtobufError;
use std::cmp::Ordering;
use std::fmt::Debug;

Some files were not shown because too many files have changed in this diff Show More