Commit c2ed2491115cb8a87f81c2c7f782fb817a473582

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

restutility -> webutility

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() (string, error) { 30 func generateSalt() (salt string, err error) {
31 salt := ""
32 rawsalt := make([]byte, saltSize) 31 rawsalt := make([]byte, saltSize)
33 _, err := rand.Read(rawsalt) 32
33 _, err = rand.Read(rawsalt)
34 if err != nil { 34 if err != nil {
35 return "", err 35 return "", err
36 } 36 }
37
37 salt = hex.EncodeToString(rawsalt) 38 salt = hex.EncodeToString(rawsalt)
38 return salt, nil 39 return salt, nil
39 } 40 }
40 41
41 func HashMessage(message string, presalt string) (string, string, error) { 42 func HashString(str string, presalt string) (hash, salt string, err error) {
42 hash, salt := "", ""
43 var err error
44
45 // chech if message is presalted 43 // chech if message is presalted
46 if presalt == "" { 44 if presalt == "" {
47 salt, err = GenerateSalt() 45 salt, err = generateSalt()
48 if err != nil { 46 if err != nil {
49 return "", "", err 47 return "", "", err
50 } 48 }
51 } else { 49 } else {
52 salt = presalt 50 salt = presalt
53 } 51 }
54 52
55 // convert strings to raw byte slices 53 // convert strings to raw byte slices
56 rawmessage := []byte(message) 54 rawstr := []byte(str)
57 rawsalt, err := hex.DecodeString(salt) 55 rawsalt, err := hex.DecodeString(salt)
58 if err != nil { 56 if err != nil {
59 return "", "", err 57 return "", "", err
60 } 58 }
61 rawdata := make([]byte, len(rawmessage) + len(rawsalt)) 59
62 rawdata = append(rawdata, rawmessage...) 60 rawdata := make([]byte, len(rawstr) + len(rawsalt))
61 rawdata = append(rawdata, rawstr...)
63 rawdata = append(rawdata, rawsalt...) 62 rawdata = append(rawdata, rawsalt...)
64 63
65 // hash message + salt 64 // hash message + salt
66 hasher := sha256.New() 65 hasher := sha256.New()
67 hasher.Write(rawdata) 66 hasher.Write(rawdata)
68 rawhash := hasher.Sum(nil) 67 rawhash := hasher.Sum(nil)
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 IssueAPIToken(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 },
format_utility.go
1 package restutility 1 package webutility
2 2
3 import ( 3 import (
4 "time" 4 "time"
5 "fmt"
5 ) 6 )
6 7
7 func UnixToDate(input int64) time.Time { 8 func UnixToDate(unix int64) time.Time {
8 return time.Unix(input, 0) 9 return time.Unix(unix, 0)
9 } 10 }
10 11
11 func DateToUnix(input interface{}) int64 { 12 func DateToUnix(date interface{}) int64 {
12 if input != nil { 13 if date != nil {
13 t := input.(time.Time) 14 t := date.(time.Time)
14 return t.Unix() 15 return t.Unix()
15 16
16 } 17 }
17 return 0 18 return 0
18 } 19 }
19 20
20 func EqualQuotes(input string) string { 21 func EqualQuotes(stmt string) string {
21 if input != "" { 22 if stmt != "" {
22 return " = '" + input + "'" 23 stmt = fmt.Sprintf(" = '%s'", stmt)
23 } 24 }
24 return "" 25 return stmt
25 } 26 }
26 27
27 func LikeQuotes(input string) string { 28 func LikeQuotes(stmt string) string {
28 if input != "" { 29 if stmt != "" {
29 return " LIKE UPPER('%" + input + "%')" 30 stmt = fmt.Sprintf(" LIKE UPPER('%s%s%s')", "%", stmt, "%")
30 } 31 }
31 return "" 32 return stmt
32 } 33 }
33 34
34 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 var _apiVersion = "/api/v1"
9 var _authEndPoint = "/token"
10
11 func SetApiVersion(ver string) string {
12 _apiVersion = ver
13 return _apiVersion
14 }
15
16 func SetAuthEndpoint(ep string) {
17 _authEndPoint = ep
18 }
19
20 const templateHttpErr500_EN = "An internal server error has occurred." 8 const templateHttpErr500_EN = "An internal server error has occurred."
21 const templateHttpErr500_RS = "Došlo je do greške na serveru." 9 const templateHttpErr500_RS = "Došlo je do greške na serveru."
22 const templateHttpErr400_EN = "Bad request: invalid request body." 10 const templateHttpErr400_EN = "Bad request: invalid request body."
23 const templateHttpErr400_RS = "Neispravan zahtev." 11 const templateHttpErr400_RS = "Neispravan zahtev."
12 const templateHttpErr401_EN = "Unauthorized request."
13 const templateHttpErr401_RS = "Neautorizovan zahtev."
24 14
25 type HttpError struct { 15 type httpError struct {
26 Error []HttpErrorDesc `json:"error"` 16 Error []HttpErrorDesc `json:"error"`
27 Request string `json:"request"` 17 Request string `json:"request"`
28 } 18 }
29 19
30 type HttpErrorDesc struct { 20 type HttpErrorDesc struct {
31 Lang string `json:"lang"` 21 Lang string `json:"lang"`
32 Desc string `json:"description"` 22 Desc string `json:"description"`
33 } 23 }
34 24
35 func RespondWithHttpError(w http.ResponseWriter, 25 func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) {
36 req *http.Request, 26 err := httpError{ desc, r.Method + " " + r.URL.Path }
37 code int,
38 httpErr []HttpErrorDesc) {
39
40 err := HttpError{
41 Error: httpErr,
42 Request: req.Method + " " + req.URL.Path,
43 }
44 w.WriteHeader(code) 27 w.WriteHeader(code)
45 json.NewEncoder(w).Encode(err) 28 json.NewEncoder(w).Encode(err)
46 } 29 }
47 30
48 func RespondWithHttpError400(w http.ResponseWriter, req *http.Request) { 31 func BadRequestResponse(w http.ResponseWriter, req *http.Request) {
49 RespondWithHttpError(w, req, http.StatusBadRequest, []HttpErrorDesc{ 32 ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{
50 {Lang: "en", Desc: templateHttpErr400_EN}, 33 { "en", templateHttpErr400_EN },
51 {Lang: "rs", Desc: templateHttpErr400_RS}, 34 { "rs", templateHttpErr400_RS },
52 }) 35 })
53 } 36 }
54 37
55 func RespondWithHttpError500(w http.ResponseWriter, req *http.Request) { 38 func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) {
56 RespondWithHttpError(w, req, http.StatusInternalServerError, []HttpErrorDesc{ 39 ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{
57 {Lang: "en", Desc: templateHttpErr500_EN}, 40 { "en", templateHttpErr500_EN },
58 {Lang: "rs", Desc: templateHttpErr500_RS}, 41 { "rs", templateHttpErr500_RS },
59 }) 42 })
60 } 43 }
61 44
62 //TODO: Add parameters to enable/disable roles authorization checks 45 func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) {
46 ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{
47 { "en", templateHttpErr500_EN },
48 { "rs", templateHttpErr500_RS },
49 })
50 }
51
52 // TODO: Check for content type
63 // Sets common headers and checks for token validity. 53 // Sets common headers and checks for token validity.
64 func HttpPreProc(handlerFunc http.HandlerFunc, authEnabled bool) http.HandlerFunc { 54 func WrapHandler(handlerFunc http.HandlerFunc, auth bool) http.HandlerFunc {
65 return func(w http.ResponseWriter, req *http.Request) { 55 return func(w http.ResponseWriter, req *http.Request) {
66 // @TODO: check Content-type header (must be application/json)
67 // ctype := w.Header.Get("Content-Type")
68 // if req.Method != "GET" && ctype != "application/json" {
69 // replyWithHttpError(w, req, http.StatusBadRequest,
70 // "Not a supported content type: " + ctype)
71 // }
72
73 w.Header().Set("Access-Control-Allow-Origin", "*") 56 w.Header().Set("Access-Control-Allow-Origin", "*")
57
74 w.Header().Set("Access-Control-Allow-Methods", 58 w.Header().Set("Access-Control-Allow-Methods",
75 `POST, 59 "POST, GET, PUT, DELETE, OPTIONS")
76 GET, 60
77 PUT,
78 DELETE,
79 OPTIONS`)
80 w.Header().Set("Access-Control-Allow-Headers", 61 w.Header().Set("Access-Control-Allow-Headers",
81 `Accept, 62 `Accept, Content-Type, Content-Length,
82 Content-Type, 63 Accept-Encoding, X-CSRF-Token, Authorization`)
83 Content-Length, 64
84 Accept-Encoding,
85 X-CSRF-Token,
86 Authorization`)
87 w.Header().Set("Content-Type", "application/json; charset=utf-8") 65 w.Header().Set("Content-Type", "application/json; charset=utf-8")
88 66
89 if req.Method == "OPTIONS" { 67 if req.Method == "OPTIONS" {
90 return 68 return
91 } 69 }
92 70
93 if authEnabled { 71 if auth {
94 if req.URL.Path != _apiVersion + _authEndPoint { 72 token := req.Header.Get("Authorization")
95 token := req.Header.Get("Authorization") 73 if _, err := ParseAPIToken(token); err != nil {
96 if _, err := ParseAPIToken(token); err != nil { 74 UnauthorizedResponse(w, req)
97 RespondWithHttpError(w, req, http.StatusUnauthorized, 75 return
98 []HttpErrorDesc{
99 {Lang: "en", Desc: "Unauthorized request."},
100 {Lang: "rs", Desc: "Neautorizovani zahtev."},
101 })
102 return
103 }
104 } 76 }
105 } 77 }
106 78
107 err := req.ParseForm() 79 err := req.ParseForm()
108 if err != nil { 80 if err != nil {
109 RespondWithHttpError400(w, req) 81 BadRequestResponse(w, req)
110 return 82 return
111 } 83 }
112 84
113 // execute HandlerFunc 85 // execute HandlerFunc
114 handlerFunc(w, req) 86 handlerFunc(w, req)
1 // @TODO: Be more verbose about corrupt config error. 1 package webutility
2 // Do the same errror checking when doing table reloading. 2
3 // Discard previous tables when doing reload. 3 import (
4 package restutility 4 "net/http"
5 5 "encoding/json"
6 import ( 6 "errors"
7 "net/http" 7 "gopkg.in/rana/ora.v3"
8 "encoding/json" 8 "io"
9 "errors" 9 "io/ioutil"
10 "sync"
10 "gopkg.in/rana/ora.v3" 11 )
11 "io" 12
13 var mu = &sync.Mutex{}
12 "io/ioutil" 14 var allPayloads []payloadBuff
13 "sync" 15
14 ) 16 type LangMap map[string]map[string]string
15 17
16 var mu = &sync.Mutex{} 18 type Field struct {
17 var allPayloads []payloadBuff 19 Parameter string `json:"param"`
18 20 Type string `json:"type"`
19 type LangMap map[string]map[string]string 21 Visible bool `json:"visible"`
20 22 Editable bool `json:"editable"`
21 type Field struct { 23 }
22 Parameter string `json:"param"` 24
23 Type string `json:"type"` 25 type CorrelationField struct {
24 Visible bool `json:"visible"` 26 Result string `json:"result"`
25 Editable bool `json:"editable"` 27 Elements []string `json:"elements"`
26 } 28 Type string `json:"type"`
27 29 }
28 type CorrelationField struct { 30
29 Result string `json:"result"` 31 type Translation struct {
30 Elements []string `json:"elements"` 32 Language string `json:"language"`
31 Type string `json:"type"` 33 FieldsLabels map[string]string `json:"fieldsLabels"`
32 } 34 }
33 35
34 type Translation struct { 36 // Field 'Type' is not required in payload.
35 Language string `json:"language"` 37 // 'payloadBuff' type is only a bridge between ORACLE CLOB and 'Payload' type.
36 FieldsLabels map[string]string `json:"fieldsLabels"` 38 type payloadBuff struct {
37 } 39 Type string `json:"tableType"`
38 40 Method string `json:"method"`
39 // Field 'Type' is not required in payload. 41 Params map[string]string `json:"params"`
40 // 'payloadBuff' type is only a bridge between ORACLE CLOB and 'Payload' type. 42 Lang []Translation `json:"lang"`
41 type payloadBuff struct { 43 Fields []Field `json:"fields"`
42 Type string `json:"tableType"` 44 Correlations []CorrelationField `json:"correlationFields"`
43 Method string `json:"method"` 45 IdField string `json:"idField"`
44 Params map[string]string `json:"params"` 46 // Data can only hold slices of any type. It can't be used for itteration
45 Lang []Translation `json:"lang"` 47 Data interface{} `json:"data"`
46 Fields []Field `json:"fields"` 48 }
47 Correlations []CorrelationField `json:"correlationFields"` 49
48 IdField string `json:"idField"` 50 type Payload struct {
49 // Data can only hold slices of any type. It can't be used for itteration 51 Method string `json:"method"`
50 Data interface{} `json:"data"` 52 Params map[string]string `json:"params"`
51 } 53 Lang []Translation `json:"lang"`
52 54 Fields []Field `json:"fields"`
53 type Payload struct { 55 Correlations []CorrelationField `json:"correlationFields"`
54 Method string `json:"method"` 56 IdField string `json:"idField"`
55 Params map[string]string `json:"params"` 57 // Data can only hold slices of any type. It can't be used for itteration
56 Lang []Translation `json:"lang"` 58 Data interface{} `json:"data"`
57 Fields []Field `json:"fields"` 59 }
58 Correlations []CorrelationField `json:"correlationFields"` 60
59 IdField string `json:"idField"` 61 func NewPayload(r *http.Request, table string) Payload {
60 // Data can only hold slices of any type. It can't be used for itteration 62 var pload Payload
61 Data interface{} `json:"data"` 63
62 } 64 pload.Method = r.Method + " " + r.URL.Path
63 65
64 func NewPayload(r *http.Request, table string) Payload { 66 if table != "" {
65 var pload Payload 67 pload.Params = make(map[string]string, 0)
66 68 pload.Lang = loadTranslations(table)
67 pload.Method = r.Method + " " + r.URL.Path 69 pload.Fields = loadFields(table)
68 70 pload.IdField = loadIdField(table)
69 if table != "" { 71 pload.Correlations = loadCorrelations(table)
70 pload.Params = make(map[string]string, 0) 72 }
71 pload.Lang = loadTranslations(table) 73
72 pload.Fields = loadFields(table) 74 return pload
73 pload.IdField = loadIdField(table) 75 }
74 pload.Correlations = loadCorrelations(table) 76
75 } 77 func DeliverPayload(w http.ResponseWriter, payload Payload) {
76 78 json.NewEncoder(w).Encode(payload)
77 return pload 79 payload.Data = nil
78 } 80 }
79 81
80 func DeliverPayload(w http.ResponseWriter, payload Payload) { 82 func loadTranslations(id string) []Translation {
81 json.NewEncoder(w).Encode(payload) 83 translations := make([]Translation, 0)
82 payload.Data = nil 84
83 } 85 for _, pload := range allPayloads {
84 86 if pload.Type == id {
85 func loadTranslations(id string) []Translation { 87 for _, t := range pload.Lang {
86 translations := make([]Translation, 0) 88 //translations[t.Language] = t.FieldsLabels
87 89 translations = append(translations, Translation{
88 for _, pload := range allPayloads { 90 Language: t.Language,
89 if pload.Type == id { 91 FieldsLabels: t.FieldsLabels,
90 for _, t := range pload.Lang { 92 })
91 //translations[t.Language] = t.FieldsLabels 93 }
92 translations = append(translations, Translation{ 94 }
93 Language: t.Language, 95 }
94 FieldsLabels: t.FieldsLabels, 96
95 }) 97 return translations
96 } 98 }
97 } 99
98 } 100 func loadFields(id string) []Field {
99 101 fields := make([]Field, 0)
100 return translations 102
101 } 103 for _, pload := range allPayloads {
102 104 if pload.Type == id{
103 func loadFields(id string) []Field { 105 for _, f := range pload.Fields {
104 fields := make([]Field, 0) 106 fields = append(fields, f)
105 107 }
106 for _, pload := range allPayloads { 108 }
107 if pload.Type == id{ 109 }
108 for _, f := range pload.Fields { 110
109 fields = append(fields, f) 111 return fields
110 } 112 }
111 } 113
112 } 114 func loadIdField(id string) string {
113 115 for _, pload := range allPayloads {
114 return fields 116 if pload.Type == id {
115 } 117 return pload.IdField
116 118 }
117 func loadIdField(id string) string { 119 }
118 for _, pload := range allPayloads { 120 return ""
119 if pload.Type == id { 121 }
120 return pload.IdField 122
121 } 123 func loadCorrelations(id string) []CorrelationField {
122 } 124 resp := make([]CorrelationField, 0)
123 return "" 125
124 } 126 for _, pload := range allPayloads {
125 127 if pload.Type == id {
126 func loadCorrelations(id string) []CorrelationField { 128 for _, f := range pload.Correlations {
127 resp := make([]CorrelationField, 0) 129 resp = append(resp, f)
128 130 }
129 for _, pload := range allPayloads { 131 }
130 if pload.Type == id { 132 }
131 for _, f := range pload.Correlations { 133
132 resp = append(resp, f) 134 return resp
133 } 135 }
134 } 136
135 } 137 func InitTables(db *ora.Ses, project string) error {
136 138 jsonbuf, _ := fetchJSON(db, EqualQuotes(project))
139 mu.Lock()
140 defer mu.Unlock()
137 return resp 141 json.Unmarshal(jsonbuf, &allPayloads)
138 } 142 if len(allPayloads) == 0 {
139 143 return errors.New("tables config is corrupt")
140 func InitTables(db *ora.Ses, project string) error { 144 }
141 jsonbuf, _ := fetchJSON(db, EqualQuotes(project)) 145 return nil
142 mu.Lock() 146 }
143 defer mu.Unlock() 147
144 json.Unmarshal(jsonbuf, &allPayloads) 148 func fetchJSON(db *ora.Ses, project string) ([]byte, error) {
145 if len(allPayloads) == 0 { 149 stmt, err := db.Prep(`SELECT
146 return errors.New("tables config is corrupt") 150 JSON_CLOB
147 } 151 FROM TABLES_CONFIG
148 return nil 152 WHERE PROJEKAT` + project, ora.S)
149 } 153 defer stmt.Close()
150 154
151 func fetchJSON(db *ora.Ses, project string) ([]byte, error) { 155 if err != nil {
152 stmt, err := db.Prep(`SELECT 156 return nil, err
153 JSON_CLOB 157 }
154 FROM TABLES_CONFIG 158
155 WHERE PROJEKAT` + project, ora.S) 159 rset, err := stmt.Qry()
156 defer stmt.Close() 160 if err != nil {
157 161 return nil, err
158 if err != nil { 162 }
159 return nil, err 163
160 } 164 bytes := make([]byte, 0)
161 165 if rset.Next() {
162 rset, err := stmt.Qry() 166 lob := rset.Row[0].(io.Reader)
163 if err != nil { 167 bytes, err = ioutil.ReadAll(lob)
164 return nil, err 168 if err != nil {
165 } 169 // Ignore for now, it's some weird streaming read/write LOB error.
166 170 // TODO: Find a fix for this.
167 bytes := make([]byte, 0) 171 //return nil, err
168 if rset.Next() { 172 }
169 lob := rset.Row[0].(io.Reader) 173 }
170 bytes, err = ioutil.ReadAll(lob) 174
171 if err != nil { 175 return bytes, nil
172 // Ignore for now, it's some weird streaming read/write LOB error. 176 }
173 // TODO: Find a fix for this. 177
178 func DecodeJSON(r io.Reader, v interface{}) error {
179 return json.NewDecoder(r).Decode(v)
180 }
174 //return nil, err 181
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, 27 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S)
28 ora.S)
29 defer stmt.Close() 28 defer stmt.Close()
30 if err != nil { 29 if err != nil {
31 return nil, err 30 return nil, err
32 } 31 }
33 32
34 rset, err := stmt.Qry() 33 rset, err := stmt.Qry()
35 if err != nil { 34 if err != nil {
36 return nil, err 35 return nil, err
37 } 36 }
38 for rset.Next() { 37 for rset.Next() {
39 resp = append(resp, SelectConfig{ 38 resp = append(resp, SelectConfig{
40 ListObjType: rset.Row[0].(string), 39 ListObjType: rset.Row[0].(string),
41 ObjType: rset.Row[1].(string), 40 ObjType: rset.Row[1].(string),
42 IdField: rset.Row[2].(string), 41 IdField: rset.Row[2].(string),
43 LabelField: rset.Row[3].(string), 42 LabelField: rset.Row[3].(string),
44 Type: rset.Row[4].(string), 43 Type: rset.Row[4].(string),
45 ValueField: rset.Row[5].(string), 44 ValueField: rset.Row[5].(string),
46 }) 45 })
47 } 46 }
48 if rset.Err != nil { 47 if rset.Err != nil {
49 return nil, rset.Err 48 return nil, rset.Err
50 } 49 }
51 50
52 return resp, nil 51 return resp, nil
53
54 } 52 }
55 53
1 package restutility 1 package webutility
2 2
3 import ( 3 import (
4 "strings" 4 "strings"
5 ) 5 )
6 6
7 func SQLProtect(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