/
operation.go
156 lines (133 loc) · 4 KB
/
operation.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
package surveygo
import (
"encoding/json"
"fmt"
"github.com/rendis/surveygo/part"
)
// RemoveQuestion removes the question with the specified name ID from the survey
func (s *Survey) RemoveQuestion(nameId string) error {
// get the internal representation of the survey.
ins, err := s.getInternal()
if err != nil {
return err
}
// check if the internal representation is empty.
if ins == nil {
return fmt.Errorf("json survey is empty, title: '%s', version: '%s'", *s.Title, *s.Version)
}
// iterate through the questions to find the one with the specified name ID.
var found bool
for i, q := range ins.Questions {
if *q.NameId == nameId {
// remove the question from the slice of questions.
ins.Questions = append(ins.Questions[:i], ins.Questions[i+1:]...)
found = true
break
}
}
if !found {
return fmt.Errorf("question '%s' not found", nameId)
}
// update the internal representation of the survey.
return s.internalUpdate(ins)
}
// AddQuestionMap adds a question to the survey given its representation as a map[string]any
func (s *Survey) AddQuestionMap(question map[string]any) error {
b, _ := json.Marshal(question)
return s.AddQuestionBytes(b)
}
// AddQuestionJson adds a question to the survey given its representation as a JSON string
func (s *Survey) AddQuestionJson(question string) error {
return s.AddQuestionBytes([]byte(question))
}
// AddQuestionBytes adds a question to the survey given its representation as a byte array
func (s *Survey) AddQuestionBytes(question []byte) error {
var pq part.Question
err := json.Unmarshal(question, &pq)
if err != nil {
return err
}
if _, ok := s.NameIdPaths[*pq.NameId]; ok {
return fmt.Errorf("pq '%s' already exists", *pq.NameId)
}
ins, err := s.getInternal()
if err != nil {
return err
}
if ins == nil {
return fmt.Errorf("json survey is empty, title: '%s', version: '%s'", *s.Title, *s.Version)
}
ins.Questions = append(ins.Questions, pq)
return s.internalUpdate(ins)
}
// UpdateQuestionMap updates an existing question in the survey with the data provided as a map.
func (s *Survey) UpdateQuestionMap(question map[string]any) error {
b, _ := json.Marshal(question)
return s.UpdateQuestionBytes(b)
}
// UpdateQuestionJson updates an existing question in the survey with the data provided as a JSON string.
func (s *Survey) UpdateQuestionJson(question string) error {
return s.UpdateQuestionBytes([]byte(question))
}
// UpdateQuestionBytes updates a question in the survey given its representation as a byte array
func (s *Survey) UpdateQuestionBytes(question []byte) error {
var pq part.Question
err := json.Unmarshal(question, &pq)
if err != nil {
return err
}
ins, err := s.getInternal()
if err != nil {
return err
}
if ins == nil {
return fmt.Errorf("json survey is empty, title: '%s', version: '%s'", *s.Title, *s.Version)
}
var found bool
for i, q := range ins.Questions {
if *q.NameId == *pq.NameId {
ins.Questions[i] = pq
found = true
break
}
}
if !found {
return fmt.Errorf("pq '%s' not found", *pq.NameId)
}
return s.internalUpdate(ins)
}
// internalUpdate updates the survey after a modification to its internal representation
func (s *Survey) internalUpdate(ins *jsonSurvey) error {
// update the name ID paths because the internal representation has changed.
paths, required, err := ins.getNameIdPaths()
if err != nil {
return err
}
// update the full JSON survey
b, err := json.Marshal(ins)
if err != nil {
return err
}
js := string(b)
s.FullJsonSurvey = &js
s.NameIdPaths = paths
s.RequiredNameIds = required
return nil
}
// getInternal returns the internal representation of the survey as a jsonSurvey struct
func (s *Survey) getInternal() (*jsonSurvey, error) {
if s.FullJsonSurvey == nil {
return &jsonSurvey{
Title: s.Title,
Version: s.Version,
Description: s.Description,
Questions: []part.Question{},
}, nil
}
var ins jsonSurvey
err := json.Unmarshal([]byte(*s.FullJsonSurvey), &ins)
if err != nil {
return nil, err
}
return &ins, nil
}