Blame view

json_utility.go 6.3 KB
ea858b8a7   Marko Tikvić   refactoring
1
  package webutility
64041a2ea   Marko Tikvić   first commit
2
3
  
  import (
8dbe745c3   Marko Tikvić   merged tables uti...
4
5
  	"encoding/json"
  	"errors"
66478e04f   Marko Tikvić   payload now retur...
6
  	"fmt"
8dbe745c3   Marko Tikvić   merged tables uti...
7
  	"io"
d2ddf82ef   Marko Tikvić   started on new rbac
8
  	"net/http"
2ea67927f   Marko Tikvić   added support for...
9
  	"os"
17a4d0447   Marko Tikvić   mutex lock for pa...
10
  	"sync"
2ea67927f   Marko Tikvić   added support for...
11
  	"time"
1d0f61553   Marko Tikvić   can't fetch clob
12

1d0f61553   Marko Tikvić   can't fetch clob
13
  	"gopkg.in/rana/ora.v4"
64041a2ea   Marko Tikvić   first commit
14
  )
2ea67927f   Marko Tikvić   added support for...
15
16
17
18
19
20
21
22
23
  var (
  	mu       = &sync.Mutex{}
  	metadata map[string]Payload
  
  	metadataDB    *ora.Ses
  	activeProject string
  
  	inited bool
  )
8dbe745c3   Marko Tikvić   merged tables uti...
24

64041a2ea   Marko Tikvić   first commit
25
26
27
  type LangMap map[string]map[string]string
  
  type Field struct {
d2ddf82ef   Marko Tikvić   started on new rbac
28
29
30
31
  	Parameter string `json:"param"`
  	Type      string `json:"type"`
  	Visible   bool   `json:"visible"`
  	Editable  bool   `json:"editable"`
64041a2ea   Marko Tikvić   first commit
32
  }
8dbe745c3   Marko Tikvić   merged tables uti...
33
34
35
36
37
38
39
  type CorrelationField struct {
  	Result   string   `json:"result"`
  	Elements []string `json:"elements"`
  	Type     string   `json:"type"`
  }
  
  type Translation struct {
ecec68b18   Marko Tikvić   updated todo list
40
  	Language     string            `json:"language"`
8dbe745c3   Marko Tikvić   merged tables uti...
41
  	FieldsLabels map[string]string `json:"fieldsLabels"`
64041a2ea   Marko Tikvić   first commit
42
  }
4a51e54d7   Marko Tikvić   simplified
43
  type Payload struct {
d2ddf82ef   Marko Tikvić   started on new rbac
44
45
46
47
  	Method       string             `json:"method"`
  	Params       map[string]string  `json:"params"`
  	Lang         []Translation      `json:"lang"`
  	Fields       []Field            `json:"fields"`
4a51e54d7   Marko Tikvić   simplified
48
49
  	Correlations []CorrelationField `json:"correlationFields"`
  	IdField      string             `json:"idField"`
e1fbb41f9   Marko Tikvić   added comments
50

66478e04f   Marko Tikvić   payload now retur...
51
  	// Data holds JSON payload. It can't be used for itteration.
d2ddf82ef   Marko Tikvić   started on new rbac
52
  	Data interface{} `json:"data"`
4a51e54d7   Marko Tikvić   simplified
53
  }
