Commit c2ed2491115cb8a87f81c2c7f782fb817a473582
Exists in
master
and in
1 other branch
restutility -> webutility
Showing
7 changed files
Show diff stats
auth_utility.go
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 |
http_utility.go
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) |
json_utility.go
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 |
list_config.go
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 |
select_config.go
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 |
sql_sequrity.go
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 |