package webutility import ( "net/http" "encoding/json" "errors" "io" //"io/ioutil" "sync" //"gopkg.in/rana/ora.v3" "gopkg.in/rana/ora.v4" ) var mu = &sync.Mutex{} var payloads []payloadBuff 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 payloadBuff struct { Type string `json:"tableType"` 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 can only hold slices of any type. It can't be used for itteration Data interface{} `json:"data"` } type Payload struct { 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 can only hold slices of any type. It can't be used for itteration Data interface{} `json:"data"` } // NewPayload returs a payload sceleton for provided table. func NewPayload(r *http.Request, table string) Payload { var pload Payload pload.Method = r.Method + " " + r.URL.Path 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 } // InitTables loads all payloads in the payloads variable. // Returns an error if it fails. func InitTables(db *ora.Ses, project string) error { jsonbuf, err := fetchJSON(db, project) if err != nil { return err } mu.Lock() defer mu.Unlock() json.Unmarshal([]byte(jsonbuf), &payloads) if len(payloads) == 0 { return errors.New("tables config is corrupt") } return nil } // 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) (string, error) { stmt, err := db.Prep(`SELECT JSON_CLOB FROM TABLES_CONFIG WHERE PROJEKAT` + EqualQuotes(project), ora.S) defer stmt.Close() if err != nil { return "", err } rset, err := stmt.Qry() if err != nil { return "", err } var data string if rset.Next() { data = rset.Row[0].(string) } return data, 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) }