blob: 4036ad93368f89924ea9afad9c820eba72a75ccc [file] [log] [blame]
Tang Cheng641ea0a2015-07-22 11:57:45 +08001// message.go
2package swservice
3
4import (
5 "encoding/json"
6 "errors"
7 "fmt"
8 // "reflect"
9 "strconv"
10)
11
12type MessageWriter struct {
Tang Cheng78513ea2015-10-28 14:32:02 +080013 FuncNo int `json:"funcno"`
Tang Cheng641ea0a2015-07-22 11:57:45 +080014 Attributes map[string]interface{}
15 ColumnNames []string
16 ColumnDescs []string
17 RowData []map[string]interface{}
18 Row map[string]interface{}
19}
20
21func NewMessageWriter(funcno int) *MessageWriter {
22 return &MessageWriter{
23 FuncNo: funcno,
24 Attributes: make(map[string]interface{}),
25 ColumnNames: make([]string, 0),
26 ColumnDescs: make([]string, 0),
27 RowData: make([]map[string]interface{}, 0)}
28}
29func (m *MessageWriter) SetAttr(name string, value interface{}) {
30 m.Attributes[name] = value
31}
32func (m *MessageWriter) AddCol(name string, value interface{}) {
33 if m.Row == nil {
34 m.Row = make(map[string]interface{})
35 }
36 m.Row[name] = value
37}
38
39func is_contains(k string, slice []string) bool {
40 for _, v := range slice {
41 if k == v {
42 return true
43 }
44 }
45 return false
46}
47
48func (m *MessageWriter) AddRow() {
49 if m.Row == nil {
50 return
51 }
52 // data := make([]interface{}, 0)
53 // if len(m.ColumnNames) == 0 {
54 // for k, v := range m.Row {
55 // m.ColumnNames = append(m.ColumnNames, k)
56 // data = append(data, v)
57 // }
58 // } else {
59 // for _, n := range m.ColumnNames {
60 // if v, ok := m.Row[n]; !ok {
61 // data = append(data, nil)
62 // } else {
63 // data = append(data, v)
64 // }
65 // }
66 // for k, v := range m.Row {
67 // if !is_contains(k, m.ColumnNames) {
68 // m.ColumnNames = append(m.ColumnNames, k)
69 // data = append(data, v)
70 // }
71 // }
72 // }
73 // m.RowData = append(m.RowData, data)
74 m.RowData = append(m.RowData, m.Row)
75 m.Row = nil
76}
77
78func (m *MessageWriter) serialize_rowdata() {
79 m.ColumnNames = make([]string, 0)
80 for _, row := range m.RowData {
81 for k, _ := range row {
82 if !is_contains(k, m.ColumnNames) {
83 m.ColumnNames = append(m.ColumnNames, k)
84 }
85 }
86 }
87 rows := make([][]interface{}, 0)
88 for _, row := range m.RowData {
89 data := make([]interface{}, 0)
90 for _, k := range m.ColumnNames {
91 if v, ok := row[k]; !ok {
92 data = append(data, nil)
93 } else {
94 data = append(data, v)
95 }
96 }
97 rows = append(rows, data)
98 }
99 m.Attributes["rowdata"] = rows
100 m.Attributes["rowcnt"] = len(rows)
101}
102
103func (m *MessageWriter) Serialize() string {
104 m.Attributes["funcno"] = m.FuncNo
105 m.serialize_rowdata()
Tang Chengf16121a2015-07-27 13:46:14 +0800106 m.Attributes["colname"] = m.ColumnNames
107 m.Attributes["coldesc"] = m.ColumnNames
Tang Cheng641ea0a2015-07-22 11:57:45 +0800108 m.Attributes["colcnt"] = len(m.ColumnNames)
109 r, _ := json.Marshal(m.Attributes)
110 return string(r)
111}
112
113//////////////////////////////////////////////////////////////////////
114type MessageReader struct {
115 FuncNo int
116 RetCode int
117 RetMsg string
118 DBMsg string
119 ErrName string
120 ColumnNames []string
121 ColumnDescs []string
122 Attributes map[string]interface{}
123 RowData []map[string]interface{}
124 RowIndex int
125}
126
127func get_value_as_int(value interface{}) int {
128 // vtype := reflect.TypeOf(value)
129 switch value.(type) {
130 case int:
131 return value.(int)
132 case float64:
133 return int(value.(float64))
134 case string:
135 i, _ := strconv.Atoi(value.(string))
136 return i
137 default:
138 panic("Error")
139 }
140}
141
142func get_column_names(data interface{}) (result []string) {
143 if data == nil {
144 return nil
145 }
146 names := data.([]interface{})
147 result = make([]string, 0)
148 for _, v := range names {
149 result = append(result, v.(string))
150 }
151 return
152}
153
154func convert_to_int(value interface{}) int {
155 if value == nil {
156 return 0
157 }
158 switch value.(type) {
159 case int:
160 return value.(int)
161 case float64:
162 return int(value.(float64))
163 case string:
164 i, _ := strconv.Atoi(value.(string))
165 return i
166 default:
167 return 0
168 }
169}
170
171func convert_to_string(value interface{}) string {
172 if value == nil {
173 return ""
174 }
175 return fmt.Sprintf("%v", value)
176}
177
178func NewMessageReader(data []byte) *MessageReader {
179 var s interface{}
180 err := json.Unmarshal(data, &s)
181 if err != nil {
182 return nil
183 }
184 obj := s.(map[string]interface{})
185
186 m := &MessageReader{Attributes: make(map[string]interface{}),
187 RowData: make([]map[string]interface{}, 0)}
188 m.FuncNo = convert_to_int(obj["funcno"])
189 m.RetCode = convert_to_int(obj["retcode"])
190 m.RetMsg = convert_to_string(obj["retmsg"])
191 m.DBMsg = convert_to_string(obj["dbmsg"])
192 m.ErrName = convert_to_string(obj["errname"])
193
Tang Chengf16121a2015-07-27 13:46:14 +0800194 m.ColumnNames = get_column_names(obj["colname"])
195 m.ColumnDescs = get_column_names(obj["coldesc"])
Tang Cheng641ea0a2015-07-22 11:57:45 +0800196
197 if rowdata, err := obj["rowdata"]; err {
198 if rowdata != nil {
199 for _, raw := range rowdata.([]interface{}) {
200 row := raw.([]interface{})
201 data := make(map[string]interface{})
202 for idx, v := range row {
203 data[m.ColumnNames[idx]] = v
204 }
205 m.RowData = append(m.RowData, data)
206 }
207 }
208 }
209 reverseKey := map[string]bool{
Tang Chengf16121a2015-07-27 13:46:14 +0800210 "funcno": true,
211 "colname": true,
212 "coldesc": true,
213 "rowcnt": true,
214 "colcnt": true,
215 "rowdata": true,
216 "retcode": true,
217 "retmsg": true,
218 "dbmsg": true,
219 "errname": true}
Tang Cheng641ea0a2015-07-22 11:57:45 +0800220
221 for k, v := range obj {
222 if _, ok := reverseKey[k]; ok {
223 continue
224 }
225 m.Attributes[k] = v
226 }
227 return m
228}
229
230func (m *MessageReader) RowCount() int {
231 return len(m.RowData)
232}
233
234func (m *MessageReader) HasMore() bool {
235 return m.RowIndex < m.RowCount()
236}
237
238func (m *MessageReader) NextRow() error {
239 m.RowIndex++
240 if m.RowIndex > m.RowCount() {
241 return errors.New("Eof of row")
242 }
243 return nil
244}
245
246func (m *MessageReader) GetCol(name string) interface{} {
247 idx := m.RowIndex - 1
248 if v, ok := m.RowData[idx][name]; !ok {
249 return nil
250 } else {
251 return v
252 }
253}
254
255func (m *MessageReader) GetColAsInt(name string) int {
256 v := m.GetCol(name)
257 switch v.(type) {
258 case float32:
259 return int(v.(float32))
260 case float64:
261 return int(v.(float64))
262 case int:
263 return v.(int)
264 case string:
265 i, _ := strconv.Atoi(v.(string))
266 return i
267 default:
268 return 0
269 }
270}
271
272func (m *MessageReader) GetColAsString(name string) string {
273 v := m.GetCol(name)
274 return fmt.Sprintf("%v", v)
275}
276
277func (m *MessageReader) GetColAsDouble(name string) float64 {
278 v := m.GetCol(name)
279 switch v.(type) {
280 case float32:
281 return float64(v.(float32))
282 case float64:
283 return v.(float64)
284 case int:
285 return float64(v.(int))
286 case string:
287 i, _ := strconv.ParseFloat(v.(string), 64)
288 return i
289 default:
290 return 0
291 }
292}
293
294func (m *MessageReader) GetAttr(name string) interface{} {
295 if v, ok := m.Attributes[name]; !ok {
296 return nil
297 } else {
298 return v
299 }
300}