mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[client]: crud with trash on server & fix some bugs
This commit is contained in:
@ -34,7 +34,7 @@ class TrashBloc extends Bloc<TrashEvent, TrashState> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
delete: (e) async* {
|
delete: (e) async* {
|
||||||
final result = await iTrash.delete(e.trashId);
|
final result = await iTrash.deleteViews([e.trashId]);
|
||||||
result.fold((l) {}, (error) {});
|
result.fold((l) {}, (error) {});
|
||||||
},
|
},
|
||||||
deleteAll: (e) async* {},
|
deleteAll: (e) async* {},
|
||||||
|
@ -8,7 +8,7 @@ abstract class ITrash {
|
|||||||
|
|
||||||
Future<Either<Unit, WorkspaceError>> putback(String trashId);
|
Future<Either<Unit, WorkspaceError>> putback(String trashId);
|
||||||
|
|
||||||
Future<Either<Unit, WorkspaceError>> delete(String trashId);
|
Future<Either<Unit, WorkspaceError>> deleteViews(List<String> trashIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef TrashUpdatedCallback = void Function(Either<List<Trash>, WorkspaceError> trashOrFailed);
|
typedef TrashUpdatedCallback = void Function(Either<List<Trash>, WorkspaceError> trashOrFailed);
|
||||||
|
@ -25,8 +25,8 @@ class ITrashImpl implements ITrash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Either<Unit, WorkspaceError>> delete(String trashId) {
|
Future<Either<Unit, WorkspaceError>> deleteViews(List<String> trashIds) {
|
||||||
return repo.delete(trashId);
|
return repo.deleteViews(trashIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import 'package:flowy_sdk/protobuf/flowy-dart-notify/subject.pb.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/trash_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/trash_create.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/trash_delete.pb.dart';
|
|
||||||
import 'package:flowy_sdk/rust_stream.dart';
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
class TrashRepo {
|
class TrashRepo {
|
||||||
@ -22,9 +21,13 @@ class TrashRepo {
|
|||||||
return WorkspaceEventPutbackTrash(id).send();
|
return WorkspaceEventPutbackTrash(id).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, WorkspaceError>> delete(String trashId) {
|
Future<Either<Unit, WorkspaceError>> deleteViews(List<String> viewIds) {
|
||||||
final id = TrashIdentifier.create()..id = trashId;
|
final trashIdentifiers = TrashIdentifiers(
|
||||||
return WorkspaceEventDeleteTrash(id).send();
|
items: viewIds.map((id) => TrashIdentifier.create()
|
||||||
|
..id = id
|
||||||
|
..ty = TrashType.View));
|
||||||
|
|
||||||
|
return WorkspaceEventDeleteTrash(trashIdentifiers).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ class WorkspaceEventPutbackTrash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WorkspaceEventDeleteTrash {
|
class WorkspaceEventDeleteTrash {
|
||||||
TrashIdentifier request;
|
TrashIdentifiers request;
|
||||||
WorkspaceEventDeleteTrash(this.request);
|
WorkspaceEventDeleteTrash(this.request);
|
||||||
|
|
||||||
Future<Either<Unit, WorkspaceError>> send() {
|
Future<Either<Unit, WorkspaceError>> send() {
|
||||||
@ -319,6 +319,34 @@ class WorkspaceEventDeleteTrash {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WorkspaceEventRestoreAll {
|
||||||
|
WorkspaceEventRestoreAll();
|
||||||
|
|
||||||
|
Future<Either<Unit, WorkspaceError>> send() {
|
||||||
|
final request = FFIRequest.create()
|
||||||
|
..event = WorkspaceEvent.RestoreAll.toString();
|
||||||
|
|
||||||
|
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
|
||||||
|
(bytes) => left(unit),
|
||||||
|
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkspaceEventDeleteAll {
|
||||||
|
WorkspaceEventDeleteAll();
|
||||||
|
|
||||||
|
Future<Either<Unit, WorkspaceError>> send() {
|
||||||
|
final request = FFIRequest.create()
|
||||||
|
..event = WorkspaceEvent.DeleteAll.toString();
|
||||||
|
|
||||||
|
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
|
||||||
|
(bytes) => left(unit),
|
||||||
|
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WorkspaceEventInitWorkspace {
|
class WorkspaceEventInitWorkspace {
|
||||||
WorkspaceEventInitWorkspace();
|
WorkspaceEventInitWorkspace();
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ export './app_query.pb.dart';
|
|||||||
export './workspace_delete.pb.dart';
|
export './workspace_delete.pb.dart';
|
||||||
export './observable.pb.dart';
|
export './observable.pb.dart';
|
||||||
export './errors.pb.dart';
|
export './errors.pb.dart';
|
||||||
export './trash_delete.pb.dart';
|
|
||||||
export './workspace_update.pb.dart';
|
export './workspace_update.pb.dart';
|
||||||
export './app_create.pb.dart';
|
export './app_create.pb.dart';
|
||||||
export './workspace_query.pb.dart';
|
export './workspace_query.pb.dart';
|
||||||
|
@ -14,15 +14,56 @@ import 'trash_create.pbenum.dart';
|
|||||||
|
|
||||||
export 'trash_create.pbenum.dart';
|
export 'trash_create.pbenum.dart';
|
||||||
|
|
||||||
class CreateTrashParams extends $pb.GeneratedMessage {
|
class TrashIdentifiers extends $pb.GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateTrashParams', createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TrashIdentifiers', createEmptyInstance: create)
|
||||||
|
..pc<TrashIdentifier>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: TrashIdentifier.create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
TrashIdentifiers._() : super();
|
||||||
|
factory TrashIdentifiers({
|
||||||
|
$core.Iterable<TrashIdentifier>? items,
|
||||||
|
}) {
|
||||||
|
final _result = create();
|
||||||
|
if (items != null) {
|
||||||
|
_result.items.addAll(items);
|
||||||
|
}
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
factory TrashIdentifiers.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory TrashIdentifiers.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
TrashIdentifiers clone() => TrashIdentifiers()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
TrashIdentifiers copyWith(void Function(TrashIdentifiers) updates) => super.copyWith((message) => updates(message as TrashIdentifiers)) as TrashIdentifiers; // ignore: deprecated_member_use
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static TrashIdentifiers create() => TrashIdentifiers._();
|
||||||
|
TrashIdentifiers createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<TrashIdentifiers> createRepeated() => $pb.PbList<TrashIdentifiers>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static TrashIdentifiers getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TrashIdentifiers>(create);
|
||||||
|
static TrashIdentifiers? _defaultInstance;
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<TrashIdentifier> get items => $_getList(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TrashIdentifier extends $pb.GeneratedMessage {
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TrashIdentifier', createEmptyInstance: create)
|
||||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
||||||
..e<TrashType>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: TrashType.Unknown, valueOf: TrashType.valueOf, enumValues: TrashType.values)
|
..e<TrashType>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: TrashType.Unknown, valueOf: TrashType.valueOf, enumValues: TrashType.values)
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
CreateTrashParams._() : super();
|
TrashIdentifier._() : super();
|
||||||
factory CreateTrashParams({
|
factory TrashIdentifier({
|
||||||
$core.String? id,
|
$core.String? id,
|
||||||
TrashType? ty,
|
TrashType? ty,
|
||||||
}) {
|
}) {
|
||||||
@ -35,26 +76,26 @@ class CreateTrashParams extends $pb.GeneratedMessage {
|
|||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
}
|
}
|
||||||
factory CreateTrashParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
factory TrashIdentifier.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
factory CreateTrashParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
factory TrashIdentifier.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
@$core.Deprecated(
|
@$core.Deprecated(
|
||||||
'Using this can add significant overhead to your binary. '
|
'Using this can add significant overhead to your binary. '
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
'Will be removed in next major version')
|
'Will be removed in next major version')
|
||||||
CreateTrashParams clone() => CreateTrashParams()..mergeFromMessage(this);
|
TrashIdentifier clone() => TrashIdentifier()..mergeFromMessage(this);
|
||||||
@$core.Deprecated(
|
@$core.Deprecated(
|
||||||
'Using this can add significant overhead to your binary. '
|
'Using this can add significant overhead to your binary. '
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
'Will be removed in next major version')
|
'Will be removed in next major version')
|
||||||
CreateTrashParams copyWith(void Function(CreateTrashParams) updates) => super.copyWith((message) => updates(message as CreateTrashParams)) as CreateTrashParams; // ignore: deprecated_member_use
|
TrashIdentifier copyWith(void Function(TrashIdentifier) updates) => super.copyWith((message) => updates(message as TrashIdentifier)) as TrashIdentifier; // ignore: deprecated_member_use
|
||||||
$pb.BuilderInfo get info_ => _i;
|
$pb.BuilderInfo get info_ => _i;
|
||||||
@$core.pragma('dart2js:noInline')
|
@$core.pragma('dart2js:noInline')
|
||||||
static CreateTrashParams create() => CreateTrashParams._();
|
static TrashIdentifier create() => TrashIdentifier._();
|
||||||
CreateTrashParams createEmptyInstance() => create();
|
TrashIdentifier createEmptyInstance() => create();
|
||||||
static $pb.PbList<CreateTrashParams> createRepeated() => $pb.PbList<CreateTrashParams>();
|
static $pb.PbList<TrashIdentifier> createRepeated() => $pb.PbList<TrashIdentifier>();
|
||||||
@$core.pragma('dart2js:noInline')
|
@$core.pragma('dart2js:noInline')
|
||||||
static CreateTrashParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateTrashParams>(create);
|
static TrashIdentifier getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TrashIdentifier>(create);
|
||||||
static CreateTrashParams? _defaultInstance;
|
static TrashIdentifier? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.String get id => $_getSZ(0);
|
$core.String get id => $_getSZ(0);
|
||||||
|
@ -19,17 +19,27 @@ const TrashType$json = const {
|
|||||||
|
|
||||||
/// Descriptor for `TrashType`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `TrashType`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List trashTypeDescriptor = $convert.base64Decode('CglUcmFzaFR5cGUSCwoHVW5rbm93bhAAEggKBFZpZXcQAQ==');
|
final $typed_data.Uint8List trashTypeDescriptor = $convert.base64Decode('CglUcmFzaFR5cGUSCwoHVW5rbm93bhAAEggKBFZpZXcQAQ==');
|
||||||
@$core.Deprecated('Use createTrashParamsDescriptor instead')
|
@$core.Deprecated('Use trashIdentifiersDescriptor instead')
|
||||||
const CreateTrashParams$json = const {
|
const TrashIdentifiers$json = const {
|
||||||
'1': 'CreateTrashParams',
|
'1': 'TrashIdentifiers',
|
||||||
|
'2': const [
|
||||||
|
const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.TrashIdentifier', '10': 'items'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `TrashIdentifiers`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List trashIdentifiersDescriptor = $convert.base64Decode('ChBUcmFzaElkZW50aWZpZXJzEiYKBWl0ZW1zGAEgAygLMhAuVHJhc2hJZGVudGlmaWVyUgVpdGVtcw==');
|
||||||
|
@$core.Deprecated('Use trashIdentifierDescriptor instead')
|
||||||
|
const TrashIdentifier$json = const {
|
||||||
|
'1': 'TrashIdentifier',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
||||||
const {'1': 'ty', '3': 2, '4': 1, '5': 14, '6': '.TrashType', '10': 'ty'},
|
const {'1': 'ty', '3': 2, '4': 1, '5': 14, '6': '.TrashType', '10': 'ty'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `CreateTrashParams`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `TrashIdentifier`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List createTrashParamsDescriptor = $convert.base64Decode('ChFDcmVhdGVUcmFzaFBhcmFtcxIOCgJpZBgBIAEoCVICaWQSGgoCdHkYAiABKA4yCi5UcmFzaFR5cGVSAnR5');
|
final $typed_data.Uint8List trashIdentifierDescriptor = $convert.base64Decode('Cg9UcmFzaElkZW50aWZpZXISDgoCaWQYASABKAlSAmlkEhoKAnR5GAIgASgOMgouVHJhc2hUeXBlUgJ0eQ==');
|
||||||
@$core.Deprecated('Use trashDescriptor instead')
|
@$core.Deprecated('Use trashDescriptor instead')
|
||||||
const Trash$json = const {
|
const Trash$json = const {
|
||||||
'1': 'Trash',
|
'1': 'Trash',
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: trash_delete.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
|
||||||
|
|
||||||
import 'dart:core' as $core;
|
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
|
||||||
|
|
||||||
class TrashIdentifier extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TrashIdentifier', createEmptyInstance: create)
|
|
||||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
TrashIdentifier._() : super();
|
|
||||||
factory TrashIdentifier({
|
|
||||||
$core.String? id,
|
|
||||||
}) {
|
|
||||||
final _result = create();
|
|
||||||
if (id != null) {
|
|
||||||
_result.id = id;
|
|
||||||
}
|
|
||||||
return _result;
|
|
||||||
}
|
|
||||||
factory TrashIdentifier.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
|
||||||
factory TrashIdentifier.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TrashIdentifier clone() => TrashIdentifier()..mergeFromMessage(this);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TrashIdentifier copyWith(void Function(TrashIdentifier) updates) => super.copyWith((message) => updates(message as TrashIdentifier)) as TrashIdentifier; // ignore: deprecated_member_use
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TrashIdentifier create() => TrashIdentifier._();
|
|
||||||
TrashIdentifier createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<TrashIdentifier> createRepeated() => $pb.PbList<TrashIdentifier>();
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TrashIdentifier getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TrashIdentifier>(create);
|
|
||||||
static TrashIdentifier? _defaultInstance;
|
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.String get id => $_getSZ(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
set id($core.String v) { $_setString(0, v); }
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.bool hasId() => $_has(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
void clearId() => clearField(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TrashIdentifiers extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TrashIdentifiers', createEmptyInstance: create)
|
|
||||||
..pPS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ids')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
TrashIdentifiers._() : super();
|
|
||||||
factory TrashIdentifiers({
|
|
||||||
$core.Iterable<$core.String>? ids,
|
|
||||||
}) {
|
|
||||||
final _result = create();
|
|
||||||
if (ids != null) {
|
|
||||||
_result.ids.addAll(ids);
|
|
||||||
}
|
|
||||||
return _result;
|
|
||||||
}
|
|
||||||
factory TrashIdentifiers.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
|
||||||
factory TrashIdentifiers.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TrashIdentifiers clone() => TrashIdentifiers()..mergeFromMessage(this);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TrashIdentifiers copyWith(void Function(TrashIdentifiers) updates) => super.copyWith((message) => updates(message as TrashIdentifiers)) as TrashIdentifiers; // ignore: deprecated_member_use
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TrashIdentifiers create() => TrashIdentifiers._();
|
|
||||||
TrashIdentifiers createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<TrashIdentifiers> createRepeated() => $pb.PbList<TrashIdentifiers>();
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TrashIdentifiers getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TrashIdentifiers>(create);
|
|
||||||
static TrashIdentifiers? _defaultInstance;
|
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.List<$core.String> get ids => $_getList(0);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: trash_delete.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: trash_delete.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
|
|
||||||
|
|
||||||
import 'dart:core' as $core;
|
|
||||||
import 'dart:convert' as $convert;
|
|
||||||
import 'dart:typed_data' as $typed_data;
|
|
||||||
@$core.Deprecated('Use trashIdentifierDescriptor instead')
|
|
||||||
const TrashIdentifier$json = const {
|
|
||||||
'1': 'TrashIdentifier',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Descriptor for `TrashIdentifier`. Decode as a `google.protobuf.DescriptorProto`.
|
|
||||||
final $typed_data.Uint8List trashIdentifierDescriptor = $convert.base64Decode('Cg9UcmFzaElkZW50aWZpZXISDgoCaWQYASABKAlSAmlk');
|
|
||||||
@$core.Deprecated('Use trashIdentifiersDescriptor instead')
|
|
||||||
const TrashIdentifiers$json = const {
|
|
||||||
'1': 'TrashIdentifiers',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'ids', '3': 1, '4': 3, '5': 9, '10': 'ids'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Descriptor for `TrashIdentifiers`. Decode as a `google.protobuf.DescriptorProto`.
|
|
||||||
final $typed_data.Uint8List trashIdentifiersDescriptor = $convert.base64Decode('ChBUcmFzaElkZW50aWZpZXJzEhAKA2lkcxgBIAMoCVIDaWRz');
|
|
@ -1,9 +0,0 @@
|
|||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: trash_delete.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
|
|
||||||
|
|
||||||
export 'trash_delete.pb.dart';
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::{net::TcpListener, time::Duration};
|
|||||||
|
|
||||||
use actix::Actor;
|
use actix::Actor;
|
||||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
||||||
use actix_web::{dev::Server, web, web::Data, App, HttpServer, Scope};
|
use actix_web::{dev::Server, middleware, web, web::Data, App, HttpServer, Scope};
|
||||||
use sqlx::{postgres::PgPoolOptions, PgPool};
|
use sqlx::{postgres::PgPoolOptions, PgPool};
|
||||||
use tokio::time::interval;
|
use tokio::time::interval;
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ pub fn run(listener: TcpListener, app_ctx: AppContext) -> Result<Server, std::io
|
|||||||
|
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
// .wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.wrap(identify_service(&domain, &secret))
|
.wrap(identify_service(&domain, &secret))
|
||||||
.wrap(crate::middleware::default_cors())
|
.wrap(crate::middleware::default_cors())
|
||||||
.wrap(crate::middleware::AuthenticationService)
|
.wrap(crate::middleware::AuthenticationService)
|
||||||
|
@ -15,25 +15,24 @@ use flowy_net::{
|
|||||||
};
|
};
|
||||||
use flowy_workspace::{
|
use flowy_workspace::{
|
||||||
entities::trash::parser::{TrashId, TrashTypeParser},
|
entities::trash::parser::{TrashId, TrashTypeParser},
|
||||||
protobuf::{CreateTrashParams, TrashIdentifiers},
|
protobuf::TrashIdentifiers,
|
||||||
};
|
};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(payload, pool, logged_user), err)]
|
||||||
pub async fn create_handler(
|
pub async fn create_handler(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
pool: Data<PgPool>,
|
pool: Data<PgPool>,
|
||||||
logged_user: LoggedUser,
|
logged_user: LoggedUser,
|
||||||
) -> Result<HttpResponse, ServerError> {
|
) -> Result<HttpResponse, ServerError> {
|
||||||
let params: CreateTrashParams = parse_from_payload(payload).await?;
|
let params: TrashIdentifiers = parse_from_payload(payload).await?;
|
||||||
let mut transaction = pool
|
let mut transaction = pool
|
||||||
.begin()
|
.begin()
|
||||||
.await
|
.await
|
||||||
.context("Failed to acquire a Postgres connection to create trash")?;
|
.context("Failed to acquire a Postgres connection to create trash")?;
|
||||||
|
log::error!("😁create handler: {:?}", params);
|
||||||
let trash_id = check_trash_id(params.id)?;
|
let _ = create_trash(&mut transaction, make_records(params)?, logged_user).await?;
|
||||||
let ty = TrashTypeParser::parse(params.ty.value()).map_err(invalid_params)?;
|
|
||||||
let _ = create_trash(&mut transaction, trash_id, ty, logged_user).await?;
|
|
||||||
|
|
||||||
transaction
|
transaction
|
||||||
.commit()
|
.commit()
|
||||||
@ -54,8 +53,7 @@ pub async fn delete_handler(
|
|||||||
.await
|
.await
|
||||||
.context("Failed to acquire a Postgres connection to delete trash")?;
|
.context("Failed to acquire a Postgres connection to delete trash")?;
|
||||||
|
|
||||||
let trash_ids = check_trash_ids(params.ids.into_vec())?;
|
let _ = delete_trash(&mut transaction, make_records(params)?, &logged_user).await?;
|
||||||
let _ = delete_trash(&mut transaction, trash_ids, &logged_user).await?;
|
|
||||||
transaction
|
transaction
|
||||||
.commit()
|
.commit()
|
||||||
.await
|
.await
|
||||||
@ -86,10 +84,11 @@ fn check_trash_id(id: String) -> Result<Uuid, ServerError> {
|
|||||||
Ok(trash_id)
|
Ok(trash_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trash_ids(ids: Vec<String>) -> Result<Vec<Uuid>, ServerError> {
|
fn make_records(identifiers: TrashIdentifiers) -> Result<Vec<(Uuid, i32)>, ServerError> {
|
||||||
let mut trash_ids = vec![];
|
let mut records = vec![];
|
||||||
for id in ids {
|
for identifier in identifiers.items {
|
||||||
trash_ids.push(check_trash_id(id)?)
|
let ty = TrashTypeParser::parse(identifier.ty.value()).map_err(invalid_params)?;
|
||||||
|
records.push((check_trash_id(identifier.id.to_owned())?, ty));
|
||||||
}
|
}
|
||||||
Ok(trash_ids)
|
Ok(records)
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,16 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use ::protobuf::ProtobufEnum;
|
use ::protobuf::ProtobufEnum;
|
||||||
use flowy_net::errors::ServerError;
|
use flowy_net::errors::ServerError;
|
||||||
use flowy_workspace::protobuf::{RepeatedTrash, Trash, TrashIdentifiers, TrashType};
|
use flowy_workspace::protobuf::{RepeatedTrash, Trash, TrashType};
|
||||||
use sqlx::{postgres::PgArguments, Postgres};
|
use sqlx::{postgres::PgArguments, Postgres};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub(crate) async fn create_trash(
|
pub(crate) async fn create_trash(
|
||||||
transaction: &mut DBTransaction<'_>,
|
transaction: &mut DBTransaction<'_>,
|
||||||
trash_id: Uuid,
|
records: Vec<(Uuid, i32)>,
|
||||||
ty: i32,
|
|
||||||
user: LoggedUser,
|
user: LoggedUser,
|
||||||
) -> Result<(), ServerError> {
|
) -> Result<(), ServerError> {
|
||||||
|
for (trash_id, ty) in records {
|
||||||
let (sql, args) = SqlBuilder::create(TRASH_TABLE)
|
let (sql, args) = SqlBuilder::create(TRASH_TABLE)
|
||||||
.add_arg("id", trash_id)
|
.add_arg("id", trash_id)
|
||||||
.add_arg("user_id", &user.user_id)
|
.add_arg("user_id", &user.user_id)
|
||||||
@ -25,19 +25,20 @@ pub(crate) async fn create_trash(
|
|||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let _ = sqlx::query_with(&sql, args)
|
let _ = sqlx::query_with(&sql, args)
|
||||||
.execute(transaction)
|
.execute(transaction as &mut DBTransaction<'_>)
|
||||||
.await
|
.await
|
||||||
.map_err(map_sqlx_error)?;
|
.map_err(map_sqlx_error)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_trash(
|
pub(crate) async fn delete_trash(
|
||||||
transaction: &mut DBTransaction<'_>,
|
transaction: &mut DBTransaction<'_>,
|
||||||
trash_ids: Vec<Uuid>,
|
records: Vec<(Uuid, i32)>,
|
||||||
_user: &LoggedUser,
|
_user: &LoggedUser,
|
||||||
) -> Result<(), ServerError> {
|
) -> Result<(), ServerError> {
|
||||||
for trash_id in trash_ids {
|
for (trash_id, _) in records {
|
||||||
// Read the trash_table and delete the original table according to the TrashType
|
// Read the trash_table and delete the original table according to the TrashType
|
||||||
let (sql, args) = SqlBuilder::select(TRASH_TABLE)
|
let (sql, args) = SqlBuilder::select(TRASH_TABLE)
|
||||||
.add_field("*")
|
.add_field("*")
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
use flowy_workspace::entities::{
|
use flowy_workspace::entities::{
|
||||||
app::{AppIdentifier, DeleteAppParams, UpdateAppParams},
|
app::{AppIdentifier, DeleteAppParams, UpdateAppParams},
|
||||||
trash::{CreateTrashParams, TrashIdentifiers, TrashType},
|
|
||||||
view::{UpdateViewParams, ViewIdentifier},
|
view::{UpdateViewParams, ViewIdentifier},
|
||||||
workspace::{CreateWorkspaceParams, DeleteWorkspaceParams, QueryWorkspaceParams, UpdateWorkspaceParams},
|
workspace::{CreateWorkspaceParams, DeleteWorkspaceParams, QueryWorkspaceParams, UpdateWorkspaceParams},
|
||||||
};
|
};
|
||||||
@ -98,11 +97,7 @@ async fn app_read_with_belongs_in_trash() {
|
|||||||
let _ = create_test_view(&test.server, &test.app.id).await;
|
let _ = create_test_view(&test.server, &test.app.id).await;
|
||||||
let view = create_test_view(&test.server, &test.app.id).await;
|
let view = create_test_view(&test.server, &test.app.id).await;
|
||||||
|
|
||||||
let params = CreateTrashParams {
|
test.server.create_view_trash(&view.id).await;
|
||||||
id: view.id.clone(),
|
|
||||||
ty: TrashType::View,
|
|
||||||
};
|
|
||||||
test.server.create_trash(params).await;
|
|
||||||
|
|
||||||
let read_params = AppIdentifier::new(&test.app.id);
|
let read_params = AppIdentifier::new(&test.app.id);
|
||||||
let app = test.server.read_app(read_params).await.unwrap();
|
let app = test.server.read_app(read_params).await.unwrap();
|
||||||
@ -159,13 +154,7 @@ async fn view_update() {
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn view_delete() {
|
async fn view_delete() {
|
||||||
let test = ViewTest::new().await;
|
let test = ViewTest::new().await;
|
||||||
|
test.server.create_view_trash(&test.view.id).await;
|
||||||
// delete
|
|
||||||
let params = CreateTrashParams {
|
|
||||||
id: test.view.id.clone(),
|
|
||||||
ty: TrashType::View,
|
|
||||||
};
|
|
||||||
test.server.create_trash(params).await;
|
|
||||||
|
|
||||||
let trash_ids = test
|
let trash_ids = test
|
||||||
.server
|
.server
|
||||||
@ -186,16 +175,8 @@ async fn view_delete() {
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn view_delete_and_then_delete_the_trash_record() {
|
async fn view_delete_and_then_delete_the_trash_record() {
|
||||||
let test = ViewTest::new().await;
|
let test = ViewTest::new().await;
|
||||||
let params = CreateTrashParams {
|
test.server.create_view_trash(&test.view.id).await;
|
||||||
id: test.view.id.clone(),
|
test.server.delete_view_trash(&test.view.id).await;
|
||||||
ty: TrashType::View,
|
|
||||||
};
|
|
||||||
test.server.create_trash(params).await;
|
|
||||||
test.server
|
|
||||||
.delete_trash(TrashIdentifiers {
|
|
||||||
ids: vec![test.view.id.clone()],
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
assert_eq!(test.server.read_trash().await.is_empty(), true);
|
assert_eq!(test.server.read_trash().await.is_empty(), true);
|
||||||
}
|
}
|
||||||
|
@ -122,14 +122,27 @@ impl TestUserServer {
|
|||||||
delete_view_request(self.user_token(), params, &url).await.unwrap();
|
delete_view_request(self.user_token(), params, &url).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_trash(&self, params: CreateTrashParams) {
|
pub async fn create_view_trash(&self, view_id: &str) {
|
||||||
|
let identifier = TrashIdentifier {
|
||||||
|
id: view_id.to_string(),
|
||||||
|
ty: TrashType::View,
|
||||||
|
};
|
||||||
let url = format!("{}/api/trash", self.http_addr());
|
let url = format!("{}/api/trash", self.http_addr());
|
||||||
create_trash_request(self.user_token(), params, &url).await.unwrap();
|
create_trash_request(self.user_token(), vec![identifier].into(), &url)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_trash(&self, params: TrashIdentifiers) {
|
pub async fn delete_view_trash(&self, trash_id: &str) {
|
||||||
let url = format!("{}/api/trash", self.http_addr());
|
let url = format!("{}/api/trash", self.http_addr());
|
||||||
delete_trash_request(self.user_token(), params, &url).await.unwrap();
|
|
||||||
|
let identifier = TrashIdentifier {
|
||||||
|
id: trash_id.to_string(),
|
||||||
|
ty: TrashType::View,
|
||||||
|
};
|
||||||
|
delete_trash_request(self.user_token(), vec![identifier].into(), &url)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_trash(&self) -> RepeatedTrash {
|
pub async fn read_trash(&self) -> RepeatedTrash {
|
||||||
|
@ -38,9 +38,8 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
|||||||
| "QueryWorkspaceRequest"
|
| "QueryWorkspaceRequest"
|
||||||
| "QueryWorkspaceParams"
|
| "QueryWorkspaceParams"
|
||||||
| "CurrentWorkspace"
|
| "CurrentWorkspace"
|
||||||
| "TrashIdentifier"
|
|
||||||
| "TrashIdentifiers"
|
| "TrashIdentifiers"
|
||||||
| "CreateTrashParams"
|
| "TrashIdentifier"
|
||||||
| "Trash"
|
| "Trash"
|
||||||
| "RepeatedTrash"
|
| "RepeatedTrash"
|
||||||
| "UpdateViewRequest"
|
| "UpdateViewRequest"
|
||||||
|
@ -19,5 +19,5 @@ chrono = "0.4.19"
|
|||||||
bytes = { version = "1.0" }
|
bytes = { version = "1.0" }
|
||||||
pin-project = "1.0"
|
pin-project = "1.0"
|
||||||
futures-core = { version = "0.3", default-features = false }
|
futures-core = { version = "0.3", default-features = false }
|
||||||
tokio = { version = "1.0", features = ["time"] }
|
tokio = { version = "1.0", features = ["time", "rt"] }
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::retry::FixedInterval;
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
@ -5,7 +6,10 @@ use std::{
|
|||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use tokio::time::{sleep_until, Duration, Instant, Sleep};
|
use tokio::{
|
||||||
|
task::JoinHandle,
|
||||||
|
time::{sleep_until, Duration, Instant, Sleep},
|
||||||
|
};
|
||||||
|
|
||||||
#[pin_project(project = RetryStateProj)]
|
#[pin_project(project = RetryStateProj)]
|
||||||
enum RetryState<A>
|
enum RetryState<A>
|
||||||
@ -171,9 +175,8 @@ pub trait Action: Send + Sync {
|
|||||||
|
|
||||||
fn run(&mut self) -> Self::Future;
|
fn run(&mut self) -> Self::Future;
|
||||||
}
|
}
|
||||||
|
// impl<R, E, T: Future<Output = Result<R, E>>, F: FnMut() -> T + Send + Sync>
|
||||||
// impl<R, E, T: Future<Output = Result<R, E>>, F: FnMut() -> T> Action for F {
|
// Action for F { type Future = T;
|
||||||
// type Future = T;
|
|
||||||
// type Item = R;
|
// type Item = R;
|
||||||
// type Error = E;
|
// type Error = E;
|
||||||
//
|
//
|
||||||
@ -187,3 +190,18 @@ pub trait Condition<E> {
|
|||||||
impl<E, F: FnMut(&E) -> bool> Condition<E> for F {
|
impl<E, F: FnMut(&E) -> bool> Condition<E> for F {
|
||||||
fn should_retry(&mut self, error: &E) -> bool { self(error) }
|
fn should_retry(&mut self, error: &E) -> bool { self(error) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn_retry<A: Action + 'static>(
|
||||||
|
millis: u64,
|
||||||
|
retry_count: usize,
|
||||||
|
action: A,
|
||||||
|
) -> JoinHandle<Result<A::Item, A::Error>>
|
||||||
|
where
|
||||||
|
A::Item: Send + Sync,
|
||||||
|
A::Error: Send + Sync,
|
||||||
|
<A as Action>::Future: Send + Sync,
|
||||||
|
{
|
||||||
|
let strategy = FixedInterval::from_millis(millis).take(retry_count);
|
||||||
|
let retry = Retry::spawn(strategy, action);
|
||||||
|
tokio::spawn(async move { retry.await })
|
||||||
|
}
|
||||||
|
@ -47,5 +47,7 @@ impl ServerConfig {
|
|||||||
|
|
||||||
pub fn doc_url(&self) -> String { format!("{}{}/api/doc", self.scheme(), self.host) }
|
pub fn doc_url(&self) -> String { format!("{}{}/api/doc", self.scheme(), self.host) }
|
||||||
|
|
||||||
|
pub fn trash_url(&self) -> String { format!("{}{}/api/trash", self.scheme(), self.host) }
|
||||||
|
|
||||||
pub fn ws_addr(&self) -> String { format!("{}://{}/ws", self.ws_schema, self.host) }
|
pub fn ws_addr(&self) -> String { format!("{}://{}/ws", self.ws_schema, self.host) }
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ pub struct DeleteAppRequest {
|
|||||||
pub app_id: String,
|
pub app_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, ProtoBuf)]
|
#[derive(Default, ProtoBuf, Clone)]
|
||||||
pub struct DeleteAppParams {
|
pub struct DeleteAppParams {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub app_id: String,
|
pub app_id: String,
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
pub mod parser;
|
pub mod parser;
|
||||||
mod trash_create;
|
mod trash_create;
|
||||||
mod trash_delete;
|
|
||||||
|
|
||||||
pub use trash_create::*;
|
pub use trash_create::*;
|
||||||
pub use trash_delete::*;
|
|
||||||
|
@ -24,7 +24,28 @@ impl std::default::Default for TrashType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, ProtoBuf, Default, Debug, Clone)]
|
#[derive(PartialEq, ProtoBuf, Default, Debug, Clone)]
|
||||||
pub struct CreateTrashParams {
|
pub struct TrashIdentifiers {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub items: Vec<TrashIdentifier>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Vec<TrashIdentifier>> for TrashIdentifiers {
|
||||||
|
fn from(items: Vec<TrashIdentifier>) -> Self { TrashIdentifiers { items } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Vec<Trash>> for TrashIdentifiers {
|
||||||
|
fn from(trash: Vec<Trash>) -> Self {
|
||||||
|
let items = trash
|
||||||
|
.into_iter()
|
||||||
|
.map(|t| TrashIdentifier { id: t.id, ty: t.ty })
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
TrashIdentifiers { items }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, ProtoBuf, Default, Debug, Clone)]
|
||||||
|
pub struct TrashIdentifier {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
use flowy_derive::ProtoBuf;
|
|
||||||
|
|
||||||
#[derive(PartialEq, ProtoBuf, Default, Debug, Clone)]
|
|
||||||
pub struct TrashIdentifier {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub id: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, ProtoBuf, Default, Debug, Clone)]
|
|
||||||
pub struct TrashIdentifiers {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub ids: Vec<String>,
|
|
||||||
}
|
|
@ -58,7 +58,7 @@ pub enum WorkspaceEvent {
|
|||||||
#[event(input = "TrashIdentifier")]
|
#[event(input = "TrashIdentifier")]
|
||||||
PutbackTrash = 301,
|
PutbackTrash = 301,
|
||||||
|
|
||||||
#[event(input = "TrashIdentifier")]
|
#[event(input = "TrashIdentifiers")]
|
||||||
DeleteTrash = 302,
|
DeleteTrash = 302,
|
||||||
|
|
||||||
#[event()]
|
#[event()]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::trash::{RepeatedTrash, TrashIdentifier},
|
entities::trash::{RepeatedTrash, TrashIdentifier, TrashIdentifiers},
|
||||||
errors::WorkspaceError,
|
errors::WorkspaceError,
|
||||||
services::TrashCan,
|
services::TrashCan,
|
||||||
};
|
};
|
||||||
@ -22,12 +22,12 @@ pub(crate) async fn putback_trash_handler(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(identifier, controller), err)]
|
#[tracing::instrument(skip(identifiers, controller), err)]
|
||||||
pub(crate) async fn delete_trash_handler(
|
pub(crate) async fn delete_trash_handler(
|
||||||
identifier: Data<TrashIdentifier>,
|
identifiers: Data<TrashIdentifiers>,
|
||||||
controller: Unit<Arc<TrashCan>>,
|
controller: Unit<Arc<TrashCan>>,
|
||||||
) -> Result<(), WorkspaceError> {
|
) -> Result<(), WorkspaceError> {
|
||||||
let _ = controller.delete(&identifier.id).await?;
|
let _ = controller.delete(identifiers.into_inner()).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ pub fn mk_workspace(
|
|||||||
) -> Arc<WorkspaceController> {
|
) -> Arc<WorkspaceController> {
|
||||||
let server = construct_workspace_server(server_config);
|
let server = construct_workspace_server(server_config);
|
||||||
|
|
||||||
let trash_can = Arc::new(TrashCan::new(database.clone()));
|
let trash_can = Arc::new(TrashCan::new(database.clone(), server.clone(), user.clone()));
|
||||||
|
|
||||||
let view_controller = Arc::new(ViewController::new(
|
let view_controller = Arc::new(ViewController::new(
|
||||||
user.clone(),
|
user.clone(),
|
||||||
|
@ -18,9 +18,6 @@ pub use observable::*;
|
|||||||
mod errors;
|
mod errors;
|
||||||
pub use errors::*;
|
pub use errors::*;
|
||||||
|
|
||||||
mod trash_delete;
|
|
||||||
pub use trash_delete::*;
|
|
||||||
|
|
||||||
mod workspace_update;
|
mod workspace_update;
|
||||||
pub use workspace_update::*;
|
pub use workspace_update::*;
|
||||||
|
|
||||||
|
@ -24,7 +24,173 @@
|
|||||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
||||||
|
|
||||||
#[derive(PartialEq,Clone,Default)]
|
#[derive(PartialEq,Clone,Default)]
|
||||||
pub struct CreateTrashParams {
|
pub struct TrashIdentifiers {
|
||||||
|
// message fields
|
||||||
|
pub items: ::protobuf::RepeatedField<TrashIdentifier>,
|
||||||
|
// special fields
|
||||||
|
pub unknown_fields: ::protobuf::UnknownFields,
|
||||||
|
pub cached_size: ::protobuf::CachedSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ::std::default::Default for &'a TrashIdentifiers {
|
||||||
|
fn default() -> &'a TrashIdentifiers {
|
||||||
|
<TrashIdentifiers as ::protobuf::Message>::default_instance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrashIdentifiers {
|
||||||
|
pub fn new() -> TrashIdentifiers {
|
||||||
|
::std::default::Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeated .TrashIdentifier items = 1;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_items(&self) -> &[TrashIdentifier] {
|
||||||
|
&self.items
|
||||||
|
}
|
||||||
|
pub fn clear_items(&mut self) {
|
||||||
|
self.items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_items(&mut self, v: ::protobuf::RepeatedField<TrashIdentifier>) {
|
||||||
|
self.items = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<TrashIdentifier> {
|
||||||
|
&mut self.items
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_items(&mut self) -> ::protobuf::RepeatedField<TrashIdentifier> {
|
||||||
|
::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Message for TrashIdentifiers {
|
||||||
|
fn is_initialized(&self) -> bool {
|
||||||
|
for v in &self.items {
|
||||||
|
if !v.is_initialized() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||||
|
while !is.eof()? {
|
||||||
|
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||||
|
match field_number {
|
||||||
|
1 => {
|
||||||
|
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.items)?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
::std::result::Result::Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute sizes of nested messages
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn compute_size(&self) -> u32 {
|
||||||
|
let mut my_size = 0;
|
||||||
|
for value in &self.items {
|
||||||
|
let len = value.compute_size();
|
||||||
|
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||||
|
};
|
||||||
|
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||||
|
self.cached_size.set(my_size);
|
||||||
|
my_size
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||||
|
for v in &self.items {
|
||||||
|
os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||||
|
os.write_raw_varint32(v.get_cached_size())?;
|
||||||
|
v.write_to_with_cached_sizes(os)?;
|
||||||
|
};
|
||||||
|
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||||
|
::std::result::Result::Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cached_size(&self) -> u32 {
|
||||||
|
self.cached_size.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
||||||
|
&self.unknown_fields
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
||||||
|
&mut self.unknown_fields
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn (::std::any::Any) {
|
||||||
|
self as &dyn (::std::any::Any)
|
||||||
|
}
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
||||||
|
self as &mut dyn (::std::any::Any)
|
||||||
|
}
|
||||||
|
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
Self::descriptor_static()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> TrashIdentifiers {
|
||||||
|
TrashIdentifiers::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
descriptor.get(|| {
|
||||||
|
let mut fields = ::std::vec::Vec::new();
|
||||||
|
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<TrashIdentifier>>(
|
||||||
|
"items",
|
||||||
|
|m: &TrashIdentifiers| { &m.items },
|
||||||
|
|m: &mut TrashIdentifiers| { &mut m.items },
|
||||||
|
));
|
||||||
|
::protobuf::reflect::MessageDescriptor::new_pb_name::<TrashIdentifiers>(
|
||||||
|
"TrashIdentifiers",
|
||||||
|
fields,
|
||||||
|
file_descriptor_proto()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_instance() -> &'static TrashIdentifiers {
|
||||||
|
static instance: ::protobuf::rt::LazyV2<TrashIdentifiers> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
instance.get(TrashIdentifiers::new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Clear for TrashIdentifiers {
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.items.clear();
|
||||||
|
self.unknown_fields.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::fmt::Debug for TrashIdentifiers {
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
|
::protobuf::text_format::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::reflect::ProtobufValue for TrashIdentifiers {
|
||||||
|
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||||
|
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq,Clone,Default)]
|
||||||
|
pub struct TrashIdentifier {
|
||||||
// message fields
|
// message fields
|
||||||
pub id: ::std::string::String,
|
pub id: ::std::string::String,
|
||||||
pub ty: TrashType,
|
pub ty: TrashType,
|
||||||
@ -33,14 +199,14 @@ pub struct CreateTrashParams {
|
|||||||
pub cached_size: ::protobuf::CachedSize,
|
pub cached_size: ::protobuf::CachedSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::std::default::Default for &'a CreateTrashParams {
|
impl<'a> ::std::default::Default for &'a TrashIdentifier {
|
||||||
fn default() -> &'a CreateTrashParams {
|
fn default() -> &'a TrashIdentifier {
|
||||||
<CreateTrashParams as ::protobuf::Message>::default_instance()
|
<TrashIdentifier as ::protobuf::Message>::default_instance()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateTrashParams {
|
impl TrashIdentifier {
|
||||||
pub fn new() -> CreateTrashParams {
|
pub fn new() -> TrashIdentifier {
|
||||||
::std::default::Default::default()
|
::std::default::Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +252,7 @@ impl CreateTrashParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::protobuf::Message for CreateTrashParams {
|
impl ::protobuf::Message for TrashIdentifier {
|
||||||
fn is_initialized(&self) -> bool {
|
fn is_initialized(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -161,8 +327,8 @@ impl ::protobuf::Message for CreateTrashParams {
|
|||||||
Self::descriptor_static()
|
Self::descriptor_static()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new() -> CreateTrashParams {
|
fn new() -> TrashIdentifier {
|
||||||
CreateTrashParams::new()
|
TrashIdentifier::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
@ -171,29 +337,29 @@ impl ::protobuf::Message for CreateTrashParams {
|
|||||||
let mut fields = ::std::vec::Vec::new();
|
let mut fields = ::std::vec::Vec::new();
|
||||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||||
"id",
|
"id",
|
||||||
|m: &CreateTrashParams| { &m.id },
|
|m: &TrashIdentifier| { &m.id },
|
||||||
|m: &mut CreateTrashParams| { &mut m.id },
|
|m: &mut TrashIdentifier| { &mut m.id },
|
||||||
));
|
));
|
||||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<TrashType>>(
|
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<TrashType>>(
|
||||||
"ty",
|
"ty",
|
||||||
|m: &CreateTrashParams| { &m.ty },
|
|m: &TrashIdentifier| { &m.ty },
|
||||||
|m: &mut CreateTrashParams| { &mut m.ty },
|
|m: &mut TrashIdentifier| { &mut m.ty },
|
||||||
));
|
));
|
||||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateTrashParams>(
|
::protobuf::reflect::MessageDescriptor::new_pb_name::<TrashIdentifier>(
|
||||||
"CreateTrashParams",
|
"TrashIdentifier",
|
||||||
fields,
|
fields,
|
||||||
file_descriptor_proto()
|
file_descriptor_proto()
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_instance() -> &'static CreateTrashParams {
|
fn default_instance() -> &'static TrashIdentifier {
|
||||||
static instance: ::protobuf::rt::LazyV2<CreateTrashParams> = ::protobuf::rt::LazyV2::INIT;
|
static instance: ::protobuf::rt::LazyV2<TrashIdentifier> = ::protobuf::rt::LazyV2::INIT;
|
||||||
instance.get(CreateTrashParams::new)
|
instance.get(TrashIdentifier::new)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::protobuf::Clear for CreateTrashParams {
|
impl ::protobuf::Clear for TrashIdentifier {
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
self.id.clear();
|
self.id.clear();
|
||||||
self.ty = TrashType::Unknown;
|
self.ty = TrashType::Unknown;
|
||||||
@ -201,13 +367,13 @@ impl ::protobuf::Clear for CreateTrashParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::fmt::Debug for CreateTrashParams {
|
impl ::std::fmt::Debug for TrashIdentifier {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
::protobuf::text_format::fmt(self, f)
|
::protobuf::text_format::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::protobuf::reflect::ProtobufValue for CreateTrashParams {
|
impl ::protobuf::reflect::ProtobufValue for TrashIdentifier {
|
||||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||||
}
|
}
|
||||||
@ -732,47 +898,52 @@ impl ::protobuf::reflect::ProtobufValue for TrashType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x12trash_create.proto\"?\n\x11CreateTrashParams\x12\x0e\n\x02id\x18\
|
\n\x12trash_create.proto\":\n\x10TrashIdentifiers\x12&\n\x05items\x18\
|
||||||
\x01\x20\x01(\tR\x02id\x12\x1a\n\x02ty\x18\x02\x20\x01(\x0e2\n.TrashType\
|
\x01\x20\x03(\x0b2\x10.TrashIdentifierR\x05items\"=\n\x0fTrashIdentifier\
|
||||||
R\x02ty\"\x8d\x01\n\x05Trash\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\
|
\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1a\n\x02ty\x18\x02\x20\
|
||||||
\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12#\n\rmodified_time\x18\
|
\x01(\x0e2\n.TrashTypeR\x02ty\"\x8d\x01\n\x05Trash\x12\x0e\n\x02id\x18\
|
||||||
\x03\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcreate_time\x18\x04\x20\
|
\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
|
||||||
\x01(\x03R\ncreateTime\x12\x1a\n\x02ty\x18\x05\x20\x01(\x0e2\n.TrashType\
|
#\n\rmodified_time\x18\x03\x20\x01(\x03R\x0cmodifiedTime\x12\x1f\n\x0bcr\
|
||||||
R\x02ty\"-\n\rRepeatedTrash\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06\
|
eate_time\x18\x04\x20\x01(\x03R\ncreateTime\x12\x1a\n\x02ty\x18\x05\x20\
|
||||||
.TrashR\x05items*\"\n\tTrashType\x12\x0b\n\x07Unknown\x10\0\x12\x08\n\
|
\x01(\x0e2\n.TrashTypeR\x02ty\"-\n\rRepeatedTrash\x12\x1c\n\x05items\x18\
|
||||||
\x04View\x10\x01J\x8a\x05\n\x06\x12\x04\0\0\x13\x01\n\x08\n\x01\x0c\x12\
|
\x01\x20\x03(\x0b2\x06.TrashR\x05items*\"\n\tTrashType\x12\x0b\n\x07Unkn\
|
||||||
\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\
|
own\x10\0\x12\x08\n\x04View\x10\x01J\xe7\x05\n\x06\x12\x04\0\0\x16\x01\n\
|
||||||
\x12\x03\x02\x08\x19\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\
|
\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x04\x01\n\n\
|
||||||
\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\
|
\n\x03\x04\0\x01\x12\x03\x02\x08\x18\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
||||||
\x03\x03\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\
|
\x04'\n\x0c\n\x05\x04\0\x02\0\x04\x12\x03\x03\x04\x0c\n\x0c\n\x05\x04\0\
|
||||||
\x04\x04\0\x02\x01\x12\x03\x04\x04\x15\n\x0c\n\x05\x04\0\x02\x01\x06\x12\
|
\x02\0\x06\x12\x03\x03\r\x1c\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x1d\
|
||||||
\x03\x04\x04\r\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0e\x10\n\x0c\n\
|
\"\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03%&\n\n\n\x02\x04\x01\x12\x04\
|
||||||
\x05\x04\0\x02\x01\x03\x12\x03\x04\x13\x14\n\n\n\x02\x04\x01\x12\x04\x06\
|
\x05\0\x08\x01\n\n\n\x03\x04\x01\x01\x12\x03\x05\x08\x17\n\x0b\n\x04\x04\
|
||||||
\0\x0c\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\r\n\x0b\n\x04\x04\x01\
|
\x01\x02\0\x12\x03\x06\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x06\
|
||||||
\x02\0\x12\x03\x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\
|
\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x06\x0b\r\n\x0c\n\x05\x04\
|
||||||
\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\x05\x04\x01\
|
\x01\x02\0\x03\x12\x03\x06\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\
|
||||||
\x02\0\x03\x12\x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\
|
\x07\x04\x15\n\x0c\n\x05\x04\x01\x02\x01\x06\x12\x03\x07\x04\r\n\x0c\n\
|
||||||
\x04\x14\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\
|
\x05\x04\x01\x02\x01\x01\x12\x03\x07\x0e\x10\n\x0c\n\x05\x04\x01\x02\x01\
|
||||||
\x04\x01\x02\x01\x01\x12\x03\x08\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\
|
\x03\x12\x03\x07\x13\x14\n\n\n\x02\x04\x02\x12\x04\t\0\x0f\x01\n\n\n\x03\
|
||||||
\x12\x03\x08\x12\x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\t\x04\x1c\n\x0c\
|
\x04\x02\x01\x12\x03\t\x08\r\n\x0b\n\x04\x04\x02\x02\0\x12\x03\n\x04\x12\
|
||||||
\n\x05\x04\x01\x02\x02\x05\x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x02\
|
\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x02\x02\0\
|
||||||
\x01\x12\x03\t\n\x17\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\t\x1a\x1b\n\
|
\x01\x12\x03\n\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\n\x10\x11\n\
|
||||||
\x0b\n\x04\x04\x01\x02\x03\x12\x03\n\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\
|
\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0b\x04\x14\n\x0c\n\x05\x04\x02\x02\
|
||||||
\x05\x12\x03\n\x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\n\n\x15\n\
|
\x01\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\x0b\
|
||||||
\x0c\n\x05\x04\x01\x02\x03\x03\x12\x03\n\x18\x19\n\x0b\n\x04\x04\x01\x02\
|
\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0b\x12\x13\n\x0b\n\x04\
|
||||||
\x04\x12\x03\x0b\x04\x15\n\x0c\n\x05\x04\x01\x02\x04\x06\x12\x03\x0b\x04\
|
\x04\x02\x02\x02\x12\x03\x0c\x04\x1c\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\
|
||||||
\r\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\x0b\x0e\x10\n\x0c\n\x05\x04\
|
\x03\x0c\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x0c\n\x17\n\x0c\n\
|
||||||
\x01\x02\x04\x03\x12\x03\x0b\x13\x14\n\n\n\x02\x04\x02\x12\x04\r\0\x0f\
|
\x05\x04\x02\x02\x02\x03\x12\x03\x0c\x1a\x1b\n\x0b\n\x04\x04\x02\x02\x03\
|
||||||
\x01\n\n\n\x03\x04\x02\x01\x12\x03\r\x08\x15\n\x0b\n\x04\x04\x02\x02\0\
|
\x12\x03\r\x04\x1a\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\r\x04\t\n\x0c\
|
||||||
\x12\x03\x0e\x04\x1d\n\x0c\n\x05\x04\x02\x02\0\x04\x12\x03\x0e\x04\x0c\n\
|
\n\x05\x04\x02\x02\x03\x01\x12\x03\r\n\x15\n\x0c\n\x05\x04\x02\x02\x03\
|
||||||
\x0c\n\x05\x04\x02\x02\0\x06\x12\x03\x0e\r\x12\n\x0c\n\x05\x04\x02\x02\0\
|
\x03\x12\x03\r\x18\x19\n\x0b\n\x04\x04\x02\x02\x04\x12\x03\x0e\x04\x15\n\
|
||||||
\x01\x12\x03\x0e\x13\x18\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0e\x1b\
|
\x0c\n\x05\x04\x02\x02\x04\x06\x12\x03\x0e\x04\r\n\x0c\n\x05\x04\x02\x02\
|
||||||
\x1c\n\n\n\x02\x05\0\x12\x04\x10\0\x13\x01\n\n\n\x03\x05\0\x01\x12\x03\
|
\x04\x01\x12\x03\x0e\x0e\x10\n\x0c\n\x05\x04\x02\x02\x04\x03\x12\x03\x0e\
|
||||||
\x10\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x11\x04\x10\n\x0c\n\x05\x05\
|
\x13\x14\n\n\n\x02\x04\x03\x12\x04\x10\0\x12\x01\n\n\n\x03\x04\x03\x01\
|
||||||
\0\x02\0\x01\x12\x03\x11\x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x11\
|
\x12\x03\x10\x08\x15\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x11\x04\x1d\n\x0c\
|
||||||
\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x12\x04\r\n\x0c\n\x05\x05\0\
|
\n\x05\x04\x03\x02\0\x04\x12\x03\x11\x04\x0c\n\x0c\n\x05\x04\x03\x02\0\
|
||||||
\x02\x01\x01\x12\x03\x12\x04\x08\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\
|
\x06\x12\x03\x11\r\x12\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x11\x13\x18\
|
||||||
\x12\x0b\x0cb\x06proto3\
|
\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x11\x1b\x1c\n\n\n\x02\x05\0\x12\
|
||||||
|
\x04\x13\0\x16\x01\n\n\n\x03\x05\0\x01\x12\x03\x13\x05\x0e\n\x0b\n\x04\
|
||||||
|
\x05\0\x02\0\x12\x03\x14\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x14\
|
||||||
|
\x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x14\x0e\x0f\n\x0b\n\x04\x05\
|
||||||
|
\0\x02\x01\x12\x03\x15\x04\r\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x15\
|
||||||
|
\x04\x08\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x15\x0b\x0cb\x06proto3\
|
||||||
";
|
";
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||||
|
@ -1,368 +0,0 @@
|
|||||||
// This file is generated by rust-protobuf 2.22.1. Do not edit
|
|
||||||
// @generated
|
|
||||||
|
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
|
||||||
#![allow(unknown_lints)]
|
|
||||||
#![allow(clippy::all)]
|
|
||||||
|
|
||||||
#![allow(unused_attributes)]
|
|
||||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
|
||||||
|
|
||||||
#![allow(box_pointers)]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
#![allow(missing_docs)]
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(non_upper_case_globals)]
|
|
||||||
#![allow(trivial_casts)]
|
|
||||||
#![allow(unused_imports)]
|
|
||||||
#![allow(unused_results)]
|
|
||||||
//! Generated file from `trash_delete.proto`
|
|
||||||
|
|
||||||
/// Generated files are compatible only with the same version
|
|
||||||
/// of protobuf runtime.
|
|
||||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
|
||||||
|
|
||||||
#[derive(PartialEq,Clone,Default)]
|
|
||||||
pub struct TrashIdentifier {
|
|
||||||
// message fields
|
|
||||||
pub id: ::std::string::String,
|
|
||||||
// special fields
|
|
||||||
pub unknown_fields: ::protobuf::UnknownFields,
|
|
||||||
pub cached_size: ::protobuf::CachedSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ::std::default::Default for &'a TrashIdentifier {
|
|
||||||
fn default() -> &'a TrashIdentifier {
|
|
||||||
<TrashIdentifier as ::protobuf::Message>::default_instance()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TrashIdentifier {
|
|
||||||
pub fn new() -> TrashIdentifier {
|
|
||||||
::std::default::Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
// string id = 1;
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get_id(&self) -> &str {
|
|
||||||
&self.id
|
|
||||||
}
|
|
||||||
pub fn clear_id(&mut self) {
|
|
||||||
self.id.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_id(&mut self, v: ::std::string::String) {
|
|
||||||
self.id = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
// If field is not initialized, it is initialized with default value first.
|
|
||||||
pub fn mut_id(&mut self) -> &mut ::std::string::String {
|
|
||||||
&mut self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_id(&mut self) -> ::std::string::String {
|
|
||||||
::std::mem::replace(&mut self.id, ::std::string::String::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Message for TrashIdentifier {
|
|
||||||
fn is_initialized(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
while !is.eof()? {
|
|
||||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
|
||||||
match field_number {
|
|
||||||
1 => {
|
|
||||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
::std::result::Result::Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute sizes of nested messages
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn compute_size(&self) -> u32 {
|
|
||||||
let mut my_size = 0;
|
|
||||||
if !self.id.is_empty() {
|
|
||||||
my_size += ::protobuf::rt::string_size(1, &self.id);
|
|
||||||
}
|
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
|
||||||
self.cached_size.set(my_size);
|
|
||||||
my_size
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
if !self.id.is_empty() {
|
|
||||||
os.write_string(1, &self.id)?;
|
|
||||||
}
|
|
||||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
|
||||||
::std::result::Result::Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cached_size(&self) -> u32 {
|
|
||||||
self.cached_size.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
|
||||||
&self.unknown_fields
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
|
||||||
&mut self.unknown_fields
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn (::std::any::Any) {
|
|
||||||
self as &dyn (::std::any::Any)
|
|
||||||
}
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
|
||||||
self as &mut dyn (::std::any::Any)
|
|
||||||
}
|
|
||||||
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
Self::descriptor_static()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new() -> TrashIdentifier {
|
|
||||||
TrashIdentifier::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
|
||||||
descriptor.get(|| {
|
|
||||||
let mut fields = ::std::vec::Vec::new();
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
|
||||||
"id",
|
|
||||||
|m: &TrashIdentifier| { &m.id },
|
|
||||||
|m: &mut TrashIdentifier| { &mut m.id },
|
|
||||||
));
|
|
||||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<TrashIdentifier>(
|
|
||||||
"TrashIdentifier",
|
|
||||||
fields,
|
|
||||||
file_descriptor_proto()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_instance() -> &'static TrashIdentifier {
|
|
||||||
static instance: ::protobuf::rt::LazyV2<TrashIdentifier> = ::protobuf::rt::LazyV2::INIT;
|
|
||||||
instance.get(TrashIdentifier::new)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Clear for TrashIdentifier {
|
|
||||||
fn clear(&mut self) {
|
|
||||||
self.id.clear();
|
|
||||||
self.unknown_fields.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Debug for TrashIdentifier {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
|
||||||
::protobuf::text_format::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::reflect::ProtobufValue for TrashIdentifier {
|
|
||||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
|
||||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq,Clone,Default)]
|
|
||||||
pub struct TrashIdentifiers {
|
|
||||||
// message fields
|
|
||||||
pub ids: ::protobuf::RepeatedField<::std::string::String>,
|
|
||||||
// special fields
|
|
||||||
pub unknown_fields: ::protobuf::UnknownFields,
|
|
||||||
pub cached_size: ::protobuf::CachedSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ::std::default::Default for &'a TrashIdentifiers {
|
|
||||||
fn default() -> &'a TrashIdentifiers {
|
|
||||||
<TrashIdentifiers as ::protobuf::Message>::default_instance()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TrashIdentifiers {
|
|
||||||
pub fn new() -> TrashIdentifiers {
|
|
||||||
::std::default::Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
// repeated string ids = 1;
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get_ids(&self) -> &[::std::string::String] {
|
|
||||||
&self.ids
|
|
||||||
}
|
|
||||||
pub fn clear_ids(&mut self) {
|
|
||||||
self.ids.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_ids(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) {
|
|
||||||
self.ids = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
pub fn mut_ids(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> {
|
|
||||||
&mut self.ids
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_ids(&mut self) -> ::protobuf::RepeatedField<::std::string::String> {
|
|
||||||
::std::mem::replace(&mut self.ids, ::protobuf::RepeatedField::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Message for TrashIdentifiers {
|
|
||||||
fn is_initialized(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
while !is.eof()? {
|
|
||||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
|
||||||
match field_number {
|
|
||||||
1 => {
|
|
||||||
::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.ids)?;
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
::std::result::Result::Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute sizes of nested messages
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn compute_size(&self) -> u32 {
|
|
||||||
let mut my_size = 0;
|
|
||||||
for value in &self.ids {
|
|
||||||
my_size += ::protobuf::rt::string_size(1, &value);
|
|
||||||
};
|
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
|
||||||
self.cached_size.set(my_size);
|
|
||||||
my_size
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
for v in &self.ids {
|
|
||||||
os.write_string(1, &v)?;
|
|
||||||
};
|
|
||||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
|
||||||
::std::result::Result::Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cached_size(&self) -> u32 {
|
|
||||||
self.cached_size.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
|
||||||
&self.unknown_fields
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
|
||||||
&mut self.unknown_fields
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn (::std::any::Any) {
|
|
||||||
self as &dyn (::std::any::Any)
|
|
||||||
}
|
|
||||||
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
|
||||||
self as &mut dyn (::std::any::Any)
|
|
||||||
}
|
|
||||||
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
Self::descriptor_static()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new() -> TrashIdentifiers {
|
|
||||||
TrashIdentifiers::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
|
||||||
descriptor.get(|| {
|
|
||||||
let mut fields = ::std::vec::Vec::new();
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
|
||||||
"ids",
|
|
||||||
|m: &TrashIdentifiers| { &m.ids },
|
|
||||||
|m: &mut TrashIdentifiers| { &mut m.ids },
|
|
||||||
));
|
|
||||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<TrashIdentifiers>(
|
|
||||||
"TrashIdentifiers",
|
|
||||||
fields,
|
|
||||||
file_descriptor_proto()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_instance() -> &'static TrashIdentifiers {
|
|
||||||
static instance: ::protobuf::rt::LazyV2<TrashIdentifiers> = ::protobuf::rt::LazyV2::INIT;
|
|
||||||
instance.get(TrashIdentifiers::new)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Clear for TrashIdentifiers {
|
|
||||||
fn clear(&mut self) {
|
|
||||||
self.ids.clear();
|
|
||||||
self.unknown_fields.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Debug for TrashIdentifiers {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
|
||||||
::protobuf::text_format::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::reflect::ProtobufValue for TrashIdentifiers {
|
|
||||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
|
||||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
|
||||||
\n\x12trash_delete.proto\"!\n\x0fTrashIdentifier\x12\x0e\n\x02id\x18\x01\
|
|
||||||
\x20\x01(\tR\x02id\"$\n\x10TrashIdentifiers\x12\x10\n\x03ids\x18\x01\x20\
|
|
||||||
\x03(\tR\x03idsJ\xbe\x01\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\
|
|
||||||
\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x04\x01\n\n\n\x03\x04\0\x01\
|
|
||||||
\x12\x03\x02\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\
|
|
||||||
\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\
|
|
||||||
\x03\x03\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\n\n\x02\
|
|
||||||
\x04\x01\x12\x04\x05\0\x07\x01\n\n\n\x03\x04\x01\x01\x12\x03\x05\x08\x18\
|
|
||||||
\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x06\x04\x1c\n\x0c\n\x05\x04\x01\x02\0\
|
|
||||||
\x04\x12\x03\x06\x04\x0c\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x06\r\x13\
|
|
||||||
\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x06\x14\x17\n\x0c\n\x05\x04\x01\
|
|
||||||
\x02\0\x03\x12\x03\x06\x1a\x1bb\x06proto3\
|
|
||||||
";
|
|
||||||
|
|
||||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
|
||||||
|
|
||||||
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
|
|
||||||
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
|
|
||||||
file_descriptor_proto_lazy.get(|| {
|
|
||||||
parse_descriptor_proto()
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,6 +1,9 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
message CreateTrashParams {
|
message TrashIdentifiers {
|
||||||
|
repeated TrashIdentifier items = 1;
|
||||||
|
}
|
||||||
|
message TrashIdentifier {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
TrashType ty = 2;
|
TrashType ty = 2;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
message TrashIdentifier {
|
|
||||||
string id = 1;
|
|
||||||
}
|
|
||||||
message TrashIdentifiers {
|
|
||||||
repeated string ids = 1;
|
|
||||||
}
|
|
@ -8,24 +8,18 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use flowy_database::SqliteConnection;
|
use flowy_database::SqliteConnection;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub(crate) struct AppController {
|
pub(crate) struct AppController {
|
||||||
user: Arc<dyn WorkspaceUser>,
|
user: Arc<dyn WorkspaceUser>,
|
||||||
sql: Arc<AppTableSql>,
|
|
||||||
database: Arc<dyn WorkspaceDatabase>,
|
database: Arc<dyn WorkspaceDatabase>,
|
||||||
server: Server,
|
server: Server,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppController {
|
impl AppController {
|
||||||
pub(crate) fn new(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>, server: Server) -> Self {
|
pub(crate) fn new(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>, server: Server) -> Self {
|
||||||
let sql = Arc::new(AppTableSql {});
|
Self { user, database, server }
|
||||||
Self {
|
|
||||||
user,
|
|
||||||
sql,
|
|
||||||
database,
|
|
||||||
server,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||||
@ -47,12 +41,12 @@ impl AppController {
|
|||||||
|
|
||||||
pub(crate) fn save_app(&self, app: App, conn: &SqliteConnection) -> Result<(), WorkspaceError> {
|
pub(crate) fn save_app(&self, app: App, conn: &SqliteConnection) -> Result<(), WorkspaceError> {
|
||||||
let app_table = AppTable::new(app.clone());
|
let app_table = AppTable::new(app.clone());
|
||||||
let _ = self.sql.create_app(app_table, &*conn)?;
|
let _ = AppTableSql::create_app(app_table, &*conn)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn read_app(&self, params: AppIdentifier) -> Result<App, WorkspaceError> {
|
pub(crate) async fn read_app(&self, params: AppIdentifier) -> Result<App, WorkspaceError> {
|
||||||
let app_table = self.sql.read_app(¶ms.app_id, &*self.database.db_connection()?)?;
|
let app_table = AppTableSql::read_app(¶ms.app_id, &*self.database.db_connection()?)?;
|
||||||
let _ = self.read_app_on_server(params)?;
|
let _ = self.read_app_on_server(params)?;
|
||||||
Ok(app_table.into())
|
Ok(app_table.into())
|
||||||
}
|
}
|
||||||
@ -61,7 +55,7 @@ impl AppController {
|
|||||||
pub(crate) async fn delete_app(&self, app_id: &str) -> Result<(), WorkspaceError> {
|
pub(crate) async fn delete_app(&self, app_id: &str) -> Result<(), WorkspaceError> {
|
||||||
let conn = &*self.database.db_connection()?;
|
let conn = &*self.database.db_connection()?;
|
||||||
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
let app = self.sql.delete_app(app_id, &*conn)?;
|
let app = AppTableSql::delete_app(app_id, &*conn)?;
|
||||||
let apps = self.read_local_apps(&app.workspace_id, &*conn)?;
|
let apps = self.read_local_apps(&app.workspace_id, &*conn)?;
|
||||||
send_dart_notification(&app.workspace_id, WorkspaceNotification::WorkspaceDeleteApp)
|
send_dart_notification(&app.workspace_id, WorkspaceNotification::WorkspaceDeleteApp)
|
||||||
.payload(apps)
|
.payload(apps)
|
||||||
@ -74,7 +68,7 @@ impl AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_local_apps(&self, workspace_id: &str, conn: &SqliteConnection) -> Result<RepeatedApp, WorkspaceError> {
|
fn read_local_apps(&self, workspace_id: &str, conn: &SqliteConnection) -> Result<RepeatedApp, WorkspaceError> {
|
||||||
let app_tables = self.sql.read_apps(workspace_id, false, conn)?;
|
let app_tables = AppTableSql::read_apps(workspace_id, false, conn)?;
|
||||||
let apps = app_tables.into_iter().map(|table| table.into()).collect::<Vec<App>>();
|
let apps = app_tables.into_iter().map(|table| table.into()).collect::<Vec<App>>();
|
||||||
Ok(RepeatedApp { items: apps })
|
Ok(RepeatedApp { items: apps })
|
||||||
}
|
}
|
||||||
@ -84,8 +78,8 @@ impl AppController {
|
|||||||
let app_id = changeset.id.clone();
|
let app_id = changeset.id.clone();
|
||||||
let conn = &*self.database.db_connection()?;
|
let conn = &*self.database.db_connection()?;
|
||||||
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
let _ = self.sql.update_app(changeset, conn)?;
|
let _ = AppTableSql::update_app(changeset, conn)?;
|
||||||
let app: App = self.sql.read_app(&app_id, conn)?.into();
|
let app: App = AppTableSql::read_app(&app_id, conn)?.into();
|
||||||
send_dart_notification(&app_id, WorkspaceNotification::AppUpdated)
|
send_dart_notification(&app_id, WorkspaceNotification::AppUpdated)
|
||||||
.payload(app)
|
.payload(app)
|
||||||
.send();
|
.send();
|
||||||
@ -137,6 +131,18 @@ impl AppController {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// let action = RetryAction::new(self.server.clone(), self.user.clone(), move
|
||||||
|
// |token, server| { let params = params.clone();
|
||||||
|
// async move {
|
||||||
|
// match server.delete_app(&token, params).await {
|
||||||
|
// Ok(_) => {},
|
||||||
|
// Err(e) => log::error!("Delete app failed: {:?}", e),
|
||||||
|
// }
|
||||||
|
// Ok::<(), WorkspaceError>(())
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// spawn_retry(500, 3, action);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,14 +150,27 @@ impl AppController {
|
|||||||
fn read_app_on_server(&self, params: AppIdentifier) -> Result<(), WorkspaceError> {
|
fn read_app_on_server(&self, params: AppIdentifier) -> Result<(), WorkspaceError> {
|
||||||
let token = self.user.token()?;
|
let token = self.user.token()?;
|
||||||
let server = self.server.clone();
|
let server = self.server.clone();
|
||||||
|
let pool = self.database.db_pool()?;
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
// Opti: retry?
|
// Opti: retry?
|
||||||
match server.read_app(&token, params).await {
|
match server.read_app(&token, params).await {
|
||||||
Ok(option) => match option {
|
Ok(Some(app)) => match pool.get() {
|
||||||
None => {},
|
Ok(conn) => {
|
||||||
Some(_app) => {},
|
let app_table = AppTable::new(app.clone());
|
||||||
|
let result = AppTableSql::create_app(app_table, &*conn);
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
send_dart_notification(&app.id, WorkspaceNotification::AppUpdated)
|
||||||
|
.payload(app)
|
||||||
|
.send();
|
||||||
},
|
},
|
||||||
Err(_) => {},
|
Err(e) => log::error!("Save app failed: {:?}", e),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => log::error!("Require db connection failed: {:?}", e),
|
||||||
|
},
|
||||||
|
Ok(None) => {},
|
||||||
|
Err(e) => log::error!("Read app failed: {:?}", e),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -8,5 +8,6 @@ mod database;
|
|||||||
mod helper;
|
mod helper;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
mod trash_can;
|
mod trash_can;
|
||||||
|
mod util;
|
||||||
mod view_controller;
|
mod view_controller;
|
||||||
mod workspace_controller;
|
mod workspace_controller;
|
||||||
|
@ -9,6 +9,7 @@ pub use server_api_mock::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::{
|
entities::{
|
||||||
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, UpdateAppParams},
|
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, UpdateAppParams},
|
||||||
|
trash::{RepeatedTrash, TrashIdentifiers},
|
||||||
view::{CreateViewParams, DeleteViewParams, UpdateViewParams, View, ViewIdentifier},
|
view::{CreateViewParams, DeleteViewParams, UpdateViewParams, View, ViewIdentifier},
|
||||||
workspace::{
|
workspace::{
|
||||||
CreateWorkspaceParams,
|
CreateWorkspaceParams,
|
||||||
@ -58,6 +59,13 @@ pub trait WorkspaceServerAPI {
|
|||||||
fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError>;
|
fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError>;
|
||||||
|
|
||||||
fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError>;
|
fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError>;
|
||||||
|
|
||||||
|
// Trash
|
||||||
|
fn create_trash(&self, token: &str, params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError>;
|
||||||
|
|
||||||
|
fn delete_trash(&self, token: &str, params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError>;
|
||||||
|
|
||||||
|
fn read_trash(&self, token: &str) -> ResultFuture<RepeatedTrash, WorkspaceError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn construct_workspace_server(config: &ServerConfig) -> Arc<dyn WorkspaceServerAPI + Send + Sync> {
|
pub(crate) fn construct_workspace_server(config: &ServerConfig) -> Arc<dyn WorkspaceServerAPI + Send + Sync> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::{
|
entities::{
|
||||||
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, UpdateAppParams},
|
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, UpdateAppParams},
|
||||||
trash::CreateTrashParams,
|
trash::{RepeatedTrash, TrashIdentifiers},
|
||||||
view::{CreateViewParams, DeleteViewParams, UpdateViewParams, View, ViewIdentifier},
|
view::{CreateViewParams, DeleteViewParams, UpdateViewParams, View, ViewIdentifier},
|
||||||
workspace::{
|
workspace::{
|
||||||
CreateWorkspaceParams,
|
CreateWorkspaceParams,
|
||||||
@ -15,8 +15,6 @@ use crate::{
|
|||||||
errors::WorkspaceError,
|
errors::WorkspaceError,
|
||||||
services::server::WorkspaceServerAPI,
|
services::server::WorkspaceServerAPI,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::entities::trash::{RepeatedTrash, TrashIdentifiers};
|
|
||||||
use flowy_infra::future::ResultFuture;
|
use flowy_infra::future::ResultFuture;
|
||||||
use flowy_net::{config::*, request::HttpRequestBuilder};
|
use flowy_net::{config::*, request::HttpRequestBuilder};
|
||||||
|
|
||||||
@ -104,6 +102,24 @@ impl WorkspaceServerAPI for WorkspaceServer {
|
|||||||
let url = self.config.app_url();
|
let url = self.config.app_url();
|
||||||
ResultFuture::new(async move { delete_app_request(&token, params, &url).await })
|
ResultFuture::new(async move { delete_app_request(&token, params, &url).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_trash(&self, token: &str, params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError> {
|
||||||
|
let token = token.to_owned();
|
||||||
|
let url = self.config.trash_url();
|
||||||
|
ResultFuture::new(async move { create_trash_request(&token, params, &url).await })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_trash(&self, token: &str, params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError> {
|
||||||
|
let token = token.to_owned();
|
||||||
|
let url = self.config.trash_url();
|
||||||
|
ResultFuture::new(async move { delete_trash_request(&token, params, &url).await })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_trash(&self, token: &str) -> ResultFuture<RepeatedTrash, WorkspaceError> {
|
||||||
|
let token = token.to_owned();
|
||||||
|
let url = self.config.trash_url();
|
||||||
|
ResultFuture::new(async move { read_trash_request(&token, &url).await })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn request_builder() -> HttpRequestBuilder {
|
pub(crate) fn request_builder() -> HttpRequestBuilder {
|
||||||
@ -250,7 +266,7 @@ pub async fn delete_view_request(token: &str, params: DeleteViewParams, url: &st
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_trash_request(token: &str, params: CreateTrashParams, url: &str) -> Result<(), WorkspaceError> {
|
pub async fn create_trash_request(token: &str, params: TrashIdentifiers, url: &str) -> Result<(), WorkspaceError> {
|
||||||
let _ = request_builder()
|
let _ = request_builder()
|
||||||
.post(&url.to_owned())
|
.post(&url.to_owned())
|
||||||
.header(HEADER_TOKEN, token)
|
.header(HEADER_TOKEN, token)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::{
|
entities::{
|
||||||
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, RepeatedApp, UpdateAppParams},
|
app::{App, AppIdentifier, CreateAppParams, DeleteAppParams, RepeatedApp, UpdateAppParams},
|
||||||
|
trash::{RepeatedTrash, TrashIdentifiers},
|
||||||
view::{CreateViewParams, DeleteViewParams, RepeatedView, UpdateViewParams, View, ViewIdentifier},
|
view::{CreateViewParams, DeleteViewParams, RepeatedView, UpdateViewParams, View, ViewIdentifier},
|
||||||
workspace::{
|
workspace::{
|
||||||
CreateWorkspaceParams,
|
CreateWorkspaceParams,
|
||||||
@ -106,4 +107,19 @@ impl WorkspaceServerAPI for WorkspaceServerMock {
|
|||||||
fn delete_app(&self, _token: &str, _params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> {
|
fn delete_app(&self, _token: &str, _params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> {
|
||||||
ResultFuture::new(async { Ok(()) })
|
ResultFuture::new(async { Ok(()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_trash(&self, _token: &str, _params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError> {
|
||||||
|
ResultFuture::new(async { Ok(()) })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_trash(&self, _token: &str, _params: TrashIdentifiers) -> ResultFuture<(), WorkspaceError> {
|
||||||
|
ResultFuture::new(async { Ok(()) })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_trash(&self, _token: &str) -> ResultFuture<RepeatedTrash, WorkspaceError> {
|
||||||
|
ResultFuture::new(async {
|
||||||
|
let repeated_trash = RepeatedTrash { items: vec![] };
|
||||||
|
Ok(repeated_trash)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,59 +1,42 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::trash::{RepeatedTrash, Trash, TrashType},
|
entities::trash::{RepeatedTrash, Trash, TrashIdentifier, TrashIdentifiers, TrashType},
|
||||||
errors::{WorkspaceError, WorkspaceResult},
|
errors::{WorkspaceError, WorkspaceResult},
|
||||||
module::WorkspaceDatabase,
|
module::{WorkspaceDatabase, WorkspaceUser},
|
||||||
notify::{send_anonymous_dart_notification, WorkspaceNotification},
|
notify::{send_anonymous_dart_notification, WorkspaceNotification},
|
||||||
|
services::{helper::spawn, server::Server},
|
||||||
sql_tables::trash::TrashTableSql,
|
sql_tables::trash::TrashTableSql,
|
||||||
};
|
};
|
||||||
use crossbeam_utils::thread;
|
use crossbeam_utils::thread;
|
||||||
use flowy_database::SqliteConnection;
|
use flowy_database::SqliteConnection;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{broadcast, mpsc};
|
use tokio::sync::{broadcast, mpsc};
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum TrashEvent {
|
|
||||||
NewTrash(TrashType, Vec<String>, mpsc::Sender<WorkspaceResult<()>>),
|
|
||||||
Putback(TrashType, Vec<String>, mpsc::Sender<WorkspaceResult<()>>),
|
|
||||||
Delete(TrashType, Vec<String>, mpsc::Sender<WorkspaceResult<()>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TrashEvent {
|
|
||||||
pub fn select(self, s: TrashType) -> Option<TrashEvent> {
|
|
||||||
match &self {
|
|
||||||
TrashEvent::Putback(source, _, _) => {
|
|
||||||
if source == &s {
|
|
||||||
return Some(self);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TrashEvent::Delete(source, _, _) => {
|
|
||||||
if source == &s {
|
|
||||||
return Some(self);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TrashEvent::NewTrash(source, _, _) => {
|
|
||||||
if source == &s {
|
|
||||||
return Some(self);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TrashCan {
|
pub struct TrashCan {
|
||||||
pub database: Arc<dyn WorkspaceDatabase>,
|
pub database: Arc<dyn WorkspaceDatabase>,
|
||||||
notify: broadcast::Sender<TrashEvent>,
|
notify: broadcast::Sender<TrashEvent>,
|
||||||
|
server: Server,
|
||||||
|
user: Arc<dyn WorkspaceUser>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrashCan {
|
impl TrashCan {
|
||||||
pub fn new(database: Arc<dyn WorkspaceDatabase>) -> Self {
|
pub fn new(database: Arc<dyn WorkspaceDatabase>, server: Server, user: Arc<dyn WorkspaceUser>) -> Self {
|
||||||
let (tx, _) = broadcast::channel(10);
|
let (tx, _) = broadcast::channel(10);
|
||||||
|
|
||||||
Self { database, notify: tx }
|
Self {
|
||||||
|
database,
|
||||||
|
notify: tx,
|
||||||
|
server,
|
||||||
|
user,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn init(&self) -> Result<(), WorkspaceError> { Ok(()) }
|
||||||
|
|
||||||
pub fn read_trash(&self, conn: &SqliteConnection) -> Result<RepeatedTrash, WorkspaceError> {
|
pub fn read_trash(&self, conn: &SqliteConnection) -> Result<RepeatedTrash, WorkspaceError> {
|
||||||
let repeated_trash = TrashTableSql::read_all(&*conn)?;
|
let repeated_trash = TrashTableSql::read_all(&*conn)?;
|
||||||
|
|
||||||
|
let _ = self.read_trash_on_server()?;
|
||||||
Ok(repeated_trash)
|
Ok(repeated_trash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,22 +56,26 @@ impl TrashCan {
|
|||||||
let _ = thread::scope(|_s| {
|
let _ = thread::scope(|_s| {
|
||||||
let conn = self.database.db_connection()?;
|
let conn = self.database.db_connection()?;
|
||||||
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
|
let repeated_trash = TrashTableSql::read_all(&conn)?;
|
||||||
let _ = TrashTableSql::delete_trash(trash_id, &*conn)?;
|
let _ = TrashTableSql::delete_trash(trash_id, &*conn)?;
|
||||||
let _ = self.notify_dart_trash_did_update(&conn)?;
|
notify_trash_num_changed(repeated_trash);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
Ok::<(), WorkspaceError>(())
|
Ok::<(), WorkspaceError>(())
|
||||||
})
|
})
|
||||||
.unwrap()?;
|
.unwrap()?;
|
||||||
|
|
||||||
tracing::Span::current().record(
|
let identifier = TrashIdentifier {
|
||||||
"putback",
|
id: trash_table.id,
|
||||||
&format!("{:?}: {}", &trash_table.ty, trash_table.id).as_str(),
|
ty: trash_table.ty.into(),
|
||||||
);
|
};
|
||||||
let _ = self
|
|
||||||
.notify
|
|
||||||
.send(TrashEvent::Putback(trash_table.ty.into(), vec![trash_table.id], tx));
|
|
||||||
|
|
||||||
|
let _ = self.delete_trash_on_server(TrashIdentifiers {
|
||||||
|
items: vec![identifier.clone()],
|
||||||
|
})?;
|
||||||
|
|
||||||
|
tracing::Span::current().record("putback", &format!("{:?}", &identifier).as_str());
|
||||||
|
let _ = self.notify.send(TrashEvent::Putback(vec![identifier].into(), tx));
|
||||||
let _ = rx.recv().await.unwrap()?;
|
let _ = rx.recv().await.unwrap()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -100,15 +87,20 @@ impl TrashCan {
|
|||||||
pub fn delete_all(&self) -> WorkspaceResult<()> { Ok(()) }
|
pub fn delete_all(&self) -> WorkspaceResult<()> { Ok(()) }
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(self) err)]
|
#[tracing::instrument(level = "debug", skip(self) err)]
|
||||||
pub async fn delete(&self, trash_id: &str) -> WorkspaceResult<()> {
|
pub async fn delete(&self, trash_identifiers: TrashIdentifiers) -> WorkspaceResult<()> {
|
||||||
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
|
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
|
||||||
let trash_table = TrashTableSql::read(trash_id, &*self.database.db_connection()?)?;
|
let _ = self.notify.send(TrashEvent::Delete(trash_identifiers.clone(), tx));
|
||||||
let _ = self
|
|
||||||
.notify
|
|
||||||
.send(TrashEvent::Delete(trash_table.ty.into(), vec![trash_table.id], tx));
|
|
||||||
|
|
||||||
let _ = rx.recv().await.unwrap()?;
|
let _ = rx.recv().await.unwrap()?;
|
||||||
let _ = TrashTableSql::delete_trash(trash_id, &*self.database.db_connection()?)?;
|
|
||||||
|
let conn = self.database.db_connection()?;
|
||||||
|
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
|
for trash_identifier in &trash_identifiers.items {
|
||||||
|
let _ = TrashTableSql::delete_trash(&trash_identifier.id, &conn)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let _ = self.delete_trash_on_server(trash_identifiers)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -123,48 +115,147 @@ impl TrashCan {
|
|||||||
pub async fn add<T: Into<Trash>>(&self, trash: Vec<T>) -> Result<(), WorkspaceError> {
|
pub async fn add<T: Into<Trash>>(&self, trash: Vec<T>) -> Result<(), WorkspaceError> {
|
||||||
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
|
let (tx, mut rx) = mpsc::channel::<WorkspaceResult<()>>(1);
|
||||||
let trash = trash.into_iter().map(|t| t.into()).collect::<Vec<Trash>>();
|
let trash = trash.into_iter().map(|t| t.into()).collect::<Vec<Trash>>();
|
||||||
let mut ids = vec![];
|
let mut items = vec![];
|
||||||
let mut trash_type = None;
|
|
||||||
let _ = thread::scope(|_s| {
|
let _ = thread::scope(|_s| {
|
||||||
let conn = self.database.db_connection()?;
|
let conn = self.database.db_connection()?;
|
||||||
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
for t in trash {
|
for t in &trash {
|
||||||
if trash_type == None {
|
|
||||||
trash_type = Some(t.ty.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if trash_type.as_ref().unwrap() != &t.ty {
|
|
||||||
return Err(WorkspaceError::internal());
|
|
||||||
}
|
|
||||||
let trash_id = t.id.clone();
|
|
||||||
log::debug!("create trash: {:?}", t);
|
log::debug!("create trash: {:?}", t);
|
||||||
let _ = TrashTableSql::create_trash(t.into(), &*conn)?;
|
items.push(TrashIdentifier {
|
||||||
ids.push(trash_id);
|
id: t.id.clone(),
|
||||||
|
ty: t.ty.clone(),
|
||||||
|
});
|
||||||
|
let _ = TrashTableSql::create_trash(t.clone().into(), &*conn)?;
|
||||||
}
|
}
|
||||||
let _ = self.notify_dart_trash_did_update(&conn)?;
|
self.create_trash_on_server(trash);
|
||||||
|
let repeated_trash = TrashTableSql::read_all(&conn)?;
|
||||||
|
notify_trash_num_changed(repeated_trash);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
Ok::<(), WorkspaceError>(())
|
Ok::<(), WorkspaceError>(())
|
||||||
})
|
})
|
||||||
.unwrap()?;
|
.unwrap()?;
|
||||||
|
|
||||||
if let Some(trash_type) = trash_type {
|
let _ = self.notify.send(TrashEvent::NewTrash(items.into(), tx));
|
||||||
let _ = self.notify.send(TrashEvent::NewTrash(trash_type, ids, tx));
|
|
||||||
let _ = rx.recv().await.unwrap()?;
|
let _ = rx.recv().await.unwrap()?;
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscribe(&self) -> broadcast::Receiver<TrashEvent> { self.notify.subscribe() }
|
pub fn subscribe(&self) -> broadcast::Receiver<TrashEvent> { self.notify.subscribe() }
|
||||||
|
}
|
||||||
|
|
||||||
fn notify_dart_trash_did_update(&self, conn: &SqliteConnection) -> WorkspaceResult<()> {
|
impl TrashCan {
|
||||||
// Opti: only push the changeset
|
#[tracing::instrument(level = "debug", skip(self, trash), err)]
|
||||||
let repeated_trash = TrashTableSql::read_all(conn)?;
|
fn create_trash_on_server<T: Into<TrashIdentifiers>>(&self, trash: T) -> WorkspaceResult<()> {
|
||||||
send_anonymous_dart_notification(WorkspaceNotification::TrashUpdated)
|
let token = self.user.token()?;
|
||||||
.payload(repeated_trash)
|
let trash_identifiers = trash.into();
|
||||||
.send();
|
let server = self.server.clone();
|
||||||
|
// TODO: retry?
|
||||||
|
let _ = tokio::spawn(async move {
|
||||||
|
match server.create_trash(&token, trash_identifiers).await {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => log::error!("Create trash failed: {:?}", e),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(self, trash), err)]
|
||||||
|
fn delete_trash_on_server<T: Into<TrashIdentifiers>>(&self, trash: T) -> WorkspaceResult<()> {
|
||||||
|
let token = self.user.token()?;
|
||||||
|
let trash_identifiers = trash.into();
|
||||||
|
let server = self.server.clone();
|
||||||
|
let _ = tokio::spawn(async move {
|
||||||
|
match server.delete_trash(&token, trash_identifiers).await {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => log::error!("Delete trash failed: {:?}", e),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||||
|
fn read_trash_on_server(&self) -> WorkspaceResult<()> {
|
||||||
|
let token = self.user.token()?;
|
||||||
|
let server = self.server.clone();
|
||||||
|
let pool = self.database.db_pool()?;
|
||||||
|
|
||||||
|
spawn(async move {
|
||||||
|
match server.read_trash(&token).await {
|
||||||
|
Ok(repeated_trash) => {
|
||||||
|
match pool.get() {
|
||||||
|
Ok(conn) => {
|
||||||
|
let result = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
|
for trash in &repeated_trash.items {
|
||||||
|
let _ = TrashTableSql::create_trash(trash.clone().into(), &*conn)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
// FIXME: User may modify the trash(add/putback) before the flying request comes
|
||||||
|
// back that will cause the trash list to be outdated.
|
||||||
|
// TODO: impl with operation transform
|
||||||
|
notify_trash_num_changed(repeated_trash);
|
||||||
|
},
|
||||||
|
Err(e) => log::error!("Save trash failed: {:?}", e),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => log::error!("Require db connection failed: {:?}", e),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => log::error!("Read trash failed: {:?}", e),
|
||||||
|
}
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(repeated_trash), fields(trash_count))]
|
||||||
|
fn notify_trash_num_changed(repeated_trash: RepeatedTrash) {
|
||||||
|
tracing::Span::current().record("trash_count", &repeated_trash.len());
|
||||||
|
|
||||||
|
send_anonymous_dart_notification(WorkspaceNotification::TrashUpdated)
|
||||||
|
.payload(repeated_trash)
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum TrashEvent {
|
||||||
|
NewTrash(TrashIdentifiers, mpsc::Sender<WorkspaceResult<()>>),
|
||||||
|
Putback(TrashIdentifiers, mpsc::Sender<WorkspaceResult<()>>),
|
||||||
|
Delete(TrashIdentifiers, mpsc::Sender<WorkspaceResult<()>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrashEvent {
|
||||||
|
pub fn select(self, s: TrashType) -> Option<TrashEvent> {
|
||||||
|
match self {
|
||||||
|
TrashEvent::Putback(mut identifiers, sender) => {
|
||||||
|
identifiers.items.retain(|item| item.ty == s);
|
||||||
|
if identifiers.items.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(TrashEvent::Putback(identifiers, sender))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TrashEvent::Delete(mut identifiers, sender) => {
|
||||||
|
identifiers.items.retain(|item| item.ty == s);
|
||||||
|
if identifiers.items.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(TrashEvent::Delete(identifiers, sender))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TrashEvent::NewTrash(mut identifiers, sender) => {
|
||||||
|
identifiers.items.retain(|item| item.ty == s);
|
||||||
|
if identifiers.items.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(TrashEvent::NewTrash(identifiers, sender))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
72
rust-lib/flowy-workspace/src/services/util.rs
Normal file
72
rust-lib/flowy-workspace/src/services/util.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use crate::{module::WorkspaceUser, services::server::Server};
|
||||||
|
use flowy_infra::retry::Action;
|
||||||
|
use pin_project::pin_project;
|
||||||
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
marker::PhantomData,
|
||||||
|
pin::Pin,
|
||||||
|
sync::Arc,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) type Builder<Fut> = Box<dyn Fn(String, Server) -> Fut + Send + Sync>;
|
||||||
|
|
||||||
|
pub(crate) struct RetryAction<Fut, T, E> {
|
||||||
|
token: String,
|
||||||
|
server: Server,
|
||||||
|
user: Arc<dyn WorkspaceUser>,
|
||||||
|
builder: Builder<Fut>,
|
||||||
|
phantom: PhantomData<(T, E)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Fut, T, E> RetryAction<Fut, T, E> {
|
||||||
|
pub(crate) fn new<F>(server: Server, user: Arc<dyn WorkspaceUser>, builder: F) -> Self
|
||||||
|
where
|
||||||
|
Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
|
||||||
|
F: Fn(String, Server) -> Fut + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let token = user.token().unwrap_or("".to_owned());
|
||||||
|
Self {
|
||||||
|
token,
|
||||||
|
server,
|
||||||
|
user,
|
||||||
|
builder: Box::new(builder),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Fut, T, E> Action for RetryAction<Fut, T, E>
|
||||||
|
where
|
||||||
|
Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
|
||||||
|
T: Send + Sync + 'static,
|
||||||
|
E: Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send + Sync>>;
|
||||||
|
type Item = T;
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn run(&mut self) -> Self::Future {
|
||||||
|
let fut = (self.builder)(self.token.clone(), self.server.clone());
|
||||||
|
Box::pin(RetryActionFut { fut: Box::pin(fut) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pin_project]
|
||||||
|
struct RetryActionFut<T, E> {
|
||||||
|
#[pin]
|
||||||
|
fut: Pin<Box<dyn Future<Output = Result<T, E>> + Send + Sync>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> Future for RetryActionFut<T, E>
|
||||||
|
where
|
||||||
|
T: Send + Sync + 'static,
|
||||||
|
E: Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
type Output = Result<T, E>;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let mut this = self.project();
|
||||||
|
this.fut.as_mut().poll(cx)
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
entities::view::{DeleteViewParams, RepeatedView, ViewIdentifier},
|
entities::view::{RepeatedView, ViewIdentifier},
|
||||||
errors::internal_error,
|
errors::internal_error,
|
||||||
module::WorkspaceUser,
|
module::WorkspaceUser,
|
||||||
notify::WorkspaceNotification,
|
notify::WorkspaceNotification,
|
||||||
@ -21,6 +21,7 @@ use flowy_document::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{entities::trash::TrashType, errors::WorkspaceResult};
|
use crate::{entities::trash::TrashType, errors::WorkspaceResult};
|
||||||
|
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -171,34 +172,31 @@ impl ViewController {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[tracing::instrument(skip(self), err)]
|
|
||||||
// fn delete_view_on_server(&self, view_ids: Vec<String>) -> Result<(),
|
|
||||||
// WorkspaceError> { let token = self.user.token()?;
|
|
||||||
// let server = self.server.clone();
|
|
||||||
// let params = DeleteViewParams { view_ids };
|
|
||||||
// spawn(async move {
|
|
||||||
// match server.delete_view(&token, params).await {
|
|
||||||
// Ok(_) => {},
|
|
||||||
// Err(e) => {
|
|
||||||
// // TODO: retry?
|
|
||||||
// log::error!("Delete view failed: {:?}", e);
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(self), err)]
|
#[tracing::instrument(skip(self), err)]
|
||||||
fn read_view_on_server(&self, params: ViewIdentifier) -> Result<(), WorkspaceError> {
|
fn read_view_on_server(&self, params: ViewIdentifier) -> Result<(), WorkspaceError> {
|
||||||
let token = self.user.token()?;
|
let token = self.user.token()?;
|
||||||
let server = self.server.clone();
|
let server = self.server.clone();
|
||||||
|
let pool = self.database.db_pool()?;
|
||||||
|
// Opti: retry?
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
match server.read_view(&token, params).await {
|
match server.read_view(&token, params).await {
|
||||||
Ok(_) => {},
|
Ok(Some(view)) => match pool.get() {
|
||||||
Err(e) => {
|
Ok(conn) => {
|
||||||
// TODO: retry?
|
let view_table = ViewTable::new(view.clone());
|
||||||
log::error!("Read view failed: {:?}", e);
|
let result = ViewTableSql::create_view(view_table, &conn);
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
send_dart_notification(&view.id, WorkspaceNotification::ViewUpdated)
|
||||||
|
.payload(view.clone())
|
||||||
|
.send();
|
||||||
},
|
},
|
||||||
|
Err(e) => log::error!("Save view failed: {:?}", e),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => log::error!("Require db connection failed: {:?}", e),
|
||||||
|
},
|
||||||
|
Ok(None) => {},
|
||||||
|
Err(e) => log::error!("Read view failed: {:?}", e),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -238,12 +236,12 @@ async fn handle_trash_event(
|
|||||||
let db_result = database.db_connection();
|
let db_result = database.db_connection();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
TrashEvent::NewTrash(_, view_ids, ret) | TrashEvent::Putback(_, view_ids, ret) => {
|
TrashEvent::NewTrash(identifiers, ret) | TrashEvent::Putback(identifiers, ret) => {
|
||||||
let result = || {
|
let result = || {
|
||||||
let conn = &*db_result?;
|
let conn = &*db_result?;
|
||||||
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
for view_id in view_ids {
|
for identifier in identifiers.items {
|
||||||
let _ = notify_view_num_did_change(&view_id, conn, trash_can.clone())?;
|
let _ = notify_view_num_changed(&identifier.id, conn, trash_can.clone())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
@ -251,14 +249,14 @@ async fn handle_trash_event(
|
|||||||
};
|
};
|
||||||
let _ = ret.send(result()).await;
|
let _ = ret.send(result()).await;
|
||||||
},
|
},
|
||||||
TrashEvent::Delete(_, delete_ids, ret) => {
|
TrashEvent::Delete(identifiers, ret) => {
|
||||||
let result = || {
|
let result = || {
|
||||||
let conn = &*db_result?;
|
let conn = &*db_result?;
|
||||||
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||||
for view_id in delete_ids {
|
for identifier in identifiers.items {
|
||||||
let _ = ViewTableSql::delete_view(&view_id, conn)?;
|
let _ = ViewTableSql::delete_view(&identifier.id, conn)?;
|
||||||
let _ = document.delete(view_id.clone().into())?;
|
let _ = document.delete(identifier.id.clone().into())?;
|
||||||
let _ = notify_view_num_did_change(&view_id, conn, trash_can.clone())?;
|
let _ = notify_view_num_changed(&identifier.id, conn, trash_can.clone())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
@ -270,9 +268,10 @@ async fn handle_trash_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(conn, trash_can), err)]
|
#[tracing::instrument(skip(conn, trash_can), err)]
|
||||||
fn notify_view_num_did_change(view_id: &str, conn: &SqliteConnection, trash_can: Arc<TrashCan>) -> WorkspaceResult<()> {
|
fn notify_view_num_changed(view_id: &str, conn: &SqliteConnection, trash_can: Arc<TrashCan>) -> WorkspaceResult<()> {
|
||||||
let view_table = ViewTableSql::read_view(view_id, conn)?;
|
let view_table = ViewTableSql::read_view(view_id, conn)?;
|
||||||
let repeated_view = read_belonging_view(&view_table.belong_to_id, trash_can, conn)?;
|
let repeated_view = read_belonging_view(&view_table.belong_to_id, trash_can, conn)?;
|
||||||
|
|
||||||
send_dart_notification(&view_table.belong_to_id, WorkspaceNotification::AppViewsChanged)
|
send_dart_notification(&view_table.belong_to_id, WorkspaceNotification::AppViewsChanged)
|
||||||
.payload(repeated_view)
|
.payload(repeated_view)
|
||||||
.send();
|
.send();
|
||||||
|
@ -45,6 +45,7 @@ impl WorkspaceController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&self) -> Result<(), WorkspaceError> {
|
pub fn init(&self) -> Result<(), WorkspaceError> {
|
||||||
|
let _ = self.trash_can.init()?;
|
||||||
let _ = self.view_controller.init()?;
|
let _ = self.view_controller.init()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use flowy_database::{
|
|||||||
pub struct AppTableSql {}
|
pub struct AppTableSql {}
|
||||||
|
|
||||||
impl AppTableSql {
|
impl AppTableSql {
|
||||||
pub(crate) fn create_app(&self, app_table: AppTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> {
|
pub(crate) fn create_app(app_table: AppTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> {
|
||||||
match diesel_record_count!(app_table, &app_table.id, conn) {
|
match diesel_record_count!(app_table, &app_table.id, conn) {
|
||||||
0 => diesel_insert_table!(app_table, &app_table, conn),
|
0 => diesel_insert_table!(app_table, &app_table, conn),
|
||||||
_ => {
|
_ => {
|
||||||
@ -22,16 +22,12 @@ impl AppTableSql {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_app(
|
pub(crate) fn update_app(changeset: AppTableChangeset, conn: &SqliteConnection) -> Result<(), WorkspaceError> {
|
||||||
&self,
|
|
||||||
changeset: AppTableChangeset,
|
|
||||||
conn: &SqliteConnection,
|
|
||||||
) -> Result<(), WorkspaceError> {
|
|
||||||
diesel_update_table!(app_table, changeset, conn);
|
diesel_update_table!(app_table, changeset, conn);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_app(&self, app_id: &str, conn: &SqliteConnection) -> Result<AppTable, WorkspaceError> {
|
pub(crate) fn read_app(app_id: &str, conn: &SqliteConnection) -> Result<AppTable, WorkspaceError> {
|
||||||
let filter = dsl::app_table.filter(app_table::id.eq(app_id)).into_boxed();
|
let filter = dsl::app_table.filter(app_table::id.eq(app_id)).into_boxed();
|
||||||
|
|
||||||
// if let Some(is_trash) = is_trash {
|
// if let Some(is_trash) = is_trash {
|
||||||
@ -43,7 +39,6 @@ impl AppTableSql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_apps(
|
pub(crate) fn read_apps(
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
is_trash: bool,
|
is_trash: bool,
|
||||||
conn: &SqliteConnection,
|
conn: &SqliteConnection,
|
||||||
@ -56,7 +51,7 @@ impl AppTableSql {
|
|||||||
Ok(app_table)
|
Ok(app_table)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn delete_app(&self, app_id: &str, conn: &SqliteConnection) -> Result<AppTable, WorkspaceError> {
|
pub(crate) fn delete_app(app_id: &str, conn: &SqliteConnection) -> Result<AppTable, WorkspaceError> {
|
||||||
let app_table = dsl::app_table
|
let app_table = dsl::app_table
|
||||||
.filter(app_table::id.eq(app_id))
|
.filter(app_table::id.eq(app_id))
|
||||||
.first::<AppTable>(conn)?;
|
.first::<AppTable>(conn)?;
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use flowy_database::{
|
use flowy_database::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
schema::{trash_table, view_table, view_table::dsl},
|
schema::{view_table, view_table::dsl},
|
||||||
SqliteConnection,
|
SqliteConnection,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use flowy_test::{workspace::*, FlowyTest};
|
use flowy_test::{workspace::*, FlowyTest};
|
||||||
use flowy_workspace::entities::{trash::TrashIdentifier, view::*};
|
use flowy_workspace::entities::{
|
||||||
|
trash::{TrashIdentifier, TrashType},
|
||||||
|
view::*,
|
||||||
|
};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
@ -24,6 +27,7 @@ async fn view_delete_and_putback() {
|
|||||||
&test.sdk,
|
&test.sdk,
|
||||||
TrashIdentifier {
|
TrashIdentifier {
|
||||||
id: test.view.id.clone(),
|
id: test.view.id.clone(),
|
||||||
|
ty: TrashType::View,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
Reference in New Issue
Block a user