This repository has been archived by the owner on Jul 19, 2020. It is now read-only.
/
url_service.go
162 lines (132 loc) · 3.52 KB
/
url_service.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package service
import (
"context"
"strconv"
"github.com/hotstone-seo/hotstone-seo/server/repository"
"github.com/hotstone-seo/hotstone-seo/server/urlstore"
log "github.com/sirupsen/logrus"
"go.uber.org/dig"
)
// URLService contain logic of url [mock]
type URLService interface {
FullSync(context.Context) error
Sync(context.Context) error
Match(url string) (int64, map[string]string)
DumpTree() string
Get(path string, pvalues []string) (data interface{}, pnames []string)
Delete(id int64) bool
Insert(id int64, key string)
Update(id int64, key string)
Count() int
}
// NewURLService return new instance of URLService [constructor]
func NewURLService(svc repository.URLSyncRepo) URLService {
return &URLServiceImpl{
URLSyncRepo: svc,
Store: urlstore.NewStore(),
LatestVersion: 0,
}
}
// URLServiceImpl is implementation of URLService
type URLServiceImpl struct {
dig.In
repository.URLSyncRepo
urlstore.Store
LatestVersion int
}
// FullSync to sync from url-sync data to in-memory url-store from beginning
func (s *URLServiceImpl) FullSync(ctx context.Context) error {
list, err := s.Find(ctx)
if err != nil {
return err
}
if len(list) == 0 {
return nil
}
s.Store = urlstore.NewStore()
s.setStore(list)
oldestURLSync := list[len(list)-1]
s.LatestVersion = int(oldestURLSync.Version)
return nil
}
// Sync to from url-sync data to in-memory url-store based on diff
func (s *URLServiceImpl) Sync(ctx context.Context) error {
LatestVersionSync, err := s.GetLatestVersion(ctx)
if err != nil {
return err
}
if s.LatestVersion == int(LatestVersionSync) {
return nil
}
if s.LatestVersion != 0 && LatestVersionSync == 0 {
s.Store = urlstore.NewStore()
s.LatestVersion = int(LatestVersionSync)
return nil
}
if s.LatestVersion > int(LatestVersionSync) {
return s.FullSync(ctx)
}
if s.LatestVersion < int(LatestVersionSync) {
listDiffURLSync, err := s.GetListDiff(ctx, int64(s.LatestVersion))
if err != nil {
return err
}
s.setStore(listDiffURLSync)
oldestURLSync := listDiffURLSync[len(listDiffURLSync)-1]
s.LatestVersion = int(oldestURLSync.Version)
}
return nil
}
// Match return rule id and parameter map
func (s *URLServiceImpl) Match(url string) (int64, map[string]string) {
maxParams := 256
pvalues := make([]string, maxParams)
varValue := map[string]string{}
data, pnames := s.Store.Get(url, pvalues)
// fmt.Printf("[DATA:%s][PNAMES:%+v]", data, pnames)
if data == nil {
return -1, varValue
}
if len(pnames) > 0 {
for i, name := range pnames {
varValue[name] = pvalues[i]
}
}
idStr, ok := data.(string)
if !ok {
log.Warnf("[GetURL] Failed to cast data to string. data=%+v", data)
return -1, varValue
}
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
log.Warnf("[GetURL] Failed to convert string data to int. idStr=%+v", idStr)
return -1, varValue
}
return id, varValue
}
// Insert to store
func (s *URLServiceImpl) Insert(id int64, key string) {
data := strconv.FormatInt(id, 10)
s.Store.Add(id, key, data)
}
// Update store
func (s *URLServiceImpl) Update(id int64, key string) {
s.Delete(id)
s.Insert(id, key)
}
// DumpTree to debug purpose
func (s *URLServiceImpl) DumpTree() string {
return s.Store.String()
}
func (s *URLServiceImpl) setStore(listURLSync []*repository.URLSync) {
for _, sync := range listURLSync {
switch sync.Operation {
case "INSERT":
s.Insert(sync.RuleID, *sync.LatestURLPattern)
case "UPDATE":
s.Update(sync.RuleID, *sync.LatestURLPattern)
case "DELETE":
s.Store.Delete(sync.RuleID)
}
}
}