Commit ea858b8a7bf83999a16faf8b4709e73c0e7e6a9f

Authored by Marko Tikvić
1 parent 4b4ea384f8
Exists in master and in 1 other branch v2

refactoring

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