This repository has been archived by the owner on Oct 17, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 147
/
search.go
106 lines (89 loc) · 2.58 KB
/
search.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package search
import (
"errors"
"time"
"github.com/short-d/short/backend/app/entity"
"github.com/short-d/short/backend/app/usecase/repository"
"github.com/short-d/short/backend/app/usecase/search/order"
)
// Search finds different types of resources matching certain criteria and sort them based on predefined orders.
type Search struct {
shortLinkRepo repository.ShortLink
userShortLinkRepo repository.UserShortLink
timeout time.Duration
}
// Result represents the result of a search query.
type Result struct {
shortLinks []entity.ShortLink
users []entity.User
}
// Search finds resources based on specified criteria.
func (s Search) Search(query Query, filter Filter) (Result, error) {
resultCh := make(chan Result)
defer close(resultCh)
orders := toOrders(filter.Orders)
for i := range filter.Resources {
go func() {
result, err := s.searchResource(filter.Resources[i], orders[i], query, filter)
if err != nil {
resultCh <- Result{}
return
}
resultCh <- result
}()
}
timeout := time.After(s.timeout)
var results []Result
for i := 0; i < len(filter.Resources); i++ {
select {
case result := <-resultCh:
results = append(results, result)
case <-timeout:
return mergeResults(results), nil
}
}
return mergeResults(results), nil
}
func (s Search) searchResource(resource Resource, orderBy order.Order, query Query, filter Filter) (Result, error) {
switch resource {
case ShortLink:
return s.searchShortLink(query, orderBy, filter)
case User:
return s.searchUser(query, orderBy, filter)
default:
return Result{}, errors.New("unknown resource")
}
}
func (s Search) searchShortLink(query Query, orderBy order.Order, filter Filter) (Result, error) {
return Result{}, nil
}
func (s Search) searchUser(query Query, orderBy order.Order, filter Filter) (Result, error) {
return Result{}, nil
}
func toOrders(ordersBy []order.By) []order.Order {
var orders []order.Order
for _, orderBy := range ordersBy {
orders = append(orders, order.NewOrder(orderBy))
}
return orders
}
func mergeResults(results []Result) Result {
var mergedResult Result
for _, result := range results {
mergedResult.shortLinks = append(mergedResult.shortLinks, result.shortLinks...)
mergedResult.users = append(mergedResult.users, result.users...)
}
return mergedResult
}
// NewSearch creates Search
func NewSearch(
shortLinkRepo repository.ShortLink,
userShortLinkRepo repository.UserShortLink,
timeout time.Duration,
) Search {
return Search{
shortLinkRepo: shortLinkRepo,
userShortLinkRepo: userShortLinkRepo,
timeout: timeout,
}
}