Commit 7d3deb50df481b887b4f3b40d170a5cf7e15aa91

Authored by Marko Tikvić
1 parent 90f4ed0790
Exists in master and in 1 other branch v2

modified list_config with navigation (old children)

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
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
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