This repository has been archived by the owner on May 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindexer.go
79 lines (69 loc) · 2.13 KB
/
indexer.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
package bucket
import (
"context"
"log"
"reflect"
"github.com/couchbase/gocb"
)
const (
tagJSON = "json"
tagIndexable = "cb_indexable"
tagReferenced = "cb_referenced" // referenced tag represents external types for id-s
)
//Index runs trough the given interface v and creates secondary indexes for all the with indexable:"true" tags
func (h *Handler) Index(ctx context.Context, v interface{}) error {
if err := h.GetManager(ctx).CreatePrimaryIndex("", true, false); err != nil {
return err
}
t := reflect.TypeOf(v)
indexables := make(map[string][]string)
goDeep(t, indexables)
for key, val := range indexables {
if err := makeIndex(h.GetManager(ctx), key, val); err != nil {
return err
}
}
return nil
}
func goDeep(t reflect.Type, indexables map[string][]string) {
indexables[t.Name()] = []string{}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Type.Kind() == reflect.Struct {
goDeep(f.Type, indexables)
} else if f.Type.Kind() == reflect.Ptr && f.Type.Elem().Kind() == reflect.Struct {
goDeep(f.Type.Elem(), indexables)
}
if f.Tag != "" {
if json := removeOmitempty(f.Tag.Get(tagJSON)); json != "" && json != "-" {
if f.Tag.Get(tagIndexable) != "" {
indexables[t.Name()] = append(indexables[t.Name()], json)
}
}
}
}
if len(indexables[t.Name()]) == 0 {
delete(indexables, t.Name())
}
}
func makeIndex(manager *gocb.BucketManager, indexName string, indexedFields []string) error {
if err := manager.CreateIndex(indexName, indexedFields, false, false); err != nil {
if err == gocb.ErrIndexAlreadyExists {
return dropAndCreateIndex(manager, indexName, indexedFields)
}
log.Printf("Error when create secondary index %+v", err)
return err
}
return nil
}
func dropAndCreateIndex(manager *gocb.BucketManager, indexName string, indexedFields []string) error {
if err := manager.DropIndex(indexName, true); err != nil {
log.Printf("Error when dropping index[%s] %+v", indexName, err)
return err
}
if err := manager.CreateIndex(indexName, indexedFields, false, false); err != nil {
log.Printf("Error when create secondary index %+v", err)
return err
}
return nil
}