2ea67927f   Marko Tikvić   added support for...
54
55
56
57
  // LoadPayloadsdetaData loads all payloads' information into 'metadata' variable.
  func LoadPayloadsMetadata(db *ora.Ses, project string, hotloading bool, hlPeriod int) error {
  	metadataDB = db
  	activeProject = project
62a69beda   Marko Tikvić   Init/Reload Table...
58

2ea67927f   Marko Tikvić   added support for...
59
60
61
  	mu.Lock()
  	defer mu.Unlock()
  	err := initMetadata(project)
d66628295   Marko Tikvić   cleaned up
62
63
64
  	if err != nil {
  		return err
  	}
2ea67927f   Marko Tikvić   added support for...
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
  	if hotloading {
  		go hotload(hlPeriod)
  	}
  	inited = true
  
  	return nil
  }
  
  func UpdateMetadataModels(md map[string][]byte) (upd, add int, err error) {
  	if !inited {
  		return 0, 0, errors.New("webutil: metadata not initialized but update was tried.")
  	}
  
  	forUpdate := make([]string, 0)
  	forCreate := make([]string, 0)
  
  	for k, _ := range md {
  		if _, exists := metadata[k]; exists {
  			forUpdate = append(forUpdate, k)
  		} else {
  			forCreate = append(forCreate, k)
  		}
  	}
  
  	for _, k := range forUpdate {
  		fmt.Printf("for update: %s
  ", k)
  		_, err := metadataDB.PrepAndExe(`update entities set
  				entity_model = :1
  				where entity_type = :2`,
  			string(md[k]),
  			k)
  
  		if err != nil {
  			fmt.Printf("webutility: update metadata: prep and exe: %v
  ", err)
  			continue
  		}
  		upd++
  	}
  
  	for _, k := range forCreate {
  		fmt.Printf("for add: %s
  ", k)
  		/*
  			_, err := metadataDB.PrepAndExe(`insert into entities
  				(projekat, metadata, entity_type, entity_model)
  				values(:1, :2, :3, :4)`,
  				activeProject, "", k, string(md[k]))
  
  			if err != nil {
  				fmt.Printf("webutility: add metadata: prep and exe: %v
  ", err)
  				continue
  			}
  		*/
  		add++
  	}
  
  	return upd, add, nil
  }
  
  func GetMetadataForAllEntities() map[string]Payload {
  	return metadata
  }
  
  func GetMetadataForEntityType(t string) Payload {
  	return metadata[t]
  }
d66628295   Marko Tikvić   cleaned up
134

2ea67927f   Marko Tikvić   added support for...
135
136
137
138
139
140
141
  func UpdateMetadata(entityType string, p *Payload) error {
  	md, err := json.Marshal(p)
  	if err != nil {
  		return err
  	}
  	fmt.Printf("md: %s %s
  ", entityType, string(md))
d66628295   Marko Tikvić   cleaned up
142
143
  	mu.Lock()
  	defer mu.Unlock()
2ea67927f   Marko Tikvić   added support for...
144
145
146
147
148
149
150
151
152
  	_, err = metadataDB.PrepAndExe(`update entities set
  		metadata = :1
  		where projekat = :2
  		and entity_type = :3`,
  		string(md),
  		activeProject,
  		entityType)
  	if err != nil {
  		return err
d66628295   Marko Tikvić   cleaned up
153
154
155
156
157
158
159
160
161
  	}
  	return nil
  }
  
  // DecodeJSON decodes JSON data from r to v.
  // Returns an error if it fails.
  func DecodeJSON(r io.Reader, v interface{}) error {
  	return json.NewDecoder(r).Decode(v)
  }
2ea67927f   Marko Tikvić   added support for...
162
163
164
  // NewPayload returs a payload sceleton for entity described with etype.
  func NewPayload(r *http.Request, etype string) Payload {
  	pload := metadata[etype]
2d79a4120   Marko Tikvić   Responses contain...
165
  	pload.Method = r.Method + " " + r.RequestURI
8dbe745c3   Marko Tikvić   merged tables uti...
166
167
  	return pload
  }
64041a2ea   Marko Tikvić   first commit
168

2ea67927f   Marko Tikvić   added support for...
169
170
171
172
173
174
175
176
177
178
179
180
181
  func initMetadata(project string) error {
  	metadataDB.SetCfg(metadataDB.Cfg().SetClob(ora.S))
  	stmt, err := metadataDB.Prep(`select
  		entity_type,
  		metadata
  		from entities
  		where projekat = `+fmt.Sprintf("'%s'", project),
  		ora.S,
  		ora.S)
  
  	defer stmt.Close()
  	if err != nil {
  		return err
64041a2ea   Marko Tikvić   first commit
182
  	}
8dbe745c3   Marko Tikvić   merged tables uti...
183

2ea67927f   Marko Tikvić   added support for...
184
185
186
187
  	rset, err := stmt.Qry()
  	if err != nil {
  		return err
  	}
8dbe745c3   Marko Tikvić   merged tables uti...
188

2ea67927f   Marko Tikvić   added support for...
189
190
191
192
193
194
  	count := 0
  	success := 0
  	metadata = make(map[string]Payload)
  	for rset.Next() {
  		name := rset.Row[0].(string)
  		load := []byte(rset.Row[1].(string))
8dbe745c3   Marko Tikvić   merged tables uti...
195

2ea67927f   Marko Tikvić   added support for...
196
197
198
199
200
201
202
203
  		p := Payload{}
  		err := json.Unmarshal(load, &p)
  		if err != nil {
  			fmt.Printf("couldn't init: '%s' metadata
  ", name)
  		} else {
  			success++
  			metadata[name] = p
8dbe745c3   Marko Tikvić   merged tables uti...
204
  		}
2ea67927f   Marko Tikvić   added support for...
205
  		count++
8dbe745c3   Marko Tikvić   merged tables uti...
206
  	}
2ea67927f   Marko Tikvić   added support for...
207
208
209
  	fmt.Printf("webutility: successfully loaded %d/%d (%.1f%%) entities
  ",
  		success, count, float32(success)/float32(count)*100.0)
8dbe745c3   Marko Tikvić   merged tables uti...
210

2ea67927f   Marko Tikvić   added support for...
211
  	return nil
8dbe745c3   Marko Tikvić   merged tables uti...
212
  }
2ea67927f   Marko Tikvić   added support for...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  func hotload(n int) {
  	entityScan := make(map[string]int64)
  	firstCheck := true
  	for {
  		time.Sleep(time.Duration(n) * time.Second)
  		stmt, err := metadataDB.Prep(`select
  			ora_rowscn,
  			entity_type
  			from entities where projekat = `+fmt.Sprintf("'%s'", activeProject),
  			ora.I64,
  			ora.S)
  		if err != nil {
  			fmt.Fprintf(os.Stderr, "hotload failed: %v
  ", err)
  			time.Sleep(time.Duration(n) * time.Second)
  			continue
8dbe745c3   Marko Tikvić   merged tables uti...
229
  		}
8dbe745c3   Marko Tikvić   merged tables uti...
230

2ea67927f   Marko Tikvić   added support for...
231
232
233
234
235
236
237
  		rset, err := stmt.Qry()
  		if err != nil {
  			fmt.Fprintf(os.Stderr, "hotload failed: %v
  ", err)
  			time.Sleep(time.Duration(n) * time.Second)
  			continue
  		}
8dbe745c3   Marko Tikvić   merged tables uti...
238

2ea67927f   Marko Tikvić   added support for...
239
240
241
242
243
244
245
246
  		var toRefresh []string
  		for rset.Next() {
  			scanID := rset.Row[0].(int64)
  			entity := rset.Row[1].(string)
  			oldID, ok := entityScan[entity]
  			if !ok || oldID != scanID {
  				entityScan[entity] = scanID
  				toRefresh = append(toRefresh, entity)
8dbe745c3   Marko Tikvić   merged tables uti...
247
248
  			}
  		}
2ea67927f   Marko Tikvić   added support for...
249
  		stmt.Close()
8dbe745c3   Marko Tikvić   merged tables uti...
250

2ea67927f   Marko Tikvić   added support for...
251
252
253
254
255
256
  		if rset.Err() != nil {
  			fmt.Fprintf(os.Stderr, "hotload rset error: %v
  ", rset.Err())
  			time.Sleep(time.Duration(n) * time.Second)
  			continue
  		}
8dbe745c3   Marko Tikvić   merged tables uti...
257

2ea67927f   Marko Tikvić   added support for...
258
259
260
261
262
263
264
265
  		if len(toRefresh) > 0 && !firstCheck {
  			mu.Lock()
  			refreshMetadata(toRefresh)
  			mu.Unlock()
  		}
  		if firstCheck {
  			firstCheck = false
  		}
8dbe745c3   Marko Tikvić   merged tables uti...
266
  	}
2ea67927f   Marko Tikvić   added support for...
267
  }
8dbe745c3   Marko Tikvić   merged tables uti...
268

2ea67927f   Marko Tikvić   added support for...
269
270
271
272
273
274
275
276
277
278
  func refreshMetadata(entities []string) {
  	for _, e := range entities {
  		//fmt.Printf("refreshing %s
  ", e)
  		stmt, err := metadataDB.Prep(`select
  			metadata
  			from entities
  			where projekat = `+fmt.Sprintf("'%s'", activeProject)+
  			` and entity_type = `+fmt.Sprintf("'%s'", e),
  			ora.S)
8dbe745c3   Marko Tikvić   merged tables uti...
279

2ea67927f   Marko Tikvić   added support for...
280
281
282
283
284
285
  		if err != nil {
  			fmt.Printf("webutility: refresh: prep: %v
  ", err)
  			stmt.Close()
  			continue
  		}
64041a2ea   Marko Tikvić   first commit
286

2ea67927f   Marko Tikvić   added support for...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  		rset, err := stmt.Qry()
  		if err != nil {
  			fmt.Printf("webutility: refresh: query: %v
  ", err)
  			stmt.Close()
  			continue
  		}
  
  		for rset.Next() {
  			load := []byte(rset.Row[0].(string))
  			p := Payload{}
  			err := json.Unmarshal(load, &p)
  			if err != nil {
  				fmt.Printf("couldn't refresh: '%s' metadata
  ", e)
  			} else {
  				metadata[e] = p
  				//fmt.Printf("unmarshaled %s %v
  ", e, metadata[e])
  			}
  		}
  		stmt.Close()
  	}
64041a2ea   Marko Tikvić   first commit
310
  }