Commit 18fcd6d6bfa31d201c800adb6a1177b34ebb1c46

Authored by Marko Tikvić
1 parent cacf57bd4a
Exists in master

merged with util package

default_values.go
1 package util 1 package webutility
2 2
3 // IntOrDefault ... 3 // IntOrDefault ...
4 func IntOrDefault(v *int) int { 4 func IntOrDefault(v *int) int {
5 if v != nil { 5 if v != nil {
6 return *v 6 return *v
7 } 7 }
8 return 0 8 return 0
9 } 9 }
10 10
11 // Int32OrDefault ... 11 // Int32OrDefault ...
12 func Int32OrDefault(v *int32) int32 { 12 func Int32OrDefault(v *int32) int32 {
13 if v != nil { 13 if v != nil {
14 return *v 14 return *v
15 } 15 }
16 return 0 16 return 0
17 } 17 }
18 18
19 // Int64OrDefault ... 19 // Int64OrDefault ...
20 func Int64OrDefault(v *int64) int64 { 20 func Int64OrDefault(v *int64) int64 {
21 if v != nil { 21 if v != nil {
22 return *v 22 return *v
23 } 23 }
24 return 0 24 return 0
25 } 25 }
26 26
27 // Uint32OrDefault ... 27 // Uint32OrDefault ...
28 func Uint32OrDefault(v *uint32) uint32 { 28 func Uint32OrDefault(v *uint32) uint32 {
29 if v != nil { 29 if v != nil {
30 return *v 30 return *v
31 } 31 }
32 return 0 32 return 0
33 } 33 }
34 34
35 // Uint64OrDefault ... 35 // Uint64OrDefault ...
36 func Uint64OrDefault(v *uint64) uint64 { 36 func Uint64OrDefault(v *uint64) uint64 {
37 if v != nil { 37 if v != nil {
38 return *v 38 return *v
39 } 39 }
40 return 0 40 return 0
41 } 41 }
42 42
43 // StringOrDefault ... 43 // StringOrDefault ...
44 func StringOrDefault(v *string) string { 44 func StringOrDefault(v *string) string {
45 if v != nil { 45 if v != nil {
46 return *v 46 return *v
47 } 47 }
48 return "" 48 return ""
49 } 49 }
50 50
51 // Float32OrDefault ... 51 // Float32OrDefault ...
52 func Float32OrDefault(v *float32) float32 { 52 func Float32OrDefault(v *float32) float32 {
53 if v != nil { 53 if v != nil {
54 return *v 54 return *v
55 } 55 }
56 return 0.0 56 return 0.0
57 } 57 }
58 58
59 // Float64OrDefault ... 59 // Float64OrDefault ...
60 func Float64OrDefault(v *float64) float64 { 60 func Float64OrDefault(v *float64) float64 {
61 if v != nil { 61 if v != nil {
62 return *v 62 return *v
63 } 63 }
64 return 0.0 64 return 0.0
65 } 65 }
66 66
1 package util 1 package webutility
2 2
3 // Diff ... 3 // Diff ...
4 func Diff(old, new []int64) (added, removed []int64) { 4 func Diff(old, new []int64) (added, removed []int64) {
5 for i := range old { 5 for i := range old {
6 isRemoved := true 6 isRemoved := true
7 for j := range new { 7 for j := range new {
8 if old[i] == new[j] { 8 if old[i] == new[j] {
9 isRemoved = false 9 isRemoved = false
10 break 10 break
11 } 11 }
12 } 12 }
13 if isRemoved { 13 if isRemoved {
14 removed = append(removed, old[i]) 14 removed = append(removed, old[i])
15 } 15 }
16 } 16 }
17 17
18 for i := range new { 18 for i := range new {
19 isAdded := true 19 isAdded := true
20 for j := range old { 20 for j := range old {
21 if new[i] == old[j] { 21 if new[i] == old[j] {
22 isAdded = false 22 isAdded = false
23 break 23 break
24 } 24 }
25 } 25 }
26 if isAdded { 26 if isAdded {
27 added = append(added, new[i]) 27 added = append(added, new[i])
28 } 28 }
29 } 29 }
30 30
31 return added, removed 31 return added, removed
32 } 32 }
33 33
1 package util 1 package webutility
2 2
3 import ( 3 import (
4 "bytes" 4 "bytes"
5 "io" 5 "io"
6 "io/ioutil" 6 "io/ioutil"
7 "os" 7 "os"
8 "strings" 8 "strings"
9 ) 9 )
10 10
11 func ReadFileContent(path string) ([]byte, error) { 11 func ReadFileContent(path string) ([]byte, error) {
12 f, err := os.Open(path) 12 f, err := os.Open(path)
13 if err != nil { 13 if err != nil {
14 return nil, err 14 return nil, err
15 } 15 }
16 defer f.Close() 16 defer f.Close()
17 17
18 buf := &bytes.Buffer{} 18 buf := &bytes.Buffer{}
19 if _, err = io.Copy(buf, f); err != nil { 19 if _, err = io.Copy(buf, f); err != nil {
20 return nil, err 20 return nil, err
21 } 21 }
22 22
23 return buf.Bytes(), nil 23 return buf.Bytes(), nil
24 } 24 }
25 25
26 // ReadFileLines ... 26 // ReadFileLines ...
27 func ReadFileLines(path string) ([]string, error) { 27 func ReadFileLines(path string) ([]string, error) {
28 f, err := os.Open(path) 28 f, err := os.Open(path)
29 if err != nil { 29 if err != nil {
30 return nil, err 30 return nil, err
31 } 31 }
32 defer f.Close() 32 defer f.Close()
33 33
34 var s strings.Builder 34 var s strings.Builder
35 35
36 if _, err = io.Copy(&s, f); err != nil { 36 if _, err = io.Copy(&s, f); err != nil {
37 return nil, err 37 return nil, err
38 } 38 }
39 39
40 lines := strings.Split(s.String(), "\n") 40 lines := strings.Split(s.String(), "\n")
41 for i := range lines { 41 for i := range lines {
42 lines[i] = strings.TrimRight(lines[i], "\r\n") 42 lines[i] = strings.TrimRight(lines[i], "\r\n")
43 } 43 }
44 44
45 return lines, nil 45 return lines, nil
46 } 46 }
47 47
48 // LinesToFile ... 48 // LinesToFile ...
49 func LinesToFile(path string, lines []string) error { 49 func LinesToFile(path string, lines []string) error {
50 content := "" 50 content := ""
51 for _, l := range lines { 51 for _, l := range lines {
52 content += l + "\n" 52 content += l + "\n"
53 } 53 }
54 54
55 return ioutil.WriteFile(path, []byte(content), 0644) // drw-r--r-- 55 return ioutil.WriteFile(path, []byte(content), 0644) // drw-r--r--
56 } 56 }
57 57
58 // InsertLine ... 58 // InsertLine ...
59 func InsertLine(lines *[]string, pos int64, l string) { 59 func InsertLine(lines *[]string, pos int64, l string) {
60 tail := append([]string{l}, (*lines)[pos:]...) 60 tail := append([]string{l}, (*lines)[pos:]...)
61 61
62 *lines = append((*lines)[:pos], tail...) 62 *lines = append((*lines)[:pos], tail...)
63 } 63 }
64 64
1 package util 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "strconv" 5 "strconv"
6 ) 6 )
7 7
8 // ClampInt64 ... 8 // ClampInt64 ...
9 func ClampInt64(v, min, max int64) int64 { 9 func ClampInt64(v, min, max int64) int64 {
10 if v < min { 10 if v < min {
11 return min 11 return min
12 } else if v > max { 12 } else if v > max {
13 return max 13 return max
14 } 14 }
15 15
16 return v 16 return v
17 } 17 }
18 18
19 // InRangeInt64 ... 19 // InRangeInt64 ...
20 func InRangeInt64(v, min, max int64) bool { 20 func InRangeInt64(v, min, max int64) bool {
21 return (v >= min && v <= max) 21 return (v >= min && v <= max)
22 } 22 }
23 23
24 // StringToInt64 ... 24 // StringToInt64 ...
25 func StringToInt64(s string) int64 { 25 func StringToInt64(s string) int64 {
26 i, _ := strconv.ParseInt(s, 10, 64) 26 i, _ := strconv.ParseInt(s, 10, 64)
27 return i 27 return i
28 } 28 }
29 29
30 // Int64ToString ... 30 // Int64ToString ...
31 func Int64ToString(i int64) string { 31 func Int64ToString(i int64) string {
32 return fmt.Sprintf("%d", i) 32 return fmt.Sprintf("%d", i)
33 } 33 }
34 34
35 // BoolToInt64 ... 35 // BoolToInt64 ...
36 func BoolToInt64(b bool) int64 { 36 func BoolToInt64(b bool) int64 {
37 if b { 37 if b {
38 return 1 38 return 1
39 } 39 }
40 return 0 40 return 0
41 } 41 }
42 42
43 // Int64ToBool ... 43 // Int64ToBool ...
44 func Int64ToBool(i int64) bool { 44 func Int64ToBool(i int64) bool {
45 return i != 0 45 return i != 0
46 } 46 }
47 47
1 package util 1 package webutility
2 2
3 import ( 3 import (
4 "database/sql" 4 "database/sql"
5 "database/sql/driver" 5 "database/sql/driver"
6 "encoding/json" 6 "encoding/json"
7 "fmt" 7 "fmt"
8 "time" 8 "time"
9 ) 9 )
10 10
11 // NullBool is a wrapper for sql.NullBool with added JSON (un)marshalling 11 // NullBool is a wrapper for sql.NullBool with added JSON (un)marshalling
12 type NullBool sql.NullBool 12 type NullBool sql.NullBool
13 13
14 // Scan ... 14 // Scan ...
15 func (nb *NullBool) Scan(value interface{}) error { 15 func (nb *NullBool) Scan(value interface{}) error {
16 var b sql.NullBool 16 var b sql.NullBool
17 if err := b.Scan(value); err != nil { 17 if err := b.Scan(value); err != nil {
18 nb.Bool, nb.Valid = false, false 18 nb.Bool, nb.Valid = false, false
19 return err 19 return err
20 } 20 }
21 nb.Bool, nb.Valid = b.Bool, b.Valid 21 nb.Bool, nb.Valid = b.Bool, b.Valid
22 return nil 22 return nil
23 } 23 }
24 24
25 // Value ... 25 // Value ...
26 func (nb *NullBool) Value() (driver.Value, error) { 26 func (nb *NullBool) Value() (driver.Value, error) {
27 if !nb.Valid { 27 if !nb.Valid {
28 return nil, nil 28 return nil, nil
29 } 29 }
30 return nb.Bool, nil 30 return nb.Bool, nil
31 } 31 }
32 32
33 // MarshalJSON ... 33 // MarshalJSON ...
34 func (nb NullBool) MarshalJSON() ([]byte, error) { 34 func (nb NullBool) MarshalJSON() ([]byte, error) {
35 if nb.Valid { 35 if nb.Valid {
36 return json.Marshal(nb.Bool) 36 return json.Marshal(nb.Bool)
37 } 37 }
38 38
39 return json.Marshal(nil) 39 return json.Marshal(nil)
40 } 40 }
41 41
42 // UnmarshalJSON ... 42 // UnmarshalJSON ...
43 func (nb *NullBool) UnmarshalJSON(b []byte) error { 43 func (nb *NullBool) UnmarshalJSON(b []byte) error {
44 var temp *bool 44 var temp *bool
45 if err := json.Unmarshal(b, &temp); err != nil { 45 if err := json.Unmarshal(b, &temp); err != nil {
46 return err 46 return err
47 } 47 }
48 if temp != nil { 48 if temp != nil {
49 nb.Valid = true 49 nb.Valid = true
50 nb.Bool = *temp 50 nb.Bool = *temp
51 } else { 51 } else {
52 nb.Valid = false 52 nb.Valid = false
53 } 53 }
54 return nil 54 return nil
55 } 55 }
56 56
57 // SQLCast ... 57 // SQLCast ...
58 func (nb *NullBool) SQLCast() sql.NullBool { 58 func (nb *NullBool) SQLCast() sql.NullBool {
59 return sql.NullBool(*nb) 59 return sql.NullBool(*nb)
60 } 60 }
61 61
62 // NullString is a wrapper for sql.NullString with added JSON (un)marshalling 62 // NullString is a wrapper for sql.NullString with added JSON (un)marshalling
63 type NullString sql.NullString 63 type NullString sql.NullString
64 64
65 // Scan ... 65 // Scan ...
66 func (ns *NullString) Scan(value interface{}) error { 66 func (ns *NullString) Scan(value interface{}) error {
67 var s sql.NullString 67 var s sql.NullString
68 if err := s.Scan(value); err != nil { 68 if err := s.Scan(value); err != nil {
69 ns.String, ns.Valid = "", false 69 ns.String, ns.Valid = "", false
70 return err 70 return err
71 } 71 }
72 ns.String, ns.Valid = s.String, s.Valid 72 ns.String, ns.Valid = s.String, s.Valid
73 return nil 73 return nil
74 } 74 }
75 75
76 // Value ... 76 // Value ...
77 func (ns *NullString) Value() (driver.Value, error) { 77 func (ns *NullString) Value() (driver.Value, error) {
78 if !ns.Valid { 78 if !ns.Valid {
79 return nil, nil 79 return nil, nil
80 } 80 }
81 return ns.String, nil 81 return ns.String, nil
82 } 82 }
83 83
84 // MarshalJSON ... 84 // MarshalJSON ...
85 func (ns NullString) MarshalJSON() ([]byte, error) { 85 func (ns NullString) MarshalJSON() ([]byte, error) {
86 if ns.Valid { 86 if ns.Valid {
87 return json.Marshal(ns.String) 87 return json.Marshal(ns.String)
88 } 88 }
89 return json.Marshal(nil) 89 return json.Marshal(nil)
90 } 90 }
91 91
92 // UnmarshalJSON ... 92 // UnmarshalJSON ...
93 func (ns *NullString) UnmarshalJSON(b []byte) error { 93 func (ns *NullString) UnmarshalJSON(b []byte) error {
94 var temp *string 94 var temp *string
95 if err := json.Unmarshal(b, &temp); err != nil { 95 if err := json.Unmarshal(b, &temp); err != nil {
96 return err 96 return err
97 } 97 }
98 if temp != nil { 98 if temp != nil {
99 ns.Valid = true 99 ns.Valid = true
100 ns.String = *temp 100 ns.String = *temp
101 } else { 101 } else {
102 ns.Valid = false 102 ns.Valid = false
103 } 103 }
104 return nil 104 return nil
105 } 105 }
106 106
107 // SQLCast ... 107 // SQLCast ...
108 func (ns *NullString) SQLCast() sql.NullString { 108 func (ns *NullString) SQLCast() sql.NullString {
109 return sql.NullString(*ns) 109 return sql.NullString(*ns)
110 } 110 }
111 111
112 // NullInt64 is a wrapper for sql.NullInt64 with added JSON (un)marshalling 112 // NullInt64 is a wrapper for sql.NullInt64 with added JSON (un)marshalling
113 type NullInt64 sql.NullInt64 113 type NullInt64 sql.NullInt64
114 114
115 // Scan ... 115 // Scan ...
116 func (ni *NullInt64) Scan(value interface{}) error { 116 func (ni *NullInt64) Scan(value interface{}) error {
117 var i sql.NullInt64 117 var i sql.NullInt64
118 if err := i.Scan(value); err != nil { 118 if err := i.Scan(value); err != nil {
119 ni.Int64, ni.Valid = 0, false 119 ni.Int64, ni.Valid = 0, false
120 return err 120 return err
121 } 121 }
122 ni.Int64, ni.Valid = i.Int64, i.Valid 122 ni.Int64, ni.Valid = i.Int64, i.Valid
123 return nil 123 return nil
124 } 124 }
125 125
126 // Value ... 126 // Value ...
127 func (ni *NullInt64) Value() (driver.Value, error) { 127 func (ni *NullInt64) Value() (driver.Value, error) {
128 if !ni.Valid { 128 if !ni.Valid {
129 return nil, nil 129 return nil, nil
130 } 130 }
131 return ni.Int64, nil 131 return ni.Int64, nil
132 } 132 }
133 133
134 // MarshalJSON ... 134 // MarshalJSON ...
135 func (ni NullInt64) MarshalJSON() ([]byte, error) { 135 func (ni NullInt64) MarshalJSON() ([]byte, error) {
136 if ni.Valid { 136 if ni.Valid {
137 return json.Marshal(ni.Int64) 137 return json.Marshal(ni.Int64)
138 } 138 }
139 return json.Marshal(nil) 139 return json.Marshal(nil)
140 } 140 }
141 141
142 // UnmarshalJSON ... 142 // UnmarshalJSON ...
143 func (ni *NullInt64) UnmarshalJSON(b []byte) error { 143 func (ni *NullInt64) UnmarshalJSON(b []byte) error {
144 var temp *int64 144 var temp *int64
145 if err := json.Unmarshal(b, &temp); err != nil { 145 if err := json.Unmarshal(b, &temp); err != nil {
146 return err 146 return err
147 } 147 }
148 if temp != nil { 148 if temp != nil {
149 ni.Valid = true 149 ni.Valid = true
150 ni.Int64 = *temp 150 ni.Int64 = *temp
151 } else { 151 } else {
152 ni.Valid = false 152 ni.Valid = false
153 } 153 }
154 return nil 154 return nil
155 } 155 }
156 156
157 // SQLCast ... 157 // SQLCast ...
158 func (ni *NullInt64) SQLCast() sql.NullInt64 { 158 func (ni *NullInt64) SQLCast() sql.NullInt64 {
159 return sql.NullInt64(*ni) 159 return sql.NullInt64(*ni)
160 } 160 }
161 161
162 // NullFloat64 is a wrapper for sql.NullFloat64 with added JSON (un)marshalling 162 // NullFloat64 is a wrapper for sql.NullFloat64 with added JSON (un)marshalling
163 type NullFloat64 sql.NullFloat64 163 type NullFloat64 sql.NullFloat64
164 164
165 // Scan ... 165 // Scan ...
166 func (nf *NullFloat64) Scan(value interface{}) error { 166 func (nf *NullFloat64) Scan(value interface{}) error {
167 var f sql.NullFloat64 167 var f sql.NullFloat64
168 if err := f.Scan(value); err != nil { 168 if err := f.Scan(value); err != nil {
169 nf.Float64, nf.Valid = 0.0, false 169 nf.Float64, nf.Valid = 0.0, false
170 return err 170 return err
171 } 171 }
172 nf.Float64, nf.Valid = f.Float64, f.Valid 172 nf.Float64, nf.Valid = f.Float64, f.Valid
173 return nil 173 return nil
174 } 174 }
175 175
176 // Value ... 176 // Value ...
177 func (nf *NullFloat64) Value() (driver.Value, error) { 177 func (nf *NullFloat64) Value() (driver.Value, error) {
178 if !nf.Valid { 178 if !nf.Valid {
179 return nil, nil 179 return nil, nil
180 } 180 }
181 return nf.Float64, nil 181 return nf.Float64, nil
182 } 182 }
183 183
184 // MarshalJSON ... 184 // MarshalJSON ...
185 func (nf NullFloat64) MarshalJSON() ([]byte, error) { 185 func (nf NullFloat64) MarshalJSON() ([]byte, error) {
186 if nf.Valid { 186 if nf.Valid {
187 return json.Marshal(nf.Float64) 187 return json.Marshal(nf.Float64)
188 } 188 }
189 return json.Marshal(nil) 189 return json.Marshal(nil)
190 } 190 }
191 191
192 // UnmarshalJSON ... 192 // UnmarshalJSON ...
193 func (nf *NullFloat64) UnmarshalJSON(b []byte) error { 193 func (nf *NullFloat64) UnmarshalJSON(b []byte) error {
194 var temp *float64 194 var temp *float64
195 if err := json.Unmarshal(b, &temp); err != nil { 195 if err := json.Unmarshal(b, &temp); err != nil {
196 return err 196 return err
197 } 197 }
198 if temp != nil { 198 if temp != nil {
199 nf.Valid = true 199 nf.Valid = true
200 nf.Float64 = *temp 200 nf.Float64 = *temp
201 } else { 201 } else {
202 nf.Valid = false 202 nf.Valid = false
203 } 203 }
204 return nil 204 return nil
205 } 205 }
206 206
207 // SQLCast ... 207 // SQLCast ...
208 func (nf *NullFloat64) SQLCast() sql.NullFloat64 { 208 func (nf *NullFloat64) SQLCast() sql.NullFloat64 {
209 return sql.NullFloat64(*nf) 209 return sql.NullFloat64(*nf)
210 } 210 }
211 211
212 // NullTime ... 212 // NullTime ...
213 type NullTime struct { 213 type NullTime struct {
214 Time time.Time 214 Time time.Time
215 Valid bool // Valid is true if Time is not NULL 215 Valid bool // Valid is true if Time is not NULL
216 } 216 }
217 217
218 // Scan ... 218 // Scan ...
219 func (nt *NullTime) Scan(value interface{}) (err error) { 219 func (nt *NullTime) Scan(value interface{}) (err error) {
220 if value == nil { 220 if value == nil {
221 nt.Time, nt.Valid = time.Time{}, false 221 nt.Time, nt.Valid = time.Time{}, false
222 return 222 return
223 } 223 }
224 224
225 switch v := value.(type) { 225 switch v := value.(type) {
226 case time.Time: 226 case time.Time:
227 nt.Time, nt.Valid = v, true 227 nt.Time, nt.Valid = v, true
228 return 228 return
229 case []byte: 229 case []byte:
230 nt.Time, err = parseDateTime(string(v), time.UTC) 230 nt.Time, err = parseDateTime(string(v), time.UTC)
231 nt.Valid = (err == nil) 231 nt.Valid = (err == nil)
232 return 232 return
233 case string: 233 case string:
234 nt.Time, err = parseDateTime(v, time.UTC) 234 nt.Time, err = parseDateTime(v, time.UTC)
235 nt.Valid = (err == nil) 235 nt.Valid = (err == nil)
236 return 236 return
237 } 237 }
238 238
239 nt.Valid = false 239 nt.Valid = false
240 return fmt.Errorf("Can't convert %T to time.Time", value) 240 return fmt.Errorf("Can't convert %T to time.Time", value)
241 } 241 }
242 242
243 // Value implements the driver Valuer interface. 243 // Value implements the driver Valuer interface.
244 func (nt NullTime) Value() (driver.Value, error) { 244 func (nt NullTime) Value() (driver.Value, error) {
245 if !nt.Valid { 245 if !nt.Valid {
246 return nil, nil 246 return nil, nil
247 } 247 }
248 return nt.Time, nil 248 return nt.Time, nil
249 } 249 }
250 250
251 // MarshalJSON ... 251 // MarshalJSON ...
252 func (nt NullTime) MarshalJSON() ([]byte, error) { 252 func (nt NullTime) MarshalJSON() ([]byte, error) {
253 if nt.Valid { 253 if nt.Valid {
254 format := nt.Time.Format("2006-01-02 15:04:05") 254 format := nt.Time.Format("2006-01-02 15:04:05")
255 return json.Marshal(format) 255 return json.Marshal(format)
256 } 256 }
257 return json.Marshal(nil) 257 return json.Marshal(nil)
258 } 258 }
259 259
260 // UnmarshalJSON ... 260 // UnmarshalJSON ...
261 func (nt *NullTime) UnmarshalJSON(b []byte) error { 261 func (nt *NullTime) UnmarshalJSON(b []byte) error {
262 var temp *time.Time 262 var temp *time.Time
263 var t1 time.Time 263 var t1 time.Time
264 var err error 264 var err error
265 265
266 s1 := string(b) 266 s1 := string(b)
267 s2 := s1[1 : len(s1)-1] 267 s2 := s1[1 : len(s1)-1]
268 if s1 == "null" { 268 if s1 == "null" {
269 temp = nil 269 temp = nil
270 } else { 270 } else {
271 t1, err = time.Parse("2006-01-02 15:04:05", s2) 271 t1, err = time.Parse("2006-01-02 15:04:05", s2)
272 if err != nil { 272 if err != nil {
273 return err 273 return err
274 } 274 }
275 temp = &t1 275 temp = &t1
276 } 276 }
277 277
278 if temp != nil { 278 if temp != nil {
279 nt.Valid = true 279 nt.Valid = true
280 nt.Time = *temp 280 nt.Time = *temp
281 } else { 281 } else {
282 nt.Valid = false 282 nt.Valid = false
283 } 283 }
284 return nil 284 return nil
285 } 285 }
286 286
287 func parseDateTime(str string, loc *time.Location) (t time.Time, err error) { 287 func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
288 base := "0000-00-00 00:00:00.0000000" 288 base := "0000-00-00 00:00:00.0000000"
289 timeFormat := "2006-01-02 15:04:05.999999" 289 timeFormat := "2006-01-02 15:04:05.999999"
290 switch len(str) { 290 switch len(str) {
291 case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM" 291 case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
292 if str == base[:len(str)] { 292 if str == base[:len(str)] {
293 return 293 return
294 } 294 }
295 t, err = time.Parse(timeFormat[:len(str)], str) 295 t, err = time.Parse(timeFormat[:len(str)], str)
296 default: 296 default:
297 err = fmt.Errorf("invalid time string: %s", str) 297 err = fmt.Errorf("invalid time string: %s", str)
298 return 298 return
299 } 299 }
300 300
301 // Adjust location 301 // Adjust location
302 if err == nil && loc != time.UTC { 302 if err == nil && loc != time.UTC {
303 y, mo, d := t.Date() 303 y, mo, d := t.Date()
304 h, mi, s := t.Clock() 304 h, mi, s := t.Clock()
305 t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil 305 t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
306 } 306 }
307 307
308 return 308 return
309 } 309 }
310 310
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "database/sql" 4 "database/sql"
5 "encoding/json" 5 "encoding/json"
6 "errors" 6 "errors"
7 "fmt" 7 "fmt"
8 "io" 8 "io"
9 "net/http" 9 "net/http"
10 "strings" 10 "strings"
11 "sync" 11 "sync"
12 "time" 12 "time"
13 13
14 "git.to-net.rs/marko.tikvic/gologger" 14 "git.to-net.rs/marko.tikvic/gologger"
15 "git.to-net.rs/marko.tikvic/util"
16 ) 15 )
17 16
18 var ( 17 var (
19 mu = &sync.Mutex{} 18 mu = &sync.Mutex{}
20 metadata = make(map[string]Payload) 19 metadata = make(map[string]Payload)
21 20
22 updateQue = make(map[string][]byte) 21 updateQue = make(map[string][]byte)
23 22
24 metadataDB *sql.DB 23 metadataDB *sql.DB
25 activeProject string 24 activeProject string
26 25
27 inited bool 26 inited bool
28 driver string 27 metaDriver string
29 logger *gologger.Logger 28 logger *gologger.Logger
30 ) 29 )
31 30
32 // LangMap ... 31 // LangMap ...
33 type LangMap map[string]map[string]string 32 type LangMap map[string]map[string]string
34 33
35 // Field ... 34 // Field ...
36 type Field struct { 35 type Field struct {
37 Parameter string `json:"param"` 36 Parameter string `json:"param"`
38 Type string `json:"type"` 37 Type string `json:"type"`
39 Visible bool `json:"visible"` 38 Visible bool `json:"visible"`
40 Editable bool `json:"editable"` 39 Editable bool `json:"editable"`
41 } 40 }
42 41
43 // CorrelationField ... 42 // CorrelationField ...
44 type CorrelationField struct { 43 type CorrelationField struct {
45 Result string `json:"result"` 44 Result string `json:"result"`
46 Elements []string `json:"elements"` 45 Elements []string `json:"elements"`
47 Type string `json:"type"` 46 Type string `json:"type"`
48 } 47 }
49 48
50 // Translation ... 49 // Translation ...
51 type Translation struct { 50 type Translation struct {
52 Language string `json:"language"` 51 Language string `json:"language"`
53 FieldsLabels map[string]string `json:"fieldsLabels"` 52 FieldsLabels map[string]string `json:"fieldsLabels"`
54 } 53 }
55 54
56 // PaginationLinks ... 55 // PaginationLinks ...
57 type PaginationLinks struct { 56 type PaginationLinks struct {
58 Base string `json:"base"` 57 Base string `json:"base"`
59 Next string `json:"next"` 58 Next string `json:"next"`
60 Prev string `json:"prev"` 59 Prev string `json:"prev"`
61 Self string `json:"self"` 60 Self string `json:"self"`
62 } 61 }
63 62
64 // PaginationParameters ... 63 // PaginationParameters ...
65 type PaginationParameters struct { 64 type PaginationParameters struct {
66 URL string `json:"-"` 65 URL string `json:"-"`
67 Offset int64 `json:"offset"` 66 Offset int64 `json:"offset"`
68 Limit int64 `json:"limit"` 67 Limit int64 `json:"limit"`
69 SortBy string `json:"sortBy"` 68 SortBy string `json:"sortBy"`
70 Order string `json:"order"` 69 Order string `json:"order"`
71 } 70 }
72 71
73 // GetPaginationParameters ... 72 // GetPaginationParameters ...
74 // TODO(marko) 73 // TODO(marko)
75 func GetPaginationParameters(req *http.Request) (p PaginationParameters) { 74 func GetPaginationParameters(req *http.Request) (p PaginationParameters) {
76 return p 75 return p
77 } 76 }
78 77
79 // TODO(marko) 78 // TODO(marko)
80 func (p *PaginationParameters) paginationLinks() (links PaginationLinks) { 79 func (p *PaginationParameters) paginationLinks() (links PaginationLinks) {
81 return links 80 return links
82 } 81 }
83 82
84 // Payload ... 83 // Payload ...
85 type Payload struct { 84 type Payload struct {
86 Method string `json:"method"` 85 Method string `json:"method"`
87 Params map[string]string `json:"params"` 86 Params map[string]string `json:"params"`
88 Lang []Translation `json:"lang"` 87 Lang []Translation `json:"lang"`
89 Fields []Field `json:"fields"` 88 Fields []Field `json:"fields"`
90 Correlations []CorrelationField `json:"correlationFields"` 89 Correlations []CorrelationField `json:"correlationFields"`
91 IDField string `json:"idField"` 90 IDField string `json:"idField"`
92 91
93 // Pagination 92 // Pagination
94 Count int64 `json:"count"` 93 Count int64 `json:"count"`
95 Total int64 `json:"total"` 94 Total int64 `json:"total"`
96 Links PaginationLinks `json:"_links"` 95 Links PaginationLinks `json:"_links"`
97 96
98 // Data holds JSON payload. It can't be used for itteration. 97 // Data holds JSON payload. It can't be used for itteration.
99 Data interface{} `json:"data"` 98 Data interface{} `json:"data"`
100 } 99 }
101 100
102 func (p *Payload) addLang(code string, labels map[string]string) { 101 func (p *Payload) addLang(code string, labels map[string]string) {
103 t := Translation{ 102 t := Translation{
104 Language: code, 103 Language: code,
105 FieldsLabels: labels, 104 FieldsLabels: labels,
106 } 105 }
107 p.Lang = append(p.Lang, t) 106 p.Lang = append(p.Lang, t)
108 } 107 }
109 108
110 // SetData ... 109 // SetData ...
111 func (p *Payload) SetData(data interface{}) { 110 func (p *Payload) SetData(data interface{}) {
112 p.Data = data 111 p.Data = data
113 } 112 }
114 113
115 // SetPaginationInfo ... 114 // SetPaginationInfo ...
116 func (p *Payload) SetPaginationInfo(count, total int64, params PaginationParameters) { 115 func (p *Payload) SetPaginationInfo(count, total int64, params PaginationParameters) {
117 p.Count = count 116 p.Count = count
118 p.Total = total 117 p.Total = total
119 p.Links = params.paginationLinks() 118 p.Links = params.paginationLinks()
120 } 119 }
121 120
122 // NewPayload returs a payload sceleton for entity described with key. 121 // NewPayload returs a payload sceleton for entity described with key.
123 func NewPayload(r *http.Request, key string) Payload { 122 func NewPayload(r *http.Request, key string) Payload {
124 p := metadata[key] 123 p := metadata[key]
125 p.Method = r.Method + " " + r.RequestURI 124 p.Method = r.Method + " " + r.RequestURI
126 return p 125 return p
127 } 126 }
128 127
129 // DecodeJSON decodes JSON data from r to v. 128 // DecodeJSON decodes JSON data from r to v.
130 // Returns an error if it fails. 129 // Returns an error if it fails.
131 func DecodeJSON(r io.Reader, v interface{}) error { 130 func DecodeJSON(r io.Reader, v interface{}) error {
132 return json.NewDecoder(r).Decode(v) 131 return json.NewDecoder(r).Decode(v)
133 } 132 }
134 133
135 // InitPayloadsMetadata loads all payloads' information into 'metadata' variable. 134 // InitPayloadsMetadata loads all payloads' information into 'metadata' variable.
136 func InitPayloadsMetadata(drv string, db *sql.DB, project string) error { 135 func InitPayloadsMetadata(drv string, db *sql.DB, project string) error {
137 var err error 136 var err error
138 if drv != "ora" && drv != "mysql" { 137 if drv != "ora" && drv != "mysql" {
139 err = errors.New("driver not supported") 138 err = errors.New("driver not supported")
140 return err 139 return err
141 } 140 }
142 141
143 driver = drv 142 metaDriver = drv
144 metadataDB = db 143 metadataDB = db
145 activeProject = project 144 activeProject = project
146 145
147 logger, err = gologger.New("metadata", gologger.MaxLogSize100KB) 146 logger, err = gologger.New("metadata", gologger.MaxLogSize100KB)
148 if err != nil { 147 if err != nil {
149 fmt.Printf("webutility: %s\n", err.Error()) 148 fmt.Printf("webutility: %s\n", err.Error())
150 } 149 }
151 150
152 mu.Lock() 151 mu.Lock()
153 defer mu.Unlock() 152 defer mu.Unlock()
154 err = initMetadata(project) 153 err = initMetadata(project)
155 if err != nil { 154 if err != nil {
156 return err 155 return err
157 } 156 }
158 inited = true 157 inited = true
159 158
160 return nil 159 return nil
161 } 160 }
162 161
163 // EnableHotloading ... 162 // EnableHotloading ...
164 func EnableHotloading(interval int) { 163 func EnableHotloading(interval int) {
165 if interval > 0 { 164 if interval > 0 {
166 go hotload(interval) 165 go hotload(interval)
167 } 166 }
168 } 167 }
169 168
170 // GetMetadataForAllEntities ... 169 // GetMetadataForAllEntities ...
171 func GetMetadataForAllEntities() map[string]Payload { 170 func GetMetadataForAllEntities() map[string]Payload {
172 return metadata 171 return metadata
173 } 172 }
174 173
175 // GetMetadataForEntity ... 174 // GetMetadataForEntity ...
176 func GetMetadataForEntity(t string) (Payload, bool) { 175 func GetMetadataForEntity(t string) (Payload, bool) {
177 p, ok := metadata[t] 176 p, ok := metadata[t]
178 return p, ok 177 return p, ok
179 } 178 }
180 179
181 // QueEntityModelUpdate ... 180 // QueEntityModelUpdate ...
182 func QueEntityModelUpdate(entityType string, v interface{}) { 181 func QueEntityModelUpdate(entityType string, v interface{}) {
183 updateQue[entityType], _ = json.Marshal(v) 182 updateQue[entityType], _ = json.Marshal(v)
184 } 183 }
185 184
186 // UpdateEntityModels ... 185 // UpdateEntityModels ...
187 func UpdateEntityModels(command string) (total, upd, add int, err error) { 186 func UpdateEntityModels(command string) (total, upd, add int, err error) {
188 if command != "force" && command != "missing" { 187 if command != "force" && command != "missing" {
189 return total, 0, 0, errors.New("webutility: unknown command: " + command) 188 return total, 0, 0, errors.New("webutility: unknown command: " + command)
190 } 189 }
191 190
192 if !inited { 191 if !inited {
193 return 0, 0, 0, errors.New("webutility: metadata not initialized but update was tried") 192 return 0, 0, 0, errors.New("webutility: metadata not initialized but update was tried")
194 } 193 }
195 194
196 total = len(updateQue) 195 total = len(updateQue)
197 196
198 toUpdate := make([]string, 0) 197 toUpdate := make([]string, 0)
199 toAdd := make([]string, 0) 198 toAdd := make([]string, 0)
200 199
201 for k := range updateQue { 200 for k := range updateQue {
202 if _, exists := metadata[k]; exists { 201 if _, exists := metadata[k]; exists {
203 if command == "force" { 202 if command == "force" {
204 toUpdate = append(toUpdate, k) 203 toUpdate = append(toUpdate, k)
205 } 204 }
206 } else { 205 } else {
207 toAdd = append(toAdd, k) 206 toAdd = append(toAdd, k)
208 } 207 }
209 } 208 }
210 209
211 var uStmt *sql.Stmt 210 var uStmt *sql.Stmt
212 if driver == "ora" { 211 if metaDriver == "ora" {
213 uStmt, err = metadataDB.Prepare("update entities set entity_model = :1 where entity_type = :2") 212 uStmt, err = metadataDB.Prepare("update entities set entity_model = :1 where entity_type = :2")
214 if err != nil { 213 if err != nil {
215 logger.Trace(err.Error()) 214 logger.Trace(err.Error())
216 return 215 return
217 } 216 }
218 } else if driver == "mysql" { 217 } else if metaDriver == "mysql" {
219 uStmt, err = metadataDB.Prepare("update entities set entity_model = ? where entity_type = ?") 218 uStmt, err = metadataDB.Prepare("update entities set entity_model = ? where entity_type = ?")
220 if err != nil { 219 if err != nil {
221 logger.Trace(err.Error()) 220 logger.Trace(err.Error())
222 return 221 return
223 } 222 }
224 } 223 }
225 for _, k := range toUpdate { 224 for _, k := range toUpdate {
226 _, err = uStmt.Exec(string(updateQue[k]), k) 225 _, err = uStmt.Exec(string(updateQue[k]), k)
227 if err != nil { 226 if err != nil {
228 logger.Trace(err.Error()) 227 logger.Trace(err.Error())
229 return 228 return
230 } 229 }
231 upd++ 230 upd++
232 } 231 }
233 232
234 blankPayload, _ := json.Marshal(Payload{}) 233 blankPayload, _ := json.Marshal(Payload{})
235 var iStmt *sql.Stmt 234 var iStmt *sql.Stmt
236 if driver == "ora" { 235 if metaDriver == "ora" {
237 iStmt, err = metadataDB.Prepare("insert into entities(projekat, metadata, entity_type, entity_model) values(:1, :2, :3, :4)") 236 iStmt, err = metadataDB.Prepare("insert into entities(projekat, metadata, entity_type, entity_model) values(:1, :2, :3, :4)")
238 if err != nil { 237 if err != nil {
239 logger.Trace(err.Error()) 238 logger.Trace(err.Error())
240 return 239 return
241 } 240 }
242 } else if driver == "mysql" { 241 } else if metaDriver == "mysql" {
243 iStmt, err = metadataDB.Prepare("insert into entities(projekat, metadata, entity_type, entity_model) values(?, ?, ?, ?)") 242 iStmt, err = metadataDB.Prepare("insert into entities(projekat, metadata, entity_type, entity_model) values(?, ?, ?, ?)")
244 if err != nil { 243 if err != nil {
245 logger.Trace(err.Error()) 244 logger.Trace(err.Error())
246 return 245 return
247 } 246 }
248 } 247 }
249 for _, k := range toAdd { 248 for _, k := range toAdd {
250 _, err = iStmt.Exec(activeProject, string(blankPayload), k, string(updateQue[k])) 249 _, err = iStmt.Exec(activeProject, string(blankPayload), k, string(updateQue[k]))
251 if err != nil { 250 if err != nil {
252 logger.Trace(err.Error()) 251 logger.Trace(err.Error())
253 return 252 return
254 } 253 }
255 metadata[k] = Payload{} 254 metadata[k] = Payload{}
256 add++ 255 add++
257 } 256 }
258 257
259 return total, upd, add, nil 258 return total, upd, add, nil
260 } 259 }
261 260
262 func initMetadata(project string) error { 261 func initMetadata(project string) error {
263 rows, err := metadataDB.Query(`select 262 rows, err := metadataDB.Query(`select
264 entity_type, 263 entity_type,
265 metadata 264 metadata
266 from entities 265 from entities
267 where projekat = ` + fmt.Sprintf("'%s'", project)) 266 where projekat = ` + fmt.Sprintf("'%s'", project))
268 if err != nil { 267 if err != nil {
269 return err 268 return err
270 } 269 }
271 defer rows.Close() 270 defer rows.Close()
272 271
273 if len(metadata) > 0 { 272 if len(metadata) > 0 {
274 metadata = nil 273 metadata = nil
275 } 274 }
276 metadata = make(map[string]Payload) 275 metadata = make(map[string]Payload)
277 for rows.Next() { 276 for rows.Next() {
278 var name, load string 277 var name, load string
279 rows.Scan(&name, &load) 278 rows.Scan(&name, &load)
280 279
281 p := Payload{} 280 p := Payload{}
282 err := json.Unmarshal([]byte(load), &p) 281 err := json.Unmarshal([]byte(load), &p)
283 if err != nil { 282 if err != nil {
284 logger.Log("webutility: couldn't init: '%s' metadata: %s:\n%s\n", name, err.Error(), load) 283 logger.Log("webutility: couldn't init: '%s' metadata: %s:\n%s\n", name, err.Error(), load)
285 } else { 284 } else {
286 metadata[name] = p 285 metadata[name] = p
287 } 286 }
288 } 287 }
289 288
290 return nil 289 return nil
291 } 290 }
292 291
293 // LoadMetadataFromFile expects file in format: 292 // LoadMetadataFromFile expects file in format:
294 // 293 //
295 // [ payload A identifier ] 294 // [ payload A identifier ]
296 // key1 = value1 295 // key1 = value1
297 // key2 = value2 296 // key2 = value2
298 // ... 297 // ...
299 // [ payload B identifier ] 298 // [ payload B identifier ]
300 // key1 = value1 299 // key1 = value1
301 // key2 = value2 300 // key2 = value2
302 // ... 301 // ...
303 // 302 //
304 // TODO(marko): Currently supports only one hardcoded language... 303 // TODO(marko): Currently supports only one hardcoded language...
305 func LoadMetadataFromFile(path string) error { 304 func LoadMetadataFromFile(path string) error {
306 lines, err := util.ReadFileLines(path) 305 lines, err := ReadFileLines(path)
307 if err != nil { 306 if err != nil {
308 return err 307 return err
309 } 308 }
310 309
311 metadata = make(map[string]Payload) 310 metadata = make(map[string]Payload)
312 311
313 var name string 312 var name string
314 for i, l := range lines { 313 for i, l := range lines {
315 // skip empty lines 314 // skip empty lines
316 if l = strings.TrimSpace(l); len(l) == 0 { 315 if l = strings.TrimSpace(l); len(l) == 0 {
317 continue 316 continue
318 } 317 }
319 318
320 if util.IsWrappedWith(l, "[", "]") { 319 if IsWrappedWith(l, "[", "]") {
321 name = strings.Trim(l, "[]") 320 name = strings.Trim(l, "[]")
322 p := Payload{} 321 p := Payload{}
323 p.addLang("sr", make(map[string]string)) 322 p.addLang("sr", make(map[string]string))
324 metadata[name] = p 323 metadata[name] = p
325 continue 324 continue
326 } 325 }
327 326
328 if name == "" { 327 if name == "" {
329 return fmt.Errorf("webutility: LoadMetadataFromFile: error on line %d: [no header] [%s]", i+1, l) 328 return fmt.Errorf("webutility: LoadMetadataFromFile: error on line %d: [no header] [%s]", i+1, l)
330 } 329 }
331 330
332 parts := strings.Split(l, "=") 331 parts := strings.Split(l, "=")
333 if len(parts) != 2 { 332 if len(parts) != 2 {
334 return fmt.Errorf("webutility: LoadMetadataFromFile: error on line %d: [invalid format] [%s]", i+1, l) 333 return fmt.Errorf("webutility: LoadMetadataFromFile: error on line %d: [invalid format] [%s]", i+1, l)
335 } 334 }
336 335
337 k := strings.TrimSpace(parts[0]) 336 k := strings.TrimSpace(parts[0])
338 v := strings.TrimSpace(parts[1]) 337 v := strings.TrimSpace(parts[1])
339 if v != "-" { 338 if v != "-" {
340 metadata[name].Lang[0].FieldsLabels[k] = v 339 metadata[name].Lang[0].FieldsLabels[k] = v
341 } 340 }
342 } 341 }
343 342
344 return nil 343 return nil
345 } 344 }
346 345
347 func hotload(n int) { 346 func hotload(n int) {
348 entityScan := make(map[string]int64) 347 entityScan := make(map[string]int64)
349 firstCheck := true 348 firstCheck := true
350 for { 349 for {
351 time.Sleep(time.Duration(n) * time.Second) 350 time.Sleep(time.Duration(n) * time.Second)
352 rows, err := metadataDB.Query(`select 351 rows, err := metadataDB.Query(`select
353 ora_rowscn, 352 ora_rowscn,
354 entity_type 353 entity_type
355 from entities where projekat = ` + fmt.Sprintf("'%s'", activeProject)) 354 from entities where projekat = ` + fmt.Sprintf("'%s'", activeProject))
356 if err != nil { 355 if err != nil {
357 logger.Log("webutility: hotload failed: %v\n", err) 356 logger.Log("webutility: hotload failed: %v\n", err)
358 time.Sleep(time.Duration(n) * time.Second) 357 time.Sleep(time.Duration(n) * time.Second)
359 continue 358 continue
360 } 359 }
361 360
362 var toRefresh []string 361 var toRefresh []string
363 for rows.Next() { 362 for rows.Next() {
364 var scanID int64 363 var scanID int64
365 var entity string 364 var entity string
366 rows.Scan(&scanID, &entity) 365 rows.Scan(&scanID, &entity)
367 oldID, ok := entityScan[entity] 366 oldID, ok := entityScan[entity]
368 if !ok || oldID != scanID { 367 if !ok || oldID != scanID {
369 entityScan[entity] = scanID 368 entityScan[entity] = scanID
370 toRefresh = append(toRefresh, entity) 369 toRefresh = append(toRefresh, entity)
371 } 370 }
372 } 371 }
373 rows.Close() 372 rows.Close()
374 373
375 if rows.Err() != nil { 374 if rows.Err() != nil {
376 logger.Log("webutility: hotload rset error: %v\n", rows.Err()) 375 logger.Log("webutility: hotload rset error: %v\n", rows.Err())
377 time.Sleep(time.Duration(n) * time.Second) 376 time.Sleep(time.Duration(n) * time.Second)
378 continue 377 continue
379 } 378 }
380 379
381 if len(toRefresh) > 0 && !firstCheck { 380 if len(toRefresh) > 0 && !firstCheck {
382 mu.Lock() 381 mu.Lock()
383 refreshMetadata(toRefresh) 382 refreshMetadata(toRefresh)
384 mu.Unlock() 383 mu.Unlock()
385 } 384 }
386 if firstCheck { 385 if firstCheck {
387 firstCheck = false 386 firstCheck = false
388 } 387 }
389 } 388 }
390 } 389 }
391 390
392 func refreshMetadata(entities []string) { 391 func refreshMetadata(entities []string) {
393 for _, e := range entities { 392 for _, e := range entities {
394 fmt.Printf("refreshing %s\n", e) 393 fmt.Printf("refreshing %s\n", e)
395 rows, err := metadataDB.Query(`select 394 rows, err := metadataDB.Query(`select
396 metadata 395 metadata
397 from entities 396 from entities
398 where projekat = ` + fmt.Sprintf("'%s'", activeProject) + 397 where projekat = ` + fmt.Sprintf("'%s'", activeProject) +
399 ` and entity_type = ` + fmt.Sprintf("'%s'", e)) 398 ` and entity_type = ` + fmt.Sprintf("'%s'", e))
400 399
401 if err != nil { 400 if err != nil {
402 logger.Log("webutility: refresh: prep: %v\n", err) 401 logger.Log("webutility: refresh: prep: %v\n", err)
403 rows.Close() 402 rows.Close()
404 continue 403 continue
405 } 404 }
406 405
407 for rows.Next() { 406 for rows.Next() {
408 var load string 407 var load string
409 rows.Scan(&load) 408 rows.Scan(&load)
410 p := Payload{} 409 p := Payload{}
411 err := json.Unmarshal([]byte(load), &p) 410 err := json.Unmarshal([]byte(load), &p)
412 if err != nil { 411 if err != nil {
413 logger.Log("webutility: couldn't refresh: '%s' metadata: %s\n%s\n", e, err.Error(), load) 412 logger.Log("webutility: couldn't refresh: '%s' metadata: %s\n%s\n", e, err.Error(), load)
414 } else { 413 } else {
415 metadata[e] = p 414 metadata[e] = p
416 } 415 }
417 } 416 }
418 rows.Close() 417 rows.Close()
419 } 418 }
420 } 419 }
421 420
422 /* 421 /*
423 func ModifyMetadataForEntity(entityType string, p *Payload) error { 422 func ModifyMetadataForEntity(entityType string, p *Payload) error {
424 md, err := json.Marshal(*p) 423 md, err := json.Marshal(*p)
425 if err != nil { 424 if err != nil {
426 return err 425 return err
427 } 426 }
428 427
429 mu.Lock() 428 mu.Lock()
430 defer mu.Unlock() 429 defer mu.Unlock()
431 _, err = metadataDB.PrepAndExe(`update entities set 430 _, err = metadataDB.PrepAndExe(`update entities set
432 metadata = :1 431 metadata = :1
433 where projekat = :2 432 where projekat = :2
434 and entity_type = :3`, 433 and entity_type = :3`,
435 string(md), 434 string(md),
436 activeProject, 435 activeProject,
437 entityType) 436 entityType)
438 if err != nil { 437 if err != nil {
439 return err 438 return err
440 } 439 }
441 return nil 440 return nil
442 } 441 }
443 442
444 func DeleteEntityModel(entityType string) error { 443 func DeleteEntityModel(entityType string) error {
445 _, err := metadataDB.PrepAndExe("delete from entities where entity_type = :1", entityType) 444 _, err := metadataDB.PrepAndExe("delete from entities where entity_type = :1", entityType)
446 if err == nil { 445 if err == nil {
447 mu.Lock() 446 mu.Lock()
448 delete(metadata, entityType) 447 delete(metadata, entityType)
449 mu.Unlock() 448 mu.Unlock()
450 } 449 }
451 return err 450 return err
452 } 451 }
453 */ 452 */
454 453
string_sanitisation.go
1 package webutility 1 package webutility
2 2
3 import "git.to-net.rs/marko.tikvic/util"
4
5 const patern = "\"';&*<>=\\`:" 3 const patern = "\"';&*<>=\\`:"
6 4
7 // SanitiseString removes characters from s found in patern and returns new modified string. 5 // SanitiseString removes characters from s found in patern and returns new modified string.
8 func SanitiseString(s string) string { 6 func SanitiseString(s string) string {
9 return util.ReplaceAny(s, patern, "") 7 return ReplaceAny(s, patern, "")
10 } 8 }
11 9
1 package util 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "strings" 5 "strings"
6 ) 6 )
7 7
8 // IsWrappedWith ... 8 // IsWrappedWith ...
9 func IsWrappedWith(src, begin, end string) bool { 9 func IsWrappedWith(src, begin, end string) bool {
10 return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) 10 return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end)
11 } 11 }
12 12
13 // ParseInt64Arr ... 13 // ParseInt64Arr ...
14 func ParseInt64Arr(s, sep string) (arr []int64) { 14 func ParseInt64Arr(s, sep string) (arr []int64) {
15 s = strings.TrimSpace(s) 15 s = strings.TrimSpace(s)
16 if s != "" { 16 if s != "" {
17 parts := strings.Split(s, sep) 17 parts := strings.Split(s, sep)
18 arr = make([]int64, len(parts)) 18 arr = make([]int64, len(parts))
19 for i, p := range parts { 19 for i, p := range parts {
20 num := StringToInt64(p) 20 num := StringToInt64(p)
21 arr[i] = num 21 arr[i] = num
22 } 22 }
23 } 23 }
24 24
25 return arr 25 return arr
26 } 26 }
27 27
28 // Int64SliceToString ... 28 // Int64SliceToString ...
29 func Int64SliceToString(arr []int64) (s string) { 29 func Int64SliceToString(arr []int64) (s string) {
30 for i, num := range arr { 30 for i, num := range arr {
31 if i == 0 { 31 if i == 0 {
32 s += fmt.Sprintf("%d", num) 32 s += fmt.Sprintf("%d", num)
33 } else { 33 } else {
34 s += fmt.Sprintf(",%d", num) 34 s += fmt.Sprintf(",%d", num)
35 } 35 }
36 } 36 }
37 37
38 return s 38 return s
39 } 39 }
40 40
41 // CombineStrings ... 41 // CombineStrings ...
42 func CombineStrings(s1, s2, s3 string) string { 42 func CombineStrings(s1, s2, s3 string) string {
43 s1 = strings.TrimSpace(s1) 43 s1 = strings.TrimSpace(s1)
44 s2 = strings.TrimSpace(s2) 44 s2 = strings.TrimSpace(s2)
45 45
46 if s1 != "" && s2 != "" { 46 if s1 != "" && s2 != "" {
47 s1 += s3 + s2 47 s1 += s3 + s2
48 } else { 48 } else {
49 s1 += s2 49 s1 += s2
50 } 50 }
51 51
52 return s1 52 return s1
53 } 53 }
54 54
55 // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. 55 // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string.
56 func ReplaceAny(s, patern, r string) (n string) { 56 func ReplaceAny(s, patern, r string) (n string) {
57 n = s 57 n = s
58 for _, c := range patern { 58 for _, c := range patern {
59 n = strings.Replace(n, string(c), r, -1) 59 n = strings.Replace(n, string(c), r, -1)
60 } 60 }
61 return n 61 return n
62 } 62 }
63 63
64 func StringToBool(s string) bool { 64 func StringToBool(s string) bool {
65 s = strings.ToLower(s) 65 s = strings.ToLower(s)
66 if s == "true" { 66 if s == "true" {
67 return true 67 return true
68 } 68 }
69 return false 69 return false
70 } 70 }
71 71
72 func BoolToString(b bool) string { 72 func BoolToString(b bool) string {
73 return fmt.Sprintf("%b", b) 73 return fmt.Sprintf("%b", b)
74 } 74 }
75 75
76 func StringSliceContains(slice []string, s string) bool { 76 func StringSliceContains(slice []string, s string) bool {
77 for i := range slice { 77 for i := range slice {
78 if slice[i] == s { 78 if slice[i] == s {
79 return true 79 return true
80 } 80 }
81 } 81 }
82 return false 82 return false
83 } 83 }
84 84