Commit d66628295471b832e377f7a6867a083f9f771b82
1 parent
1769d6d42e
Exists in
master
and in
1 other branch
cleaned up
Showing
5 changed files
with
65 additions
and
69 deletions
Show diff stats
http_utility.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "encoding/json" | 4 | "encoding/json" |
5 | "net/http" | 5 | "net/http" |
6 | ) | 6 | ) |
7 | 7 | ||
8 | const templateHttpErr500_EN = "An internal server error has occurred." | 8 | const ( |
9 | const templateHttpErr500_RS = "Došlo je do greške na serveru." | 9 | templateHttpErr500_EN = "An internal server error has occurred." |
10 | const templateHttpErr400_EN = "Bad request: invalid request body." | 10 | templateHttpErr500_RS = "Došlo je do greške na serveru." |
11 | const templateHttpErr400_RS = "Neispravan zahtev." | 11 | templateHttpErr400_EN = "Bad request: invalid request body." |
12 | const templateHttpErr401_EN = "Unauthorized request." | 12 | templateHttpErr400_RS = "Neispravan zahtev." |
13 | const templateHttpErr401_RS = "Neautorizovan zahtev." | 13 | templateHttpErr401_EN = "Unauthorized request." |
14 | templateHttpErr401_RS = "Neautorizovan zahtev." | ||
15 | ) | ||
14 | 16 | ||
15 | type httpError struct { | 17 | type httpError struct { |
16 | Error []HttpErrorDesc `json:"error"` | 18 | Error []HttpErrorDesc `json:"error"` |
17 | Request string `json:"request"` | 19 | Request string `json:"request"` |
18 | } | 20 | } |
19 | 21 | ||
20 | type HttpErrorDesc struct { | 22 | type HttpErrorDesc struct { |
21 | Lang string `json:"lang"` | 23 | Lang string `json:"lang"` |
22 | Desc string `json:"description"` | 24 | Desc string `json:"description"` |
23 | } | 25 | } |
24 | 26 | ||
25 | // ErrorResponse writes HTTP error to w. | 27 | // ErrorResponse writes HTTP error to w. |
26 | func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) { | 28 | func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) { |
27 | err := httpError{desc, r.Method + " " + r.URL.Path} | 29 | err := httpError{desc, r.Method + " " + r.URL.Path} |
28 | w.WriteHeader(code) | 30 | w.WriteHeader(code) |
29 | json.NewEncoder(w).Encode(err) | 31 | json.NewEncoder(w).Encode(err) |
30 | } | 32 | } |
31 | 33 | ||
32 | // BadRequestResponse writes HTTP error 400 to w. | 34 | // BadRequestResponse writes HTTP error 400 to w. |
33 | func BadRequestResponse(w http.ResponseWriter, req *http.Request) { | 35 | func BadRequestResponse(w http.ResponseWriter, req *http.Request) { |
34 | ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{ | 36 | ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{ |
35 | {"en", templateHttpErr400_EN}, | 37 | {"en", templateHttpErr400_EN}, |
36 | {"rs", templateHttpErr400_RS}, | 38 | {"rs", templateHttpErr400_RS}, |
37 | }) | 39 | }) |
38 | } | 40 | } |
39 | 41 | ||
40 | // InternalSeverErrorResponse writes HTTP error 500 to w. | 42 | // InternalSeverErrorResponse writes HTTP error 500 to w. |
41 | func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { | 43 | func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { |
42 | ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{ | 44 | ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{ |
43 | {"en", templateHttpErr500_EN}, | 45 | {"en", templateHttpErr500_EN}, |
44 | {"rs", templateHttpErr500_RS}, | 46 | {"rs", templateHttpErr500_RS}, |
45 | }) | 47 | }) |
46 | } | 48 | } |
47 | 49 | ||
48 | // UnauthorizedError writes HTTP error 401 to w. | 50 | // UnauthorizedError writes HTTP error 401 to w. |
49 | func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { | 51 | func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { |
50 | ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{ | 52 | ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{ |
51 | {"en", templateHttpErr401_EN}, | 53 | {"en", templateHttpErr401_EN}, |
52 | {"rs", templateHttpErr401_RS}, | 54 | {"rs", templateHttpErr401_RS}, |
53 | }) | 55 | }) |
54 | } | 56 | } |
55 | 57 | ||
56 | // NotFoundHandler writes HTTP error 404 to w. | 58 | // NotFoundHandler writes HTTP error 404 to w. |
57 | func NotFoundHandler(w http.ResponseWriter, req *http.Request) { | 59 | func NotFoundHandler(w http.ResponseWriter, req *http.Request) { |
58 | SetDefaultHeaders(w) | 60 | SetDefaultHeaders(w) |
59 | if req.Method == "OPTIONS" { | 61 | if req.Method == "OPTIONS" { |
60 | return | 62 | return |
61 | } | 63 | } |
62 | ErrorResponse(w, req, http.StatusNotFound, []HttpErrorDesc{ | 64 | ErrorResponse(w, req, http.StatusNotFound, []HttpErrorDesc{ |
63 | {"en", "Not found."}, | 65 | {"en", "Not found."}, |
64 | {"rs", "Traženi resurs ne postoji."}, | 66 | {"rs", "Traženi resurs ne postoji."}, |
65 | }) | 67 | }) |
66 | } | 68 | } |
67 | 69 | ||
70 | // SetDefaultHeaders set's default headers for an HTTP response. | ||
68 | func SetDefaultHeaders(w http.ResponseWriter) { | 71 | func SetDefaultHeaders(w http.ResponseWriter) { |
69 | w.Header().Set("Access-Control-Allow-Origin", "*") | 72 | w.Header().Set("Access-Control-Allow-Origin", "*") |
70 | 73 | ||
71 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") | 74 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") |
72 | 75 | ||
73 | w.Header().Set("Access-Control-Allow-Headers", `Accept, Content-Type, | 76 | w.Header().Set("Access-Control-Allow-Headers", `Accept, Content-Type, |
74 | Content-Length, Accept-Encoding, X-CSRF-Token, Authorization`) | 77 | Content-Length, Accept-Encoding, X-CSRF-Token, Authorization`) |
75 | 78 | ||
76 | w.Header().Set("Content-Type", "application/json; charset=utf-8") | 79 | w.Header().Set("Content-Type", "application/json; charset=utf-8") |
77 | } | 80 | } |
78 | 81 |
json_utility.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | //"fmt" | ||
5 | "encoding/json" | 4 | "encoding/json" |
6 | "errors" | 5 | "errors" |
7 | "io" | 6 | "io" |
8 | "net/http" | 7 | "net/http" |
9 | //"io/ioutil" | ||
10 | "sync" | 8 | "sync" |
11 | 9 | ||
12 | //"gopkg.in/rana/ora.v3" | ||
13 | "gopkg.in/rana/ora.v4" | 10 | "gopkg.in/rana/ora.v4" |
14 | ) | 11 | ) |
15 | 12 | ||
16 | var mu = &sync.Mutex{} | 13 | var mu = &sync.Mutex{} |
17 | var payloads []payloadBuff | 14 | var payloads []payloadBuff |
18 | 15 | ||
19 | type LangMap map[string]map[string]string | 16 | type LangMap map[string]map[string]string |
20 | 17 | ||
21 | type Field struct { | 18 | type Field struct { |
22 | Parameter string `json:"param"` | 19 | Parameter string `json:"param"` |
23 | Type string `json:"type"` | 20 | Type string `json:"type"` |
24 | Visible bool `json:"visible"` | 21 | Visible bool `json:"visible"` |
25 | Editable bool `json:"editable"` | 22 | Editable bool `json:"editable"` |
26 | } | 23 | } |
27 | 24 | ||
28 | type CorrelationField struct { | 25 | type CorrelationField struct { |
29 | Result string `json:"result"` | 26 | Result string `json:"result"` |
30 | Elements []string `json:"elements"` | 27 | Elements []string `json:"elements"` |
31 | Type string `json:"type"` | 28 | Type string `json:"type"` |
32 | } | 29 | } |
33 | 30 | ||
34 | type Translation struct { | 31 | type Translation struct { |
35 | Language string `json:"language"` | 32 | Language string `json:"language"` |
36 | FieldsLabels map[string]string `json:"fieldsLabels"` | 33 | FieldsLabels map[string]string `json:"fieldsLabels"` |
37 | } | 34 | } |
38 | 35 | ||
39 | type payloadBuff struct { | 36 | type payloadBuff struct { |
40 | Type string `json:"tableType"` | 37 | Type string `json:"tableType"` |
41 | Method string `json:"method"` | 38 | Method string `json:"method"` |
42 | Params map[string]string `json:"params"` | 39 | Params map[string]string `json:"params"` |
43 | Lang []Translation `json:"lang"` | 40 | Lang []Translation `json:"lang"` |
44 | Fields []Field `json:"fields"` | 41 | Fields []Field `json:"fields"` |
45 | Correlations []CorrelationField `json:"correlationFields"` | 42 | Correlations []CorrelationField `json:"correlationFields"` |
46 | IdField string `json:"idField"` | 43 | IdField string `json:"idField"` |
47 | 44 | ||
48 | // Data can only hold slices of any type. It can't be used for itteration | 45 | // Data can only hold slices of any type. It can't be used for itteration |
49 | Data interface{} `json:"data"` | 46 | Data interface{} `json:"data"` |
50 | } | 47 | } |
51 | 48 | ||
52 | type Payload struct { | 49 | type Payload struct { |
53 | Method string `json:"method"` | 50 | Method string `json:"method"` |
54 | Params map[string]string `json:"params"` | 51 | Params map[string]string `json:"params"` |
55 | Lang []Translation `json:"lang"` | 52 | Lang []Translation `json:"lang"` |
56 | Fields []Field `json:"fields"` | 53 | Fields []Field `json:"fields"` |
57 | Correlations []CorrelationField `json:"correlationFields"` | 54 | Correlations []CorrelationField `json:"correlationFields"` |
58 | IdField string `json:"idField"` | 55 | IdField string `json:"idField"` |
59 | 56 | ||
60 | // Data can only hold slices of any type. It can't be used for itteration | 57 | // Data contains JSON payload. |
58 | // It can't be used for itteration | ||
61 | Data interface{} `json:"data"` | 59 | Data interface{} `json:"data"` |
62 | } | 60 | } |
63 | 61 | ||
62 | // InitTables loads all payloads in the payloads variable. | ||
63 | // Returns an error if it fails. | ||
64 | func InitTables(db *ora.Ses, project string) error { | ||
65 | jsonbuf, err := fetchJSON(db, project) | ||
66 | if err != nil { | ||
67 | return err | ||
68 | } | ||
69 | |||
70 | mu.Lock() | ||
71 | defer mu.Unlock() | ||
72 | json.Unmarshal(jsonbuf, &payloads) | ||
73 | if len(payloads) == 0 { | ||
74 | return errors.New("tables config is corrupt") | ||
75 | } | ||
76 | return nil | ||
77 | } | ||
78 | |||
79 | // DecodeJSON decodes JSON data from r to v. | ||
80 | // Returns an error if it fails. | ||
81 | func DecodeJSON(r io.Reader, v interface{}) error { | ||
82 | return json.NewDecoder(r).Decode(v) | ||
83 | } | ||
84 | |||
64 | // NewPayload returs a payload sceleton for provided table. | 85 | // NewPayload returs a payload sceleton for provided table. |
65 | func NewPayload(r *http.Request, table string) Payload { | 86 | func NewPayload(r *http.Request, table string) Payload { |
66 | var pload Payload | 87 | var pload Payload |
67 | 88 | ||
68 | pload.Method = r.Method + " " + r.URL.Path | 89 | pload.Method = r.Method + " " + r.URL.Path |
69 | if table != "" { | 90 | if table != "" { |
70 | pload.Params = make(map[string]string, 0) | 91 | pload.Params = make(map[string]string, 0) |
71 | pload.Lang = translations(table) | 92 | pload.Lang = translations(table) |
72 | pload.Fields = fields(table) | 93 | pload.Fields = fields(table) |
73 | pload.IdField = id(table) | 94 | pload.IdField = id(table) |
74 | pload.Correlations = correlations(table) | 95 | pload.Correlations = correlations(table) |
75 | } | 96 | } |
76 | return pload | 97 | return pload |
77 | } | 98 | } |
78 | 99 | ||
79 | // DeliverPayload encodes payload to w. | 100 | // DeliverPayload encodes payload to w. |
80 | func DeliverPayload(w http.ResponseWriter, payload Payload) { | 101 | func DeliverPayload(w http.ResponseWriter, payload Payload) { |
81 | json.NewEncoder(w).Encode(payload) | 102 | json.NewEncoder(w).Encode(payload) |
82 | payload.Data = nil | 103 | payload.Data = nil |
83 | } | 104 | } |
84 | 105 | ||
85 | // translations returns a slice of translations for a payload/table of ptype type. | 106 | // translations returns a slice of translations for a payload/table of ptype type. |
86 | func translations(ptype string) []Translation { | 107 | func translations(ptype string) []Translation { |
87 | var translations []Translation | 108 | var translations []Translation |
88 | 109 | ||
89 | for _, pload := range payloads { | 110 | for _, pload := range payloads { |
90 | if pload.Type == ptype { | 111 | if pload.Type == ptype { |
91 | for _, t := range pload.Lang { | 112 | for _, t := range pload.Lang { |
92 | translations = append(translations, Translation{ | 113 | translations = append(translations, Translation{ |
93 | Language: t.Language, | 114 | Language: t.Language, |
94 | FieldsLabels: t.FieldsLabels, | 115 | FieldsLabels: t.FieldsLabels, |
95 | }) | 116 | }) |
96 | } | 117 | } |
97 | } | 118 | } |
98 | } | 119 | } |
99 | 120 | ||
100 | return translations | 121 | return translations |
101 | } | 122 | } |
102 | 123 | ||
103 | // fields returns a slice of fields for a payload/table of ptype type. | 124 | // fields returns a slice of fields for a payload/table of ptype type. |
104 | func fields(ptype string) []Field { | 125 | func fields(ptype string) []Field { |
105 | var fields []Field | 126 | var fields []Field |
106 | 127 | ||
107 | for _, pload := range payloads { | 128 | for _, pload := range payloads { |
108 | if pload.Type == ptype { | 129 | if pload.Type == ptype { |
109 | for _, f := range pload.Fields { | 130 | for _, f := range pload.Fields { |
110 | fields = append(fields, f) | 131 | fields = append(fields, f) |
111 | } | 132 | } |
112 | } | 133 | } |
113 | } | 134 | } |
114 | 135 | ||
115 | return fields | 136 | return fields |
116 | } | 137 | } |
117 | 138 | ||
118 | // id returns the name of ID field of a payload/table of ptype type. | 139 | // id returns the name of ID field of a payload/table of ptype type. |
119 | func id(ptype string) string { | 140 | func id(ptype string) string { |
120 | for _, pload := range payloads { | 141 | for _, pload := range payloads { |
121 | if pload.Type == ptype { | 142 | if pload.Type == ptype { |
122 | return pload.IdField | 143 | return pload.IdField |
123 | } | 144 | } |
124 | } | 145 | } |
125 | return "" | 146 | return "" |
126 | } | 147 | } |
127 | 148 | ||
128 | // correlations returns a slice of correlation fields for a payload/table of ptype type. | 149 | // correlations returns a slice of correlation fields for a payload/table of ptype type. |
129 | func correlations(ptype string) []CorrelationField { | 150 | func correlations(ptype string) []CorrelationField { |
130 | var corr []CorrelationField | 151 | var corr []CorrelationField |
131 | 152 | ||
132 | for _, pload := range payloads { | 153 | for _, pload := range payloads { |
133 | if pload.Type == ptype { | 154 | if pload.Type == ptype { |
134 | for _, c := range pload.Correlations { | 155 | for _, c := range pload.Correlations { |
135 | corr = append(corr, c) | 156 | corr = append(corr, c) |
136 | } | 157 | } |
137 | } | 158 | } |
138 | } | 159 | } |
139 | 160 | ||
140 | return corr | 161 | return corr |
141 | } | 162 | } |
142 | 163 | ||
143 | // InitTables loads all payloads in the payloads variable. | ||
144 | // Returns an error if it fails. | ||
145 | func InitTables(db *ora.Ses, project string) error { | ||
146 | jsonbuf, err := fetchJSON(db, project) | ||
147 | if err != nil { | ||
148 | return err | ||
149 | } | ||
150 | |||
151 | mu.Lock() | ||
152 | defer mu.Unlock() | ||
153 | json.Unmarshal(jsonbuf, &payloads) | ||
154 | if len(payloads) == 0 { | ||
155 | return errors.New("tables config is corrupt") | ||
156 | } | ||
157 | return nil | ||
158 | } | ||
159 | |||
160 | // fetchJSON returns a byte slice of JSON configuration file from TABLES_CONFIG table. | 164 | // fetchJSON returns a byte slice of JSON configuration file from TABLES_CONFIG table. |
161 | // Returns an error if it fails. | 165 | // Returns an error if it fails. |
162 | func fetchJSON(db *ora.Ses, project string) ([]byte, error) { | 166 | func fetchJSON(db *ora.Ses, project string) ([]byte, error) { |
163 | db.SetCfg(db.Cfg().SetClob(ora.S)) | 167 | db.SetCfg(db.Cfg().SetClob(ora.S)) |
164 | stmt, err := db.Prep(`SELECT JSON_NCLOB FROM TABLES_CONFIG WHERE PROJEKAT`+EqualQuotes(project), ora.S) | 168 | stmt, err := db.Prep(`SELECT JSON_NCLOB FROM TABLES_CONFIG WHERE PROJEKAT`+EqualQuotes(project), ora.S) |
165 | defer stmt.Close() | 169 | defer stmt.Close() |
list_config.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | //import "gopkg.in/rana/ora.v3" | ||
4 | import "gopkg.in/rana/ora.v4" | 3 | import "gopkg.in/rana/ora.v4" |
5 | 4 | ||
6 | type ListOptions struct { | 5 | type ListOptions struct { |
7 | GlobalFilter bool `json:"globalFilter"` | 6 | GlobalFilter bool `json:"globalFilter"` |
8 | LocalFilters bool `json:"localFilters"` | 7 | LocalFilters bool `json:"localFilters"` |
9 | RemoteFilters bool `json:"remoteFilters"` | 8 | RemoteFilters bool `json:"remoteFilters"` |
10 | Pagination bool `json:"pagination"` | 9 | Pagination bool `json:"pagination"` |
11 | PageSize uint64 `json:"pageSize"` | 10 | PageSize uint64 `json:"pageSize"` |
12 | Pivot bool `json:"pivot"` | 11 | Pivot bool `json:"pivot"` |
13 | Detail bool `json:"detail"` | 12 | Detail bool `json:"detail"` |
14 | Total bool `json:"total"` | 13 | Total bool `json:"total"` |
15 | } | 14 | } |
16 | 15 | ||
17 | type ListFilter struct { | 16 | type ListFilter struct { |
18 | Position uint32 `json:"-"` | 17 | Position uint32 `json:"-"` |
19 | ObjectType string `json:"-"` | 18 | ObjectType string `json:"-"` |
20 | FiltersField string `json:"filtersField"` | 19 | FiltersField string `json:"filtersField"` |
21 | DefaultValues string `json:"defaultValues"` | 20 | DefaultValues string `json:"defaultValues"` |
22 | FiltersType string `json:"filtersType"` | 21 | FiltersType string `json:"filtersType"` |
23 | FiltersLabel string `json:"filtersLabel"` | 22 | FiltersLabel string `json:"filtersLabel"` |
24 | DropdownConfig Dropdown `json:"dropdownConfig"` | 23 | DropdownConfig Dropdown `json:"dropdownConfig"` |
25 | } | 24 | } |
26 | 25 | ||
27 | type Dropdown struct { | 26 | type Dropdown struct { |
28 | ObjectType string `json:"objectType"` | 27 | ObjectType string `json:"objectType"` |
29 | FiltersField string `json:"filtersField"` | 28 | FiltersField string `json:"filtersField"` |
30 | IDField string `json:"idField"` | 29 | IDField string `json:"idField"` |
31 | LabelField string `json:"labelField"` | 30 | LabelField string `json:"labelField"` |
32 | |||
33 | } | 31 | } |
34 | 32 | ||
35 | type ListGraph struct { | 33 | type ListGraph struct { |
36 | ObjectType string `json:"objectType"` | 34 | ObjectType string `json:"objectType"` |
37 | X string `json:"xField"` | 35 | X string `json:"xField"` |
38 | Y string `json:"yField"` | 36 | Y string `json:"yField"` |
39 | GroupField string `json:"groupField"` | 37 | GroupField string `json:"groupField"` |
40 | Label string `json:"label"` | 38 | Label string `json:"label"` |
41 | } | 39 | } |
42 | 40 | ||
43 | type ListActions struct { | 41 | type ListActions struct { |
44 | Create bool `json:"create"` | 42 | Create bool `json:"create"` |
45 | Update bool `json:"update"` | 43 | Update bool `json:"update"` |
46 | Delete bool `json:"delete"` | 44 | Delete bool `json:"delete"` |
47 | Export bool `json:"export"` | 45 | Export bool `json:"export"` |
48 | Print bool `json:"print"` | 46 | Print bool `json:"print"` |
49 | Graph bool `json:"graph"` | 47 | Graph bool `json:"graph"` |
50 | } | 48 | } |
51 | 49 | ||
52 | type ListNavNode struct { | 50 | type ListNavNode struct { |
53 | ObjectType string `json:"objectType"` | 51 | ObjectType string `json:"objectType"` |
54 | LabelField string `json:"label"` | 52 | LabelField string `json:"label"` |
55 | Icon string `json:"icon"` | 53 | Icon string `json:"icon"` |
56 | ParentObjectType string `json:"parentObjectType"` | 54 | ParentObjectType string `json:"parentObjectType"` |
57 | ParentIDField string `json:"parentIdField"` | 55 | ParentIDField string `json:"parentIdField"` |
58 | ParentFilterField string `json:"parentFilterField"` | 56 | ParentFilterField string `json:"parentFilterField"` |
59 | } | 57 | } |
60 | 58 | ||
61 | type ListParentNode struct { | 59 | type ListParentNode struct { |
62 | ObjectType string `json:"objectType"` | 60 | ObjectType string `json:"objectType"` |
63 | LabelField string `json:"labelField"` | 61 | LabelField string `json:"labelField"` |
64 | FilterField string `json:"filterField"` | 62 | FilterField string `json:"filterField"` |
65 | } | 63 | } |
66 | 64 | ||
67 | type ListPivot struct { | 65 | type ListPivot struct { |
68 | ObjectType string `json:"objectType"` | 66 | ObjectType string `json:"objectType"` |
69 | GroupField string `json:"groupField"` | 67 | GroupField string `json:"groupField"` |
70 | DistinctField string `json:"distinctField"` | 68 | DistinctField string `json:"distinctField"` |
71 | Value string `json:"valueField"` | 69 | Value string `json:"valueField"` |
72 | } | 70 | } |
73 | 71 | ||
74 | type ListDetails struct { | 72 | type ListDetails struct { |
75 | ObjectType string `json:"objectType"` | 73 | ObjectType string `json:"objectType"` |
76 | ParentObjectType string `json:"parentObjectType"` | 74 | ParentObjectType string `json:"parentObjectType"` |
77 | ParentFilterField string `json:"parentFilterField"` | 75 | ParentFilterField string `json:"parentFilterField"` |
78 | SingleDetail bool `json:"singleDetail"` | 76 | SingleDetail bool `json:"singleDetail"` |
79 | } | 77 | } |
80 | 78 | ||
81 | type ListConfig struct { | 79 | type ListConfig struct { |
82 | ObjectType string `json:"objectType"` | 80 | ObjectType string `json:"objectType"` |
83 | Title string `json:"title"` | 81 | Title string `json:"title"` |
84 | LazyLoad bool `json:"lazyLoad"` | 82 | LazyLoad bool `json:"lazyLoad"` |
85 | InlineEdit bool `json:"inlineEdit"` | 83 | InlineEdit bool `json:"inlineEdit"` |
86 | Options ListOptions `json:"options"` | 84 | Options ListOptions `json:"options"` |
87 | Filters []ListFilter `json:"defaultFilters"` | 85 | Filters []ListFilter `json:"defaultFilters"` |
88 | Graphs []ListGraph `json:"graphs"` | 86 | Graphs []ListGraph `json:"graphs"` |
89 | Actions ListActions `json:"actions"` | 87 | Actions ListActions `json:"actions"` |
90 | Parent []ListParentNode `json:"parent"` | 88 | Parent []ListParentNode `json:"parent"` |
91 | Navigation []ListNavNode `json:"navigation"` | 89 | Navigation []ListNavNode `json:"navigation"` |
92 | Pivots []ListPivot `json:"pivots"` | 90 | Pivots []ListPivot `json:"pivots"` |
93 | Details ListDetails `json:"details"` | 91 | Details ListDetails `json:"details"` |
94 | } | 92 | } |
95 | 93 | ||
96 | // GetListConfig returns list configuration for the provided object type for the front-end application | 94 | // GetListConfig returns list configuration for the provided object type for the front-end application |
97 | // or an error if it fails. | 95 | // or an error if it fails. |
98 | func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { | 96 | func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { |
99 | resp := newDefaultList(objType) | 97 | resp := newDefaultList(objType) |
100 | var err error | 98 | var err error |
101 | 99 | ||
102 | err = setListParams(db, &resp, objType) | 100 | err = setListParams(db, &resp, objType) |
103 | resp.Navigation, err = getListNavigation(db, objType) | 101 | resp.Navigation, err = getListNavigation(db, objType) |
104 | resp.Actions, err = getListActions(db, objType) | 102 | resp.Actions, err = getListActions(db, objType) |
105 | resp.Filters, err = getListFilters(db, objType) | 103 | resp.Filters, err = getListFilters(db, objType) |
106 | resp.Options, err = getListOptions(db, objType) | 104 | resp.Options, err = getListOptions(db, objType) |
107 | resp.Parent, err = getListParent(db, objType) | 105 | resp.Parent, err = getListParent(db, objType) |
108 | resp.Graphs, err = getListGraph(db, objType) | 106 | resp.Graphs, err = getListGraph(db, objType) |
109 | resp.Pivots, err = getListPivot(db, objType) | 107 | resp.Pivots, err = getListPivot(db, objType) |
110 | resp.Details, err = getListDetails(db, objType) | 108 | resp.Details, err = getListDetails(db, objType) |
111 | 109 | ||
112 | if err != nil { | 110 | if err != nil { |
113 | return ListConfig{}, err | 111 | return ListConfig{}, err |
114 | } | 112 | } |
115 | 113 | ||
116 | return resp, nil | 114 | return resp, nil |
117 | } | 115 | } |
118 | 116 | ||
119 | // GetListConfigObjectIDField takes in database connection and an object type and it returns the | 117 | // GetListConfigObjectIDField takes in database connection and an object type and it returns the |
120 | // ID field name for the provided object type. | 118 | // ID field name for the provided object type. |
121 | func GetListConfigObjectIDField(db *ora.Ses, otype string) string { | 119 | func GetListConfigObjectIDField(db *ora.Ses, otype string) string { |
122 | var resp string | 120 | var resp string |
123 | var err error | 121 | var err error |
124 | var stmt *ora.Stmt | 122 | var stmt *ora.Stmt |
125 | 123 | ||
126 | stmt, err = db.Prep(`SELECT | 124 | stmt, err = db.Prep(`SELECT |
127 | ID_FIELD | 125 | ID_FIELD |
128 | FROM LIST_CONFIG_ID_FIELD | 126 | FROM LIST_CONFIG_ID_FIELD |
129 | WHERE OBJECT_TYPE = '` + otype + `'`, | 127 | WHERE OBJECT_TYPE = '`+otype+`'`, |
130 | ora.S) | 128 | ora.S) |
131 | 129 | ||
132 | defer stmt.Close() | 130 | defer stmt.Close() |
133 | 131 | ||
134 | if err != nil { | 132 | if err != nil { |
135 | return "" | 133 | return "" |
136 | } | 134 | } |
137 | 135 | ||
138 | rset, err := stmt.Qry() | 136 | rset, err := stmt.Qry() |
139 | if rset.Next() { | 137 | if rset.Next() { |
140 | resp = rset.Row[0].(string) | 138 | resp = rset.Row[0].(string) |
141 | } | 139 | } |
142 | 140 | ||
143 | if rset.Err() != nil { | 141 | if rset.Err() != nil { |
144 | return "" | 142 | return "" |
145 | } | 143 | } |
146 | 144 | ||
147 | return resp | 145 | return resp |
148 | } | 146 | } |
149 | 147 | ||
150 | // newDefaultList returns default configuration for the provided object type. | 148 | // newDefaultList returns default configuration for the provided object type. |
151 | func newDefaultList(objType string) ListConfig { | 149 | func newDefaultList(objType string) ListConfig { |
152 | list := ListConfig{ | 150 | list := ListConfig{ |
153 | ObjectType: objType, | 151 | ObjectType: objType, |
154 | Title: objType, | 152 | Title: objType, |
155 | LazyLoad: false, | 153 | LazyLoad: false, |
156 | Options: ListOptions{ | 154 | Options: ListOptions{ |
157 | GlobalFilter: true, | 155 | GlobalFilter: true, |
158 | LocalFilters: true, | 156 | LocalFilters: true, |
159 | RemoteFilters: false, | 157 | RemoteFilters: false, |
160 | Pagination: true, | 158 | Pagination: true, |
161 | PageSize: 20, | 159 | PageSize: 20, |
162 | }, | 160 | }, |
163 | Filters: nil, | 161 | Filters: nil, |
164 | Actions: ListActions{ | 162 | Actions: ListActions{ |
165 | Create: false, | 163 | Create: false, |
166 | Update: false, | 164 | Update: false, |
167 | Delete: false, | 165 | Delete: false, |
168 | Export: false, | 166 | Export: false, |
169 | Print: false, | 167 | Print: false, |
170 | Graph: false, | 168 | Graph: false, |
171 | }, | 169 | }, |
172 | Parent: nil, | 170 | Parent: nil, |
173 | Navigation: nil, | 171 | Navigation: nil, |
174 | } | 172 | } |
175 | 173 | ||
176 | return list | 174 | return list |
177 | } | 175 | } |
178 | 176 | ||
179 | // setListParams sets the default parameters of the provided configuration list for the provided object type. | 177 | // setListParams sets the default parameters of the provided configuration list for the provided object type. |
180 | func setListParams(db *ora.Ses, list *ListConfig, objType string) error { | 178 | func setListParams(db *ora.Ses, list *ListConfig, objType string) error { |
181 | var err error | 179 | var err error |
182 | var stmt *ora.Stmt | 180 | var stmt *ora.Stmt |
183 | query := `SELECT | 181 | query := `SELECT |
184 | OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT | 182 | OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT |
185 | FROM LIST_CONFIG | 183 | FROM LIST_CONFIG |
186 | WHERE OBJECT_TYPE = '` + objType + `'` | 184 | WHERE OBJECT_TYPE = '` + objType + `'` |
187 | 185 | ||
188 | stmt, err = db.Prep(query, ora.S, ora.S, ora.U32, ora.U32) | 186 | stmt, err = db.Prep(query, ora.S, ora.S, ora.U32, ora.U32) |
189 | if err != nil { | 187 | if err != nil { |
190 | return err | 188 | return err |
191 | } | 189 | } |
192 | defer stmt.Close() | 190 | defer stmt.Close() |
193 | 191 | ||
194 | rset, err := stmt.Qry() | 192 | rset, err := stmt.Qry() |
195 | if err != nil { | 193 | if err != nil { |
196 | return err | 194 | return err |
197 | } | 195 | } |
198 | if rset.Next() { | 196 | if rset.Next() { |
199 | otype := rset.Row[0].(string) | 197 | otype := rset.Row[0].(string) |
200 | if otype != "" { | 198 | if otype != "" { |
201 | list.ObjectType = otype | 199 | list.ObjectType = otype |
202 | } | 200 | } |
203 | 201 | ||
204 | title := rset.Row[1].(string) | 202 | title := rset.Row[1].(string) |
205 | if title != "" { | 203 | if title != "" { |
206 | list.Title = title | 204 | list.Title = title |
207 | } | 205 | } |
208 | list.LazyLoad = rset.Row[2].(uint32) != 0 | 206 | list.LazyLoad = rset.Row[2].(uint32) != 0 |
209 | list.InlineEdit = rset.Row[3].(uint32) != 0 | 207 | list.InlineEdit = rset.Row[3].(uint32) != 0 |
210 | } | 208 | } |
211 | if rset.Err() != nil { | 209 | if rset.Err() != nil { |
212 | return rset.Err() | 210 | return rset.Err() |
213 | } | 211 | } |
214 | return nil | 212 | return nil |
215 | } | 213 | } |
216 | 214 | ||
217 | // getListNavigation returns list navigation node slice for the provided objectType. | 215 | // getListNavigation returns list navigation node slice for the provided objectType. |
218 | func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { | 216 | func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { |
219 | resp := make([]ListNavNode, 0) | 217 | resp := make([]ListNavNode, 0) |
220 | var err error | 218 | var err error |
221 | var stmt *ora.Stmt | 219 | var stmt *ora.Stmt |
222 | query := `SELECT | 220 | query := `SELECT |
223 | a.OBJECT_TYPE, a.PARENT_OBJECT_TYPE, a.LABEL, a.ICON, a.PARENT_FILTER_FIELD, b.PARENT_ID_FIELD, b.RB | 221 | a.OBJECT_TYPE, a.PARENT_OBJECT_TYPE, a.LABEL, a.ICON, a.PARENT_FILTER_FIELD, b.PARENT_ID_FIELD, b.RB |
224 | FROM LIST_CONFIG_NAVIGATION b | 222 | FROM LIST_CONFIG_NAVIGATION b |
225 | JOIN LIST_CONFIG_CHILD a ON b.PARENT_CHILD_ID = a.PARENT_CHILD_ID | 223 | JOIN LIST_CONFIG_CHILD a ON b.PARENT_CHILD_ID = a.PARENT_CHILD_ID |
226 | WHERE b.LIST_OBJECT_TYPE = '`+listObjType+`' | 224 | WHERE b.LIST_OBJECT_TYPE = '` + listObjType + `' |
227 | ORDER BY b.RB ASC` | 225 | ORDER BY b.RB ASC` |
228 | 226 | ||
229 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S) | 227 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S) |
230 | if err != nil { | 228 | if err != nil { |
231 | return resp, err | 229 | return resp, err |
232 | } | 230 | } |
233 | defer stmt.Close() | 231 | defer stmt.Close() |
234 | 232 | ||
235 | rset, err := stmt.Qry() | 233 | rset, err := stmt.Qry() |
236 | if err != nil { | 234 | if err != nil { |
237 | return resp, err | 235 | return resp, err |
238 | } | 236 | } |
239 | for rset.Next() { | 237 | for rset.Next() { |
240 | resp = append(resp, ListNavNode{ | 238 | resp = append(resp, ListNavNode{ |
241 | ObjectType: rset.Row[0].(string), | 239 | ObjectType: rset.Row[0].(string), |
242 | ParentObjectType: rset.Row[1].(string), | 240 | ParentObjectType: rset.Row[1].(string), |
243 | LabelField: rset.Row[2].(string), | 241 | LabelField: rset.Row[2].(string), |
244 | Icon: rset.Row[3].(string), | 242 | Icon: rset.Row[3].(string), |
245 | ParentFilterField: rset.Row[4].(string), | 243 | ParentFilterField: rset.Row[4].(string), |
246 | ParentIDField: rset.Row[5].(string), | 244 | ParentIDField: rset.Row[5].(string), |
247 | // RB is ignored | 245 | // RB is ignored |
248 | }) | 246 | }) |
249 | } | 247 | } |
250 | if rset.Err() != nil { | 248 | if rset.Err() != nil { |
251 | return nil, rset.Err() | 249 | return nil, rset.Err() |
252 | } | 250 | } |
253 | 251 | ||
254 | return resp, nil | 252 | return resp, nil |
255 | } | 253 | } |
256 | 254 | ||
257 | // getListActions returns list actions for the provided object type. | 255 | // getListActions returns list actions for the provided object type. |
258 | func getListActions(db *ora.Ses, objType string) (ListActions, error) { | 256 | func getListActions(db *ora.Ses, objType string) (ListActions, error) { |
259 | var resp ListActions | 257 | var resp ListActions |
260 | var err error | 258 | var err error |
261 | var stmt *ora.Stmt | 259 | var stmt *ora.Stmt |
262 | query := `SELECT | 260 | query := `SELECT |
263 | ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT, | 261 | ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT, |
264 | ACTION_PRINT, ACTION_GRAPH | 262 | ACTION_PRINT, ACTION_GRAPH |
265 | FROM LIST_CONFIG | 263 | FROM LIST_CONFIG |
266 | WHERE OBJECT_TYPE = '` + objType + `'` | 264 | WHERE OBJECT_TYPE = '` + objType + `'` |
267 | 265 | ||
268 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, | 266 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, |
269 | ora.U32, ora.U32) | 267 | ora.U32, ora.U32) |
270 | if err != nil { | 268 | if err != nil { |
271 | return ListActions{}, err | 269 | return ListActions{}, err |
272 | } | 270 | } |
273 | defer stmt.Close() | 271 | defer stmt.Close() |
274 | 272 | ||
275 | rset, err := stmt.Qry() | 273 | rset, err := stmt.Qry() |
276 | if err != nil { | 274 | if err != nil { |
277 | return ListActions{}, err | 275 | return ListActions{}, err |
278 | } | 276 | } |
279 | if rset.Next() { | 277 | if rset.Next() { |
280 | resp.Create = rset.Row[0].(uint32) != 0 | 278 | resp.Create = rset.Row[0].(uint32) != 0 |
281 | resp.Update = rset.Row[1].(uint32) != 0 | 279 | resp.Update = rset.Row[1].(uint32) != 0 |
282 | resp.Delete = rset.Row[2].(uint32) != 0 | 280 | resp.Delete = rset.Row[2].(uint32) != 0 |
283 | resp.Export = rset.Row[3].(uint32) != 0 | 281 | resp.Export = rset.Row[3].(uint32) != 0 |
284 | resp.Print = rset.Row[4].(uint32) != 0 | 282 | resp.Print = rset.Row[4].(uint32) != 0 |
285 | resp.Graph = rset.Row[5].(uint32) != 0 | 283 | resp.Graph = rset.Row[5].(uint32) != 0 |
286 | } | 284 | } |
287 | if rset.Err() != nil { | 285 | if rset.Err() != nil { |
288 | return ListActions{}, rset.Err() | 286 | return ListActions{}, rset.Err() |
289 | } | 287 | } |
290 | return resp, nil | 288 | return resp, nil |
291 | } | 289 | } |
292 | 290 | ||
293 | // getListFiters returns list filter slice for the provided object type. | 291 | // getListFiters returns list filter slice for the provided object type. |
294 | func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { | 292 | func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { |
295 | resp := make([]ListFilter, 0) | 293 | resp := make([]ListFilter, 0) |
296 | filtersFields, err := getFilterFieldsAndPosition(db, objType) | 294 | filtersFields, err := getFilterFieldsAndPosition(db, objType) |
297 | if err != nil { | 295 | if err != nil { |
298 | return nil, err | 296 | return nil, err |
299 | } | 297 | } |
300 | for field, pos := range filtersFields { | 298 | for field, pos := range filtersFields { |
301 | filters, _ := getFiltersByFilterField(db, field) | 299 | filters, _ := getFiltersByFilterField(db, field) |
302 | for _, filter := range filters { | 300 | for _, filter := range filters { |
303 | var f ListFilter | 301 | var f ListFilter |
304 | f.Position = pos | 302 | f.Position = pos |
305 | f.ObjectType = objType | 303 | f.ObjectType = objType |
306 | f.FiltersField = field | 304 | f.FiltersField = field |
307 | f.DefaultValues = filter.DefaultValues | 305 | f.DefaultValues = filter.DefaultValues |
308 | f.FiltersLabel = filter.Label | 306 | f.FiltersLabel = filter.Label |
309 | f.FiltersType = filter.Type | 307 | f.FiltersType = filter.Type |
310 | if filter.Type == "dropdown" { | 308 | if filter.Type == "dropdown" { |
311 | f.DropdownConfig, err = getFilterDropdownConfig(db, field) | 309 | f.DropdownConfig, err = getFilterDropdownConfig(db, field) |
312 | if err != nil { | 310 | if err != nil { |
313 | return nil, err | 311 | return nil, err |
314 | } | 312 | } |
315 | } | 313 | } |
316 | resp = append(resp, f) | 314 | resp = append(resp, f) |
317 | } | 315 | } |
318 | } | 316 | } |
319 | 317 | ||
320 | sortFilters(resp) | 318 | sortFilters(resp) |
321 | 319 | ||
322 | return resp, nil | 320 | return resp, nil |
323 | } | 321 | } |
324 | 322 | ||
325 | // getFilterFieldsAndPosition returns a map of filter fields and their respective position in the menu. | 323 | // getFilterFieldsAndPosition returns a map of filter fields and their respective position in the menu. |
326 | func getFilterFieldsAndPosition(db *ora.Ses, objType string) (map[string]uint32, error) { | 324 | func getFilterFieldsAndPosition(db *ora.Ses, objType string) (map[string]uint32, error) { |
327 | filtersField := make(map[string]uint32, 0) | 325 | filtersField := make(map[string]uint32, 0) |
328 | var err error | 326 | var err error |
329 | var stmt *ora.Stmt | 327 | var stmt *ora.Stmt |
330 | query := `SELECT | 328 | query := `SELECT |
331 | FILTERS_FIELD, RB | 329 | FILTERS_FIELD, RB |
332 | FROM LIST_CONFIG_FILTERS | 330 | FROM LIST_CONFIG_FILTERS |
333 | WHERE OBJECT_TYPE = '` + objType + `'` | 331 | WHERE OBJECT_TYPE = '` + objType + `'` |
334 | 332 | ||
335 | stmt, err = db.Prep(query, ora.S, ora.U32) | 333 | stmt, err = db.Prep(query, ora.S, ora.U32) |
336 | if err != nil { | 334 | if err != nil { |
337 | return nil, err | 335 | return nil, err |
338 | } | 336 | } |
339 | defer stmt.Close() | 337 | defer stmt.Close() |
340 | 338 | ||
341 | rset, err := stmt.Qry() | 339 | rset, err := stmt.Qry() |
342 | if err != nil { | 340 | if err != nil { |
343 | return nil, err | 341 | return nil, err |
344 | } | 342 | } |
345 | for rset.Next() { | 343 | for rset.Next() { |
346 | filtersField[rset.Row[0].(string)] = rset.Row[1].(uint32) | 344 | filtersField[rset.Row[0].(string)] = rset.Row[1].(uint32) |
347 | } | 345 | } |
348 | if rset.Err() != nil { | 346 | if rset.Err() != nil { |
349 | return nil, rset.Err() | 347 | return nil, rset.Err() |
350 | } | 348 | } |
351 | return filtersField, nil | 349 | return filtersField, nil |
352 | } | 350 | } |
353 | 351 | ||
354 | type _filter struct { | 352 | type _filter struct { |
355 | DefaultValues string | 353 | DefaultValues string |
356 | Label string | 354 | Label string |
357 | Type string | 355 | Type string |
358 | } | 356 | } |
359 | 357 | ||
360 | // getFiltersByFilterField returns filter slice for the provided filter field. | 358 | // getFiltersByFilterField returns filter slice for the provided filter field. |
361 | func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error) { | 359 | func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error) { |
362 | resp := make([]_filter, 0) | 360 | resp := make([]_filter, 0) |
363 | var err error | 361 | var err error |
364 | var stmt *ora.Stmt | 362 | var stmt *ora.Stmt |
365 | query := `SELECT | 363 | query := `SELECT |
366 | FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES | 364 | FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES |
367 | FROM LIST_FILTERS_FIELD | 365 | FROM LIST_FILTERS_FIELD |
368 | WHERE FILTERS_FIELD = '` + filtersField + `'` | 366 | WHERE FILTERS_FIELD = '` + filtersField + `'` |
369 | 367 | ||
370 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) | 368 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) |
371 | if err != nil { | 369 | if err != nil { |
372 | return resp, err | 370 | return resp, err |
373 | } | 371 | } |
374 | defer stmt.Close() | 372 | defer stmt.Close() |
375 | 373 | ||
376 | rset, err := stmt.Qry() | 374 | rset, err := stmt.Qry() |
377 | if err != nil { | 375 | if err != nil { |
378 | return resp, err | 376 | return resp, err |
379 | } | 377 | } |
380 | for rset.Next() { | 378 | for rset.Next() { |
381 | resp = append(resp, _filter{ | 379 | resp = append(resp, _filter{ |
382 | Type: rset.Row[0].(string), | 380 | Type: rset.Row[0].(string), |
383 | Label: rset.Row[1].(string), | 381 | Label: rset.Row[1].(string), |
384 | DefaultValues: rset.Row[2].(string), | 382 | DefaultValues: rset.Row[2].(string), |
385 | }) | 383 | }) |
386 | } | 384 | } |
387 | if rset.Err() != nil { | 385 | if rset.Err() != nil { |
388 | return resp, rset.Err() | 386 | return resp, rset.Err() |
389 | } | 387 | } |
390 | return resp, nil | 388 | return resp, nil |
391 | } | 389 | } |
392 | 390 | ||
393 | // getFilterDropdownConfig returns dropdown menu for the provided filter field. | 391 | // getFilterDropdownConfig returns dropdown menu for the provided filter field. |
394 | func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { | 392 | func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { |
395 | var resp Dropdown | 393 | var resp Dropdown |
396 | var err error | 394 | var err error |
397 | var stmt *ora.Stmt | 395 | var stmt *ora.Stmt |
398 | query := `SELECT | 396 | query := `SELECT |
399 | FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD | 397 | FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD |
400 | FROM LIST_DROPDOWN_FILTER | 398 | FROM LIST_DROPDOWN_FILTER |
401 | WHERE FILTERS_FIELD = '` + filtersField + `'` | 399 | WHERE FILTERS_FIELD = '` + filtersField + `'` |
402 | 400 | ||
403 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 401 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
404 | if err != nil { | 402 | if err != nil { |
405 | return resp, err | 403 | return resp, err |
406 | } | 404 | } |
407 | defer stmt.Close() | 405 | defer stmt.Close() |
408 | 406 | ||
409 | rset, err := stmt.Qry() | 407 | rset, err := stmt.Qry() |
410 | if err != nil { | 408 | if err != nil { |
411 | return resp, err | 409 | return resp, err |
412 | } | 410 | } |
413 | if rset.Next() { | 411 | if rset.Next() { |
414 | resp.FiltersField = rset.Row[0].(string) | 412 | resp.FiltersField = rset.Row[0].(string) |
415 | resp.ObjectType = rset.Row[1].(string) | 413 | resp.ObjectType = rset.Row[1].(string) |
416 | resp.IDField = rset.Row[2].(string) | 414 | resp.IDField = rset.Row[2].(string) |
417 | resp.LabelField = rset.Row[3].(string) | 415 | resp.LabelField = rset.Row[3].(string) |
418 | } | 416 | } |
419 | if rset.Err() != nil { | 417 | if rset.Err() != nil { |
420 | return resp, rset.Err() | 418 | return resp, rset.Err() |
421 | } | 419 | } |
422 | return resp, nil | 420 | return resp, nil |
423 | } | 421 | } |
424 | 422 | ||
425 | // sortFilters bubble sorts provided filters slice by position field. | 423 | // sortFilters bubble sorts provided filters slice by position field. |
426 | func sortFilters(filters []ListFilter) { | 424 | func sortFilters(filters []ListFilter) { |
427 | done := false | 425 | done := false |
428 | var temp ListFilter | 426 | var temp ListFilter |
429 | for !done { | 427 | for !done { |
430 | done = true | 428 | done = true |
431 | for i := 0; i < len(filters) - 1; i++ { | 429 | for i := 0; i < len(filters)-1; i++ { |
432 | if filters[i].Position > filters[i+1].Position { | 430 | if filters[i].Position > filters[i+1].Position { |
433 | done = false | 431 | done = false |
434 | temp = filters[i] | 432 | temp = filters[i] |
435 | filters[i] = filters[i+1] | 433 | filters[i] = filters[i+1] |
436 | filters[i+1] = temp | 434 | filters[i+1] = temp |
437 | } | 435 | } |
438 | } | 436 | } |
439 | } | 437 | } |
440 | } | 438 | } |
441 | 439 | ||
442 | // getListGraph return list graph slice for the provided object type. | 440 | // getListGraph return list graph slice for the provided object type. |
443 | func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { | 441 | func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { |
444 | resp := make([]ListGraph, 0) | 442 | resp := make([]ListGraph, 0) |
445 | var err error | 443 | var err error |
446 | var stmt *ora.Stmt | 444 | var stmt *ora.Stmt |
447 | query := `SELECT | 445 | query := `SELECT |
448 | OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL | 446 | OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL |
449 | FROM LIST_GRAPHS | 447 | FROM LIST_GRAPHS |
450 | WHERE OBJECT_TYPE = '` + objType + `'` | 448 | WHERE OBJECT_TYPE = '` + objType + `'` |
451 | 449 | ||
452 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 450 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
453 | if err != nil { | 451 | if err != nil { |
454 | return resp, err | 452 | return resp, err |
455 | } | 453 | } |
456 | defer stmt.Close() | 454 | defer stmt.Close() |
457 | 455 | ||
458 | rset, err := stmt.Qry() | 456 | rset, err := stmt.Qry() |
459 | if err != nil { | 457 | if err != nil { |
460 | return resp, err | 458 | return resp, err |
461 | } | 459 | } |
462 | for rset.Next() { | 460 | for rset.Next() { |
463 | resp = append(resp, ListGraph{ | 461 | resp = append(resp, ListGraph{ |
464 | ObjectType: rset.Row[0].(string), | 462 | ObjectType: rset.Row[0].(string), |
465 | X: rset.Row[1].(string), | 463 | X: rset.Row[1].(string), |
466 | Y: rset.Row[2].(string), | 464 | Y: rset.Row[2].(string), |
467 | GroupField: rset.Row[3].(string), | 465 | GroupField: rset.Row[3].(string), |
468 | Label: rset.Row[4].(string), | 466 | Label: rset.Row[4].(string), |
469 | }) | 467 | }) |
470 | } | 468 | } |
471 | if rset.Err() != nil { | 469 | if rset.Err() != nil { |
472 | return resp, rset.Err() | 470 | return resp, rset.Err() |
473 | } | 471 | } |
474 | return resp, nil | 472 | return resp, nil |
475 | } | 473 | } |
476 | 474 | ||
477 | // getListOptions returns list options for the provided object type. | 475 | // getListOptions returns list options for the provided object type. |
478 | func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { | 476 | func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { |
479 | var resp ListOptions | 477 | var resp ListOptions |
480 | var err error | 478 | var err error |
481 | var stmt *ora.Stmt | 479 | var stmt *ora.Stmt |
482 | query := `SELECT | 480 | query := `SELECT |
483 | GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION, | 481 | GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION, |
484 | PAGE_SIZE, PIVOT, DETAIL, TOTAL | 482 | PAGE_SIZE, PIVOT, DETAIL, TOTAL |
485 | FROM LIST_CONFIG | 483 | FROM LIST_CONFIG |
486 | WHERE OBJECT_TYPE = '` + objType + `'` | 484 | WHERE OBJECT_TYPE = '` + objType + `'` |
487 | 485 | ||
488 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, | 486 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, |
489 | ora.U64, ora.U64, ora.U32, ora.U32) | 487 | ora.U64, ora.U64, ora.U32, ora.U32) |
490 | if err != nil { | 488 | if err != nil { |
491 | return ListOptions{}, err | 489 | return ListOptions{}, err |
492 | } | 490 | } |
493 | defer stmt.Close() | 491 | defer stmt.Close() |
494 | 492 | ||
495 | rset, err := stmt.Qry() | 493 | rset, err := stmt.Qry() |
496 | if err != nil { | 494 | if err != nil { |
497 | return ListOptions{}, err | 495 | return ListOptions{}, err |
498 | } | 496 | } |
499 | if rset.Next() { | 497 | if rset.Next() { |
500 | resp.GlobalFilter = rset.Row[0].(uint32) != 0 | 498 | resp.GlobalFilter = rset.Row[0].(uint32) != 0 |
501 | resp.LocalFilters = rset.Row[1].(uint32) != 0 | 499 | resp.LocalFilters = rset.Row[1].(uint32) != 0 |
502 | resp.RemoteFilters = rset.Row[2].(uint32) != 0 | 500 | resp.RemoteFilters = rset.Row[2].(uint32) != 0 |
503 | resp.Pagination = rset.Row[3].(uint32) != 0 | 501 | resp.Pagination = rset.Row[3].(uint32) != 0 |
504 | resp.PageSize = rset.Row[4].(uint64) | 502 | resp.PageSize = rset.Row[4].(uint64) |
505 | resp.Pivot = rset.Row[5].(uint64) != 0 | 503 | resp.Pivot = rset.Row[5].(uint64) != 0 |
506 | resp.Detail = rset.Row[6].(uint32) != 0 | 504 | resp.Detail = rset.Row[6].(uint32) != 0 |
507 | resp.Total = rset.Row[7].(uint32) != 0 | 505 | resp.Total = rset.Row[7].(uint32) != 0 |
508 | } | 506 | } |
509 | if rset.Err() != nil { | 507 | if rset.Err() != nil { |
510 | return ListOptions{}, rset.Err() | 508 | return ListOptions{}, rset.Err() |
511 | } | 509 | } |
512 | return resp, nil | 510 | return resp, nil |
513 | } | 511 | } |
514 | 512 | ||
515 | // getListParent returns list parent node slice for the provided object type. | 513 | // getListParent returns list parent node slice for the provided object type. |
516 | func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { | 514 | func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { |
517 | resp := make([]ListParentNode, 0) | 515 | resp := make([]ListParentNode, 0) |
518 | var err error | 516 | var err error |
519 | var stmt *ora.Stmt | 517 | var stmt *ora.Stmt |
520 | query := `SELECT | 518 | query := `SELECT |
521 | PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD | 519 | PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD |
522 | FROM LIST_CONFIG_CHILD | 520 | FROM LIST_CONFIG_CHILD |
523 | WHERE OBJECT_TYPE = '` + objType + `'` | 521 | WHERE OBJECT_TYPE = '` + objType + `'` |
524 | 522 | ||
525 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) | 523 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) |
526 | if err != nil { | 524 | if err != nil { |
527 | return resp, err | 525 | return resp, err |
528 | } | 526 | } |
529 | defer stmt.Close() | 527 | defer stmt.Close() |
530 | 528 | ||
531 | rset, err := stmt.Qry() | 529 | rset, err := stmt.Qry() |
532 | if err != nil { | 530 | if err != nil { |
533 | return resp, err | 531 | return resp, err |
534 | } | 532 | } |
535 | for rset.Next() { | 533 | for rset.Next() { |
536 | resp = append(resp, ListParentNode{ | 534 | resp = append(resp, ListParentNode{ |
537 | ObjectType: rset.Row[0].(string), | 535 | ObjectType: rset.Row[0].(string), |
538 | LabelField: rset.Row[1].(string), | 536 | LabelField: rset.Row[1].(string), |
539 | FilterField: rset.Row[2].(string), | 537 | FilterField: rset.Row[2].(string), |
540 | }) | 538 | }) |
541 | } | 539 | } |
542 | if rset.Err() != nil { | 540 | if rset.Err() != nil { |
543 | return nil, rset.Err() | 541 | return nil, rset.Err() |
544 | } | 542 | } |
545 | 543 | ||
546 | return resp, nil | 544 | return resp, nil |
547 | } | 545 | } |
548 | 546 | ||
549 | // getListPivot list pivot slice for the provided object type. | 547 | // getListPivot list pivot slice for the provided object type. |
550 | func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { | 548 | func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { |
551 | resp := make([]ListPivot, 0) | 549 | resp := make([]ListPivot, 0) |
552 | var err error | 550 | var err error |
553 | var stmt *ora.Stmt | 551 | var stmt *ora.Stmt |
554 | query := `SELECT | 552 | query := `SELECT |
555 | OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD | 553 | OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD |
556 | FROM LIST_PIVOTS | 554 | FROM LIST_PIVOTS |
557 | WHERE OBJECT_TYPE = '` + objType + `'` | 555 | WHERE OBJECT_TYPE = '` + objType + `'` |
558 | 556 | ||
559 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 557 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
560 | if err != nil { | 558 | if err != nil { |
561 | return resp, err | 559 | return resp, err |
562 | } | 560 | } |
563 | defer stmt.Close() | 561 | defer stmt.Close() |
564 | 562 | ||
565 | rset, err := stmt.Qry() | 563 | rset, err := stmt.Qry() |
566 | if err != nil { | 564 | if err != nil { |
567 | return resp, err | 565 | return resp, err |
568 | } | 566 | } |
569 | for rset.Next() { | 567 | for rset.Next() { |
570 | resp = append(resp, ListPivot{ | 568 | resp = append(resp, ListPivot{ |
571 | ObjectType: rset.Row[0].(string), | 569 | ObjectType: rset.Row[0].(string), |
572 | GroupField: rset.Row[1].(string), | 570 | GroupField: rset.Row[1].(string), |
573 | DistinctField: rset.Row[2].(string), | 571 | DistinctField: rset.Row[2].(string), |
574 | Value: rset.Row[3].(string), | 572 | Value: rset.Row[3].(string), |
575 | }) | 573 | }) |
576 | } | 574 | } |
577 | if rset.Err() != nil { | 575 | if rset.Err() != nil { |
578 | return nil, rset.Err() | 576 | return nil, rset.Err() |
579 | } | 577 | } |
580 | 578 | ||
581 | return resp, nil | 579 | return resp, nil |
582 | } | 580 | } |
583 | 581 | ||
584 | // getListDetails returns list details for the provided object type. | 582 | // getListDetails returns list details for the provided object type. |
585 | func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { | 583 | func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { |
586 | var resp ListDetails | 584 | var resp ListDetails |
587 | var err error | 585 | var err error |
588 | var stmt *ora.Stmt | 586 | var stmt *ora.Stmt |
589 | query := `SELECT | 587 | query := `SELECT |
590 | OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL | 588 | OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL |
591 | FROM LIST_CONFIG_DETAIL | 589 | FROM LIST_CONFIG_DETAIL |
592 | WHERE PARENT_OBJECT_TYPE = '` + objType + `'` | 590 | WHERE PARENT_OBJECT_TYPE = '` + objType + `'` |
593 | 591 | ||
594 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.U32) | 592 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.U32) |
595 | if err != nil { | 593 | if err != nil { |
596 | return resp, err | 594 | return resp, err |
597 | } | 595 | } |
598 | defer stmt.Close() | 596 | defer stmt.Close() |
599 | 597 | ||
600 | rset, err := stmt.Qry() | 598 | rset, err := stmt.Qry() |
601 | if err != nil { | 599 | if err != nil { |
602 | return resp, err | 600 | return resp, err |
603 | } | 601 | } |
604 | if rset.Next() { | 602 | if rset.Next() { |
605 | resp.ObjectType = rset.Row[0].(string) | 603 | resp.ObjectType = rset.Row[0].(string) |
606 | resp.ParentObjectType = rset.Row[1].(string) | 604 | resp.ParentObjectType = rset.Row[1].(string) |
607 | resp.ParentFilterField = rset.Row[2].(string) | 605 | resp.ParentFilterField = rset.Row[2].(string) |
608 | resp.SingleDetail = rset.Row[3].(uint32) != 0 | 606 | resp.SingleDetail = rset.Row[3].(uint32) != 0 |
609 | } | 607 | } |
610 | if rset.Err() != nil { | 608 | if rset.Err() != nil { |
611 | return resp, rset.Err() | 609 | return resp, rset.Err() |
612 | } | 610 | } |
613 | 611 | ||
614 | return resp, nil | 612 | return resp, nil |
615 | } | 613 | } |
616 | 614 |
select_config.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | //import "gopkg.in/rana/ora.v3" | ||
4 | import "gopkg.in/rana/ora.v4" | 3 | import "gopkg.in/rana/ora.v4" |
5 | 4 | ||
6 | type SelectConfig struct { | 5 | type SelectConfig struct { |
7 | ListObjType string `json:"listObjectType"` | 6 | ListObjType string `json:"listObjectType"` |
8 | ObjType string `json:"objectType"` | 7 | ObjType string `json:"objectType"` |
9 | Type string `json:"type"` | 8 | Type string `json:"type"` |
10 | IdField string `json:"idField"` | 9 | IdField string `json:"idField"` |
11 | LabelField string `json:"labelField"` | 10 | LabelField string `json:"labelField"` |
12 | ValueField string `json:"valueField"` | 11 | ValueField string `json:"valueField"` |
13 | } | 12 | } |
14 | 13 | ||
15 | // GetSelectConfig returns select configuration slice for the given object type. | 14 | // GetSelectConfig returns select configuration slice for the given object type. |
16 | func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { | 15 | func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { |
17 | resp := make([]SelectConfig, 0) | 16 | resp := make([]SelectConfig, 0) |
18 | var err error | 17 | var err error |
19 | var stmt *ora.Stmt | 18 | var stmt *ora.Stmt |
20 | query := `SELECT | 19 | query := `SELECT |
21 | a.LIST_OBJECT_TYPE, | 20 | a.LIST_OBJECT_TYPE, |
22 | a.OBJECT_TYPE, | 21 | a.OBJECT_TYPE, |
23 | a.ID_FIELD, | 22 | a.ID_FIELD, |
24 | a.LABEL_FIELD, | 23 | a.LABEL_FIELD, |
25 | a.TYPE, | 24 | a.TYPE, |
26 | b.FIELD | 25 | b.FIELD |
27 | FROM LIST_SELECT_CONFIG a, LIST_VALUE_FIELD b | 26 | FROM LIST_SELECT_CONFIG a, LIST_VALUE_FIELD b |
28 | WHERE a.LIST_OBJECT_TYPE` + otype + ` | 27 | WHERE a.LIST_OBJECT_TYPE` + otype + ` |
29 | AND b.LIST_TYPE = a.LIST_OBJECT_TYPE | 28 | AND b.LIST_TYPE = a.LIST_OBJECT_TYPE |
30 | AND b.OBJECT_TYPE = a.OBJECT_TYPE` | 29 | AND b.OBJECT_TYPE = a.OBJECT_TYPE` |
31 | 30 | ||
32 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S) | 31 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S) |
33 | defer stmt.Close() | 32 | defer stmt.Close() |
34 | if err != nil { | 33 | if err != nil { |
35 | return nil, err | 34 | return nil, err |
36 | } | 35 | } |
37 | 36 | ||
38 | rset, err := stmt.Qry() | 37 | rset, err := stmt.Qry() |
39 | if err != nil { | 38 | if err != nil { |
40 | return nil, err | 39 | return nil, err |
41 | } | 40 | } |
42 | for rset.Next() { | 41 | for rset.Next() { |
43 | resp = append(resp, SelectConfig{ | 42 | resp = append(resp, SelectConfig{ |
44 | ListObjType: rset.Row[0].(string), | 43 | ListObjType: rset.Row[0].(string), |
45 | ObjType: rset.Row[1].(string), | 44 | ObjType: rset.Row[1].(string), |
46 | IdField: rset.Row[2].(string), | 45 | IdField: rset.Row[2].(string), |
47 | LabelField: rset.Row[3].(string), | 46 | LabelField: rset.Row[3].(string), |
48 | Type: rset.Row[4].(string), | 47 | Type: rset.Row[4].(string), |
49 | ValueField: rset.Row[5].(string), | 48 | ValueField: rset.Row[5].(string), |
50 | }) | 49 | }) |
51 | } | 50 | } |
52 | if rset.Err() != nil { | 51 | if rset.Err() != nil { |
53 | return nil, rset.Err() | 52 | return nil, rset.Err() |
54 | } | 53 | } |
55 | 54 | ||
56 | return resp, nil | 55 | return resp, nil |
57 | } | 56 | } |
58 | 57 |
sql_sequrity.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import "strings" |
4 | "strings" | ||
5 | ) | ||
6 | 4 | ||
7 | var patern string = "\"';&*<>=\\`:" | 5 | var patern string = "\"';&*<>=\\`:" |
8 | 6 | ||
9 | // SQLSafeString removes characters from s found in patern and returns new modified string. | 7 | // SQLSafeString removes characters from s found in patern and returns new modified string. |
10 | func SQLSafeString(s string) (safe string) { | 8 | func SQLSafeString(s string) (safe string) { |
11 | for _, c := range patern { | 9 | for _, c := range patern { |
12 | safe = strings.Replace(s, string(c), "", -1) | 10 | safe = strings.Replace(s, string(c), "", -1) |
13 | } | 11 | } |
14 | return safe | 12 | return safe |
15 | } | 13 | } |
16 | 14 |