eintopf.info@v0.13.16/service/indexo/indexo.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 // Package indexo provides an operator with an index and a delete operation, 17 // that operates on a search index 18 package indexo 19 20 import ( 21 "context" 22 23 "eintopf.info/service/event" 24 "eintopf.info/service/group" 25 "eintopf.info/service/oqueue" 26 "eintopf.info/service/place" 27 "eintopf.info/service/search" 28 ) 29 30 // Service defines an operation indexer service. 31 type Service interface { 32 // Reindex takes all models, that are searchable and indexes them into the 33 // search index. 34 Reindex(ctx context.Context) error 35 } 36 37 type service struct { 38 queue oqueue.Service 39 40 searchService search.Service 41 eventService event.Storer 42 groupService group.Service 43 placeService place.Service 44 } 45 46 // NewService returns a new index operator service. 47 func NewService( 48 queue oqueue.Service, 49 searchService search.Service, 50 eventService event.Storer, 51 groupService group.Service, 52 placeService place.Service, 53 ) Service { 54 s := &service{ 55 queue: queue, 56 searchService: searchService, 57 eventService: eventService, 58 groupService: groupService, 59 placeService: placeService, 60 } 61 62 queue.AddSubscriber(s.consumeOperation, 1) 63 64 return s 65 } 66 67 // consumeOperation consumes an event, group and place operations of the type 68 // create, update and delete. Depending on wether the model is searchable, it 69 // performs an index or a delete operation on the search index. 70 func (s *service) consumeOperation(op oqueue.Operation) error { 71 switch op := op.(type) { 72 case group.CreateOperation: 73 if op.Group.Indexable() { 74 return s.indexGroup(op.Group) 75 } 76 case group.UpdateOperation: 77 if op.Group.Indexable() { 78 return s.indexGroup(op.Group) 79 } else { 80 return s.searchService.Delete("group", op.Group.ID) 81 } 82 case group.DeleteOperation: 83 return s.searchService.Delete("group", op.ID) 84 case place.CreateOperation: 85 if op.Place.Indexable() { 86 return s.indexPlace(op.Place) 87 } 88 case place.UpdateOperation: 89 if op.Place.Indexable() { 90 return s.indexPlace(op.Place) 91 } else { 92 return s.searchService.Delete("place", op.Place.ID) 93 } 94 case place.DeleteOperation: 95 return s.searchService.Delete("place", op.ID) 96 } 97 return nil 98 } 99 100 func (s *service) Reindex(ctx context.Context) error { 101 groups, _, err := s.groupService.Find(ctx, nil) 102 if err != nil { 103 return err 104 } 105 docs := []search.Indexable{} 106 for _, group := range groups { 107 if group.Indexable() { 108 docs = append(docs, groupDocumentFromGroup(group)) 109 } 110 } 111 112 places, _, err := s.placeService.Find(ctx, nil) 113 if err != nil { 114 return err 115 } 116 for _, place := range places { 117 if place.Indexable() { 118 docs = append(docs, placeDocumentFromPlace(place)) 119 } 120 } 121 return s.searchService.Index(docs...) 122 }