Commit 90fd36e9b6905db92e6323daa89e0474e8d060c7

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

resolved some dependency issues

File was created 1 package restutility
2
3 import (
4 // "fmt"
5 "errors"
6 // "os"
7 "time"
8 "crypto/sha256"
9 "crypto/rand"
10 "encoding/hex"
11 "strings"
12 "github.com/dgrijalva/jwt-go"
13 // "github.com/SermoDigital/jose/jwt"
14 )
15
16 const OneDay = time.Hour*24
17 const OneWeek = OneDay*7
18 const saltSize = 32
19 const appName = "korisnicki-centar"
20 const secret = "korisnicki-centar-api"
21
22 type Token struct {
23 TokenString string `json:"token"`
24 }
25
26 type TokenClaims struct {
27 Username string `json:"username"`
28 Role string `json:"role"`
29 jwt.StandardClaims
30 }
31
32 type CredentialsStruct struct {
33 Username string `json:"username"`
34 Password string `json:"password"`
35 }
36
37 func generateSalt() (string, error) {
38 salt := ""
39
40 rawsalt := make([]byte, saltSize)
41 _, err := rand.Read(rawsalt)
42 if err != nil {
43 return "", err
44 }
45 salt = hex.EncodeToString(rawsalt)
46 return salt, nil
47 }
48
49 func hashMessage(message string, presalt string) (string, string, error) {
50 hash, salt := "", ""
51 var err error
52
53 // chech if message is presalted
54 if presalt == "" {
55 salt, err = generateSalt()
56 if err != nil {
57 return "", "", err
58 }
59 } else {
60 salt = presalt
61 }
62
63 // convert strings to raw byte slices
64 rawmessage := []byte(message)
65 rawsalt, err := hex.DecodeString(salt)
66 if err != nil {
67 return "", "", err
68 }
69 rawdata := make([]byte, len(rawmessage) + len(rawsalt))
70 rawdata = append(rawdata, rawmessage...)
71 rawdata = append(rawdata, rawsalt...)
72
73 // hash message + salt
74 hasher := sha256.New()
75 hasher.Write(rawdata)
76 rawhash := hasher.Sum(nil)
77 hash = hex.EncodeToString(rawhash)
78 return hash, salt, nil
79 }
80
81 func issueAPIToken(username, role string) (Token, error) {
82 var apiToken Token
83 var err error
84
85 if err != nil {
86 return Token{}, err
87 }
88
89 claims := TokenClaims{
90 username,
91 role,
92 jwt.StandardClaims{
93 ExpiresAt: (time.Now().Add(OneWeek)).Unix(),
94 Issuer: appName,
95 },
96 }
97
98 jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
99 apiToken.TokenString, err = jwtToken.SignedString([]byte(secret))
100 if err != nil {
101 return Token{}, err
102 }
103 return apiToken, nil
104 }
105
106 func refreshAPIToken(tokenString string) (Token, error) {
107 var newToken Token
108 tokenString = strings.TrimPrefix(tokenString, "Bearer ")
109 token, err := parseTokenFunc(tokenString)
110 if err != nil {
111 return Token{}, err
112 }
113
114 // type assertion
115 claims, ok := token.Claims.(*TokenClaims)
116 if !ok || !token.Valid {
117 return Token{}, errors.New("token is not valid")
118 }
119
120 claims.ExpiresAt = (time.Now().Add(OneWeek)).Unix()
121 jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
122
123 newToken.TokenString, err = jwtToken.SignedString([]byte(secret))
124 if err != nil {
125 return Token{}, err
126 }
127
128 return newToken, nil
129 }
130
131 func parseAPIToken(tokenString string) (*TokenClaims, error) {
132 if ok := strings.HasPrefix(tokenString, "Bearer"); ok {
133 tokenString = strings.TrimPrefix(tokenString, "Bearer ")
134 } else {
135 return &TokenClaims{}, errors.New("Authorization header is incomplete")
136 }
137
138 token, err := parseTokenFunc(tokenString)
139 if err != nil {
140 return &TokenClaims{}, err
141 }
142
143 // type assertion
144 claims, ok := token.Claims.(*TokenClaims)
145 if !ok || !token.Valid {
146 return &TokenClaims{}, errors.New("token is not valid")
147 }
148 return claims, nil
149 }
150
151 func parseTokenFunc(tokenString string) (*jwt.Token, error) {
152 token, err := jwt.ParseWithClaims(tokenString,
153 &TokenClaims{},
154 func(token *jwt.Token) (interface{}, error) {
155 return []byte(secret), nil
156 },
157 )
158 return token, err
159 }
160
161 func authMinRegReq(uname, pword string) (bool, error) {
162 return true, nil
163 }
164
165
format_utility.go
1 package main 1 package restutility
2 2
3 import ( 3 import (
4 "strings" 4 "strings"
5 "time" 5 "time"
6 "strconv" 6 "strconv"
7 ) 7 )
8 8
9 //// 9 ////
10 //// TIME FORMAT UTILITY 10 //// TIME FORMAT UTILITY
11 //// 11 ////
12 12
13 func unixToDate(input int64) time.Time { 13 func unixToDate(input int64) time.Time {
14 return time.Unix(input, 0) 14 return time.Unix(input, 0)
15 } 15 }
16 16
17 func dateToUnix(input interface{}) int64 { 17 func dateToUnix(input interface{}) int64 {
18 if input != nil { 18 if input != nil {
19 t := input.(time.Time) 19 t := input.(time.Time)
20 return t.Unix() 20 return t.Unix()
21 21
22 } 22 }
23 return 0 23 return 0
24 } 24 }
25 25
26 func aersDate(unixString string) (string, error) { 26 func aersDate(unixString string) (string, error) {
27 unixTime, err := strconv.ParseInt(unixString, 10, 64) 27 unixTime, err := strconv.ParseInt(unixString, 10, 64)
28 if err != nil { 28 if err != nil {
29 return "", err 29 return "", err
30 } 30 }
31 31
32 date := unixToDate(unixTime).String() 32 date := unixToDate(unixTime).String()
33 tokens := strings.Split(date, "-") 33 tokens := strings.Split(date, "-")
34 dateString := tokens[0] + tokens[1] + strings.Split(tokens[2], " ")[0] 34 dateString := tokens[0] + tokens[1] + strings.Split(tokens[2], " ")[0]
35 35
36 return dateString, nil 36 return dateString, nil
37 } 37 }
38 38
39 //// 39 ////
40 //// STRING UTILITY 40 //// STRING UTILITY
41 //// 41 ////
42 42
43 // surrondWithSingleQuotes is used when url param is of type string 43 // surrondWithSingleQuotes is used when url param is of type string
44 func putQuotes(input string) string { 44 func putQuotes(input string) string {
45 if input != "" { 45 if input != "" {
46 return " = '" + input + "'" 46 return " = '" + input + "'"
47 } 47 }
48 return "" 48 return ""
49 } 49 }
50 50
51 func putLikeQuotes(input string) string { 51 func putLikeQuotes(input string) string {
52 if input != "" { 52 if input != "" {
53 return " LIKE UPPER('%" + input + "%')" 53 return " LIKE UPPER('%" + input + "%')"
54 } 54 }
55 return "" 55 return ""
56 } 56 }
57 57
58 58
1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "encoding/json" 5 "encoding/json"
6 ) 6 )
7 7
8 const APIVersion = "/api/v1"
9
8 //// 10 ////
9 //// ERROR UTILITY 11 //// ERROR UTILITY
10 //// 12 ////
11 13
12 const templateHttpErr500_EN = "An internal server error has occurred." 14 const templateHttpErr500_EN = "An internal server error has occurred."
13 const templateHttpErr500_RS = "Došlo je do greške na serveru." 15 const templateHttpErr500_RS = "Došlo je do greške na serveru."
14 const templateHttpErr400_EN = "Bad request: invalid request body." 16 const templateHttpErr400_EN = "Bad request: invalid request body."
15 const templateHttpErr400_RS = "Neispravan zahtev." 17 const templateHttpErr400_RS = "Neispravan zahtev."
16 18
17 type HttpError struct { 19 type HttpError struct {
18 Error []HttpErrorDesc `json:"error"` 20 Error []HttpErrorDesc `json:"error"`
19 Request string `json:"request"` 21 Request string `json:"request"`
20 } 22 }
21 23
22 type HttpErrorDesc struct { 24 type HttpErrorDesc struct {
23 Lang string `json:"lang"` 25 Lang string `json:"lang"`
24 Desc string `json:"description"` 26 Desc string `json:"description"`
25 } 27 }
26 28
27 func respondWithHttpError(w http.ResponseWriter, 29 func respondWithHttpError(w http.ResponseWriter,
28 req *http.Request, 30 req *http.Request,
29 code int, 31 code int,
30 httpErr []HttpErrorDesc) { 32 httpErr []HttpErrorDesc) {
31 33
32 err := HttpError{ 34 err := HttpError{
33 Error: httpErr, 35 Error: httpErr,
34 Request: req.Method + " " + req.URL.Path, 36 Request: req.Method + " " + req.URL.Path,
35 } 37 }
36 w.WriteHeader(code) 38 w.WriteHeader(code)
37 json.NewEncoder(w).Encode(err) 39 json.NewEncoder(w).Encode(err)
38 } 40 }
39 41
40 func respondWithHttpError400(w http.ResponseWriter, req *http.Request) { 42 func respondWithHttpError400(w http.ResponseWriter, req *http.Request) {
41 respondWithHttpError(w, req, http.StatusBadRequest, 43 respondWithHttpError(w, req, http.StatusBadRequest,
42 []HttpErrorDesc{ 44 []HttpErrorDesc{
43 { 45 {
44 Lang: "en", 46 Lang: "en",
45 Desc: templateHttpErr400_EN, 47 Desc: templateHttpErr400_EN,
46 }, 48 },
47 { 49 {
48 Lang: "rs", 50 Lang: "rs",
49 Desc: templateHttpErr400_RS, 51 Desc: templateHttpErr400_RS,
50 }, 52 },
51 }) 53 })
52 } 54 }
53 55
54 func respondWithHttpError500(w http.ResponseWriter, req *http.Request) { 56 func respondWithHttpError500(w http.ResponseWriter, req *http.Request) {
55 respondWithHttpError(w, req, http.StatusInternalServerError, 57 respondWithHttpError(w, req, http.StatusInternalServerError,
56 []HttpErrorDesc{ 58 []HttpErrorDesc{
57 { 59 {
58 Lang: "en", 60 Lang: "en",
59 Desc: templateHttpErr500_EN, 61 Desc: templateHttpErr500_EN,
60 }, 62 },
61 { 63 {
62 Lang: "rs", 64 Lang: "rs",
63 Desc: templateHttpErr500_RS, 65 Desc: templateHttpErr500_RS,
64 }, 66 },
65 }) 67 })
66 } 68 }
67 69
68 func deliverPayload(w http.ResponseWriter, payload JSONPayload) { 70 func deliverPayload(w http.ResponseWriter, payload JSONPayload) {
69 json.NewEncoder(w).Encode(payload) 71 json.NewEncoder(w).Encode(payload)
70 payload.Data = nil 72 payload.Data = nil
71 } 73 }
72 74
73 //// 75 ////
74 //// HANDLER FUNC WRAPPER 76 //// HANDLER FUNC WRAPPER
75 //// 77 ////
76 78
77 // wrapHandlerFunc is as wrapper function for route handlers. 79 // wrapHandlerFunc is as wrapper function for route handlers.
78 // Sets common headers and checks for token validity. 80 // Sets common headers and checks for token validity.
79 func commonHttpWrap(fn http.HandlerFunc) http.HandlerFunc { 81 func commonHttpWrap(fn http.HandlerFunc) http.HandlerFunc {
80 return func(w http.ResponseWriter, req *http.Request) { 82 return func(w http.ResponseWriter, req *http.Request) {
81 // @TODO: check Content-type header (must be application/json) 83 // @TODO: check Content-type header (must be application/json)
82 // ctype := w.Header.Get("Content-Type") 84 // ctype := w.Header.Get("Content-Type")
83 // if req.Method != "GET" && ctype != "application/json" { 85 // if req.Method != "GET" && ctype != "application/json" {
84 // replyWithHttpError(w, req, http.StatusBadRequest, 86 // replyWithHttpError(w, req, http.StatusBadRequest,
85 // "Not a supported content type: " + ctype) 87 // "Not a supported content type: " + ctype)
86 // } 88 // }
87 89
88 w.Header().Set("Access-Control-Allow-Origin", "*") 90 w.Header().Set("Access-Control-Allow-Origin", "*")
89 w.Header().Set("Access-Control-Allow-Methods", 91 w.Header().Set("Access-Control-Allow-Methods",
90 `POST, 92 `POST,
91 GET, 93 GET,
92 PUT, 94 PUT,
93 DELETE, 95 DELETE,
94 OPTIONS`) 96 OPTIONS`)
95 w.Header().Set("Access-Control-Allow-Headers", 97 w.Header().Set("Access-Control-Allow-Headers",
96 `Accept, 98 `Accept,
97 Content-Type, 99 Content-Type,
98 Content-Length, 100 Content-Length,
99 Accept-Encoding, 101 Accept-Encoding,
100 X-CSRF-Token, 102 X-CSRF-Token,
101 Authorization`) 103 Authorization`)
102 w.Header().Set("Content-Type", "application/json; charset=utf-8") 104 w.Header().Set("Content-Type", "application/json; charset=utf-8")
103 105
104 if req.Method == "OPTIONS" { 106 if req.Method == "OPTIONS" {
105 return 107 return
106 } 108 }
107 109
108 if req.URL.Path != APIVersion + "/token/new" { 110 if req.URL.Path != APIVersion + "/token/new" {
109 token := req.Header.Get("Authorization") 111 token := req.Header.Get("Authorization")
110 if _, err := parseAPIToken(token); err != nil { 112 if _, err := parseAPIToken(token); err != nil {
111 respondWithHttpError(w, req, http.StatusUnauthorized, 113 respondWithHttpError(w, req, http.StatusUnauthorized,
112 []HttpErrorDesc{ 114 []HttpErrorDesc{
113 { 115 {
114 Lang: "en", 116 Lang: "en",
115 Desc: "Unauthorized request.", 117 Desc: "Unauthorized request.",
116 }, 118 },
117 { 119 {
118 Lang: "rs", 120 Lang: "rs",
119 Desc: "Neautorizovani zahtev.", 121 Desc: "Neautorizovani zahtev.",
120 }, 122 },
121 }) 123 })
122 return 124 return
123 } 125 }
124 } 126 }
125 127
126 err := req.ParseForm() 128 err := req.ParseForm()
127 if err != nil { 129 if err != nil {
128 respondWithHttpError(w, req, http.StatusBadRequest, 130 respondWithHttpError(w, req, http.StatusBadRequest,
129 []HttpErrorDesc{ 131 []HttpErrorDesc{
130 { 132 {
131 Lang: "en", 133 Lang: "en",
132 Desc: templateHttpErr400_EN, 134 Desc: templateHttpErr400_EN,
133 }, 135 },
134 { 136 {
135 Lang: "rs", 137 Lang: "rs",
136 Desc: templateHttpErr400_RS, 138 Desc: templateHttpErr400_RS,
137 }, 139 },
138 }) 140 })
139 return 141 return
140 } 142 }
141 fn(w, req) 143 fn(w, req)
142 } 144 }
143 } 145 }
144 146
145 //// 147 ////
146 //// NOT FOUND HANDLER 148 //// NOT FOUND HANDLER
147 //// 149 ////
148 150
149 func notFoundHandler(w http.ResponseWriter, req *http.Request) { 151 func notFoundHandler(w http.ResponseWriter, req *http.Request) {
150 respondWithHttpError(w, req, http.StatusNotFound, 152 respondWithHttpError(w, req, http.StatusNotFound,
151 []HttpErrorDesc{ 153 []HttpErrorDesc{
152 { 154 {
153 Lang: "en", 155 Lang: "en",
154 Desc: "Not found.", 156 Desc: "Not found.",
155 }, 157 },
156 { 158 {
157 Lang: "rs", 159 Lang: "rs",
158 Desc: "Traženi resurs ne postoji.", 160 Desc: "Traženi resurs ne postoji.",
159 }, 161 },
160 }) 162 })
161 } 163 }
162 164
1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "strings" 5 "strings"
6 ) 6 )
7 7
8 const APIVersion "/api/v1"
9
10 type LangMap map[string]map[string]string 8 type LangMap map[string]map[string]string
11 9
12 type Field struct { 10 type Field struct {
13 Parameter string `json:"param"` 11 Parameter string `json:"param"`
14 Type string `json:"type"` 12 Type string `json:"type"`
15 Visible bool `json:"visible"` 13 Visible bool `json:"visible"`
16 Editable bool `json:"editable"` 14 Editable bool `json:"editable"`
17 } 15 }
18 16
19 type JSONParams struct { 17 type JSONParams struct {
20 Lang LangMap 18 Lang LangMap
21 Fields []Field 19 Fields []Field
22 IdField string 20 IdField string
23 Correlations []CorrelationField `json:"correlation_fields"` 21 Correlations []CorrelationField `json:"correlation_fields"`
24 } 22 }
25 23
26 type JSONPayload struct { 24 type JSONPayload struct {
27 Method string `json:"method"` 25 Method string `json:"method"`
28 Params map[string]string `json:"params"` 26 Params map[string]string `json:"params"`
29 Lang LangMap `json:"lang"` 27 Lang LangMap `json:"lang"`
30 Fields []Field `json:"fields"` 28 Fields []Field `json:"fields"`
31 Correlations []CorrelationField `json:"correlation_fields"` 29 Correlations []CorrelationField `json:"correlation_fields"`
32 IdField string `json:"idField"` 30 IdField string `json:"idField"`
33 // Data can only hold slices of any type. It can't be used for itteration 31 // Data can only hold slices of any type. It can't be used for itteration
34 Data interface{} `json:"data"` 32 Data interface{} `json:"data"`
35 } 33 }
36 34
37 func NewJSONParams(lang LangMap, 35 func NewJSONParams(lang LangMap,
38 fields []Field, 36 fields []Field,
39 id string, 37 id string,
40 correlations []CorrelationField) JSONParams { 38 correlations []CorrelationField) JSONParams {
41 39
42 var jp JSONParams 40 var jp JSONParams
43 41
44 jp.Lang = lang 42 jp.Lang = lang
45 jp.Fields = fields 43 jp.Fields = fields
46 jp.IdField = id 44 jp.IdField = id
47 jp.Correlations = correlations 45 jp.Correlations = correlations
48 46
49 return jp 47 return jp
50 } 48 }
51 49
52 func NewJSONPayload(r *http.Request, params JSONParams) JSONPayload { 50 func NewJSONPayload(r *http.Request, params JSONParams) JSONPayload {
53 var obj JSONPayload 51 var obj JSONPayload
54 obj.Method = strings.ToLower(r.Method + " " + r.URL.Path) 52 obj.Method = strings.ToLower(r.Method + " " + r.URL.Path)
55 obj.Params = make(map[string]string, 0) 53 obj.Params = make(map[string]string, 0)
56 obj.Lang = make(map[string]map[string]string, 0) 54 obj.Lang = make(map[string]map[string]string, 0)
57 obj.Fields = make([]Field, 0) 55 obj.Fields = make([]Field, 0)
58 obj.IdField = params.IdField 56 obj.IdField = params.IdField
59 obj.Correlations = params.Correlations 57 obj.Correlations = params.Correlations
60 58
61 for k, m := range params.Lang { 59 for k, m := range params.Lang {
62 obj.Lang[k] = m 60 obj.Lang[k] = m
63 } 61 }
64 for _, f := range params.Fields { 62 for _, f := range params.Fields {
65 obj.Fields = append(obj.Fields, f) 63 obj.Fields = append(obj.Fields, f)
66 } 64 }
67 65
68 return obj 66 return obj
69 } 67 }
70 68
71 69
tables_utility.go
1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "io"
6 "io/ioutil"
7 "errors" 5 "errors"
8 "fmt"
9 "gopkg.in/rana/ora.v3"
10 ) 6 )
11 7
12 type TableConfig struct { 8 type TableConfig struct {
13 Tables []Table 9 Tables []Table
14 } 10 }
15 11
16 type Table struct { 12 type Table struct {
17 TableType string `json:"tableType"` 13 TableType string `json:"tableType"`
18 Translations []TableTranslation `json:"translations"` 14 Translations []TableTranslation `json:"translations"`
19 TableFields []Field `json:"tableFields"` 15 TableFields []Field `json:"tableFields"`
20 Correlations []CorrelationField `json:"correlation_fields"` 16 Correlations []CorrelationField `json:"correlation_fields"`
21 IdField string `json:"idField"` 17 IdField string `json:"idField"`
22 } 18 }
23 19
24 type CorrelationField struct { 20 type CorrelationField struct {
25 Result string `json:"result"` 21 Result string `json:"result"`
26 Elements []string `json:"elements"` 22 Elements []string `json:"elements"`
27 Type string `json:"type"` 23 Type string `json:"type"`
28 } 24 }
29 25
30 type TableTranslation struct { 26 type TableTranslation struct {
31 Language string `json:"language"` 27 Language string `json:"language"`
32 FieldsLabels map[string]string `json:"fieldsLabels"` 28 FieldsLabels map[string]string `json:"fieldsLabels"`
33 } 29 }
34 30
35 func (tl TableConfig) LoadTranslations(tableType string) LangMap { 31 func (tl TableConfig) LoadTranslations(tableType string) LangMap {
36 translations := make(LangMap, 0) 32 translations := make(LangMap, 0)
37 33
38 for _, table := range tl.Tables { 34 for _, table := range tl.Tables {
39 if tableType == table.TableType { 35 if tableType == table.TableType {
40 for _, t := range table.Translations { 36 for _, t := range table.Translations {
41 translations[t.Language] = t.FieldsLabels 37 translations[t.Language] = t.FieldsLabels
42 } 38 }
43 } 39 }
44 } 40 }
45 41
46 return translations 42 return translations
47 } 43 }
48 44
49 func (tl TableConfig) LoadFields(tableType string) []Field { 45 func (tl TableConfig) LoadFields(tableType string) []Field {
50 fields := make([]Field, 0) 46 fields := make([]Field, 0)
51 47
52 for _, table := range tl.Tables { 48 for _, table := range tl.Tables {
53 if tableType == table.TableType { 49 if tableType == table.TableType {
54 for _, f := range table.TableFields { 50 for _, f := range table.TableFields {
55 fields = append(fields, f) 51 fields = append(fields, f)
56 } 52 }
57 } 53 }
58 } 54 }
59 55
60 return fields 56 return fields
61 } 57 }
62 58
63 func (tl TableConfig) LoadIdField(tableType string) string { 59 func (tl TableConfig) LoadIdField(tableType string) string {
64 for _, table := range tl.Tables { 60 for _, table := range tl.Tables {
65 if tableType == table.TableType { 61 if tableType == table.TableType {
66 return table.IdField 62 return table.IdField
67 } 63 }
68 } 64 }
69 return "" 65 return ""
70 } 66 }
71 67
72 func (tl TableConfig) LoadCorrelations(tableType string) []CorrelationField { 68 func (tl TableConfig) LoadCorrelations(tableType string) []CorrelationField {
73 resp := make([]CorrelationField, 0) 69 resp := make([]CorrelationField, 0)
74 70
75 for _, table := range tl.Tables { 71 for _, table := range tl.Tables {
76 if tableType == table.TableType { 72 if tableType == table.TableType {
77 for _, f := range table.Correlations { 73 for _, f := range table.Correlations {
78 resp = append(resp, f) 74 resp = append(resp, f)
79 } 75 }
80 } 76 }
81 } 77 }
82 78
83 return resp 79 return resp
84 } 80 }
85 81
86 var _tables TableConfig 82 var _tables TableConfig
87 var _prevProject string 83 var _prevProject string
88 84
89 func getTablesConfigJSON(project string) error { 85 func loadTablesConfig(jsonbuf []byte) error {
90 _prevProject = project 86 json.Unmarshal(jsonbuf, &_tables.Tables)
91 stmt, err := Oracle.Ses.Prep(`SELECT
92 JSON_CLOB
93 FROM TABLES_CONFIG
94 WHERE PROJEKAT` + project, ora.S)
95 defer stmt.Close()
96 87
97 if err != nil { 88 if len(_tables.Tables) == 0 {
98 return err
99 }
100
101 rset, err := stmt.Qry()
102 if err != nil {
103 return err
104 }
105
106 if rset.Next() {
107 lob := rset.Row[0].(io.Reader)
108 bytes, err := ioutil.ReadAll(lob)
109 if err != nil {
110 fmt.Printf("mega error: %v\n", err)
111 }
112 json.Unmarshal(bytes, &_tables.Tables)
113 }
114
115 return nil
116 }
117
118 func loadTablesConfig(project string) error {
119 err := getTablesConfigJSON(putQuotes(project))
120 //file, err := ioutil.ReadFile("./config/tables-config.json")
121 if err != nil {
122 fmt.Printf("%v\n", err);
123 return errors.New("unable to load tables config")
124 }
125
126 //json.Unmarshal(file, &_TABLES_CONFIG.Tables)
127
128 if len(_TABLES_CONFIG.Tables) == 0 {
129 return errors.New("tables config is corrupt") 89 return errors.New("tables config is corrupt")
130 } 90 }
131 91
132 return nil 92 return nil
133 } 93 }
134 94
135 func loadTable(table string) JSONParams { 95 func loadTable(table string) JSONParams {
136 return NewJSONParams(_tables.LoadTranslations(table), 96 return NewJSONParams(_tables.LoadTranslations(table),
137 _tables.LoadFields(table), 97 _tables.LoadFields(table),
138 _tables.LoadIdField(table), 98 _tables.LoadIdField(table),
139 _tables.LoadCorrelations(table)) 99 _tables.LoadCorrelations(table))
140 } 100 }
141 101
142 func refreshTables() error {
143 return getTablesConfigJSON(_prevProject)
144 }
145 102