mirror of
https://github.com/wahyd4/zendesk.git
synced 2026-08-08 21:02:44 +10:00
Add functionality to build index for organisation
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
module github.com/wahyd4/zendesk
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/davecgh/go-spew v1.1.1
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -1,7 +1,19 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/wahyd4/zendesk/search"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("I am placeholder of application")
|
||||
|
||||
app := search.InitAPP("data/organizations.json", "data/users.json", "data/tickets.json")
|
||||
if err := app.Parse(); err != nil {
|
||||
panic("cannot load data: " + err.Error())
|
||||
}
|
||||
if err := app.BuildOrganisationIndex(); err != nil {
|
||||
panic("failed to build indexes: " + err.Error())
|
||||
}
|
||||
fmt.Println("---------------")
|
||||
}
|
||||
|
||||
@@ -1,15 +1,48 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/wahyd4/zendesk/model"
|
||||
)
|
||||
|
||||
const (
|
||||
OrganisationsKey = "organisations"
|
||||
UsersKey = "users"
|
||||
TicketsKey = "tickets"
|
||||
)
|
||||
|
||||
// APP represents the application
|
||||
type APP struct {
|
||||
jsonContents map[string][]byte
|
||||
organisations map[string]*model.Organisation
|
||||
users map[string]*model.User
|
||||
tickets map[string]*model.Ticket
|
||||
|
||||
organisationIndex map[string]map[string][]*model.Organisation
|
||||
// userIndex map[string]map[string][]*model.User
|
||||
// ticketIndex map[string]map[string][]*model.Ticket
|
||||
}
|
||||
|
||||
func InitAPP(organisationsFile, usersFile, ticketsFile string) *APP {
|
||||
files := map[string]string{
|
||||
OrganisationsKey: organisationsFile,
|
||||
UsersKey: usersFile,
|
||||
TicketsKey: ticketsFile,
|
||||
}
|
||||
jsonContents := make(map[string][]byte)
|
||||
for fileType, file := range files {
|
||||
bytes, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
panic("cannot init application due to unable to load:" + file)
|
||||
}
|
||||
jsonContents[fileType] = bytes
|
||||
}
|
||||
|
||||
return &APP{
|
||||
jsonContents: jsonContents,
|
||||
organisationIndex: make(map[string]map[string][]*model.Organisation),
|
||||
}
|
||||
}
|
||||
|
||||
// FindOrganisation find a organisation by organisation ID
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/wahyd4/zendesk/model"
|
||||
)
|
||||
|
||||
const (
|
||||
idKey = "_id"
|
||||
)
|
||||
|
||||
var (
|
||||
arrayKeys = []string{"domain_names", "tags"}
|
||||
booleanKeys = []string{"shared_tickets"}
|
||||
integerKeys = []string{"_id"}
|
||||
)
|
||||
|
||||
func (app *APP) BuildOrganisationIndex() error {
|
||||
bytes := app.jsonContents[OrganisationsKey]
|
||||
|
||||
var organisations []map[string]interface{}
|
||||
|
||||
err := json.Unmarshal(bytes, &organisations)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal json to organisations array: %w", err)
|
||||
}
|
||||
|
||||
if len(organisations) == 0 {
|
||||
return nil
|
||||
}
|
||||
searchIndex := app.organisationIndex
|
||||
organisationsTemplate := organisations[0]
|
||||
|
||||
for fieldKey := range organisationsTemplate {
|
||||
|
||||
for _, organisation := range organisations {
|
||||
organisationID := stringifyID(int(organisation[idKey].(float64)))
|
||||
|
||||
if searchIndex[fieldKey] == nil {
|
||||
searchIndex[fieldKey] = make(map[string][]*model.Organisation)
|
||||
}
|
||||
|
||||
fieldIndex := searchIndex[fieldKey]
|
||||
|
||||
fieldValues := make([]string, 0)
|
||||
|
||||
// process value based on different types
|
||||
if OneOfTheKeys(integerKeys, fieldKey) {
|
||||
fieldValues = append(fieldValues, stringifyID(int(organisation[fieldKey].(float64))))
|
||||
} else if OneOfTheKeys(booleanKeys, fieldKey) {
|
||||
fieldValues = append(fieldValues, fmt.Sprintf("%t", organisation[fieldKey].(bool)))
|
||||
} else if OneOfTheKeys(arrayKeys, fieldKey) {
|
||||
fieldValues = toStringSlice(organisation[fieldKey].([]interface{}))
|
||||
} else {
|
||||
fieldValues = append(fieldValues, organisation[fieldKey].(string))
|
||||
}
|
||||
|
||||
// build fieldValue based indeX
|
||||
for _, fieldValue := range fieldValues {
|
||||
if fieldIndex[fieldValue] == nil {
|
||||
sameValueList := make([]*model.Organisation, 0)
|
||||
fieldIndex[fieldValue] = sameValueList
|
||||
}
|
||||
|
||||
fieldIndex[fieldValue] = append(fieldIndex[fieldValue], app.FindOrganisation(organisationID))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func OneOfTheKeys(keys []string, target string) bool {
|
||||
for _, key := range keys {
|
||||
if key == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
+9
-9
@@ -13,9 +13,9 @@ type dataHandler func(jsonContent []byte) error
|
||||
// Parse parse all json contents and build all data and it's relationships into app
|
||||
func (app *APP) Parse() error {
|
||||
dataHandlers := map[string]dataHandler{
|
||||
"organisations": app.LoadOrganisationsFromJSON,
|
||||
"users": app.LoadUsersFromJSON,
|
||||
"tickets": app.LoadTicketsFromJSON,
|
||||
OrganisationsKey: app.LoadOrganisationsFromJSON,
|
||||
UsersKey: app.LoadUsersFromJSON,
|
||||
TicketsKey: app.LoadTicketsFromJSON,
|
||||
}
|
||||
|
||||
for dataType, dataHandler := range dataHandlers {
|
||||
@@ -63,7 +63,7 @@ func (app *APP) LoadTicketsFromJSON(jsonContent []byte) error {
|
||||
func convertOrganisationViews(views []*view.Organisation) map[string]*model.Organisation {
|
||||
models := make(map[string]*model.Organisation)
|
||||
for _, view := range views {
|
||||
models[stringID(view.ID)] = convertOrganisationView(view)
|
||||
models[stringifyID(view.ID)] = convertOrganisationView(view)
|
||||
}
|
||||
return models
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func convertOrganisationViews(views []*view.Organisation) map[string]*model.Orga
|
||||
func (app *APP) convertUserViews(views []*view.User) map[string]*model.User {
|
||||
models := make(map[string]*model.User)
|
||||
for _, view := range views {
|
||||
models[stringID(view.ID)] = app.convertUserView(view)
|
||||
models[stringifyID(view.ID)] = app.convertUserView(view)
|
||||
}
|
||||
return models
|
||||
}
|
||||
@@ -115,7 +115,7 @@ func (app *APP) convertUserView(view *view.User) *model.User {
|
||||
Email: view.Email,
|
||||
Phone: view.Phone,
|
||||
Signature: view.Signature,
|
||||
Organization: app.FindOrganisation(stringID(view.OrganizationID)),
|
||||
Organization: app.FindOrganisation(stringifyID(view.OrganizationID)),
|
||||
Tags: view.Tags,
|
||||
Suspended: view.Suspended,
|
||||
Role: view.Role,
|
||||
@@ -133,9 +133,9 @@ func (app *APP) convertTicketView(view *view.Ticket) *model.Ticket {
|
||||
Description: view.Description,
|
||||
Priority: view.Priority,
|
||||
Status: view.Status,
|
||||
Submitter: app.FindUser(stringID(view.SubmitterID)),
|
||||
Assignee: app.FindUser(stringID(view.AssigneeID)),
|
||||
Organization: app.FindOrganisation(stringID(view.OrganizationID)),
|
||||
Submitter: app.FindUser(stringifyID(view.SubmitterID)),
|
||||
Assignee: app.FindUser(stringifyID(view.AssigneeID)),
|
||||
Organization: app.FindOrganisation(stringifyID(view.OrganizationID)),
|
||||
Tags: view.Tags,
|
||||
HasIncidents: view.HasIncidents,
|
||||
DueAt: view.DueAt,
|
||||
|
||||
+9
-1
@@ -4,6 +4,14 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func stringID(id int) string {
|
||||
func stringifyID(id int) string {
|
||||
return fmt.Sprintf("%d", id)
|
||||
}
|
||||
|
||||
func toStringSlice(arr []interface{}) []string {
|
||||
result := make([]string, len(arr))
|
||||
for _, item := range arr {
|
||||
result = append(result, item.(string))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user