Add functionality to build index for organisation

This commit is contained in:
2020-03-01 21:38:54 +11:00
parent 97e5caafd0
commit 2b6dcc36e8
7 changed files with 151 additions and 12 deletions
+2
View File
@@ -1,3 +1,5 @@
module github.com/wahyd4/zendesk
go 1.13
require github.com/davecgh/go-spew v1.1.1
+2
View File
@@ -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=
+14 -2
View File
@@ -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("---------------")
}
+33
View File
@@ -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
+82
View File
@@ -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
View File
@@ -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
View File
@@ -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
}