Commit 7c41a4c3ed0874ac24e53b7fd3aae69e099b53e4

Authored by Marko Tikvić
1 parent 437859ae90
Exists in master and in 1 other branch v2

added mutex lock for allPayloads

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