fix: Fix hive type adapter for empty clases causing app to crash

This commit is contained in:
Anton Stubenbord
2023-10-06 21:37:24 +02:00
parent 5dcae3f0b3
commit 690e4558cb
13 changed files with 194 additions and 198 deletions

View File

@@ -39,9 +39,9 @@ class HiveTypeIds {
static const clientCertificate = 5;
static const localUserCredentials = 6;
static const localUserAccount = 7;
static const localUserAppState = 8;
static const viewType = 9;
static const fileDownloadType = 10;
static const localUserAppState = 8;
}
void registerHiveAdapters() {

View File

@@ -64,9 +64,9 @@ String get defaultPreferredLocaleSubtag {
}
Map<String, Future<void> Function()> _migrations = {
'3.0.0': () {
'3.0.1': () async {
// Remove all stored data due to updates in schema
return Future.wait([
await Future.wait([
for (var box in HiveBoxes.all) Hive.deleteBoxFromDisk(box),
]);
},
@@ -96,10 +96,8 @@ Future<void> performMigrations() async {
Future<void> _initHive() async {
await Hive.initFlutter();
await performMigrations();
// await performMigrations();
registerHiveAdapters();
// await getApplicationDocumentsDirectory().then((value) => value.deleteSync(recursive: true));
await Hive.openBox<LocalUserAccount>(HiveBoxes.localUserAccount);
await Hive.openBox<LocalUserAppState>(HiveBoxes.localUserAppState);
await Hive.openBox<String>(HiveBoxes.hosts);

View File

@@ -3,7 +3,7 @@ import 'package:paperless_api/paperless_api.dart';
class PaperlessApiHiveTypeIds {
PaperlessApiHiveTypeIds._();
static const int documentFilter = 100;
static const int idQueryParameter = 101;
static const int tagsQuery = 102;
static const int anyAssignedTagsQuery = 103;
@@ -31,6 +31,7 @@ class PaperlessApiHiveTypeIds {
static const int permissions = 125;
static const int userModelv2 = 126;
static const int usersAndGroupsPermissions = 127;
static const int documentFilter = 128;
}
void registerPaperlessApiHiveTypeAdapters() {

View File

@@ -1,2 +1 @@
export 'document_model_json_converter.dart';
export 'date_range_query_json_converter.dart';

View File

@@ -1,30 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/src/models/models.dart';
class DateRangeQueryJsonConverter
extends JsonConverter<DateRangeQuery, Map<String, dynamic>> {
const DateRangeQueryJsonConverter();
@override
DateRangeQuery fromJson(Map<String, dynamic> json) {
final type = json['type'];
final data = json['data'];
switch (json['type'] as String) {
case 'UnsetDateRangeQuery':
return const UnsetDateRangeQuery();
case 'AbsoluteDateRangeQuery':
return AbsoluteDateRangeQuery.fromJson(data);
case 'RelativeDateRangeQuery':
return RelativeDateRangeQuery.fromJson(data);
default:
throw Exception('Error parsing DateRangeQuery: Unknown type $type');
}
}
@override
Map<String, dynamic> toJson(DateRangeQuery object) {
return {
'type': object.runtimeType.toString(),
'data': object.toJson(),
};
}
}

View File

@@ -1,14 +1,11 @@
import 'package:collection/collection.dart';
import 'package:equatable/equatable.dart';
import 'package:hive/hive.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query_field.dart';
part 'document_filter.g.dart';
@DateRangeQueryJsonConverter()
// @JsonSerializable(explicitToJson: true)
@HiveType(typeId: PaperlessApiHiveTypeIds.documentFilter)
class DocumentFilter extends Equatable {
static const DocumentFilter initial = DocumentFilter();

View File

@@ -11,34 +11,27 @@ import 'date_range_unit.dart';
part 'date_range_query.g.dart';
sealed class DateRangeQuery extends Equatable {
sealed class DateRangeQuery {
const DateRangeQuery();
Map<String, String> toQueryParameter(DateRangeQueryField field);
Map<String, dynamic> toJson();
bool matches(DateTime dt);
}
// @HiveType(typeId: PaperlessApiHiveTypeIds.unsetDateRangeQuery)
class UnsetDateRangeQuery extends DateRangeQuery {
const UnsetDateRangeQuery();
@override
List<Object?> get props => [];
@override
Map<String, String> toQueryParameter(DateRangeQueryField field) => const {};
@override
Map<String, dynamic> toJson() => const {};
@override
bool matches(DateTime dt) => true;
}
@JsonSerializable()
@HiveType(typeId: PaperlessApiHiveTypeIds.relativeDateRangeQuery)
class RelativeDateRangeQuery extends DateRangeQuery {
class RelativeDateRangeQuery extends DateRangeQuery with EquatableMixin {
@HiveField(0)
final int offset;
@HiveField(1)
@@ -83,12 +76,6 @@ class RelativeDateRangeQuery extends DateRangeQuery {
}
}
@override
Map<String, dynamic> toJson() => _$RelativeDateRangeQueryToJson(this);
factory RelativeDateRangeQuery.fromJson(Map<String, dynamic> json) =>
_$RelativeDateRangeQueryFromJson(json);
@override
bool matches(DateTime dt) {
return dt.isAfter(dateTime) || dt == dateTime;
@@ -97,7 +84,7 @@ class RelativeDateRangeQuery extends DateRangeQuery {
@JsonSerializable()
@HiveType(typeId: PaperlessApiHiveTypeIds.absoluteDateRangeQuery)
class AbsoluteDateRangeQuery extends DateRangeQuery {
class AbsoluteDateRangeQuery extends DateRangeQuery with EquatableMixin {
@LocalDateTimeJsonConverter()
@HiveField(0)
final DateTime? after;
@@ -138,12 +125,6 @@ class AbsoluteDateRangeQuery extends DateRangeQuery {
);
}
factory AbsoluteDateRangeQuery.fromJson(json) =>
_$AbsoluteDateRangeQueryFromJson(json);
@override
Map<String, dynamic> toJson() => _$AbsoluteDateRangeQueryToJson(this);
@override
bool matches(DateTime dt) {
//TODO: Check if after and before are inclusive or exclusive definitions.

View File

@@ -1,11 +1,7 @@
import 'dart:isolate';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:equatable/equatable.dart';
import 'package:hive/hive.dart';
import 'package:paperless_api/config/hive/hive_type_ids.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'id_query_parameter.freezed.dart';
part 'id_query_parameter.g.dart';
sealed class IdQueryParameter {
@@ -19,12 +15,9 @@ sealed class IdQueryParameter {
bool get isOnlyAssigned => this is AnyAssignedIdQueryParameter;
}
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
@Freezed(toJson: false, fromJson: false)
class UnsetIdQueryParameter extends IdQueryParameter
with _$UnsetIdQueryParameter {
const UnsetIdQueryParameter._();
const factory UnsetIdQueryParameter() = _UnsetIdQueryParameter;
// @HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
class UnsetIdQueryParameter extends IdQueryParameter {
const UnsetIdQueryParameter();
@override
Map<String, String> toQueryParameter(String field) => {};
@@ -32,12 +25,10 @@ class UnsetIdQueryParameter extends IdQueryParameter
bool matches(int? id) => true;
}
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
@Freezed(toJson: false, fromJson: false)
class NotAssignedIdQueryParameter extends IdQueryParameter
with _$NotAssignedIdQueryParameter {
const NotAssignedIdQueryParameter._();
const factory NotAssignedIdQueryParameter() = _NotAssignedIdQueryParameter;
// @HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
class NotAssignedIdQueryParameter extends IdQueryParameter {
const NotAssignedIdQueryParameter();
@override
Map<String, String> toQueryParameter(String field) {
return {'${field}__isnull': '1'};
@@ -47,12 +38,9 @@ class NotAssignedIdQueryParameter extends IdQueryParameter
bool matches(int? id) => id == null;
}
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
@Freezed(toJson: false, fromJson: false)
class AnyAssignedIdQueryParameter extends IdQueryParameter
with _$AnyAssignedIdQueryParameter {
const factory AnyAssignedIdQueryParameter() = _AnyAssignedIdQueryParameter;
const AnyAssignedIdQueryParameter._();
// @HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
class AnyAssignedIdQueryParameter extends IdQueryParameter {
const AnyAssignedIdQueryParameter();
@override
Map<String, String> toQueryParameter(String field) {
return {'${field}__isnull': '0'};
@@ -63,12 +51,12 @@ class AnyAssignedIdQueryParameter extends IdQueryParameter
}
@HiveType(typeId: PaperlessApiHiveTypeIds.setIdQueryParameter)
@Freezed(toJson: false, fromJson: false)
class SetIdQueryParameter extends IdQueryParameter with _$SetIdQueryParameter {
const SetIdQueryParameter._();
const factory SetIdQueryParameter({
@HiveField(0) required int id,
}) = _SetIdQueryParameter;
class SetIdQueryParameter extends IdQueryParameter with EquatableMixin {
@HiveField(0)
final int id;
const SetIdQueryParameter({required this.id});
@override
Map<String, String> toQueryParameter(String field) {
return {'${field}__id': '$id'};
@@ -76,4 +64,89 @@ class SetIdQueryParameter extends IdQueryParameter with _$SetIdQueryParameter {
@override
bool matches(int? id) => id == this.id;
@override
List<Object?> get props => [id];
}
/// Custom Adapters
class UnsetIdQueryParameterAdapter extends TypeAdapter<UnsetIdQueryParameter> {
@override
final int typeId = 116;
@override
UnsetIdQueryParameter read(BinaryReader reader) {
reader.readByte();
return const UnsetIdQueryParameter();
}
@override
void write(BinaryWriter writer, UnsetIdQueryParameter obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is UnsetIdQueryParameterAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class NotAssignedIdQueryParameterAdapter
extends TypeAdapter<NotAssignedIdQueryParameter> {
@override
final int typeId = 117;
@override
NotAssignedIdQueryParameter read(BinaryReader reader) {
reader.readByte();
return const NotAssignedIdQueryParameter();
}
@override
void write(BinaryWriter writer, NotAssignedIdQueryParameter obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is NotAssignedIdQueryParameterAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class AnyAssignedIdQueryParameterAdapter
extends TypeAdapter<AnyAssignedIdQueryParameter> {
@override
final int typeId = 118;
@override
AnyAssignedIdQueryParameter read(BinaryReader reader) {
reader.readByte();
return const AnyAssignedIdQueryParameter();
}
@override
void write(BinaryWriter writer, AnyAssignedIdQueryParameter obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AnyAssignedIdQueryParameterAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -1,7 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:equatable/equatable.dart';
import 'package:hive/hive.dart';
import 'package:paperless_api/config/hive/hive_type_ids.dart';
part 'tags_query.freezed.dart';
part 'tags_query.g.dart';
sealed class TagsQuery {
@@ -10,11 +10,9 @@ sealed class TagsQuery {
bool matches(Iterable<int> ids);
}
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
@Freezed(toJson: false, fromJson: false)
class NotAssignedTagsQuery extends TagsQuery with _$NotAssignedTagsQuery {
const NotAssignedTagsQuery._();
const factory NotAssignedTagsQuery() = _NotAssignedTagsQuery;
// @HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
class NotAssignedTagsQuery extends TagsQuery {
const NotAssignedTagsQuery();
@override
Map<String, String> toQueryParameter() {
return {'is_tagged': '0'};
@@ -25,12 +23,13 @@ class NotAssignedTagsQuery extends TagsQuery with _$NotAssignedTagsQuery {
}
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedTagsQuery)
@Freezed(toJson: false, fromJson: false)
class AnyAssignedTagsQuery extends TagsQuery with _$AnyAssignedTagsQuery {
const AnyAssignedTagsQuery._();
const factory AnyAssignedTagsQuery({
@HiveField(0) @Default([]) List<int> tagIds,
}) = _AnyAssignedTagsQuery;
class AnyAssignedTagsQuery extends TagsQuery with EquatableMixin {
@HiveField(0)
final List<int> tagIds;
const AnyAssignedTagsQuery({
this.tagIds = const [],
});
@override
Map<String, String> toQueryParameter() {
if (tagIds.isEmpty) {
@@ -41,16 +40,29 @@ class AnyAssignedTagsQuery extends TagsQuery with _$AnyAssignedTagsQuery {
@override
bool matches(Iterable<int> ids) => ids.isNotEmpty;
AnyAssignedTagsQuery copyWith({
List<int>? tagIds,
}) {
return AnyAssignedTagsQuery(
tagIds: tagIds ?? this.tagIds,
);
}
@override
List<Object?> get props => [tagIds];
}
@HiveType(typeId: PaperlessApiHiveTypeIds.idsTagsQuery)
@Freezed(toJson: false, fromJson: false)
class IdsTagsQuery extends TagsQuery with _$IdsTagsQuery {
const IdsTagsQuery._();
const factory IdsTagsQuery({
@HiveField(0) @Default([]) List<int> include,
@HiveField(1) @Default([]) List<int> exclude,
}) = _IdsTagsQuery;
class IdsTagsQuery extends TagsQuery with EquatableMixin {
@HiveField(0)
final List<int> include;
@HiveField(1)
final List<int> exclude;
const IdsTagsQuery({
this.include = const [],
this.exclude = const [],
});
@override
Map<String, String> toQueryParameter() {
final Map<String, String> params = {};
@@ -68,4 +80,45 @@ class IdsTagsQuery extends TagsQuery with _$IdsTagsQuery {
return include.toSet().difference(ids.toSet()).isEmpty &&
exclude.toSet().intersection(ids.toSet()).isEmpty;
}
IdsTagsQuery copyWith({
List<int>? include,
List<int>? exclude,
}) {
return IdsTagsQuery(
include: include ?? this.include,
exclude: exclude ?? this.exclude,
);
}
@override
List<Object?> get props => [include, exclude];
}
/// Custom adapters
class NotAssignedTagsQueryAdapter extends TypeAdapter<NotAssignedTagsQuery> {
@override
final int typeId = PaperlessApiHiveTypeIds.notAssignedTagsQuery;
@override
NotAssignedTagsQuery read(BinaryReader reader) {
reader.readByte();
return const NotAssignedTagsQuery();
}
@override
void write(BinaryWriter writer, NotAssignedTagsQuery obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is NotAssignedTagsQueryAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -1,5 +1,3 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/widgets.dart';
import 'package:hive/hive.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/config/hive/hive_type_ids.dart';
@@ -8,9 +6,7 @@ import 'query_type.dart';
part 'text_query.g.dart';
//TODO: Realize with freezed...
@HiveType(typeId: PaperlessApiHiveTypeIds.textQuery)
@JsonSerializable()
class TextQuery {
@HiveField(0)
final QueryType queryType;
@@ -85,11 +81,6 @@ class TextQuery {
}
}
Map<String, dynamic> toJson() => _$TextQueryToJson(this);
factory TextQuery.fromJson(Map<String, dynamic> json) =>
_$TextQueryFromJson(json);
@override
bool operator ==(Object? other) {
if (identical(this, other)) return true;

View File

@@ -20,7 +20,7 @@ dependencies:
dio: ^5.0.0
collection: ^1.17.0
jiffy: ^5.0.0
freezed_annotation: ^2.2.0
freezed_annotation: ^2.4.1
hive: ^2.2.3
dev_dependencies:
@@ -28,9 +28,9 @@ dev_dependencies:
sdk: flutter
flutter_lints: ^2.0.0
json_serializable: ^6.5.4
build_runner: ^2.4.2
freezed: ^2.3.3
hive_generator: ^2.0.0
build_runner: ^2.4.6
freezed: ^2.4.1
hive_generator: ^2.0.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

View File

@@ -17,14 +17,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.13.0"
analyzer_plugin:
dependency: transitive
description:
name: analyzer_plugin
sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d
url: "https://pub.dev"
source: hosted
version: "0.11.2"
animations:
dependency: "direct main"
description:
@@ -33,14 +25,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.8"
ansicolor:
dependency: transitive
description:
name: ansicolor
sha256: "607f8fa9786f392043f169898923e6c59b4518242b68b8862eb8a8b7d9c30b4a"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
archive:
dependency: transitive
description:
@@ -65,22 +49,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_route:
dependency: transitive
description:
name: auto_route
sha256: "12047baeca0e01df93165ef33275b32119d72699ab9a49dc64c20e78f586f96d"
url: "https://pub.dev"
source: hosted
version: "5.0.4"
auto_route_generator:
dependency: "direct dev"
description:
name: auto_route_generator
sha256: de5bfbc02ae4eebb339dd90d325749ae7536e903f6513ef72b88954072d72b0e
url: "https://pub.dev"
source: hosted
version: "5.0.3"
badges:
dependency: "direct main"
description:
@@ -313,22 +281,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.17.3"
dart_code_metrics:
dependency: "direct dev"
description:
name: dart_code_metrics
sha256: "3dede3f7abc077a4181ec7445448a289a9ce08e2981e6a4d49a3fb5099d47e1f"
url: "https://pub.dev"
source: hosted
version: "5.7.6"
dart_code_metrics_presets:
dependency: transitive
description:
name: dart_code_metrics_presets
sha256: b71eadf02a3787ebd5c887623f83f6fdc204d45c75a081bd636c4104b3fd8b73
url: "https://pub.dev"
source: hosted
version: "1.8.0"
dart_style:
dependency: transitive
description:
@@ -1052,14 +1004,6 @@ packages:
relative: true
source: path
version: "0.0.1"
mockito:
dependency: "direct dev"
description:
name: mockito
sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616"
url: "https://pub.dev"
source: hosted
version: "5.4.2"
mocktail:
dependency: transitive
description:
@@ -1363,14 +1307,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pub_updater:
dependency: transitive
description:
name: pub_updater
sha256: b06600619c8c219065a548f8f7c192b3e080beff95488ed692780f48f69c0625
url: "https://pub.dev"
source: hosted
version: "0.3.1"
pubspec_parse:
dependency: transitive
description:

View File

@@ -82,7 +82,7 @@ dependencies:
flutter_displaymode: ^0.5.0
dynamic_color: ^1.5.4
flutter_html: ^3.0.0-alpha.6
freezed_annotation: ^2.2.0
freezed_annotation: ^2.4.1
animations: ^2.0.7
hive_flutter: ^1.1.0
flutter_secure_storage: ^8.0.0
@@ -108,16 +108,13 @@ dev_dependencies:
sdk: flutter
flutter_test:
sdk: flutter
build_runner: ^2.4.2
mockito: ^5.3.2
build_runner: ^2.4.6
bloc_test: ^9.1.0
dependency_validator: ^3.0.0
flutter_lints: ^1.0.0
json_serializable: ^6.5.4
dart_code_metrics: ^5.4.0
auto_route_generator: ^5.0.3
freezed: ^2.3.3
hive_generator: ^2.0.0
freezed: ^2.4.1
hive_generator: ^2.0.1
mock_server:
path: packages/mock_server
go_router_builder: ^2.2.4