package webutility import ( "encoding/json" "errors" "fmt" "io" "net/http" "sync" "gopkg.in/rana/ora.v4" ) var mu = &sync.Mutex{} var payloads []Payload type LangMap map[string]map[string]string type Field struct { Parameter string `json:"param"` Type string `json:"type"` Visible bool `json:"visible"` Editable bool `json:"editable"` } type CorrelationField struct { Result string `json:"result"` Elements []string `json:"elements"` Type string `json:"type"` } type Translation struct { Language string `json:"language"` FieldsLabels map[string]string `json:"fieldsLabels"` } type Payload struct { Type string `json:"type"` Method string `json:"method"` Params map[string]string `json:"params"` Lang []Translation `json:"lang"` Fields []Field `json:"fields"` Correlations []CorrelationField `json:"correlationFields"` IdField string `json:"idField"` // Data holds JSON payload. It can't be used for itteration. Data interface{} `json:"data"` } // InitPayloadsMetaData loads all payloads in the payloads variable. // Returns an error if it fails. func InitPayloadsMetaData(db *ora.Ses, project string) error { payloads = make([]Payload, 0) jsonbuf, err := fetchJSON(db, project) if err != nil { return err } mu.Lock() defer mu.Unlock() json.Unmarshal(jsonbuf, &payloads) if len(payloads) == 0 { return errors.New("tables config is corrupt") } 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) } // NewPayload returs a payload sceleton for provided table. func NewPayload(r *http.Request, table string) Payload { var pload Payload pload.Method = r.Method + " " + r.RequestURI pload.Type = table if table != "" { pload.Params = make(map[string]string, 0) pload.Lang = translations(table) pload.Fields = fields(table) pload.IdField = id(table) pload.Correlations = correlations(table) } return pload } // DeliverPayload encodes payload to w. func DeliverPayload(w http.ResponseWriter, payload Payload) { json.NewEncoder(w).Encode(payload) payload.Data = nil } // translations returns a slice of translations for a payload/table of ptype type. func translations(ptype string) []Translation { var translations []Translation for _, pload := range payloads { if pload.Type == ptype { for _, t := range pload.Lang { translations = append(translations, Translation{ Language: t.Language, FieldsLabels: t.FieldsLabels, }) } } } return translations } // fields returns a slice of fields for a payload/table of ptype type. func fields(ptype string) []Field { var fields []Field for _, pload := range payloads { if pload.Type == ptype { for _, f := range pload.Fields { fields = append(fields, f) } } } return fields } // id returns the name of ID field of a payload/table of ptype type. func id(ptype string) string { for _, pload := range payloads { if pload.Type == ptype { return pload.IdField } } return "" } // correlations returns a slice of correlation fields for a payload/table of ptype type. func correlations(ptype string) []CorrelationField { var corr []CorrelationField for _, pload := range payloads { if pload.Type == ptype { for _, c := range pload.Correlations { corr = append(corr, c) } } } return corr } // fetchJSON returns a byte slice of JSON configuration file from TABLES_CONFIG table. // Returns an error if it fails. func fetchJSON(db *ora.Ses, project string) ([]byte, error) { db.SetCfg(db.Cfg().SetClob(ora.S)) stmt, err := db.Prep(`SELECT JSON_NCLOB FROM TABLES_CONFIG WHERE PROJEKAT = `+fmt.Sprintf("'%s'", project), ora.S) defer stmt.Close() if err != nil { return nil, err } rset, err := stmt.Qry() if err != nil { return nil, err } var data string if rset.Next() { data = rset.Row[0].(string) } //fmt.Println(data) return []byte(data), nil }