Commit 7d3deb50df481b887b4f3b40d170a5cf7e15aa91
1 parent
90f4ed0790
Exists in
master
and in
1 other branch
modified list_config with navigation (old children)
Showing
3 changed files
with
63 additions
and
36 deletions
Show diff stats
auth_utility.go
1 | package restutility | 1 | package restutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "errors" | 4 | "errors" |
5 | "time" | 5 | "time" |
6 | "crypto/sha256" | 6 | "crypto/sha256" |
7 | "crypto/rand" | 7 | "crypto/rand" |
8 | "encoding/hex" | 8 | "encoding/hex" |
9 | "strings" | 9 | "strings" |
10 | "github.com/dgrijalva/jwt-go" | 10 | "github.com/dgrijalva/jwt-go" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | const OneDay = time.Hour*24 | 13 | const OneDay = time.Hour*24 |
14 | const OneWeek = OneDay*7 | 14 | const OneWeek = OneDay*7 |
15 | const saltSize = 32 | 15 | const saltSize = 32 |
16 | const appName = "korisnicki-centar" | 16 | const appName = "korisnicki-centar" |
17 | const secret = "korisnicki-centar-api" | 17 | const secret = "korisnicki-centar-api" |
18 | 18 | ||
19 | type TokenClaims struct { | 19 | type TokenClaims struct { |
20 | Username string `json:"username"` | 20 | Username string `json:"username"` |
21 | Role string `json:"role"` | 21 | Role string `json:"role"` |
22 | jwt.StandardClaims | 22 | jwt.StandardClaims |
23 | } | 23 | } |
24 | 24 | ||
25 | type CredentialsStruct struct { | 25 | type CredentialsStruct struct { |
26 | Username string `json:"username"` | 26 | Username string `json:"username"` |
27 | Password string `json:"password"` | 27 | Password string `json:"password"` |
28 | } | 28 | } |
29 | 29 | ||
30 | func GenerateSalt() (string, error) { | 30 | func GenerateSalt() (string, error) { |
31 | salt := "" | 31 | salt := "" |
32 | |||
33 | rawsalt := make([]byte, saltSize) | 32 | rawsalt := make([]byte, saltSize) |
34 | _, err := rand.Read(rawsalt) | 33 | _, err := rand.Read(rawsalt) |
35 | if err != nil { | 34 | if err != nil { |
36 | return "", err | 35 | return "", err |
37 | } | 36 | } |
38 | salt = hex.EncodeToString(rawsalt) | 37 | salt = hex.EncodeToString(rawsalt) |
39 | return salt, nil | 38 | return salt, nil |
40 | } | 39 | } |
41 | 40 | ||
42 | func HashMessage(message string, presalt string) (string, string, error) { | 41 | func HashMessage(message string, presalt string) (string, string, error) { |
43 | hash, salt := "", "" | 42 | hash, salt := "", "" |
44 | var err error | 43 | var err error |
45 | 44 | ||
46 | // chech if message is presalted | 45 | // chech if message is presalted |
47 | if presalt == "" { | 46 | if presalt == "" { |
48 | salt, err = GenerateSalt() | 47 | salt, err = GenerateSalt() |
49 | if err != nil { | 48 | if err != nil { |
50 | return "", "", err | 49 | return "", "", err |
51 | } | 50 | } |
52 | } else { | 51 | } else { |
53 | salt = presalt | 52 | salt = presalt |
54 | } | 53 | } |
55 | 54 | ||
56 | // convert strings to raw byte slices | 55 | // convert strings to raw byte slices |
57 | rawmessage := []byte(message) | 56 | rawmessage := []byte(message) |
58 | rawsalt, err := hex.DecodeString(salt) | 57 | rawsalt, err := hex.DecodeString(salt) |
59 | if err != nil { | 58 | if err != nil { |
60 | return "", "", err | 59 | return "", "", err |
61 | } | 60 | } |
62 | rawdata := make([]byte, len(rawmessage) + len(rawsalt)) | 61 | rawdata := make([]byte, len(rawmessage) + len(rawsalt)) |
63 | rawdata = append(rawdata, rawmessage...) | 62 | rawdata = append(rawdata, rawmessage...) |
64 | rawdata = append(rawdata, rawsalt...) | 63 | rawdata = append(rawdata, rawsalt...) |
65 | 64 | ||
66 | // hash message + salt | 65 | // hash message + salt |
67 | hasher := sha256.New() | 66 | hasher := sha256.New() |
68 | hasher.Write(rawdata) | 67 | hasher.Write(rawdata) |
69 | rawhash := hasher.Sum(nil) | 68 | rawhash := hasher.Sum(nil) |
70 | hash = hex.EncodeToString(rawhash) | 69 | hash = hex.EncodeToString(rawhash) |
71 | return hash, salt, nil | 70 | return hash, salt, nil |
72 | } | 71 | } |
73 | 72 | ||
74 | func IssueAPIToken(username, role string) (string, error) { | 73 | func IssueAPIToken(username, role string) (string, error) { |
75 | var apiToken string | 74 | var apiToken string |
76 | var err error | 75 | var err error |
77 | 76 | ||
78 | if err != nil { | 77 | if err != nil { |
79 | return "", err | 78 | return "", err |
80 | } | 79 | } |
81 | 80 | ||
82 | claims := TokenClaims{ | 81 | claims := TokenClaims{ |
83 | username, | 82 | username, |
84 | role, | 83 | role, |
85 | jwt.StandardClaims{ | 84 | jwt.StandardClaims{ |
86 | ExpiresAt: (time.Now().Add(OneWeek)).Unix(), | 85 | ExpiresAt: (time.Now().Add(OneWeek)).Unix(), |
87 | Issuer: appName, | 86 | Issuer: appName, |
88 | }, | 87 | }, |
89 | } | 88 | } |
90 | 89 | ||
91 | jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) | 90 | jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) |
92 | apiToken, err = jwtToken.SignedString([]byte(secret)) | 91 | apiToken, err = jwtToken.SignedString([]byte(secret)) |
93 | if err != nil { | 92 | if err != nil { |
94 | return "", err | 93 | return "", err |
95 | } | 94 | } |
96 | return apiToken, nil | 95 | return apiToken, nil |
97 | } | 96 | } |
98 | 97 | ||
99 | func RefreshAPIToken(tokenString string) (string, error) { | 98 | func RefreshAPIToken(tokenString string) (string, error) { |
100 | var newToken string | 99 | var newToken string |
101 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") | 100 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") |
102 | token, err := parseTokenFunc(tokenString) | 101 | token, err := parseTokenFunc(tokenString) |
103 | if err != nil { | 102 | if err != nil { |
104 | return "", err | 103 | return "", err |
105 | } | 104 | } |
106 | 105 | ||
107 | // type assertion | 106 | // type assertion |
108 | claims, ok := token.Claims.(*TokenClaims) | 107 | claims, ok := token.Claims.(*TokenClaims) |
109 | if !ok || !token.Valid { | 108 | if !ok || !token.Valid { |
110 | return "", errors.New("token is not valid") | 109 | return "", errors.New("token is not valid") |
111 | } | 110 | } |
112 | 111 | ||
113 | claims.ExpiresAt = (time.Now().Add(OneWeek)).Unix() | 112 | claims.ExpiresAt = (time.Now().Add(OneWeek)).Unix() |
114 | jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) | 113 | jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) |
115 | 114 | ||
116 | newToken, err = jwtToken.SignedString([]byte(secret)) | 115 | newToken, err = jwtToken.SignedString([]byte(secret)) |
117 | if err != nil { | 116 | if err != nil { |
118 | return "", err | 117 | return "", err |
119 | } | 118 | } |
120 | 119 | ||
121 | return newToken, nil | 120 | return newToken, nil |
122 | } | 121 | } |
123 | 122 | ||
124 | func ParseAPIToken(tokenString string) (*TokenClaims, error) { | 123 | func ParseAPIToken(tokenString string) (*TokenClaims, error) { |
125 | if ok := strings.HasPrefix(tokenString, "Bearer"); ok { | 124 | if ok := strings.HasPrefix(tokenString, "Bearer"); ok { |
126 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") | 125 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") |
127 | } else { | 126 | } else { |
128 | return &TokenClaims{}, errors.New("Authorization header is incomplete") | 127 | return &TokenClaims{}, errors.New("Authorization header is incomplete") |
129 | } | 128 | } |
130 | 129 | ||
131 | token, err := parseTokenFunc(tokenString) | 130 | token, err := parseTokenFunc(tokenString) |
132 | if err != nil { | 131 | if err != nil { |
133 | return &TokenClaims{}, err | 132 | return &TokenClaims{}, err |
134 | } | 133 | } |
135 | 134 | ||
136 | // type assertion | 135 | // type assertion |
137 | claims, ok := token.Claims.(*TokenClaims) | 136 | claims, ok := token.Claims.(*TokenClaims) |
138 | if !ok || !token.Valid { | 137 | if !ok || !token.Valid { |
139 | return &TokenClaims{}, errors.New("token is not valid") | 138 | return &TokenClaims{}, errors.New("token is not valid") |
140 | } | 139 | } |
141 | return claims, nil | 140 | return claims, nil |
142 | } | 141 | } |
143 | 142 | ||
144 | func parseTokenFunc(tokenString string) (*jwt.Token, error) { | 143 | func parseTokenFunc(tokenString string) (*jwt.Token, error) { |
145 | token, err := jwt.ParseWithClaims(tokenString, | 144 | token, err := jwt.ParseWithClaims(tokenString, |
146 | &TokenClaims{}, | 145 | &TokenClaims{}, |
147 | func(token *jwt.Token) (interface{}, error) { | 146 | func(token *jwt.Token) (interface{}, error) { |
148 | return []byte(secret), nil | 147 | return []byte(secret), nil |
149 | }, | 148 | }, |
150 | ) | 149 | ) |
151 | return token, err | 150 | return token, err |
152 | } | 151 | } |
153 | 152 |
json_utility.go
1 | package restutility | 1 | package restutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "net/http" | 4 | "net/http" |
5 | "encoding/json" | 5 | "encoding/json" |
6 | "errors" | 6 | "errors" |
7 | "gopkg.in/rana/ora.v3" | 7 | "gopkg.in/rana/ora.v3" |
8 | "io" | 8 | "io" |
9 | "io/ioutil" | 9 | "io/ioutil" |
10 | ) | 10 | ) |
11 | 11 | ||
12 | var allPayloads []payloadBuff | 12 | var allPayloads []payloadBuff |
13 | 13 | ||
14 | type LangMap map[string]map[string]string | 14 | type LangMap map[string]map[string]string |
15 | 15 | ||
16 | type Field struct { | 16 | type Field struct { |
17 | Parameter string `json:"param"` | 17 | Parameter string `json:"param"` |
18 | Type string `json:"type"` | 18 | Type string `json:"type"` |
19 | Visible bool `json:"visible"` | 19 | Visible bool `json:"visible"` |
20 | Editable bool `json:"editable"` | 20 | Editable bool `json:"editable"` |
21 | } | 21 | } |
22 | 22 | ||
23 | type CorrelationField struct { | 23 | type CorrelationField struct { |
24 | Result string `json:"result"` | 24 | Result string `json:"result"` |
25 | Elements []string `json:"elements"` | 25 | Elements []string `json:"elements"` |
26 | Type string `json:"type"` | 26 | Type string `json:"type"` |
27 | } | 27 | } |
28 | 28 | ||
29 | type Translation struct { | 29 | type Translation struct { |
30 | Language string `json:"language"` | 30 | Language string `json:"language"` |
31 | FieldsLabels map[string]string `json:"fieldsLabels"` | 31 | FieldsLabels map[string]string `json:"fieldsLabels"` |
32 | } | 32 | } |
33 | 33 | ||
34 | // Type is not required in payload. This is only a bridge between ORACLE CLOB and | ||
35 | // Payload type. | ||
34 | type payloadBuff struct { | 36 | type payloadBuff struct { |
35 | Type string `json:"tableType"` | 37 | Type string `json:"tableType"` |
36 | Method string `json:"method"` | 38 | Method string `json:"method"` |
37 | Params map[string]string `json:"params"` | 39 | Params map[string]string `json:"params"` |
38 | Lang []Translation `json:"lang"` | 40 | Lang []Translation `json:"lang"` |
39 | Fields []Field `json:"fields"` | 41 | Fields []Field `json:"fields"` |
40 | Correlations []CorrelationField `json:"correlationFields"` | 42 | Correlations []CorrelationField `json:"correlationFields"` |
41 | IdField string `json:"idField"` | 43 | IdField string `json:"idField"` |
42 | // Data can only hold slices of any type. It can't be used for itteration | 44 | // Data can only hold slices of any type. It can't be used for itteration |
43 | Data interface{} `json:"data"` | 45 | Data interface{} `json:"data"` |
44 | } | 46 | } |
45 | 47 | ||
46 | type Payload struct { | 48 | type Payload struct { |
47 | Method string `json:"method"` | 49 | Method string `json:"method"` |
48 | Params map[string]string `json:"params"` | 50 | Params map[string]string `json:"params"` |
49 | Lang []Translation `json:"lang"` | 51 | Lang []Translation `json:"lang"` |
50 | Fields []Field `json:"fields"` | 52 | Fields []Field `json:"fields"` |
51 | Correlations []CorrelationField `json:"correlationFields"` | 53 | Correlations []CorrelationField `json:"correlationFields"` |
52 | IdField string `json:"idField"` | 54 | IdField string `json:"idField"` |
53 | // Data can only hold slices of any type. It can't be used for itteration | 55 | // Data can only hold slices of any type. It can't be used for itteration |
54 | Data interface{} `json:"data"` | 56 | Data interface{} `json:"data"` |
55 | } | 57 | } |
56 | 58 | ||
57 | func NewPayload(r *http.Request, table string) Payload { | 59 | func NewPayload(r *http.Request, table string) Payload { |
58 | var pload Payload | 60 | var pload Payload |
59 | 61 | ||
60 | pload.Method = r.Method + " " + r.URL.Path | 62 | pload.Method = r.Method + " " + r.URL.Path |
61 | 63 | ||
62 | if table != "" { | 64 | if table != "" { |
63 | pload.Params = make(map[string]string, 0) | 65 | pload.Params = make(map[string]string, 0) |
64 | pload.Lang = loadTranslations(table) | 66 | pload.Lang = loadTranslations(table) |
65 | pload.Fields = loadFields(table) | 67 | pload.Fields = loadFields(table) |
66 | pload.IdField = loadIdField(table) | 68 | pload.IdField = loadIdField(table) |
67 | pload.Correlations = loadCorrelations(table) | 69 | pload.Correlations = loadCorrelations(table) |
68 | } | 70 | } |
69 | 71 | ||
70 | return pload | 72 | return pload |
71 | } | 73 | } |
72 | 74 | ||
73 | func DeliverPayload(w http.ResponseWriter, payload Payload) { | 75 | func DeliverPayload(w http.ResponseWriter, payload Payload) { |
74 | json.NewEncoder(w).Encode(payload) | 76 | json.NewEncoder(w).Encode(payload) |
75 | payload.Data = nil | 77 | payload.Data = nil |
76 | } | 78 | } |
77 | 79 | ||
78 | func loadTranslations(id string) []Translation { | 80 | func loadTranslations(id string) []Translation { |
79 | translations := make([]Translation, 0) | 81 | translations := make([]Translation, 0) |
80 | 82 | ||
81 | for _, pload := range allPayloads { | 83 | for _, pload := range allPayloads { |
82 | if pload.Type == id { | 84 | if pload.Type == id { |
83 | for _, t := range pload.Lang { | 85 | for _, t := range pload.Lang { |
84 | //translations[t.Language] = t.FieldsLabels | 86 | //translations[t.Language] = t.FieldsLabels |
85 | translations = append(translations, Translation{ | 87 | translations = append(translations, Translation{ |
86 | Language: t.Language, | 88 | Language: t.Language, |
87 | FieldsLabels: t.FieldsLabels, | 89 | FieldsLabels: t.FieldsLabels, |
88 | }) | 90 | }) |
89 | } | 91 | } |
90 | } | 92 | } |
91 | } | 93 | } |
92 | 94 | ||
93 | return translations | 95 | return translations |
94 | } | 96 | } |
95 | 97 | ||
96 | func loadFields(id string) []Field { | 98 | func loadFields(id string) []Field { |
97 | fields := make([]Field, 0) | 99 | fields := make([]Field, 0) |
98 | 100 | ||
99 | for _, pload := range allPayloads { | 101 | for _, pload := range allPayloads { |
100 | if pload.Type == id{ | 102 | if pload.Type == id{ |
101 | for _, f := range pload.Fields { | 103 | for _, f := range pload.Fields { |
102 | fields = append(fields, f) | 104 | fields = append(fields, f) |
103 | } | 105 | } |
104 | } | 106 | } |
105 | } | 107 | } |
106 | 108 | ||
107 | return fields | 109 | return fields |
108 | } | 110 | } |
109 | 111 | ||
110 | func loadIdField(id string) string { | 112 | func loadIdField(id string) string { |
111 | for _, pload := range allPayloads { | 113 | for _, pload := range allPayloads { |
112 | if pload.Type == id { | 114 | if pload.Type == id { |
113 | return pload.IdField | 115 | return pload.IdField |
114 | } | 116 | } |
115 | } | 117 | } |
116 | return "" | 118 | return "" |
117 | } | 119 | } |
118 | 120 | ||
119 | func loadCorrelations(id string) []CorrelationField { | 121 | func loadCorrelations(id string) []CorrelationField { |
120 | resp := make([]CorrelationField, 0) | 122 | resp := make([]CorrelationField, 0) |
121 | 123 | ||
122 | for _, pload := range allPayloads { | 124 | for _, pload := range allPayloads { |
123 | if pload.Type == id { | 125 | if pload.Type == id { |
124 | for _, f := range pload.Correlations { | 126 | for _, f := range pload.Correlations { |
125 | resp = append(resp, f) | 127 | resp = append(resp, f) |
126 | } | 128 | } |
127 | } | 129 | } |
128 | } | 130 | } |
129 | 131 | ||
130 | return resp | 132 | return resp |
131 | } | 133 | } |
132 | 134 | ||
133 | func InitTables(db *ora.Ses, project string) error { | 135 | func InitTables(db *ora.Ses, project string) error { |
134 | jsonbuf, _ := fetchTablesConfig(db, EqualQuotes(project)) | 136 | jsonbuf, _ := fetchJSON(db, EqualQuotes(project)) |
135 | json.Unmarshal(jsonbuf, &allPayloads) | 137 | json.Unmarshal(jsonbuf, &allPayloads) |
136 | if len(allPayloads) == 0 { | 138 | if len(allPayloads) == 0 { |
137 | return errors.New("tables config is corrupt") | 139 | return errors.New("tables config is corrupt") |
138 | } | 140 | } |
139 | return nil | 141 | return nil |
140 | } | 142 | } |
141 | 143 | ||
142 | func fetchTablesConfig(db *ora.Ses, project string) ([]byte, error) { | 144 | func fetchJSON(db *ora.Ses, project string) ([]byte, error) { |
143 | stmt, err := db.Prep(`SELECT | 145 | stmt, err := db.Prep(`SELECT |
144 | JSON_CLOB | 146 | JSON_CLOB |
145 | FROM TABLES_CONFIG | 147 | FROM TABLES_CONFIG |
146 | WHERE PROJEKAT` + project, ora.S) | 148 | WHERE PROJEKAT` + project, ora.S) |
147 | defer stmt.Close() | 149 | defer stmt.Close() |
148 | 150 | ||
149 | if err != nil { | 151 | if err != nil { |
150 | return nil, err | 152 | return nil, err |
151 | } | 153 | } |
152 | 154 | ||
153 | rset, err := stmt.Qry() | 155 | rset, err := stmt.Qry() |
154 | if err != nil { | 156 | if err != nil { |
155 | return nil, err | 157 | return nil, err |
156 | } | 158 | } |
157 | 159 | ||
158 | bytes := make([]byte, 0) | 160 | bytes := make([]byte, 0) |
159 | if rset.Next() { | 161 | if rset.Next() { |
160 | lob := rset.Row[0].(io.Reader) | 162 | lob := rset.Row[0].(io.Reader) |
161 | bytes, err = ioutil.ReadAll(lob) | 163 | bytes, err = ioutil.ReadAll(lob) |
162 | if err != nil { | 164 | if err != nil { |
165 | // Ignore for now, it's some weird streaming read/write LOB error. | ||
163 | // TODO: Find a fix for this. | 166 | // TODO: Find a fix for this. |
164 | // Ignore, it's some weird streaming read/write LOB error. | ||
165 | //return nil, err | 167 | //return nil, err |
166 | } | 168 | } |
167 | } | 169 | } |
168 | 170 | ||
169 | return bytes, nil | 171 | return bytes, nil |
170 | } | 172 | } |
171 | 173 |
list_config.go
1 | package restutility | 1 | package restutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "gopkg.in/rana/ora.v3" | 4 | "gopkg.in/rana/ora.v3" |
5 | ) | 5 | ) |
6 | 6 | ||
7 | type ListOptions struct { | 7 | type ListOptions struct { |
8 | GlobalFilter bool `json:"globalFilter"` | 8 | GlobalFilter bool `json:"globalFilter"` |
9 | LocalFilters bool `json:"localFilters"` | 9 | LocalFilters bool `json:"localFilters"` |
10 | RemoteFilters bool `json:"remoteFilters"` | 10 | RemoteFilters bool `json:"remoteFilters"` |
11 | Pagination bool `json:"pagination"` | 11 | Pagination bool `json:"pagination"` |
12 | PageSize uint64 `json:"pageSize"` | 12 | PageSize uint64 `json:"pageSize"` |
13 | Pivot bool `json:"pivot"` | 13 | Pivot bool `json:"pivot"` |
14 | Detail bool `json:"detail"` | 14 | Detail bool `json:"detail"` |
15 | } | 15 | } |
16 | 16 | ||
17 | type ListFilter struct { | 17 | type ListFilter struct { |
18 | Position uint32 `json:"-"` | ||
18 | ObjectType string `json:"-"` | 19 | ObjectType string `json:"-"` |
19 | FiltersField string `json:"filtersField"` | 20 | FiltersField string `json:"filtersField"` |
20 | DefaultValues string `json:"defaultValues"` | 21 | DefaultValues string `json:"defaultValues"` |
21 | FiltersType string `json:"filtersType"` | 22 | FiltersType string `json:"filtersType"` |
22 | FiltersLabel string `json:"filtersLabel"` | 23 | FiltersLabel string `json:"filtersLabel"` |
23 | DropdownConfig Dropdown `json:"dropdownConfig"` | 24 | DropdownConfig Dropdown `json:"dropdownConfig"` |
24 | } | 25 | } |
25 | 26 | ||
26 | type Dropdown struct { | 27 | type Dropdown struct { |
27 | ObjectType string `json:"objectType"` | 28 | ObjectType string `json:"objectType"` |
28 | FiltersField string `json:"filtersField"` | 29 | FiltersField string `json:"filtersField"` |
29 | IdField string `json:"idField"` | 30 | IdField string `json:"idField"` |
30 | LabelField string `json:"labelField"` | 31 | LabelField string `json:"labelField"` |
31 | 32 | ||
32 | } | 33 | } |
33 | 34 | ||
34 | type ListGraph struct { | 35 | type ListGraph struct { |
35 | ObjectType string `json:"objectType"` | 36 | ObjectType string `json:"objectType"` |
36 | X string `json:"xField"` | 37 | X string `json:"xField"` |
37 | Y string `json:"yField"` | 38 | Y string `json:"yField"` |
38 | GroupField string `json:"groupField"` | 39 | GroupField string `json:"groupField"` |
39 | Label string `json:"label"` | 40 | Label string `json:"label"` |
40 | } | 41 | } |
41 | 42 | ||
42 | type ListActions struct { | 43 | type ListActions struct { |
43 | Create bool `json:"create"` | 44 | Create bool `json:"create"` |
44 | Update bool `json:"update"` | 45 | Update bool `json:"update"` |
45 | Delete bool `json:"delete"` | 46 | Delete bool `json:"delete"` |
46 | Export bool `json:"export"` | 47 | Export bool `json:"export"` |
47 | Print bool `json:"print"` | 48 | Print bool `json:"print"` |
48 | Graph bool `json:"graph"` | 49 | Graph bool `json:"graph"` |
49 | } | 50 | } |
50 | 51 | ||
51 | type ListChildNode struct { | 52 | type ListNavNode struct { |
52 | ObjectType string `json:"objectType"` | 53 | ObjectType string `json:"objectType"` |
53 | LabelField string `json:"label"` | 54 | LabelField string `json:"label"` |
54 | Icon string `json:"icon"` | 55 | Icon string `json:"icon"` |
56 | ParentObjectType string `json:"parentObjectType"` | ||
57 | ParentIdField string `json:"parentIdField"` | ||
55 | } | 58 | } |
56 | 59 | ||
57 | type ListParentNode struct { | 60 | type ListParentNode struct { |
58 | ObjectType string `json:"objectType"` | 61 | ObjectType string `json:"objectType"` |
59 | LabelField string `json:"labelField"` | 62 | LabelField string `json:"labelField"` |
60 | FilterField string `json:"filterField"` | 63 | FilterField string `json:"filterField"` |
61 | } | 64 | } |
62 | 65 | ||
63 | type ListPivot struct { | 66 | type ListPivot struct { |
64 | ObjectType string `json:"objectType"` | 67 | ObjectType string `json:"objectType"` |
65 | GroupField string `json:"groupField"` | 68 | GroupField string `json:"groupField"` |
66 | DistinctField string `json:"distinctField"` | 69 | DistinctField string `json:"distinctField"` |
67 | Value string `json:"valueField"` | 70 | Value string `json:"valueField"` |
68 | } | 71 | } |
69 | 72 | ||
70 | type ListDetails struct { | 73 | type ListDetails struct { |
71 | ObjectType string `json:"objectType"` | 74 | ObjectType string `json:"objectType"` |
72 | ParentObjectType string `json:"parentObjectType"` | 75 | ParentObjectType string `json:"parentObjectType"` |
73 | ParentFilterField string `json:"parentFilterField"` | 76 | ParentFilterField string `json:"parentFilterField"` |
74 | SingleDetail bool `json:"singleDetail"` | 77 | SingleDetail bool `json:"singleDetail"` |
75 | } | 78 | } |
76 | 79 | ||
77 | type ListConfig struct { | 80 | type ListConfig struct { |
78 | ObjectType string `json:"objectType"` | 81 | ObjectType string `json:"objectType"` |
79 | Title string `json:"title"` | 82 | Title string `json:"title"` |
80 | LazyLoad bool `json:"lazyLoad"` | 83 | LazyLoad bool `json:"lazyLoad"` |
81 | InlineEdit bool `json:"inlineEdit"` | 84 | InlineEdit bool `json:"inlineEdit"` |
82 | Options ListOptions `json:"options"` | 85 | Options ListOptions `json:"options"` |
83 | Filters []ListFilter `json:"defaultFilters"` | 86 | Filters []ListFilter `json:"defaultFilters"` |
84 | Graphs []ListGraph `json:"graphs"` | 87 | Graphs []ListGraph `json:"graphs"` |
85 | Actions ListActions `json:"actions"` | 88 | Actions ListActions `json:"actions"` |
86 | Parent []ListParentNode `json:"parent"` | 89 | Parent []ListParentNode `json:"parent"` |
87 | Children []ListChildNode `json:"children"` | 90 | Navigation []ListNavNode `json:"navigation"` |
88 | Pivots []ListPivot `json:"pivots"` | 91 | Pivots []ListPivot `json:"pivots"` |
89 | Details ListDetails `json:"details"` | 92 | Details ListDetails `json:"details"` |
90 | } | 93 | } |
91 | 94 | ||
92 | func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { | 95 | func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { |
93 | resp := NewDefaultList(objType) | 96 | resp := NewDefaultList(objType) |
94 | var err error | 97 | var err error |
95 | 98 | ||
96 | err = setListParams(db, &resp, objType) | 99 | err = setListParams(db, &resp, objType) |
97 | resp.Children, err = getListChildren(db, objType) | 100 | resp.Navigation, err = getListNavigation(db, objType) |
98 | resp.Actions, err = getListActions(db, objType) | 101 | resp.Actions, err = getListActions(db, objType) |
99 | resp.Filters, err = getListFilters(db, objType) | 102 | resp.Filters, err = getListFilters(db, objType) |
100 | resp.Options, err = getListOptions(db, objType) | 103 | resp.Options, err = getListOptions(db, objType) |
101 | resp.Parent, err = getListParent(db, objType) | 104 | resp.Parent, err = getListParent(db, objType) |
102 | resp.Graphs, err = getListGraph(db, objType) | 105 | resp.Graphs, err = getListGraph(db, objType) |
103 | resp.Pivots, err = getListPivot(db, objType) | 106 | resp.Pivots, err = getListPivot(db, objType) |
104 | resp.Details, err = getListDetails(db, objType) | 107 | resp.Details, err = getListDetails(db, objType) |
105 | 108 | ||
106 | if err != nil { | 109 | if err != nil { |
107 | return ListConfig{}, err | 110 | return ListConfig{}, err |
108 | } | 111 | } |
109 | 112 | ||
110 | return resp, nil | 113 | return resp, nil |
111 | } | 114 | } |
112 | 115 | ||
113 | func GetListConfigObjectIdField(db *ora.Ses, otype string) string { | 116 | func GetListConfigObjectIdField(db *ora.Ses, otype string) string { |
114 | var resp string | 117 | var resp string |
115 | var err error | 118 | var err error |
116 | var stmt *ora.Stmt | 119 | var stmt *ora.Stmt |
117 | 120 | ||
118 | stmt, err = db.Prep(`SELECT | 121 | stmt, err = db.Prep(`SELECT |
119 | ID_FIELD | 122 | ID_FIELD |
120 | FROM LIST_CONFIG_ID_FIELD | 123 | FROM LIST_CONFIG_ID_FIELD |
121 | WHERE OBJECT_TYPE = '` + otype + `'`, | 124 | WHERE OBJECT_TYPE = '` + otype + `'`, |
122 | ora.S) | 125 | ora.S) |
123 | 126 | ||
124 | defer stmt.Close() | 127 | defer stmt.Close() |
125 | 128 | ||
126 | if err != nil { | 129 | if err != nil { |
127 | return "" | 130 | return "" |
128 | } | 131 | } |
129 | 132 | ||
130 | rset, err := stmt.Qry() | 133 | rset, err := stmt.Qry() |
131 | if rset.Next() { | 134 | if rset.Next() { |
132 | resp = rset.Row[0].(string) | 135 | resp = rset.Row[0].(string) |
133 | } | 136 | } |
134 | 137 | ||
135 | if rset.Err != nil { | 138 | if rset.Err != nil { |
136 | return "" | 139 | return "" |
137 | } | 140 | } |
138 | 141 | ||
139 | return resp | 142 | return resp |
140 | } | 143 | } |
141 | 144 | ||
142 | func NewDefaultList(objType string) ListConfig { | 145 | func NewDefaultList(objType string) ListConfig { |
143 | list := ListConfig{ | 146 | list := ListConfig{ |
144 | ObjectType: objType, | 147 | ObjectType: objType, |
145 | Title: objType, | 148 | Title: objType, |
146 | LazyLoad: false, | 149 | LazyLoad: false, |
147 | Options: ListOptions{ | 150 | Options: ListOptions{ |
148 | GlobalFilter: true, | 151 | GlobalFilter: true, |
149 | LocalFilters: true, | 152 | LocalFilters: true, |
150 | RemoteFilters: false, | 153 | RemoteFilters: false, |
151 | Pagination: true, | 154 | Pagination: true, |
152 | PageSize: 20, | 155 | PageSize: 20, |
153 | }, | 156 | }, |
154 | Filters: nil, | 157 | Filters: nil, |
155 | Actions: ListActions{ | 158 | Actions: ListActions{ |
156 | Create: false, | 159 | Create: false, |
157 | Update: false, | 160 | Update: false, |
158 | Delete: false, | 161 | Delete: false, |
159 | Export: false, | 162 | Export: false, |
160 | Print: false, | 163 | Print: false, |
161 | Graph: false, | 164 | Graph: false, |
162 | }, | 165 | }, |
163 | Parent: nil, | 166 | Parent: nil, |
164 | Children: nil, | 167 | Navigation: nil, |
165 | } | 168 | } |
166 | 169 | ||
167 | return list | 170 | return list |
168 | } | 171 | } |
169 | 172 | ||
170 | func setListParams(db *ora.Ses, list *ListConfig, objType string) error { | 173 | func setListParams(db *ora.Ses, list *ListConfig, objType string) error { |
171 | var err error | 174 | var err error |
172 | var stmt *ora.Stmt | 175 | var stmt *ora.Stmt |
173 | query := `SELECT | 176 | query := `SELECT |
174 | OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT | 177 | OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT |
175 | FROM LIST_CONFIG | 178 | FROM LIST_CONFIG |
176 | WHERE OBJECT_TYPE = '` + objType + `'` | 179 | WHERE OBJECT_TYPE = '` + objType + `'` |
177 | 180 | ||
178 | stmt, err = db.Prep(query, ora.S, ora.S, ora.U32, ora.U32) | 181 | stmt, err = db.Prep(query, ora.S, ora.S, ora.U32, ora.U32) |
179 | if err != nil { | 182 | if err != nil { |
180 | return err | 183 | return err |
181 | } | 184 | } |
182 | defer stmt.Close() | 185 | defer stmt.Close() |
183 | 186 | ||
184 | rset, err := stmt.Qry() | 187 | rset, err := stmt.Qry() |
185 | if err != nil { | 188 | if err != nil { |
186 | return err | 189 | return err |
187 | } | 190 | } |
188 | if rset.Next() { | 191 | if rset.Next() { |
189 | otype := rset.Row[0].(string) | 192 | otype := rset.Row[0].(string) |
190 | if otype != "" { | 193 | if otype != "" { |
191 | list.ObjectType = otype | 194 | list.ObjectType = otype |
192 | } | 195 | } |
193 | 196 | ||
194 | title := rset.Row[1].(string) | 197 | title := rset.Row[1].(string) |
195 | if title != "" { | 198 | if title != "" { |
196 | list.Title = title | 199 | list.Title = title |
197 | } | 200 | } |
198 | list.LazyLoad = rset.Row[2].(uint32) != 0 | 201 | list.LazyLoad = rset.Row[2].(uint32) != 0 |
199 | list.InlineEdit = rset.Row[3].(uint32) != 0 | 202 | list.InlineEdit = rset.Row[3].(uint32) != 0 |
200 | } | 203 | } |
201 | if rset.Err != nil { | 204 | if rset.Err != nil { |
202 | return rset.Err | 205 | return rset.Err |
203 | } | 206 | } |
204 | return nil | 207 | return nil |
205 | } | 208 | } |
206 | 209 | ||
207 | func getListChildren(db *ora.Ses, objType string) ([]ListChildNode, error) { | 210 | func getListNavigation(db *ora.Ses, objType string) ([]ListNavNode, error) { |
208 | resp := make([]ListChildNode, 0) | 211 | resp := make([]ListNavNode, 0) |
209 | var err error | 212 | var err error |
210 | var stmt *ora.Stmt | 213 | var stmt *ora.Stmt |
211 | query := `SELECT | 214 | query := `SELECT |
212 | OBJECT_TYPE, LABEL, ICON | 215 | a.OBJECT_TYPE, a.LABEL, a.ICON, b.LIST_OBJECT_TYPE, b.PARENT_ID_FIELD, b.RB |
213 | FROM LIST_CONFIG_CHILD | 216 | FROM LIST_CONFIG_CHILD a |
214 | WHERE PARENT_OBJECT_TYPE = '` + objType + `'` | 217 | JOIN LIST_CONFIG_NAVIGATION b ON a.PARENT_CHILD_ID = b.PARENT_CHILD_ID |
218 | WHERE a.PARENT_OBJECT_TYPE = '`+objType+`' | ||
219 | ORDER BY b.RB ASC` | ||
215 | 220 | ||
216 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) | 221 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S) |
217 | if err != nil { | 222 | if err != nil { |
218 | return resp, err | 223 | return resp, err |
219 | } | 224 | } |
220 | defer stmt.Close() | 225 | defer stmt.Close() |
221 | 226 | ||
222 | rset, err := stmt.Qry() | 227 | rset, err := stmt.Qry() |
223 | if err != nil { | 228 | if err != nil { |
224 | return resp, err | 229 | return resp, err |
225 | } | 230 | } |
226 | for rset.Next() { | 231 | for rset.Next() { |
227 | resp = append(resp, ListChildNode{ | 232 | resp = append(resp, ListNavNode{ |
228 | ObjectType: rset.Row[0].(string), | 233 | ObjectType: rset.Row[0].(string), |
229 | LabelField: rset.Row[1].(string), | 234 | LabelField: rset.Row[1].(string), |
230 | Icon: rset.Row[2].(string), | 235 | Icon: rset.Row[2].(string), |
236 | ParentObjectType: rset.Row[3].(string), | ||
237 | ParentIdField: rset.Row[4].(string), | ||
231 | }) | 238 | }) |
232 | } | 239 | } |
233 | if rset.Err != nil { | 240 | if rset.Err != nil { |
234 | return nil, rset.Err | 241 | return nil, rset.Err |
235 | } | 242 | } |
236 | 243 | ||
237 | return resp, nil | 244 | return resp, nil |
238 | } | 245 | } |
239 | 246 | ||
240 | func getListActions(db *ora.Ses, objType string) (ListActions, error) { | 247 | func getListActions(db *ora.Ses, objType string) (ListActions, error) { |
241 | var resp ListActions | 248 | var resp ListActions |
242 | var err error | 249 | var err error |
243 | var stmt *ora.Stmt | 250 | var stmt *ora.Stmt |
244 | query := `SELECT | 251 | query := `SELECT |
245 | ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT, | 252 | ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT, |
246 | ACTION_PRINT, ACTION_GRAPH | 253 | ACTION_PRINT, ACTION_GRAPH |
247 | FROM LIST_CONFIG | 254 | FROM LIST_CONFIG |
248 | WHERE OBJECT_TYPE = '` + objType + `'` | 255 | WHERE OBJECT_TYPE = '` + objType + `'` |
249 | 256 | ||
250 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, | 257 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, |
251 | ora.U32, ora.U32) | 258 | ora.U32, ora.U32) |
252 | if err != nil { | 259 | if err != nil { |
253 | return ListActions{}, err | 260 | return ListActions{}, err |
254 | } | 261 | } |
255 | defer stmt.Close() | 262 | defer stmt.Close() |
256 | 263 | ||
257 | rset, err := stmt.Qry() | 264 | rset, err := stmt.Qry() |
258 | if err != nil { | 265 | if err != nil { |
259 | return ListActions{}, err | 266 | return ListActions{}, err |
260 | } | 267 | } |
261 | if rset.Next() { | 268 | if rset.Next() { |
262 | resp.Create = rset.Row[0].(uint32) != 0 | 269 | resp.Create = rset.Row[0].(uint32) != 0 |
263 | resp.Update = rset.Row[1].(uint32) != 0 | 270 | resp.Update = rset.Row[1].(uint32) != 0 |
264 | resp.Delete = rset.Row[2].(uint32) != 0 | 271 | resp.Delete = rset.Row[2].(uint32) != 0 |
265 | resp.Export = rset.Row[3].(uint32) != 0 | 272 | resp.Export = rset.Row[3].(uint32) != 0 |
266 | resp.Print = rset.Row[4].(uint32) != 0 | 273 | resp.Print = rset.Row[4].(uint32) != 0 |
267 | resp.Graph = rset.Row[5].(uint32) != 0 | 274 | resp.Graph = rset.Row[5].(uint32) != 0 |
268 | } | 275 | } |
269 | if rset.Err != nil { | 276 | if rset.Err != nil { |
270 | return ListActions{}, rset.Err | 277 | return ListActions{}, rset.Err |
271 | } | 278 | } |
272 | return resp, nil | 279 | return resp, nil |
273 | } | 280 | } |
274 | 281 | ||
275 | func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { | 282 | func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { |
276 | resp := make([]ListFilter, 0) | 283 | resp := make([]ListFilter, 0) |
277 | filtersField, err := getFilterFields(db, objType) | 284 | filtersFields, err := getFilterFieldsAndPosition(db, objType) |
278 | if err != nil { | 285 | if err != nil { |
279 | return nil, err | 286 | return nil, err |
280 | } | 287 | } |
281 | for _, field := range filtersField { | 288 | for field, pos := range filtersFields { |
282 | filters, _ := getFiltersByFilterField(db, field) | 289 | filters, _ := getFiltersByFilterField(db, field) |
283 | for _, filter := range filters { | 290 | for _, filter := range filters { |
284 | var f ListFilter | 291 | var f ListFilter |
292 | f.Position = pos | ||
285 | f.ObjectType = objType | 293 | f.ObjectType = objType |
286 | f.FiltersField = field | 294 | f.FiltersField = field |
287 | f.DefaultValues = filter.DefaultValues | 295 | f.DefaultValues = filter.DefaultValues |
288 | f.FiltersLabel = filter.Label | 296 | f.FiltersLabel = filter.Label |
289 | f.FiltersType = filter.Type | 297 | f.FiltersType = filter.Type |
290 | if filter.Type == "dropdown" { | 298 | if filter.Type == "dropdown" { |
291 | f.DropdownConfig, err = getFilterDropdownConfig(db, field) | 299 | f.DropdownConfig, err = getFilterDropdownConfig(db, field) |
292 | if err != nil { | 300 | if err != nil { |
293 | return nil, err | 301 | return nil, err |
294 | } | 302 | } |
295 | } | 303 | } |
296 | resp = append(resp, f) | 304 | resp = append(resp, f) |
297 | } | 305 | } |
298 | } | 306 | } |
299 | 307 | ||
308 | sortFilters(resp) | ||
309 | |||
300 | return resp, nil | 310 | return resp, nil |
301 | } | 311 | } |
302 | 312 | ||
303 | func getFilterFields(db *ora.Ses, objType string) ([]string, error) { | 313 | func getFilterFieldsAndPosition(db *ora.Ses, objType string) (map[string]uint32, error) { |
304 | filtersField := make([]string, 0) | 314 | filtersField := make(map[string]uint32, 0) |
305 | var err error | 315 | var err error |
306 | var stmt *ora.Stmt | 316 | var stmt *ora.Stmt |
307 | query := `SELECT | 317 | query := `SELECT |
308 | FILTERS_FIELD | 318 | FILTERS_FIELD, RB |
309 | FROM LIST_CONFIG_FILTERS | 319 | FROM LIST_CONFIG_FILTERS |
310 | WHERE OBJECT_TYPE = '` + objType + `'` | 320 | WHERE OBJECT_TYPE = '` + objType + `'` |
311 | 321 | ||
312 | stmt, err = db.Prep(query, ora.S) | 322 | stmt, err = db.Prep(query, ora.S, ora.U32) |
313 | if err != nil { | 323 | if err != nil { |
314 | return nil, err | 324 | return nil, err |
315 | } | 325 | } |
316 | defer stmt.Close() | 326 | defer stmt.Close() |
317 | 327 | ||
318 | rset, err := stmt.Qry() | 328 | rset, err := stmt.Qry() |
319 | if err != nil { | 329 | if err != nil { |
320 | return nil, err | 330 | return nil, err |
321 | } | 331 | } |
322 | for rset.Next() { | 332 | for rset.Next() { |
323 | filtersField = append(filtersField, rset.Row[0].(string)) | 333 | filtersField[rset.Row[0].(string)] = rset.Row[1].(uint32) |
324 | } | 334 | } |
325 | if rset.Err != nil { | 335 | if rset.Err != nil { |
326 | return nil, rset.Err | 336 | return nil, rset.Err |
327 | } | 337 | } |
328 | return filtersField, nil | 338 | return filtersField, nil |
329 | } | 339 | } |
330 | 340 | ||
331 | type TempFilter struct { | 341 | type _filter struct { |
332 | DefaultValues string | 342 | DefaultValues string |
333 | Label string | 343 | Label string |
334 | Type string | 344 | Type string |
335 | } | 345 | } |
336 | 346 | ||
337 | func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]TempFilter, error) { | 347 | func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error) { |
338 | resp := make([]TempFilter, 0) | 348 | resp := make([]_filter, 0) |
339 | var err error | 349 | var err error |
340 | var stmt *ora.Stmt | 350 | var stmt *ora.Stmt |
341 | query := `SELECT | 351 | query := `SELECT |
342 | FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES | 352 | FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES |
343 | FROM LIST_FILTERS_FIELD | 353 | FROM LIST_FILTERS_FIELD |
344 | WHERE FILTERS_FIELD = '` + filtersField + `'` | 354 | WHERE FILTERS_FIELD = '` + filtersField + `'` |
345 | 355 | ||
346 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) | 356 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) |
347 | if err != nil { | 357 | if err != nil { |
348 | return resp, err | 358 | return resp, err |
349 | } | 359 | } |
350 | defer stmt.Close() | 360 | defer stmt.Close() |
351 | 361 | ||
352 | rset, err := stmt.Qry() | 362 | rset, err := stmt.Qry() |
353 | if err != nil { | 363 | if err != nil { |
354 | return resp, err | 364 | return resp, err |
355 | } | 365 | } |
356 | for rset.Next() { | 366 | for rset.Next() { |
357 | resp = append(resp, TempFilter{ | 367 | resp = append(resp, _filter{ |
358 | Type: rset.Row[0].(string), | 368 | Type: rset.Row[0].(string), |
359 | Label: rset.Row[1].(string), | 369 | Label: rset.Row[1].(string), |
360 | DefaultValues: rset.Row[2].(string), | 370 | DefaultValues: rset.Row[2].(string), |
361 | }) | 371 | }) |
362 | } | 372 | } |
363 | if rset.Err != nil { | 373 | if rset.Err != nil { |
364 | return resp, rset.Err | 374 | return resp, rset.Err |
365 | } | 375 | } |
366 | return resp, nil | 376 | return resp, nil |
367 | } | 377 | } |
368 | 378 | ||
369 | func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { | 379 | func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { |
370 | var resp Dropdown | 380 | var resp Dropdown |
371 | var err error | 381 | var err error |
372 | var stmt *ora.Stmt | 382 | var stmt *ora.Stmt |
373 | query := `SELECT | 383 | query := `SELECT |
374 | FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD | 384 | FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD |
375 | FROM LIST_DROPDOWN_FILTER | 385 | FROM LIST_DROPDOWN_FILTER |
376 | WHERE FILTERS_FIELD = '` + filtersField + `'` | 386 | WHERE FILTERS_FIELD = '` + filtersField + `'` |
377 | 387 | ||
378 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 388 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
379 | if err != nil { | 389 | if err != nil { |
380 | return resp, err | 390 | return resp, err |
381 | } | 391 | } |
382 | defer stmt.Close() | 392 | defer stmt.Close() |
383 | 393 | ||
384 | rset, err := stmt.Qry() | 394 | rset, err := stmt.Qry() |
385 | if err != nil { | 395 | if err != nil { |
386 | return resp, err | 396 | return resp, err |
387 | } | 397 | } |
388 | if rset.Next() { | 398 | if rset.Next() { |
389 | resp.FiltersField = rset.Row[0].(string) | 399 | resp.FiltersField = rset.Row[0].(string) |
390 | resp.ObjectType = rset.Row[1].(string) | 400 | resp.ObjectType = rset.Row[1].(string) |
391 | resp.IdField = rset.Row[2].(string) | 401 | resp.IdField = rset.Row[2].(string) |
392 | resp.LabelField = rset.Row[3].(string) | 402 | resp.LabelField = rset.Row[3].(string) |
393 | } | 403 | } |
394 | if rset.Err != nil { | 404 | if rset.Err != nil { |
395 | return resp, rset.Err | 405 | return resp, rset.Err |
396 | } | 406 | } |
397 | return resp, nil | 407 | return resp, nil |
398 | } | 408 | } |
399 | 409 | ||
410 | func sortFilters(filters []ListFilter) { | ||
411 | done := false | ||
412 | var temp ListFilter | ||
413 | for !done { | ||
414 | done = true | ||
415 | for i := 0; i < len(filters) - 1; i++ { | ||
416 | if filters[i].Position > filters[i+1].Position { | ||
417 | done = false | ||
418 | temp = filters[i] | ||
419 | filters[i] = filters[i+1] | ||
420 | filters[i+1] = temp | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
400 | func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { | 426 | func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { |
401 | resp := make([]ListGraph, 0) | 427 | resp := make([]ListGraph, 0) |
402 | var err error | 428 | var err error |
403 | var stmt *ora.Stmt | 429 | var stmt *ora.Stmt |
404 | query := `SELECT | 430 | query := `SELECT |
405 | OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL | 431 | OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL |
406 | FROM LIST_GRAPHS | 432 | FROM LIST_GRAPHS |
407 | WHERE OBJECT_TYPE = '` + objType + `'` | 433 | WHERE OBJECT_TYPE = '` + objType + `'` |
408 | 434 | ||
409 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 435 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
410 | if err != nil { | 436 | if err != nil { |
411 | return resp, err | 437 | return resp, err |
412 | } | 438 | } |
413 | defer stmt.Close() | 439 | defer stmt.Close() |
414 | 440 | ||
415 | rset, err := stmt.Qry() | 441 | rset, err := stmt.Qry() |
416 | if err != nil { | 442 | if err != nil { |
417 | return resp, err | 443 | return resp, err |
418 | } | 444 | } |
419 | for rset.Next() { | 445 | for rset.Next() { |
420 | resp = append(resp, ListGraph{ | 446 | resp = append(resp, ListGraph{ |
421 | ObjectType: rset.Row[0].(string), | 447 | ObjectType: rset.Row[0].(string), |
422 | X: rset.Row[1].(string), | 448 | X: rset.Row[1].(string), |
423 | Y: rset.Row[2].(string), | 449 | Y: rset.Row[2].(string), |
424 | GroupField: rset.Row[3].(string), | 450 | GroupField: rset.Row[3].(string), |
425 | Label: rset.Row[4].(string), | 451 | Label: rset.Row[4].(string), |
426 | }) | 452 | }) |
427 | } | 453 | } |
428 | if rset.Err != nil { | 454 | if rset.Err != nil { |
429 | return resp, rset.Err | 455 | return resp, rset.Err |
430 | } | 456 | } |
431 | return resp, nil | 457 | return resp, nil |
432 | } | 458 | } |
433 | 459 | ||
434 | func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { | 460 | func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { |
435 | var resp ListOptions | 461 | var resp ListOptions |
436 | var err error | 462 | var err error |
437 | var stmt *ora.Stmt | 463 | var stmt *ora.Stmt |
438 | query := `SELECT | 464 | query := `SELECT |
439 | GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION, | 465 | GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION, |
440 | PAGE_SIZE, PIVOT, DETAIL | 466 | PAGE_SIZE, PIVOT, DETAIL |
441 | FROM LIST_CONFIG | 467 | FROM LIST_CONFIG |
442 | WHERE OBJECT_TYPE = '` + objType + `'` | 468 | WHERE OBJECT_TYPE = '` + objType + `'` |
443 | 469 | ||
444 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, | 470 | stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32, |
445 | ora.U64, ora.U64, ora.U32) | 471 | ora.U64, ora.U64, ora.U32) |
446 | if err != nil { | 472 | if err != nil { |
447 | return ListOptions{}, err | 473 | return ListOptions{}, err |
448 | } | 474 | } |
449 | defer stmt.Close() | 475 | defer stmt.Close() |
450 | 476 | ||
451 | rset, err := stmt.Qry() | 477 | rset, err := stmt.Qry() |
452 | if err != nil { | 478 | if err != nil { |
453 | return ListOptions{}, err | 479 | return ListOptions{}, err |
454 | } | 480 | } |
455 | if rset.Next() { | 481 | if rset.Next() { |
456 | resp.GlobalFilter = rset.Row[0].(uint32) != 0 | 482 | resp.GlobalFilter = rset.Row[0].(uint32) != 0 |
457 | resp.LocalFilters = rset.Row[1].(uint32) != 0 | 483 | resp.LocalFilters = rset.Row[1].(uint32) != 0 |
458 | resp.RemoteFilters = rset.Row[2].(uint32) != 0 | 484 | resp.RemoteFilters = rset.Row[2].(uint32) != 0 |
459 | resp.Pagination = rset.Row[3].(uint32) != 0 | 485 | resp.Pagination = rset.Row[3].(uint32) != 0 |
460 | resp.PageSize = rset.Row[4].(uint64) | 486 | resp.PageSize = rset.Row[4].(uint64) |
461 | resp.Pivot = rset.Row[5].(uint64) != 0 | 487 | resp.Pivot = rset.Row[5].(uint64) != 0 |
462 | resp.Detail = rset.Row[6].(uint32) != 0 | 488 | resp.Detail = rset.Row[6].(uint32) != 0 |
463 | } | 489 | } |
464 | if rset.Err != nil { | 490 | if rset.Err != nil { |
465 | return ListOptions{}, rset.Err | 491 | return ListOptions{}, rset.Err |
466 | } | 492 | } |
467 | return resp, nil | 493 | return resp, nil |
468 | } | 494 | } |
469 | 495 | ||
470 | func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { | 496 | func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { |
471 | resp := make([]ListParentNode, 0) | 497 | resp := make([]ListParentNode, 0) |
472 | var err error | 498 | var err error |
473 | var stmt *ora.Stmt | 499 | var stmt *ora.Stmt |
474 | query := `SELECT | 500 | query := `SELECT |
475 | PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD | 501 | PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD |
476 | FROM LIST_CONFIG_CHILD | 502 | FROM LIST_CONFIG_CHILD |
477 | WHERE OBJECT_TYPE = '` + objType + `'` | 503 | WHERE OBJECT_TYPE = '` + objType + `'` |
478 | 504 | ||
479 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) | 505 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S) |
480 | if err != nil { | 506 | if err != nil { |
481 | return resp, err | 507 | return resp, err |
482 | } | 508 | } |
483 | defer stmt.Close() | 509 | defer stmt.Close() |
484 | 510 | ||
485 | rset, err := stmt.Qry() | 511 | rset, err := stmt.Qry() |
486 | if err != nil { | 512 | if err != nil { |
487 | return resp, err | 513 | return resp, err |
488 | } | 514 | } |
489 | for rset.Next() { | 515 | for rset.Next() { |
490 | resp = append(resp, ListParentNode{ | 516 | resp = append(resp, ListParentNode{ |
491 | ObjectType: rset.Row[0].(string), | 517 | ObjectType: rset.Row[0].(string), |
492 | LabelField: rset.Row[1].(string), | 518 | LabelField: rset.Row[1].(string), |
493 | FilterField: rset.Row[2].(string), | 519 | FilterField: rset.Row[2].(string), |
494 | }) | 520 | }) |
495 | } | 521 | } |
496 | if rset.Err != nil { | 522 | if rset.Err != nil { |
497 | return nil, rset.Err | 523 | return nil, rset.Err |
498 | } | 524 | } |
499 | 525 | ||
500 | return resp, nil | 526 | return resp, nil |
501 | } | 527 | } |
502 | 528 | ||
503 | func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { | 529 | func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { |
504 | resp := make([]ListPivot, 0) | 530 | resp := make([]ListPivot, 0) |
505 | var err error | 531 | var err error |
506 | var stmt *ora.Stmt | 532 | var stmt *ora.Stmt |
507 | query := `SELECT | 533 | query := `SELECT |
508 | OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD | 534 | OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD |
509 | FROM LIST_PIVOTS | 535 | FROM LIST_PIVOTS |
510 | WHERE OBJECT_TYPE = '` + objType + `'` | 536 | WHERE OBJECT_TYPE = '` + objType + `'` |
511 | 537 | ||
512 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) | 538 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S) |
513 | if err != nil { | 539 | if err != nil { |
514 | return resp, err | 540 | return resp, err |
515 | } | 541 | } |
516 | defer stmt.Close() | 542 | defer stmt.Close() |
517 | 543 | ||
518 | rset, err := stmt.Qry() | 544 | rset, err := stmt.Qry() |
519 | if err != nil { | 545 | if err != nil { |
520 | return resp, err | 546 | return resp, err |
521 | } | 547 | } |
522 | for rset.Next() { | 548 | for rset.Next() { |
523 | resp = append(resp, ListPivot{ | 549 | resp = append(resp, ListPivot{ |
524 | ObjectType: rset.Row[0].(string), | 550 | ObjectType: rset.Row[0].(string), |
525 | GroupField: rset.Row[1].(string), | 551 | GroupField: rset.Row[1].(string), |
526 | DistinctField: rset.Row[2].(string), | 552 | DistinctField: rset.Row[2].(string), |
527 | Value: rset.Row[3].(string), | 553 | Value: rset.Row[3].(string), |
528 | }) | 554 | }) |
529 | } | 555 | } |
530 | if rset.Err != nil { | 556 | if rset.Err != nil { |
531 | return nil, rset.Err | 557 | return nil, rset.Err |
532 | } | 558 | } |
533 | 559 | ||
534 | return resp, nil | 560 | return resp, nil |
535 | } | 561 | } |
536 | 562 | ||
537 | func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { | 563 | func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { |
538 | var resp ListDetails | 564 | var resp ListDetails |
539 | var err error | 565 | var err error |
540 | var stmt *ora.Stmt | 566 | var stmt *ora.Stmt |
541 | query := `SELECT | 567 | query := `SELECT |
542 | OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL | 568 | OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL |
543 | FROM LIST_CONFIG_DETAIL | 569 | FROM LIST_CONFIG_DETAIL |
544 | WHERE PARENT_OBJECT_TYPE = '` + objType + `'` | 570 | WHERE PARENT_OBJECT_TYPE = '` + objType + `'` |
545 | 571 | ||
546 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.U32) | 572 | stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.U32) |
547 | if err != nil { | 573 | if err != nil { |
548 | return resp, err | 574 | return resp, err |
549 | } | 575 | } |
550 | defer stmt.Close() | 576 | defer stmt.Close() |
551 | 577 | ||
552 | rset, err := stmt.Qry() | 578 | rset, err := stmt.Qry() |
553 | if err != nil { | 579 | if err != nil { |
554 | return resp, err | 580 | return resp, err |
555 | } | 581 | } |
556 | if rset.Next() { | 582 | if rset.Next() { |
557 | resp.ObjectType = rset.Row[0].(string) | 583 | resp.ObjectType = rset.Row[0].(string) |
558 | resp.ParentObjectType = rset.Row[1].(string) | 584 | resp.ParentObjectType = rset.Row[1].(string) |
559 | resp.ParentFilterField = rset.Row[2].(string) | 585 | resp.ParentFilterField = rset.Row[2].(string) |
560 | resp.SingleDetail = rset.Row[3].(uint32) != 0 | 586 | resp.SingleDetail = rset.Row[3].(uint32) != 0 |
561 | } | 587 | } |
562 | if rset.Err != nil { | 588 | if rset.Err != nil { |
563 | return resp, rset.Err | 589 | return resp, rset.Err |
564 | } | 590 | } |
565 | 591 | ||
566 | return resp, nil | 592 | return resp, nil |
567 | } | 593 | } |
568 | 594 |