Commit 17a4d0447632580c46fe7bd46b54dd82dcca012b

Authored by Marko Tikvić
1 parent 3b2c2699fe
Exists in master and in 1 other branch v2

mutex lock for payloads

Showing 1 changed file with 4 additions and 0 deletions   Show diff stats
1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "encoding/json" 5 "encoding/json"
6 "errors" 6 "errors"
7 "gopkg.in/rana/ora.v3" 7 "gopkg.in/rana/ora.v3"
8 "io" 8 "io"
9 "io/ioutil" 9 "io/ioutil"
10 "sync"
10 ) 11 )
11 12
13 var mu = &sync.Mutex{}
12 var allPayloads []payloadBuff 14 var allPayloads []payloadBuff
13 15
14 type LangMap map[string]map[string]string 16 type LangMap map[string]map[string]string
15 17
16 type Field struct { 18 type Field struct {
17 Parameter string `json:"param"` 19 Parameter string `json:"param"`
18 Type string `json:"type"` 20 Type string `json:"type"`
19 Visible bool `json:"visible"` 21 Visible bool `json:"visible"`
20 Editable bool `json:"editable"` 22 Editable bool `json:"editable"`
21 } 23 }
22 24
23 type CorrelationField struct { 25 type CorrelationField struct {
24 Result string `json:"result"` 26 Result string `json:"result"`
25 Elements []string `json:"elements"` 27 Elements []string `json:"elements"`
26 Type string `json:"type"` 28 Type string `json:"type"`
27 } 29 }
28 30
29 type Translation struct { 31 type Translation struct {
30 Language string `json:"language"` 32 Language string `json:"language"`
31 FieldsLabels map[string]string `json:"fieldsLabels"` 33 FieldsLabels map[string]string `json:"fieldsLabels"`
32 } 34 }
33 35
34 // Field 'Type' is not required in payload. 36 // Field 'Type' is not required in payload.
35 // 'payloadBuff' type is only a bridge between ORACLE CLOB and 'Payload' type. 37 // 'payloadBuff' type is only a bridge between ORACLE CLOB and 'Payload' type.
36 type payloadBuff struct { 38 type payloadBuff struct {
37 Type string `json:"tableType"` 39 Type string `json:"tableType"`
38 Method string `json:"method"` 40 Method string `json:"method"`
39 Params map[string]string `json:"params"` 41 Params map[string]string `json:"params"`
40 Lang []Translation `json:"lang"` 42 Lang []Translation `json:"lang"`
41 Fields []Field `json:"fields"` 43 Fields []Field `json:"fields"`
42 Correlations []CorrelationField `json:"correlationFields"` 44 Correlations []CorrelationField `json:"correlationFields"`
43 IdField string `json:"idField"` 45 IdField string `json:"idField"`
44 // Data can only hold slices of any type. It can't be used for itteration 46 // Data can only hold slices of any type. It can't be used for itteration
45 Data interface{} `json:"data"` 47 Data interface{} `json:"data"`
46 } 48 }
47 49
48 type Payload struct { 50 type Payload struct {
49 Method string `json:"method"` 51 Method string `json:"method"`
50 Params map[string]string `json:"params"` 52 Params map[string]string `json:"params"`
51 Lang []Translation `json:"lang"` 53 Lang []Translation `json:"lang"`
52 Fields []Field `json:"fields"` 54 Fields []Field `json:"fields"`
53 Correlations []CorrelationField `json:"correlationFields"` 55 Correlations []CorrelationField `json:"correlationFields"`
54 IdField string `json:"idField"` 56 IdField string `json:"idField"`
55 // Data can only hold slices of any type. It can't be used for itteration 57 // Data can only hold slices of any type. It can't be used for itteration
56 Data interface{} `json:"data"` 58 Data interface{} `json:"data"`
57 } 59 }
58 60
59 func NewPayload(r *http.Request, table string) Payload { 61 func NewPayload(r *http.Request, table string) Payload {
60 var pload Payload 62 var pload Payload
61 63
62 pload.Method = r.Method + " " + r.URL.Path 64 pload.Method = r.Method + " " + r.URL.Path
63 65
64 if table != "" { 66 if table != "" {
65 pload.Params = make(map[string]string, 0) 67 pload.Params = make(map[string]string, 0)
66 pload.Lang = loadTranslations(table) 68 pload.Lang = loadTranslations(table)
67 pload.Fields = loadFields(table) 69 pload.Fields = loadFields(table)
68 pload.IdField = loadIdField(table) 70 pload.IdField = loadIdField(table)
69 pload.Correlations = loadCorrelations(table) 71 pload.Correlations = loadCorrelations(table)
70 } 72 }
71 73
72 return pload 74 return pload
73 } 75 }
74 76
75 func DeliverPayload(w http.ResponseWriter, payload Payload) { 77 func DeliverPayload(w http.ResponseWriter, payload Payload) {
76 json.NewEncoder(w).Encode(payload) 78 json.NewEncoder(w).Encode(payload)
77 payload.Data = nil 79 payload.Data = nil
78 } 80 }
79 81
80 func loadTranslations(id string) []Translation { 82 func loadTranslations(id string) []Translation {
81 translations := make([]Translation, 0) 83 translations := make([]Translation, 0)
82 84
83 for _, pload := range allPayloads { 85 for _, pload := range allPayloads {
84 if pload.Type == id { 86 if pload.Type == id {
85 for _, t := range pload.Lang { 87 for _, t := range pload.Lang {
86 //translations[t.Language] = t.FieldsLabels 88 //translations[t.Language] = t.FieldsLabels
87 translations = append(translations, Translation{ 89 translations = append(translations, Translation{
88 Language: t.Language, 90 Language: t.Language,
89 FieldsLabels: t.FieldsLabels, 91 FieldsLabels: t.FieldsLabels,
90 }) 92 })
91 } 93 }
92 } 94 }
93 } 95 }
94 96
95 return translations 97 return translations
96 } 98 }
97 99
98 func loadFields(id string) []Field { 100 func loadFields(id string) []Field {
99 fields := make([]Field, 0) 101 fields := make([]Field, 0)
100 102
101 for _, pload := range allPayloads { 103 for _, pload := range allPayloads {
102 if pload.Type == id{ 104 if pload.Type == id{
103 for _, f := range pload.Fields { 105 for _, f := range pload.Fields {
104 fields = append(fields, f) 106 fields = append(fields, f)
105 } 107 }
106 } 108 }
107 } 109 }
108 110
109 return fields 111 return fields
110 } 112 }
111 113
112 func loadIdField(id string) string { 114 func loadIdField(id string) string {
113 for _, pload := range allPayloads { 115 for _, pload := range allPayloads {
114 if pload.Type == id { 116 if pload.Type == id {
115 return pload.IdField 117 return pload.IdField
116 } 118 }
117 } 119 }
118 return "" 120 return ""
119 } 121 }
120 122
121 func loadCorrelations(id string) []CorrelationField { 123 func loadCorrelations(id string) []CorrelationField {
122 resp := make([]CorrelationField, 0) 124 resp := make([]CorrelationField, 0)
123 125
124 for _, pload := range allPayloads { 126 for _, pload := range allPayloads {
125 if pload.Type == id { 127 if pload.Type == id {
126 for _, f := range pload.Correlations { 128 for _, f := range pload.Correlations {
127 resp = append(resp, f) 129 resp = append(resp, f)
128 } 130 }
129 } 131 }
130 } 132 }
131 133
132 return resp 134 return resp
133 } 135 }
134 136
135 func InitTables(db *ora.Ses, project string) error { 137 func InitTables(db *ora.Ses, project string) error {
136 jsonbuf, _ := fetchJSON(db, EqualQuotes(project)) 138 jsonbuf, _ := fetchJSON(db, EqualQuotes(project))
139 mu.Lock()
140 defer mu.Unlock()
137 json.Unmarshal(jsonbuf, &allPayloads) 141 json.Unmarshal(jsonbuf, &allPayloads)
138 if len(allPayloads) == 0 { 142 if len(allPayloads) == 0 {
139 return errors.New("tables config is corrupt") 143 return errors.New("tables config is corrupt")
140 } 144 }
141 return nil 145 return nil
142 } 146 }
143 147
144 func fetchJSON(db *ora.Ses, project string) ([]byte, error) { 148 func fetchJSON(db *ora.Ses, project string) ([]byte, error) {
145 stmt, err := db.Prep(`SELECT 149 stmt, err := db.Prep(`SELECT
146 JSON_CLOB 150 JSON_CLOB
147 FROM TABLES_CONFIG 151 FROM TABLES_CONFIG
148 WHERE PROJEKAT` + project, ora.S) 152 WHERE PROJEKAT` + project, ora.S)
149 defer stmt.Close() 153 defer stmt.Close()
150 154
151 if err != nil { 155 if err != nil {
152 return nil, err 156 return nil, err
153 } 157 }
154 158
155 rset, err := stmt.Qry() 159 rset, err := stmt.Qry()
156 if err != nil { 160 if err != nil {
157 return nil, err 161 return nil, err
158 } 162 }
159 163
160 bytes := make([]byte, 0) 164 bytes := make([]byte, 0)
161 if rset.Next() { 165 if rset.Next() {
162 lob := rset.Row[0].(io.Reader) 166 lob := rset.Row[0].(io.Reader)
163 bytes, err = ioutil.ReadAll(lob) 167 bytes, err = ioutil.ReadAll(lob)
164 if err != nil { 168 if err != nil {
165 // Ignore for now, it's some weird streaming read/write LOB error. 169 // Ignore for now, it's some weird streaming read/write LOB error.
166 // TODO: Find a fix for this. 170 // TODO: Find a fix for this.
167 //return nil, err 171 //return nil, err
168 } 172 }
169 } 173 }
170 174
171 return bytes, nil 175 return bytes, nil
172 } 176 }
173 177
174 178