From 896e3bee9f1a4e3367392a331908c767eb99328e Mon Sep 17 00:00:00 2001 From: Gustl22 Date: Wed, 11 Sep 2024 09:27:25 +0200 Subject: [PATCH] fix: Use common searchable data types --- .../lib/view/screens/home/home.dart | 8 +----- .../lib/src/data/club.dart | 2 ++ .../lib/src/data/membership.dart | 2 ++ .../lib/src/data/organization.dart | 2 ++ .../lib/src/data/person.dart | 8 ++++++ .../lib/src/data/team.dart | 2 ++ .../lib/src/data/team_match/division.dart | 2 ++ .../lib/src/data/team_match/league.dart | 2 ++ .../lib/src/data/weight_class.dart | 5 ++++ .../lib/src/data/wrestling_event.dart | 2 ++ .../lib/src/util/data_wrapper.dart | 17 ++++++++++++ .../lib/controllers/club_controller.dart | 3 --- .../lib/controllers/division_controller.dart | 3 --- .../lib/controllers/entity_controller.dart | 7 ++--- .../lib/controllers/league_controller.dart | 3 --- .../controllers/membership_controller.dart | 3 --- .../controllers/organization_controller.dart | 11 ++++---- .../lib/controllers/person_controller.dart | 9 ------- .../lib/controllers/search_controller.dart | 26 ++++++++++++------- .../lib/controllers/team_controller.dart | 3 --- .../controllers/team_match_controller.dart | 3 --- .../controllers/weight_class_controller.dart | 6 ----- 22 files changed, 70 insertions(+), 59 deletions(-) diff --git a/wrestling_scoreboard_client/lib/view/screens/home/home.dart b/wrestling_scoreboard_client/lib/view/screens/home/home.dart index d49e1fe6..cc5070c8 100644 --- a/wrestling_scoreboard_client/lib/view/screens/home/home.dart +++ b/wrestling_scoreboard_client/lib/view/screens/home/home.dart @@ -183,13 +183,7 @@ class HomeState extends ConsumerState { Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: SimpleDropdown( - options: [ - null, - ...dataTypes - ..remove(ParticipantState) - ..remove(User) - ..remove(SecuredUser) - ].map((type) => MapEntry( + options: [null, ...searchableDataTypes.keys].map((type) => MapEntry( type, Text(type != null ? localizeType(context, type) : '${localizations.optionSelect} Type'), )), diff --git a/wrestling_scoreboard_common/lib/src/data/club.dart b/wrestling_scoreboard_common/lib/src/data/club.dart index f2bfce6e..f05d7375 100644 --- a/wrestling_scoreboard_common/lib/src/data/club.dart +++ b/wrestling_scoreboard_common/lib/src/data/club.dart @@ -46,4 +46,6 @@ class Club with _$Club implements DataObject, Organizational { Club copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'no', 'name'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/membership.dart b/wrestling_scoreboard_common/lib/src/data/membership.dart index 254ead12..7eb1dcae 100644 --- a/wrestling_scoreboard_common/lib/src/data/membership.dart +++ b/wrestling_scoreboard_common/lib/src/data/membership.dart @@ -58,4 +58,6 @@ class Membership with _$Membership implements DataObject, Organizational { Membership copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'no'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/organization.dart b/wrestling_scoreboard_common/lib/src/data/organization.dart index bda9d785..dff46dd8 100644 --- a/wrestling_scoreboard_common/lib/src/data/organization.dart +++ b/wrestling_scoreboard_common/lib/src/data/organization.dart @@ -65,4 +65,6 @@ class Organization with _$Organization implements DataObject { Organization copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'name', 'abbreviation'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/person.dart b/wrestling_scoreboard_common/lib/src/data/person.dart index 1a8821b8..d3d07b3c 100644 --- a/wrestling_scoreboard_common/lib/src/data/person.dart +++ b/wrestling_scoreboard_common/lib/src/data/person.dart @@ -88,4 +88,12 @@ class Person with _$Person implements DataObject, Organizational { Person copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = { + 'prename', + 'surname', + // 'gender', // Cannot currently search non-string values + 'nationality', + // 'birth_date', // Cannot currently search non-string values + }; } diff --git a/wrestling_scoreboard_common/lib/src/data/team.dart b/wrestling_scoreboard_common/lib/src/data/team.dart index cbcfb195..0f5d95a1 100644 --- a/wrestling_scoreboard_common/lib/src/data/team.dart +++ b/wrestling_scoreboard_common/lib/src/data/team.dart @@ -53,4 +53,6 @@ class Team with _$Team implements DataObject, Organizational { Team copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'name', 'description'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/team_match/division.dart b/wrestling_scoreboard_common/lib/src/data/team_match/division.dart index eae27115..bf09d6aa 100644 --- a/wrestling_scoreboard_common/lib/src/data/team_match/division.dart +++ b/wrestling_scoreboard_common/lib/src/data/team_match/division.dart @@ -65,4 +65,6 @@ class Division with _$Division implements DataObject, Organizational { Division copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'name'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/team_match/league.dart b/wrestling_scoreboard_common/lib/src/data/team_match/league.dart index f3391b59..5ddc9d9c 100644 --- a/wrestling_scoreboard_common/lib/src/data/team_match/league.dart +++ b/wrestling_scoreboard_common/lib/src/data/team_match/league.dart @@ -61,4 +61,6 @@ class League with _$League implements DataObject, Organizational { League copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = {'name'}; } diff --git a/wrestling_scoreboard_common/lib/src/data/weight_class.dart b/wrestling_scoreboard_common/lib/src/data/weight_class.dart index 2acc7e9d..8514361e 100644 --- a/wrestling_scoreboard_common/lib/src/data/weight_class.dart +++ b/wrestling_scoreboard_common/lib/src/data/weight_class.dart @@ -59,4 +59,9 @@ class WeightClass with _$WeightClass implements DataObject { WeightClass copyWithId(int? id) { return copyWith(id: id); } + + static Set searchableAttributes = { + 'weight', + 'suffix', + }; } diff --git a/wrestling_scoreboard_common/lib/src/data/wrestling_event.dart b/wrestling_scoreboard_common/lib/src/data/wrestling_event.dart index 520b8fae..a9fabd0e 100644 --- a/wrestling_scoreboard_common/lib/src/data/wrestling_event.dart +++ b/wrestling_scoreboard_common/lib/src/data/wrestling_event.dart @@ -39,4 +39,6 @@ abstract class WrestlingEvent implements DataObject, Organizational { 'comment': comment, }; } + + static Set searchableAttributes = {'no', 'location', 'comment'}; } diff --git a/wrestling_scoreboard_common/lib/src/util/data_wrapper.dart b/wrestling_scoreboard_common/lib/src/util/data_wrapper.dart index 944d87e9..e684fee8 100644 --- a/wrestling_scoreboard_common/lib/src/util/data_wrapper.dart +++ b/wrestling_scoreboard_common/lib/src/util/data_wrapper.dart @@ -312,3 +312,20 @@ final dataTypes = [ SecuredUser, User, ]; + +/// Returns a map of data types with searchable attributes. +/// TODO: with macros, apply it to the property @Searchable. +final Map> searchableDataTypes = { + Person: Person.searchableAttributes, + Membership: Membership.searchableAttributes, + Club: Club.searchableAttributes, + Organization: Organization.searchableAttributes, + WeightClass: WeightClass.searchableAttributes, + // Uses same attributes as WrestlingEvent ATM + Competition: WrestlingEvent.searchableAttributes, + // Uses same attributes as WrestlingEvent ATM + TeamMatch: WrestlingEvent.searchableAttributes, + Division: Division.searchableAttributes, + League: League.searchableAttributes, + Team: Team.searchableAttributes, +}; diff --git a/wrestling_scoreboard_server/lib/controllers/club_controller.dart b/wrestling_scoreboard_server/lib/controllers/club_controller.dart index efb8d49e..6f43da6c 100644 --- a/wrestling_scoreboard_server/lib/controllers/club_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/club_controller.dart @@ -32,7 +32,4 @@ class ClubController extends OrganizationalController { obfuscate: user?.obfuscate ?? true, ); } - - @override - Set getSearchableAttributes() => {'no', 'name'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/division_controller.dart b/wrestling_scoreboard_server/lib/controllers/division_controller.dart index 331ff942..8a99e602 100644 --- a/wrestling_scoreboard_server/lib/controllers/division_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/division_controller.dart @@ -68,7 +68,4 @@ class DivisionController extends OrganizationalController { obfuscate: user?.obfuscate ?? true, ); } - - @override - Set getSearchableAttributes() => {'name'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/entity_controller.dart b/wrestling_scoreboard_server/lib/controllers/entity_controller.dart index 08845b1e..9339ff3d 100644 --- a/wrestling_scoreboard_server/lib/controllers/entity_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/entity_controller.dart @@ -365,10 +365,11 @@ abstract class EntityController { String searchStr, { int? organizationId, required bool obfuscate, + required Set searchableAttributes, }) async { final postgresTypes = getPostgresDataTypes(); bool needsPreciseSearch = false; - final orConditions = getSearchableAttributes() + final orConditions = searchableAttributes .map((attr) { // TODO: get postgres types generated from attributes via macros. final postgresType = postgresTypes.containsKey(attr) ? postgresTypes[attr] : psql.Type.varChar; @@ -408,10 +409,6 @@ abstract class EntityController { ); } - /// Returns a list of searchable attributes. - /// TODO: with macros, apply it to the property @Searchable. - Set getSearchableAttributes() => {}; - Future> getMany({ List? conditions, Conjunction conjunction = Conjunction.and, diff --git a/wrestling_scoreboard_server/lib/controllers/league_controller.dart b/wrestling_scoreboard_server/lib/controllers/league_controller.dart index e1b62a5f..dbfe5699 100644 --- a/wrestling_scoreboard_server/lib/controllers/league_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/league_controller.dart @@ -104,7 +104,4 @@ class LeagueController extends OrganizationalController { return Response.internalServerError(body: '{"err": "$err", "stackTrace": "$stackTrace"}'); } } - - @override - Set getSearchableAttributes() => {'name'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/membership_controller.dart b/wrestling_scoreboard_server/lib/controllers/membership_controller.dart index c53c04ec..66bb5d30 100644 --- a/wrestling_scoreboard_server/lib/controllers/membership_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/membership_controller.dart @@ -15,7 +15,4 @@ class MembershipController extends OrganizationalController { raw['no'] = null; return raw; } - - @override - Set getSearchableAttributes() => {'no'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/organization_controller.dart b/wrestling_scoreboard_server/lib/controllers/organization_controller.dart index a382c0ce..41216efc 100644 --- a/wrestling_scoreboard_server/lib/controllers/organization_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/organization_controller.dart @@ -123,15 +123,16 @@ class OrganizationController extends ShelfController { } } - Future> search(Request request, int id, - {required String searchStr, required Type searchType}) async { + Future> search( + Request request, + int id, { + required String searchStr, + required Type searchType, + }) async { final apiProvider = await initApiProvider(request, id); if (apiProvider == null) { throw Exception('No API provider selected for the organization $id.'); } return await apiProvider.search(searchStr: searchStr, searchType: searchType); } - - @override - Set getSearchableAttributes() => {'name', 'abbreviation'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/person_controller.dart b/wrestling_scoreboard_server/lib/controllers/person_controller.dart index 5b84af89..5d0e2317 100644 --- a/wrestling_scoreboard_server/lib/controllers/person_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/person_controller.dart @@ -41,13 +41,4 @@ class PersonController extends OrganizationalController { 'gender': null, }; } - - @override - Set getSearchableAttributes() => { - 'prename', - 'surname', - // 'gender', // Cannot currently search non-string values - 'nationality', - // 'birth_date', // Cannot currently search non-string values - }; } diff --git a/wrestling_scoreboard_server/lib/controllers/search_controller.dart b/wrestling_scoreboard_server/lib/controllers/search_controller.dart index aa3be204..92482752 100644 --- a/wrestling_scoreboard_server/lib/controllers/search_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/search_controller.dart @@ -15,11 +15,11 @@ class SearchController { final queryParams = request.requestedUri.queryParameters; final likeParam = queryParams['like']; - final querySearchType = queryParams['type']; + final querySearchTypeStr = queryParams['type']; final searchOrganizationId = int.tryParse(queryParams['org'] ?? ''); final useProvider = bool.parse(queryParams['use_provider'] ?? 'false'); final isValidLikeSearch = likeParam != null && (likeParam.length >= 3 || double.tryParse(likeParam) != null); - final searchAllTypes = querySearchType == null; + final searchAllTypes = querySearchTypeStr == null; if (useProvider && (!isValidLikeSearch || searchAllTypes || searchOrganizationId == null)) { return Response.badRequest( @@ -27,24 +27,32 @@ class SearchController { 'Searching the API provider without specifying a type, the organization and a search string is not supported!'); } - final Iterable searchTypes; + final Map> searchTypeMap; if (!searchAllTypes) { - searchTypes = [querySearchType]; + final querySearchType = getTypeFromTableName(querySearchTypeStr); + final searchableAttr = searchableDataTypes[querySearchType]; + searchTypeMap = {if (searchableAttr != null) querySearchType: searchableAttr}; } else { // All searchable types - searchTypes = dataTypes.map((d) => getTableNameFromType(d)); + searchTypeMap = searchableDataTypes; } try { final raw = request.isRaw; List> manyJsonList = []; - for (final tableName in searchTypes) { - final searchType = getTypeFromTableName(tableName); + for (final searchTypeEntry in searchTypeMap.entries) { + final searchType = searchTypeEntry.key; final entityController = ShelfController.getControllerFromDataType(searchType); Map? manyJson; if (isValidLikeSearch) { - manyJson = await entityController?.getManyJsonLike(raw, likeParam, - organizationId: searchOrganizationId, obfuscate: obfuscate); + final searchableAttributes = searchTypeEntry.value; + manyJson = await entityController?.getManyJsonLike( + raw, + likeParam, + organizationId: searchOrganizationId, + searchableAttributes: searchableAttributes, + obfuscate: obfuscate, + ); if (!searchAllTypes && useProvider && searchOrganizationId != null) { final orgSearchRes = await OrganizationController().search( request, diff --git a/wrestling_scoreboard_server/lib/controllers/team_controller.dart b/wrestling_scoreboard_server/lib/controllers/team_controller.dart index 45924ce6..08903e7a 100644 --- a/wrestling_scoreboard_server/lib/controllers/team_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/team_controller.dart @@ -30,7 +30,4 @@ class TeamController extends OrganizationalController { Future import(Request request, User? user, String teamId) async { return Response.notFound('This operation is not supported yet!'); } - - @override - Set getSearchableAttributes() => {'name', 'description'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/team_match_controller.dart b/wrestling_scoreboard_server/lib/controllers/team_match_controller.dart index a42d3a1d..8c330316 100644 --- a/wrestling_scoreboard_server/lib/controllers/team_match_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/team_match_controller.dart @@ -216,7 +216,4 @@ class TeamMatchController extends OrganizationalController { } return null; } - - @override - Set getSearchableAttributes() => {'no', 'location', 'comment'}; } diff --git a/wrestling_scoreboard_server/lib/controllers/weight_class_controller.dart b/wrestling_scoreboard_server/lib/controllers/weight_class_controller.dart index 8cf0f16a..513dc8a3 100644 --- a/wrestling_scoreboard_server/lib/controllers/weight_class_controller.dart +++ b/wrestling_scoreboard_server/lib/controllers/weight_class_controller.dart @@ -20,10 +20,4 @@ class WeightClassController extends ShelfController { 'unit': null, }; } - - @override - Set getSearchableAttributes() => { - 'weight', - 'suffix', - }; }