feat: get all databases (#1983)

This commit is contained in:
Nathan.fooo 2023-03-14 01:02:54 +08:00 committed by GitHub
parent 5a17716fd8
commit ad5213cfad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 234 additions and 189 deletions

View file

@ -12,7 +12,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'dart:async'; import 'dart:async';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'database_service.dart'; import 'database_view_service.dart';
import 'defines.dart'; import 'defines.dart';
import 'layout/layout_setting_listener.dart'; import 'layout/layout_setting_listener.dart';
import 'row/row_cache.dart'; import 'row/row_cache.dart';
@ -67,7 +67,7 @@ class DatabaseCallbacks {
class DatabaseController { class DatabaseController {
final String viewId; final String viewId;
final DatabaseBackendService _databaseBackendSvc; final DatabaseViewBackendService _databaseViewBackendSvc;
final FieldController fieldController; final FieldController fieldController;
late DatabaseViewCache _viewCache; late DatabaseViewCache _viewCache;
final LayoutTypePB layoutType; final LayoutTypePB layoutType;
@ -87,7 +87,7 @@ class DatabaseController {
DatabaseController({required ViewPB view, required this.layoutType}) DatabaseController({required ViewPB view, required this.layoutType})
: viewId = view.id, : viewId = view.id,
_databaseBackendSvc = DatabaseBackendService(viewId: view.id), _databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
fieldController = FieldController(viewId: view.id), fieldController = FieldController(viewId: view.id),
groupListener = DatabaseGroupListener(view.id), groupListener = DatabaseGroupListener(view.id),
layoutListener = DatabaseLayoutListener(view.id) { layoutListener = DatabaseLayoutListener(view.id) {
@ -112,7 +112,7 @@ class DatabaseController {
} }
Future<Either<Unit, FlowyError>> open() async { Future<Either<Unit, FlowyError>> open() async {
return _databaseBackendSvc.openGrid().then((result) { return _databaseViewBackendSvc.openGrid().then((result) {
return result.fold( return result.fold(
(database) async { (database) async {
_databaseCallbacks?.onDatabaseChanged?.call(database); _databaseCallbacks?.onDatabaseChanged?.call(database);
@ -152,7 +152,7 @@ class DatabaseController {
cellDataByFieldId = rowBuilder.build(); cellDataByFieldId = rowBuilder.build();
} }
return _databaseBackendSvc.createRow( return _databaseViewBackendSvc.createRow(
startRowId: startRowId, startRowId: startRowId,
groupId: groupId, groupId: groupId,
cellDataByFieldId: cellDataByFieldId, cellDataByFieldId: cellDataByFieldId,
@ -161,7 +161,7 @@ class DatabaseController {
Future<Either<Unit, FlowyError>> moveRow(RowPB fromRow, Future<Either<Unit, FlowyError>> moveRow(RowPB fromRow,
{RowPB? toRow, String? groupId}) { {RowPB? toRow, String? groupId}) {
return _databaseBackendSvc.moveRow( return _databaseViewBackendSvc.moveRow(
fromRowId: fromRow.id, fromRowId: fromRow.id,
toGroupId: groupId, toGroupId: groupId,
toRowId: toRow?.id, toRowId: toRow?.id,
@ -170,7 +170,7 @@ class DatabaseController {
Future<Either<Unit, FlowyError>> moveGroup( Future<Either<Unit, FlowyError>> moveGroup(
{required String fromGroupId, required String toGroupId}) { {required String fromGroupId, required String toGroupId}) {
return _databaseBackendSvc.moveGroup( return _databaseViewBackendSvc.moveGroup(
fromGroupId: fromGroupId, fromGroupId: fromGroupId,
toGroupId: toGroupId, toGroupId: toGroupId,
); );
@ -178,7 +178,7 @@ class DatabaseController {
Future<void> updateCalenderLayoutSetting( Future<void> updateCalenderLayoutSetting(
CalendarLayoutSettingsPB layoutSetting) async { CalendarLayoutSettingsPB layoutSetting) async {
await _databaseBackendSvc await _databaseViewBackendSvc
.updateLayoutSetting(calendarLayoutSetting: layoutSetting) .updateLayoutSetting(calendarLayoutSetting: layoutSetting)
.then((result) { .then((result) {
result.fold((l) => null, (r) => Log.error(r)); result.fold((l) => null, (r) => Log.error(r));
@ -186,13 +186,13 @@ class DatabaseController {
} }
Future<void> dispose() async { Future<void> dispose() async {
await _databaseBackendSvc.closeView(); await _databaseViewBackendSvc.closeView();
await fieldController.dispose(); await fieldController.dispose();
await groupListener.stop(); await groupListener.stop();
} }
Future<void> _loadGroups() async { Future<void> _loadGroups() async {
final result = await _databaseBackendSvc.loadGroups(); final result = await _databaseViewBackendSvc.loadGroups();
return Future( return Future(
() => result.fold( () => result.fold(
(groups) { (groups) {
@ -204,7 +204,7 @@ class DatabaseController {
} }
Future<void> _loadLayoutSetting() async { Future<void> _loadLayoutSetting() async {
_databaseBackendSvc.getLayoutSetting(layoutType).then((result) { _databaseViewBackendSvc.getLayoutSetting(layoutType).then((result) {
result.fold( result.fold(
(l) { (l) {
_layoutCallbacks?.onLoadLayout(l); _layoutCallbacks?.onLoadLayout(l);

View file

@ -1,121 +1,13 @@
import 'package:appflowy_backend/protobuf/flowy-database/calendar_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/group_changeset.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/setting_entities.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
class DatabaseBackendService { class DatabaseBackendService {
final String viewId; static Future<Either<List<DatabaseDescriptionPB>, FlowyError>>
DatabaseBackendService({ getAllDatabase() {
required this.viewId, return DatabaseEventGetDatabases().send().then((result) {
});
Future<Either<DatabasePB, FlowyError>> openGrid() async {
await FolderEventSetLatestView(ViewIdPB(value: viewId)).send();
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetDatabase(payload).send();
}
Future<Either<RowPB, FlowyError>> createRow({
String? startRowId,
String? groupId,
Map<String, String>? cellDataByFieldId,
}) {
var payload = CreateRowPayloadPB.create()..viewId = viewId;
if (startRowId != null) {
payload.startRowId = startRowId;
}
if (groupId != null) {
payload.groupId = groupId;
}
if (cellDataByFieldId != null && cellDataByFieldId.isNotEmpty) {
payload.data = RowDataPB(cellDataByFieldId: cellDataByFieldId);
}
return DatabaseEventCreateRow(payload).send();
}
Future<Either<Unit, FlowyError>> moveRow({
required String fromRowId,
required String? toGroupId,
required String? toRowId,
}) {
var payload = MoveGroupRowPayloadPB.create()
..viewId = viewId
..fromRowId = fromRowId;
if (toGroupId != null) {
payload.toGroupId = toGroupId;
}
if (toRowId != null) {
payload.toRowId = toRowId;
}
return DatabaseEventMoveGroupRow(payload).send();
}
Future<Either<Unit, FlowyError>> moveGroup({
required String fromGroupId,
required String toGroupId,
}) {
final payload = MoveGroupPayloadPB.create()
..viewId = viewId
..fromGroupId = fromGroupId
..toGroupId = toGroupId;
return DatabaseEventMoveGroup(payload).send();
}
Future<Either<List<FieldPB>, FlowyError>> getFields(
{List<FieldIdPB>? fieldIds}) {
var payload = GetFieldPayloadPB.create()..viewId = viewId;
if (fieldIds != null) {
payload.fieldIds = RepeatedFieldIdPB(items: fieldIds);
}
return DatabaseEventGetFields(payload).send().then((result) {
return result.fold((l) => left(l.items), (r) => right(r)); return result.fold((l) => left(l.items), (r) => right(r));
}); });
} }
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
LayoutTypePB layoutType) {
final payload = DatabaseLayoutIdPB.create()
..viewId = viewId
..layout = layoutType;
return DatabaseEventGetLayoutSetting(payload).send();
}
Future<Either<Unit, FlowyError>> updateLayoutSetting(
{CalendarLayoutSettingsPB? calendarLayoutSetting}) {
final layoutSetting = LayoutSettingPB.create();
if (calendarLayoutSetting != null) {
layoutSetting.calendar = calendarLayoutSetting;
}
final payload = UpdateLayoutSettingPB.create()
..viewId = viewId
..layoutSetting = layoutSetting;
return DatabaseEventSetLayoutSetting(payload).send();
}
Future<Either<Unit, FlowyError>> closeView() {
final request = ViewIdPB(value: viewId);
return FolderEventCloseView(request).send();
}
Future<Either<RepeatedGroupPB, FlowyError>> loadGroups() {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetGroups(payload).send();
}
} }

View file

@ -0,0 +1,121 @@
import 'package:appflowy_backend/protobuf/flowy-database/calendar_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/group_changeset.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/setting_entities.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
class DatabaseViewBackendService {
final String viewId;
DatabaseViewBackendService({
required this.viewId,
});
Future<Either<DatabasePB, FlowyError>> openGrid() async {
await FolderEventSetLatestView(ViewIdPB(value: viewId)).send();
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetDatabase(payload).send();
}
Future<Either<RowPB, FlowyError>> createRow({
String? startRowId,
String? groupId,
Map<String, String>? cellDataByFieldId,
}) {
var payload = CreateRowPayloadPB.create()..viewId = viewId;
if (startRowId != null) {
payload.startRowId = startRowId;
}
if (groupId != null) {
payload.groupId = groupId;
}
if (cellDataByFieldId != null && cellDataByFieldId.isNotEmpty) {
payload.data = RowDataPB(cellDataByFieldId: cellDataByFieldId);
}
return DatabaseEventCreateRow(payload).send();
}
Future<Either<Unit, FlowyError>> moveRow({
required String fromRowId,
required String? toGroupId,
required String? toRowId,
}) {
var payload = MoveGroupRowPayloadPB.create()
..viewId = viewId
..fromRowId = fromRowId;
if (toGroupId != null) {
payload.toGroupId = toGroupId;
}
if (toRowId != null) {
payload.toRowId = toRowId;
}
return DatabaseEventMoveGroupRow(payload).send();
}
Future<Either<Unit, FlowyError>> moveGroup({
required String fromGroupId,
required String toGroupId,
}) {
final payload = MoveGroupPayloadPB.create()
..viewId = viewId
..fromGroupId = fromGroupId
..toGroupId = toGroupId;
return DatabaseEventMoveGroup(payload).send();
}
Future<Either<List<FieldPB>, FlowyError>> getFields(
{List<FieldIdPB>? fieldIds}) {
var payload = GetFieldPayloadPB.create()..viewId = viewId;
if (fieldIds != null) {
payload.fieldIds = RepeatedFieldIdPB(items: fieldIds);
}
return DatabaseEventGetFields(payload).send().then((result) {
return result.fold((l) => left(l.items), (r) => right(r));
});
}
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
LayoutTypePB layoutType) {
final payload = DatabaseLayoutIdPB.create()
..viewId = viewId
..layout = layoutType;
return DatabaseEventGetLayoutSetting(payload).send();
}
Future<Either<Unit, FlowyError>> updateLayoutSetting(
{CalendarLayoutSettingsPB? calendarLayoutSetting}) {
final layoutSetting = LayoutSettingPB.create();
if (calendarLayoutSetting != null) {
layoutSetting.calendar = calendarLayoutSetting;
}
final payload = UpdateLayoutSettingPB.create()
..viewId = viewId
..layoutSetting = layoutSetting;
return DatabaseEventSetLayoutSetting(payload).send();
}
Future<Either<Unit, FlowyError>> closeView() {
final request = ViewIdPB(value: viewId);
return FolderEventCloseView(request).send();
}
Future<Either<RepeatedGroupPB, FlowyError>> loadGroups() {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetGroups(payload).send();
}
}

View file

@ -11,7 +11,7 @@ import 'package:appflowy_backend/protobuf/flowy-database/util.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../../grid/presentation/widgets/filter/filter_info.dart'; import '../../grid/presentation/widgets/filter/filter_info.dart';
import '../../grid/presentation/widgets/sort/sort_info.dart'; import '../../grid/presentation/widgets/sort/sort_info.dart';
import '../database_service.dart'; import '../database_view_service.dart';
import '../filter/filter_listener.dart'; import '../filter/filter_listener.dart';
import '../filter/filter_service.dart'; import '../filter/filter_service.dart';
import '../row/row_cache.dart'; import '../row/row_cache.dart';
@ -80,7 +80,7 @@ class FieldController {
final SortsListener _sortsListener; final SortsListener _sortsListener;
// FFI services // FFI services
final DatabaseBackendService _databaseBackendSvc; final DatabaseViewBackendService _databaseViewBackendSvc;
final SettingBackendService _settingBackendSvc; final SettingBackendService _settingBackendSvc;
final FilterBackendService _filterBackendSvc; final FilterBackendService _filterBackendSvc;
final SortBackendService _sortBackendSvc; final SortBackendService _sortBackendSvc;
@ -152,7 +152,7 @@ class FieldController {
_settingListener = DatabaseSettingListener(viewId: viewId), _settingListener = DatabaseSettingListener(viewId: viewId),
_filterBackendSvc = FilterBackendService(viewId: viewId), _filterBackendSvc = FilterBackendService(viewId: viewId),
_filtersListener = FiltersListener(viewId: viewId), _filtersListener = FiltersListener(viewId: viewId),
_databaseBackendSvc = DatabaseBackendService(viewId: viewId), _databaseViewBackendSvc = DatabaseViewBackendService(viewId: viewId),
_sortBackendSvc = SortBackendService(viewId: viewId), _sortBackendSvc = SortBackendService(viewId: viewId),
_sortsListener = SortsListener(viewId: viewId), _sortsListener = SortsListener(viewId: viewId),
_settingBackendSvc = SettingBackendService(viewId: viewId) { _settingBackendSvc = SettingBackendService(viewId: viewId) {
@ -448,7 +448,7 @@ class FieldController {
Future<Either<Unit, FlowyError>> loadFields({ Future<Either<Unit, FlowyError>> loadFields({
required List<FieldIdPB> fieldIds, required List<FieldIdPB> fieldIds,
}) async { }) async {
final result = await _databaseBackendSvc.getFields(fieldIds: fieldIds); final result = await _databaseViewBackendSvc.getFields(fieldIds: fieldIds);
return Future( return Future(
() => result.fold( () => result.fold(
(newFields) { (newFields) {

View file

@ -59,7 +59,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
); );
}, },
future: AppService().getView(appID, gridID), future: AppBackendService().getView(appID, gridID),
); );
} }

View file

@ -169,7 +169,7 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
); );
} }
}, },
future: AppService().fetchViews(widget.layoutType), future: AppBackendService().fetchViews(widget.layoutType),
); );
} }

View file

@ -18,11 +18,11 @@ import 'package:dartz/dartz.dart';
part 'app_bloc.freezed.dart'; part 'app_bloc.freezed.dart';
class AppBloc extends Bloc<AppEvent, AppState> { class AppBloc extends Bloc<AppEvent, AppState> {
final AppService appService; final AppBackendService appService;
final AppListener appListener; final AppListener appListener;
AppBloc({required AppPB app}) AppBloc({required AppPB app})
: appService = AppService(), : appService = AppBackendService(),
appListener = AppListener(appId: app.id), appListener = AppListener(appId: app.id),
super(AppState.initial(app)) { super(AppState.initial(app)) {
on<AppEvent>((event, emit) async { on<AppEvent>((event, emit) async {

View file

@ -8,7 +8,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
class AppService { class AppBackendService {
Future<Either<AppPB, FlowyError>> readApp({required String appId}) { Future<Either<AppPB, FlowyError>> readApp({required String appId}) {
final payload = AppIdPB.create()..value = appId; final payload = AppIdPB.create()..value = appId;
@ -21,9 +21,18 @@ class AppService {
String? desc, String? desc,
required ViewLayoutTypePB layoutType, required ViewLayoutTypePB layoutType,
/// The initial data should be the JSON of the doucment /// The initial data should be the JSON of the document.
/// For example: {"document":{"type":"editor","children":[]}} /// Currently, only support create document with initial data.
///
/// The initial data must be follow this format as shown below.
/// {"document":{"type":"editor","children":[]}}
String? initialData, String? initialData,
/// The [ext] is used to pass through the custom configuration
/// to the backend.
/// Linking the view to the existing database, it needs to pass
/// the database id. For example: "database_id": "xxx"
///
Map<String, String> ext = const {}, Map<String, String> ext = const {},
}) { }) {
final payload = CreateViewPayloadPB.create() final payload = CreateViewPayloadPB.create()

View file

@ -13,11 +13,11 @@ class ViewSectionBloc extends Bloc<ViewSectionEvent, ViewSectionState> {
void Function()? _viewsListener; void Function()? _viewsListener;
void Function()? _selectedViewlistener; void Function()? _selectedViewlistener;
final AppViewDataContext _appViewData; final AppViewDataContext _appViewData;
late final AppService _appService; late final AppBackendService _appService;
ViewSectionBloc({ ViewSectionBloc({
required AppViewDataContext appViewData, required AppViewDataContext appViewData,
}) : _appService = AppService(), }) : _appService = AppBackendService(),
_appViewData = appViewData, _appViewData = appViewData,
super(ViewSectionState.initial(appViewData)) { super(ViewSectionState.initial(appViewData)) {
on<ViewSectionEvent>((event, emit) async { on<ViewSectionEvent>((event, emit) async {

View file

@ -30,7 +30,7 @@ class AppFlowyBoardTest {
Future<BoardTestContext> createTestBoard() async { Future<BoardTestContext> createTestBoard() async {
final app = await unitTest.createTestApp(); final app = await unitTest.createTestApp();
final builder = BoardPluginBuilder(); final builder = BoardPluginBuilder();
return AppService() return AppBackendService()
.createView( .createView(
appId: app.id, appId: app.id,
name: "Test Board", name: "Test Board",

View file

@ -8,7 +8,7 @@ import '../util.dart';
Future<GridTestContext> createTestFilterGrid(AppFlowyGridTest gridTest) async { Future<GridTestContext> createTestFilterGrid(AppFlowyGridTest gridTest) async {
final app = await gridTest.unitTest.createTestApp(); final app = await gridTest.unitTest.createTestApp();
final builder = GridPluginBuilder(); final builder = GridPluginBuilder();
final context = await AppService() final context = await AppBackendService()
.createView( .createView(
appId: app.id, appId: app.id,
name: "Filter Grid", name: "Filter Grid",

View file

@ -165,7 +165,7 @@ class AppFlowyGridTest {
Future<GridTestContext> createTestGrid() async { Future<GridTestContext> createTestGrid() async {
final app = await unitTest.createTestApp(); final app = await unitTest.createTestApp();
final builder = GridPluginBuilder(); final builder = GridPluginBuilder();
final context = await AppService() final context = await AppBackendService()
.createView( .createView(
appId: app.id, appId: app.id,
name: "Test Grid", name: "Test Grid",

View file

@ -155,7 +155,7 @@ impl TryInto<MoveGroupRowParams> for MoveGroupRowPayloadPB {
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf)]
pub struct DatabaseDescPB { pub struct DatabaseDescriptionPB {
#[pb(index = 1)] #[pb(index = 1)]
pub name: String, pub name: String,
@ -164,9 +164,9 @@ pub struct DatabaseDescPB {
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedDatabaseDescPB { pub struct RepeatedDatabaseDescriptionPB {
#[pb(index = 1)] #[pb(index = 1)]
pub items: Vec<DatabaseDescPB>, pub items: Vec<DatabaseDescriptionPB>,
} }
#[derive(Debug, Clone, Default, ProtoBuf)] #[derive(Debug, Clone, Default, ProtoBuf)]

View file

@ -575,17 +575,17 @@ pub(crate) async fn move_group_row_handler(
#[tracing::instrument(level = "debug", skip(manager), err)] #[tracing::instrument(level = "debug", skip(manager), err)]
pub(crate) async fn get_databases_handler( pub(crate) async fn get_databases_handler(
manager: AFPluginState<Arc<DatabaseManager>>, manager: AFPluginState<Arc<DatabaseManager>>,
) -> DataResult<RepeatedDatabaseDescPB, FlowyError> { ) -> DataResult<RepeatedDatabaseDescriptionPB, FlowyError> {
let items = manager let items = manager
.get_databases() .get_databases()
.await? .await?
.into_iter() .into_iter()
.map(|database_info| DatabaseDescPB { .map(|database_info| DatabaseDescriptionPB {
name: database_info.name, name: database_info.name,
database_id: database_info.database_id, database_id: database_info.database_id,
}) })
.collect::<Vec<DatabaseDescPB>>(); .collect::<Vec<DatabaseDescriptionPB>>();
data_result_ok(RepeatedDatabaseDescPB { items }) data_result_ok(RepeatedDatabaseDescriptionPB { items })
} }
#[tracing::instrument(level = "debug", skip(data, manager), err)] #[tracing::instrument(level = "debug", skip(data, manager), err)]

View file

@ -238,7 +238,8 @@ pub enum DatabaseEvent {
#[event(input = "MoveGroupRowPayloadPB")] #[event(input = "MoveGroupRowPayloadPB")]
GroupByField = 113, GroupByField = 113,
#[event(output = "RepeatedDatabaseDescPB")] /// Returns all the databases
#[event(output = "RepeatedDatabaseDescriptionPB")]
GetDatabases = 114, GetDatabases = 114,
#[event(input = "UpdateLayoutSettingPB")] #[event(input = "UpdateLayoutSettingPB")]

View file

@ -7,7 +7,9 @@ use crate::services::database_view::{
make_database_view_rev_manager, make_database_view_revision_pad, DatabaseViewEditor, make_database_view_rev_manager, make_database_view_revision_pad, DatabaseViewEditor,
}; };
use crate::services::persistence::block_index::BlockRowIndexer; use crate::services::persistence::block_index::BlockRowIndexer;
use crate::services::persistence::database_ref::{DatabaseInfo, DatabaseRef, DatabaseRefIndexer}; use crate::services::persistence::database_ref::{
DatabaseInfo, DatabaseRefIndexer, DatabaseViewRef,
};
use crate::services::persistence::kv::DatabaseKVPersistence; use crate::services::persistence::kv::DatabaseKVPersistence;
use crate::services::persistence::migration::DatabaseMigration; use crate::services::persistence::migration::DatabaseMigration;
use crate::services::persistence::rev_sqlite::{ use crate::services::persistence::rev_sqlite::{
@ -192,7 +194,10 @@ impl DatabaseManager {
self.database_ref_indexer.get_all_databases() self.database_ref_indexer.get_all_databases()
} }
pub async fn get_database_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseRef>> { pub async fn get_database_ref_views(
&self,
database_id: &str,
) -> FlowyResult<Vec<DatabaseViewRef>> {
self self
.database_ref_indexer .database_ref_indexer
.get_ref_views_with_database(database_id) .get_ref_views_with_database(database_id)
@ -425,13 +430,13 @@ pub async fn create_new_database(
} }
impl DatabaseRefIndexerQuery for DatabaseRefIndexer { impl DatabaseRefIndexerQuery for DatabaseRefIndexer {
fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseRef>> { fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseViewRef>> {
self.get_ref_views_with_database(database_id) self.get_ref_views_with_database(database_id)
} }
} }
impl DatabaseRefIndexerQuery for Arc<DatabaseRefIndexer> { impl DatabaseRefIndexerQuery for Arc<DatabaseRefIndexer> {
fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseRef>> { fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseViewRef>> {
(**self).get_ref_views(database_id) (**self).get_ref_views(database_id)
} }
} }

View file

@ -18,7 +18,7 @@ use crate::services::database_view::{
}; };
use crate::services::filter::FilterType; use crate::services::filter::FilterType;
use crate::services::persistence::block_index::BlockRowIndexer; use crate::services::persistence::block_index::BlockRowIndexer;
use crate::services::persistence::database_ref::DatabaseRef; use crate::services::persistence::database_ref::DatabaseViewRef;
use crate::services::row::{DatabaseBlockRow, DatabaseBlockRowRevision, RowRevisionBuilder}; use crate::services::row::{DatabaseBlockRow, DatabaseBlockRowRevision, RowRevisionBuilder};
use bytes::Bytes; use bytes::Bytes;
use database_model::*; use database_model::*;
@ -42,7 +42,7 @@ use std::sync::Arc;
use tokio::sync::{broadcast, RwLock}; use tokio::sync::{broadcast, RwLock};
pub trait DatabaseRefIndexerQuery: Send + Sync + 'static { pub trait DatabaseRefIndexerQuery: Send + Sync + 'static {
fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseRef>>; fn get_ref_views(&self, database_id: &str) -> FlowyResult<Vec<DatabaseViewRef>>;
} }
pub struct DatabaseEditor { pub struct DatabaseEditor {

View file

@ -45,7 +45,10 @@ impl DatabaseRefIndexer {
Ok(()) Ok(())
} }
pub fn get_ref_views_with_database(&self, database_id: &str) -> FlowyResult<Vec<DatabaseRef>> { pub fn get_ref_views_with_database(
&self,
database_id: &str,
) -> FlowyResult<Vec<DatabaseViewRef>> {
let conn = self.database.get_db_connection()?; let conn = self.database.get_db_connection()?;
let views = dsl::database_refs let views = dsl::database_refs
.filter(database_refs::database_id.like(database_id)) .filter(database_refs::database_id.like(database_id))
@ -93,12 +96,12 @@ struct DatabaseRefRecord {
database_id: String, database_id: String,
} }
pub struct DatabaseRef { pub struct DatabaseViewRef {
pub view_id: String, pub view_id: String,
pub name: String, pub name: String,
pub database_id: String, pub database_id: String,
} }
impl std::convert::From<DatabaseRefRecord> for DatabaseRef { impl std::convert::From<DatabaseRefRecord> for DatabaseViewRef {
fn from(record: DatabaseRefRecord) -> Self { fn from(record: DatabaseRefRecord) -> Self {
Self { Self {
view_id: record.view_id, view_id: record.view_id,

View file

@ -2,12 +2,12 @@ use crate::database::block_test::util::DatabaseRowTestBuilder;
use crate::database::database_editor::DatabaseEditorTest; use crate::database::database_editor::DatabaseEditorTest;
use database_model::RowRevision; use database_model::RowRevision;
use flowy_database::services::database::DatabaseEditor; use flowy_database::services::database::DatabaseEditor;
use flowy_database::services::persistence::database_ref::{DatabaseInfo, DatabaseRef}; use flowy_database::services::persistence::database_ref::{DatabaseInfo, DatabaseViewRef};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
pub enum DatabaseRefScript { pub enum LinkDatabaseTestScript {
LinkGridToDatabase { CreateGridViewAndLinkToDatabase {
database_id: String, database_id: String,
}, },
#[allow(dead_code)] #[allow(dead_code)]
@ -28,17 +28,17 @@ pub enum DatabaseRefScript {
}, },
} }
pub struct DatabaseRefTest { pub struct LinkDatabaseTest {
inner: DatabaseEditorTest, inner: DatabaseEditorTest,
} }
impl DatabaseRefTest { impl LinkDatabaseTest {
pub async fn new() -> Self { pub async fn new() -> Self {
let inner = DatabaseEditorTest::new_grid().await; let inner = DatabaseEditorTest::new_grid().await;
Self { inner } Self { inner }
} }
pub async fn run_scripts(&mut self, scripts: Vec<DatabaseRefScript>) { pub async fn run_scripts(&mut self, scripts: Vec<LinkDatabaseTestScript>) {
for script in scripts { for script in scripts {
self.run_script(script).await; self.run_script(script).await;
} }
@ -61,7 +61,7 @@ impl DatabaseRefTest {
.unwrap() .unwrap()
} }
pub async fn all_database_ref_views(&self, database_id: &str) -> Vec<DatabaseRef> { pub async fn all_database_ref_views(&self, database_id: &str) -> Vec<DatabaseViewRef> {
self self
.inner .inner
.sdk .sdk
@ -87,9 +87,9 @@ impl DatabaseRefTest {
DatabaseRowTestBuilder::new(self.block_id(view_id).await, field_revs) DatabaseRowTestBuilder::new(self.block_id(view_id).await, field_revs)
} }
pub async fn run_script(&mut self, script: DatabaseRefScript) { pub async fn run_script(&mut self, script: LinkDatabaseTestScript) {
match script { match script {
DatabaseRefScript::LinkGridToDatabase { database_id } => { LinkDatabaseTestScript::CreateGridViewAndLinkToDatabase { database_id } => {
let mut ext = HashMap::new(); let mut ext = HashMap::new();
ext.insert("database_id".to_owned(), database_id); ext.insert("database_id".to_owned(), database_id);
self self
@ -99,7 +99,7 @@ impl DatabaseRefTest {
.create_test_grid_view(&self.inner.app_id, "test link grid", ext) .create_test_grid_view(&self.inner.app_id, "test link grid", ext)
.await; .await;
}, },
DatabaseRefScript::LinkBoardToDatabase { database_id } => { LinkDatabaseTestScript::LinkBoardToDatabase { database_id } => {
let mut ext = HashMap::new(); let mut ext = HashMap::new();
ext.insert("database_id".to_owned(), database_id); ext.insert("database_id".to_owned(), database_id);
self self
@ -109,7 +109,7 @@ impl DatabaseRefTest {
.create_test_board_view(&self.inner.app_id, "test link board", ext) .create_test_board_view(&self.inner.app_id, "test link board", ext)
.await; .await;
}, },
DatabaseRefScript::CreateNewGrid => { LinkDatabaseTestScript::CreateNewGrid => {
self self
.inner .inner
.sdk .sdk
@ -117,15 +117,15 @@ impl DatabaseRefTest {
.create_test_grid_view(&self.inner.app_id, "Create test grid", HashMap::new()) .create_test_grid_view(&self.inner.app_id, "Create test grid", HashMap::new())
.await; .await;
}, },
DatabaseRefScript::AssertNumberOfDatabase { expected } => { LinkDatabaseTestScript::AssertNumberOfDatabase { expected } => {
let databases = self.all_databases().await; let databases = self.all_databases().await;
assert_eq!(databases.len(), expected); assert_eq!(databases.len(), expected);
}, },
DatabaseRefScript::CreateRow { view_id, row_rev } => { LinkDatabaseTestScript::CreateRow { view_id, row_rev } => {
let editor = self.get_database_editor(&view_id).await; let editor = self.get_database_editor(&view_id).await;
let _ = editor.insert_rows(vec![row_rev]).await.unwrap(); let _ = editor.insert_rows(vec![row_rev]).await.unwrap();
}, },
DatabaseRefScript::AssertNumberOfRows { view_id, expected } => { LinkDatabaseTestScript::AssertNumberOfRows { view_id, expected } => {
let editor = self.get_database_editor(&view_id).await; let editor = self.get_database_editor(&view_id).await;
let rows = editor.get_all_row_revs(&view_id).await.unwrap(); let rows = editor.get_all_row_revs(&view_id).await.unwrap();
assert_eq!(rows.len(), expected); assert_eq!(rows.len(), expected);

View file

@ -1,11 +1,12 @@
use crate::database::database_ref_test::script::DatabaseRefScript::*; use crate::database::database_ref_test::script::LinkDatabaseTest;
use crate::database::database_ref_test::script::DatabaseRefTest; use crate::database::database_ref_test::script::LinkDatabaseTestScript::*;
#[tokio::test] #[tokio::test]
async fn database_ref_number_of_database_test() { async fn number_of_database_test() {
let mut test = DatabaseRefTest::new().await; let mut test = LinkDatabaseTest::new().await;
test test
.run_scripts(vec![ .run_scripts(vec![
// After the LinkDatabaseTest initialize, it will create a grid.
AssertNumberOfDatabase { expected: 1 }, AssertNumberOfDatabase { expected: 1 },
CreateNewGrid, CreateNewGrid,
AssertNumberOfDatabase { expected: 2 }, AssertNumberOfDatabase { expected: 2 },
@ -14,12 +15,12 @@ async fn database_ref_number_of_database_test() {
} }
#[tokio::test] #[tokio::test]
async fn database_ref_link_with_existing_database_test() { async fn database_view_link_with_existing_database_test() {
let mut test = DatabaseRefTest::new().await; let mut test = LinkDatabaseTest::new().await;
let database = test.all_databases().await.pop().unwrap(); let database = test.all_databases().await.pop().unwrap();
test test
.run_scripts(vec![ .run_scripts(vec![
LinkGridToDatabase { CreateGridViewAndLinkToDatabase {
database_id: database.database_id, database_id: database.database_id,
}, },
AssertNumberOfDatabase { expected: 1 }, AssertNumberOfDatabase { expected: 1 },
@ -28,36 +29,48 @@ async fn database_ref_link_with_existing_database_test() {
} }
#[tokio::test] #[tokio::test]
async fn database_ref_link_with_existing_database_row_test() { async fn check_number_of_rows_in_linked_database_view() {
let mut test = DatabaseRefTest::new().await; let mut test = LinkDatabaseTest::new().await;
let database = test.all_databases().await.pop().unwrap(); let database = test.all_databases().await.pop().unwrap();
let view = test
.all_database_ref_views(&database.database_id)
.await
.remove(0);
test test
.run_scripts(vec![ .run_scripts(vec![
LinkGridToDatabase { CreateGridViewAndLinkToDatabase {
database_id: database.database_id, database_id: database.database_id,
}, },
AssertNumberOfDatabase { expected: 1 }, // The initial number of rows is 6
AssertNumberOfRows {
view_id: view.view_id.clone(),
expected: 6,
},
]) ])
.await; .await;
} }
#[tokio::test] #[tokio::test]
async fn database_ref_create_new_row_test() { async fn multiple_views_share_database_rows() {
let mut test = DatabaseRefTest::new().await; let mut test = LinkDatabaseTest::new().await;
// After the LinkDatabaseTest initialize, it will create a default database
// with Grid layout.
let database = test.all_databases().await.pop().unwrap(); let database = test.all_databases().await.pop().unwrap();
let database_views = test.all_database_ref_views(&database.database_id).await; let mut database_views = test.all_database_ref_views(&database.database_id).await;
assert_eq!(database_views.len(), 1); assert_eq!(database_views.len(), 1);
let view_id_1 = database_views.get(0).unwrap().view_id.clone(); let view = database_views.remove(0);
test test
.run_scripts(vec![ .run_scripts(vec![
AssertNumberOfRows { AssertNumberOfRows {
view_id: view_id_1.clone(), view_id: view.view_id.clone(),
expected: 6, expected: 6,
}, },
LinkGridToDatabase { CreateGridViewAndLinkToDatabase {
database_id: database.database_id.clone(), database_id: database.database_id.clone(),
}, },
AssertNumberOfDatabase { expected: 1 },
]) ])
.await; .await;
@ -84,6 +97,7 @@ async fn database_ref_create_new_row_test() {
view_id: view_id_2, view_id: view_id_2,
expected: 7, expected: 7,
}, },
AssertNumberOfDatabase { expected: 1 },
]) ])
.await; .await;
} }