Commit cacf57bd4a044185604faf7d45dce09df11fc9cc

Authored by Marko Tikvić
1 parent d9855ed8cd
Exists in master

merging with /utility package

default_values.go
File was created 1 package util
2
3 // IntOrDefault ...
4 func IntOrDefault(v *int) int {
5 if v != nil {
6 return *v
7 }
8 return 0
9 }
10
11 // Int32OrDefault ...
12 func Int32OrDefault(v *int32) int32 {
13 if v != nil {
14 return *v
15 }
16 return 0
17 }
18
19 // Int64OrDefault ...
20 func Int64OrDefault(v *int64) int64 {
21 if v != nil {
22 return *v
23 }
24 return 0
25 }
26
27 // Uint32OrDefault ...
28 func Uint32OrDefault(v *uint32) uint32 {
29 if v != nil {
30 return *v
31 }
32 return 0
33 }
34
35 // Uint64OrDefault ...
36 func Uint64OrDefault(v *uint64) uint64 {
37 if v != nil {
38 return *v
39 }
40 return 0
41 }
42
43 // StringOrDefault ...
44 func StringOrDefault(v *string) string {
45 if v != nil {
46 return *v
47 }
48 return ""
49 }
50
51 // Float32OrDefault ...
52 func Float32OrDefault(v *float32) float32 {
53 if v != nil {
54 return *v
55 }
56 return 0.0
57 }
58
59 // Float64OrDefault ...
60 func Float64OrDefault(v *float64) float64 {
61 if v != nil {
62 return *v
63 }
64 return 0.0
65 }
66
File was created 1 package util
2
3 // Diff ...
4 func Diff(old, new []int64) (added, removed []int64) {
5 for i := range old {
6 isRemoved := true
7 for j := range new {
8 if old[i] == new[j] {
9 isRemoved = false
10 break
11 }
12 }
13 if isRemoved {
14 removed = append(removed, old[i])
15 }
16 }
17
18 for i := range new {
19 isAdded := true
20 for j := range old {
21 if new[i] == old[j] {
22 isAdded = false
23 break
24 }
25 }
26 if isAdded {
27 added = append(added, new[i])
28 }
29 }
30
31 return added, removed
32 }
33
File was created 1 package util
2
3 import (
4 "bytes"
5 "io"
6 "io/ioutil"
7 "os"
8 "strings"
9 )
10
11 func ReadFileContent(path string) ([]byte, error) {
12 f, err := os.Open(path)
13 if err != nil {
14 return nil, err
15 }
16 defer f.Close()
17
18 buf := &bytes.Buffer{}
19 if _, err = io.Copy(buf, f); err != nil {
20 return nil, err
21 }
22
23 return buf.Bytes(), nil
24 }
25
26 // ReadFileLines ...
27 func ReadFileLines(path string) ([]string, error) {
28 f, err := os.Open(path)
29 if err != nil {
30 return nil, err
31 }
32 defer f.Close()
33
34 var s strings.Builder
35
36 if _, err = io.Copy(&s, f); err != nil {
37 return nil, err
38 }
39
40 lines := strings.Split(s.String(), "\n")
41 for i := range lines {
42 lines[i] = strings.TrimRight(lines[i], "\r\n")
43 }
44
45 return lines, nil
46 }
47
48 // LinesToFile ...
49 func LinesToFile(path string, lines []string) error {
50 content := ""
51 for _, l := range lines {
52 content += l + "\n"
53 }
54
55 return ioutil.WriteFile(path, []byte(content), 0644) // drw-r--r--
56 }
57
58 // InsertLine ...
59 func InsertLine(lines *[]string, pos int64, l string) {
60 tail := append([]string{l}, (*lines)[pos:]...)
61
62 *lines = append((*lines)[:pos], tail...)
63 }
64
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "fmt" 5 "fmt"
6 "net/http" 6 "net/http"
7 ) 7 )
8 8
9 // StatusRecorder ... 9 // StatusRecorder ...
10 type StatusRecorder struct { 10 type StatusRecorder struct {
11 writer http.ResponseWriter 11 writer http.ResponseWriter
12 status int 12 status int
13 size int 13 size int
14 } 14 }
15 15
16 // NewStatusRecorder ... 16 // NewStatusRecorder ...
17 func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder { 17 func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder {
18 return &StatusRecorder{ 18 return &StatusRecorder{
19 writer: w, 19 writer: w,
20 status: 0, 20 status: 0,
21 size: 0, 21 size: 0,
22 } 22 }
23 } 23 }
24 24
25 // WriteHeader is a wrapper http.ResponseWriter interface 25 // WriteHeader is a wrapper http.ResponseWriter interface
26 func (r *StatusRecorder) WriteHeader(code int) { 26 func (r *StatusRecorder) WriteHeader(code int) {
27 r.status = code 27 r.status = code
28 r.writer.WriteHeader(code) 28 r.writer.WriteHeader(code)
29 } 29 }
30 30
31 // Write is a wrapper for http.ResponseWriter interface 31 // Write is a wrapper for http.ResponseWriter interface
32 func (r *StatusRecorder) Write(in []byte) (int, error) { 32 func (r *StatusRecorder) Write(in []byte) (int, error) {
33 r.size = len(in) 33 r.size = len(in)
34 return r.writer.Write(in) 34 return r.writer.Write(in)
35 } 35 }
36 36
37 // Header is a wrapper for http.ResponseWriter interface 37 // Header is a wrapper for http.ResponseWriter interface
38 func (r *StatusRecorder) Header() http.Header { 38 func (r *StatusRecorder) Header() http.Header {
39 return r.writer.Header() 39 return r.writer.Header()
40 } 40 }
41 41
42 // Status ... 42 // Status ...
43 func (r *StatusRecorder) Status() int { 43 func (r *StatusRecorder) Status() int {
44 return r.status 44 return r.status
45 } 45 }
46 46
47 // Size ... 47 // Size ...
48 func (r *StatusRecorder) Size() int { 48 func (r *StatusRecorder) Size() int {
49 return r.size 49 return r.size
50 } 50 }
51 51
52 // NotFoundHandlerFunc writes HTTP error 404 to w. 52 // NotFoundHandlerFunc writes HTTP error 404 to w.
53 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { 53 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) {
54 SetDefaultHeaders(w) 54 SetDefaultHeaders(w)
55 if req.Method == "OPTIONS" { 55 if req.Method == "OPTIONS" {
56 return 56 return
57 } 57 }
58 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String())) 58 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String()))
59 } 59 }
60 60
61 func SetContentType(w http.ResponseWriter, ctype string) {
62 w.Header().Set("Content-Type", ctype)
63 }
64
65 func SetResponseStatus(w http.ResponseWriter, status int) {
66 w.WriteHeader(status)
67 }
68
69 func WriteResponse(w http.ResponseWriter, content []byte) {
70 w.Write(content)
71 }
72
61 // SetDefaultHeaders set's default headers for an HTTP response. 73 // SetDefaultHeaders set's default headers for an HTTP response.
62 func SetDefaultHeaders(w http.ResponseWriter) { 74 func SetDefaultHeaders(w http.ResponseWriter) {
63 w.Header().Set("Access-Control-Allow-Origin", "*") 75 w.Header().Set("Access-Control-Allow-Origin", "*")
64 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") 76 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
65 w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") 77 w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
66 w.Header().Set("Content-Type", "application/json; charset=utf-8") 78 SetContentType(w, "application/json; charset=utf-8")
67 } 79 }
68 80
69 // GetLocale ... 81 // GetLocale ...
70 func GetLocale(req *http.Request, dflt string) string { 82 func GetLocale(req *http.Request, dflt string) string {
71 loc := req.FormValue("locale") 83 loc := req.FormValue("locale")
72 if loc == "" { 84 if loc == "" {
73 return dflt 85 return dflt
74 } 86 }
75 return loc 87 return loc
76 } 88 }
77 89
78 // Success ... 90 // Success ...
79 func Success(w http.ResponseWriter, payload interface{}, code int) { 91 func Success(w http.ResponseWriter, payload interface{}, code int) {
80 w.WriteHeader(code) 92 w.WriteHeader(code)
81 if payload != nil { 93 if payload != nil {
82 json.NewEncoder(w).Encode(payload) 94 json.NewEncoder(w).Encode(payload)
83 } 95 }
84 } 96 }
85 97
86 // OK ... 98 // OK ...
87 func OK(w http.ResponseWriter, payload interface{}) { 99 func OK(w http.ResponseWriter, payload interface{}) {
88 Success(w, payload, http.StatusOK) 100 Success(w, payload, http.StatusOK)
89 } 101 }
90 102
91 // Created ... 103 // Created ...
92 func Created(w http.ResponseWriter, payload interface{}) { 104 func Created(w http.ResponseWriter, payload interface{}) {
93 Success(w, payload, http.StatusCreated) 105 Success(w, payload, http.StatusCreated)
94 } 106 }
95 107
96 type weberror struct { 108 type weberror struct {
97 Request string `json:"request"` 109 Request string `json:"request"`
98 Error string `json:"error"` 110 Error string `json:"error"`
99 } 111 }
100 112
101 // Error ... 113 // Error ...
102 func Error(w http.ResponseWriter, r *http.Request, code int, err string) { 114 func Error(w http.ResponseWriter, r *http.Request, code int, err string) {
103 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI} 115 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI}
104 w.WriteHeader(code) 116 w.WriteHeader(code)
105 json.NewEncoder(w).Encode(werr) 117 json.NewEncoder(w).Encode(werr)
106 } 118 }
107 119
108 // BadRequest ... 120 // BadRequest ...
109 func BadRequest(w http.ResponseWriter, r *http.Request, err string) { 121 func BadRequest(w http.ResponseWriter, r *http.Request, err string) {
110 Error(w, r, http.StatusBadRequest, err) 122 Error(w, r, http.StatusBadRequest, err)
111 } 123 }
112 124
113 // Unauthorized ... 125 // Unauthorized ...
114 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) { 126 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) {
115 Error(w, r, http.StatusUnauthorized, err) 127 Error(w, r, http.StatusUnauthorized, err)
116 } 128 }
117 129
118 // Forbidden ... 130 // Forbidden ...
119 func Forbidden(w http.ResponseWriter, r *http.Request, err string) { 131 func Forbidden(w http.ResponseWriter, r *http.Request, err string) {
120 Error(w, r, http.StatusForbidden, err) 132 Error(w, r, http.StatusForbidden, err)
121 } 133 }
122 134
123 // NotFound ... 135 // NotFound ...
124 func NotFound(w http.ResponseWriter, r *http.Request, err string) { 136 func NotFound(w http.ResponseWriter, r *http.Request, err string) {
125 Error(w, r, http.StatusNotFound, err) 137 Error(w, r, http.StatusNotFound, err)
126 } 138 }
127 139
128 // Conflict ... 140 // Conflict ...
129 func Conflict(w http.ResponseWriter, r *http.Request, err string) { 141 func Conflict(w http.ResponseWriter, r *http.Request, err string) {
130 Error(w, r, http.StatusConflict, err) 142 Error(w, r, http.StatusConflict, err)
131 } 143 }
132 144
133 // InternalServerError ... 145 // InternalServerError ...
134 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { 146 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) {
135 Error(w, r, http.StatusInternalServerError, err) 147 Error(w, r, http.StatusInternalServerError, err)
136 } 148 }
137
File was created 1 package util
2
3 import (
4 "fmt"
5 "strconv"
6 )
7
8 // ClampInt64 ...
9 func ClampInt64(v, min, max int64) int64 {
10 if v < min {
11 return min
12 } else if v > max {
13 return max
14 }
15
16 return v
17 }
18
19 // InRangeInt64 ...
20 func InRangeInt64(v, min, max int64) bool {
21 return (v >= min && v <= max)
22 }
23
24 // StringToInt64 ...
25 func StringToInt64(s string) int64 {
26 i, _ := strconv.ParseInt(s, 10, 64)
27 return i
28 }
29
30 // Int64ToString ...
31 func Int64ToString(i int64) string {
32 return fmt.Sprintf("%d", i)
33 }
34
35 // BoolToInt64 ...
36 func BoolToInt64(b bool) int64 {
37 if b {
38 return 1
39 }
40 return 0
41 }
42
43 // Int64ToBool ...
44 func Int64ToBool(i int64) bool {
45 return i != 0
46 }
47
File was created 1 package util
2
3 import (
4 "database/sql"
5 "database/sql/driver"
6 "encoding/json"
7 "fmt"
8 "time"
9 )
10
11 // NullBool is a wrapper for sql.NullBool with added JSON (un)marshalling
12 type NullBool sql.NullBool
13
14 // Scan ...
15 func (nb *NullBool) Scan(value interface{}) error {
16 var b sql.NullBool
17 if err := b.Scan(value); err != nil {
18 nb.Bool, nb.Valid = false, false
19 return err
20 }
21 nb.Bool, nb.Valid = b.Bool, b.Valid
22 return nil
23 }
24
25 // Value ...
26 func (nb *NullBool) Value() (driver.Value, error) {
27 if !nb.Valid {
28 return nil, nil
29 }
30 return nb.Bool, nil
31 }
32
33 // MarshalJSON ...
34 func (nb NullBool) MarshalJSON() ([]byte, error) {
35 if nb.Valid {
36 return json.Marshal(nb.Bool)
37 }
38
39 return json.Marshal(nil)
40 }
41
42 // UnmarshalJSON ...
43 func (nb *NullBool) UnmarshalJSON(b []byte) error {
44 var temp *bool
45 if err := json.Unmarshal(b, &temp); err != nil {
46 return err
47 }
48 if temp != nil {
49 nb.Valid = true
50 nb.Bool = *temp
51 } else {
52 nb.Valid = false
53 }
54 return nil
55 }
56
57 // SQLCast ...
58 func (nb *NullBool) SQLCast() sql.NullBool {
59 return sql.NullBool(*nb)
60 }
61
62 // NullString is a wrapper for sql.NullString with added JSON (un)marshalling
63 type NullString sql.NullString
64
65 // Scan ...
66 func (ns *NullString) Scan(value interface{}) error {
67 var s sql.NullString
68 if err := s.Scan(value); err != nil {
69 ns.String, ns.Valid = "", false
70 return err
71 }
72 ns.String, ns.Valid = s.String, s.Valid
73 return nil
74 }
75
76 // Value ...
77 func (ns *NullString) Value() (driver.Value, error) {
78 if !ns.Valid {
79 return nil, nil
80 }
81 return ns.String, nil
82 }
83
84 // MarshalJSON ...
85 func (ns NullString) MarshalJSON() ([]byte, error) {
86 if ns.Valid {
87 return json.Marshal(ns.String)
88 }
89 return json.Marshal(nil)
90 }
91
92 // UnmarshalJSON ...
93 func (ns *NullString) UnmarshalJSON(b []byte) error {
94 var temp *string
95 if err := json.Unmarshal(b, &temp); err != nil {
96 return err
97 }
98 if temp != nil {
99 ns.Valid = true
100 ns.String = *temp
101 } else {
102 ns.Valid = false
103 }
104 return nil
105 }
106
107 // SQLCast ...
108 func (ns *NullString) SQLCast() sql.NullString {
109 return sql.NullString(*ns)
110 }
111
112 // NullInt64 is a wrapper for sql.NullInt64 with added JSON (un)marshalling
113 type NullInt64 sql.NullInt64
114
115 // Scan ...
116 func (ni *NullInt64) Scan(value interface{}) error {
117 var i sql.NullInt64
118 if err := i.Scan(value); err != nil {
119 ni.Int64, ni.Valid = 0, false
120 return err
121 }
122 ni.Int64, ni.Valid = i.Int64, i.Valid
123 return nil
124 }
125
126 // Value ...
127 func (ni *NullInt64) Value() (driver.Value, error) {
128 if !ni.Valid {
129 return nil, nil
130 }
131 return ni.Int64, nil
132 }
133
134 // MarshalJSON ...
135 func (ni NullInt64) MarshalJSON() ([]byte, error) {
136 if ni.Valid {
137 return json.Marshal(ni.Int64)
138 }
139 return json.Marshal(nil)
140 }
141
142 // UnmarshalJSON ...
143 func (ni *NullInt64) UnmarshalJSON(b []byte) error {
144 var temp *int64
145 if err := json.Unmarshal(b, &temp); err != nil {
146 return err
147 }
148 if temp != nil {
149 ni.Valid = true
150 ni.Int64 = *temp
151 } else {
152 ni.Valid = false
153 }
154 return nil
155 }
156
157 // SQLCast ...
158 func (ni *NullInt64) SQLCast() sql.NullInt64 {
159 return sql.NullInt64(*ni)
160 }
161
162 // NullFloat64 is a wrapper for sql.NullFloat64 with added JSON (un)marshalling
163 type NullFloat64 sql.NullFloat64
164
165 // Scan ...
166 func (nf *NullFloat64) Scan(value interface{}) error {
167 var f sql.NullFloat64
168 if err := f.Scan(value); err != nil {
169 nf.Float64, nf.Valid = 0.0, false
170 return err
171 }
172 nf.Float64, nf.Valid = f.Float64, f.Valid
173 return nil
174 }
175
176 // Value ...
177 func (nf *NullFloat64) Value() (driver.Value, error) {
178 if !nf.Valid {
179 return nil, nil
180 }
181 return nf.Float64, nil
182 }
183
184 // MarshalJSON ...
185 func (nf NullFloat64) MarshalJSON() ([]byte, error) {
186 if nf.Valid {
187 return json.Marshal(nf.Float64)
188 }
189 return json.Marshal(nil)
190 }
191
192 // UnmarshalJSON ...
193 func (nf *NullFloat64) UnmarshalJSON(b []byte) error {
194 var temp *float64
195 if err := json.Unmarshal(b, &temp); err != nil {
196 return err
197 }
198 if temp != nil {
199 nf.Valid = true
200 nf.Float64 = *temp
201 } else {
202 nf.Valid = false
203 }
204 return nil
205 }
206
207 // SQLCast ...
208 func (nf *NullFloat64) SQLCast() sql.NullFloat64 {
209 return sql.NullFloat64(*nf)
210 }
211
212 // NullTime ...
213 type NullTime struct {
214 Time time.Time
215 Valid bool // Valid is true if Time is not NULL
216 }
217
218 // Scan ...
219 func (nt *NullTime) Scan(value interface{}) (err error) {
220 if value == nil {
221 nt.Time, nt.Valid = time.Time{}, false
222 return
223 }
224
225 switch v := value.(type) {
226 case time.Time:
227 nt.Time, nt.Valid = v, true
228 return
229 case []byte:
230 nt.Time, err = parseDateTime(string(v), time.UTC)
231 nt.Valid = (err == nil)
232 return
233 case string:
234 nt.Time, err = parseDateTime(v, time.UTC)
235 nt.Valid = (err == nil)
236 return
237 }
238
239 nt.Valid = false
240 return fmt.Errorf("Can't convert %T to time.Time", value)
241 }
242
243 // Value implements the driver Valuer interface.
244 func (nt NullTime) Value() (driver.Value, error) {
245 if !nt.Valid {
246 return nil, nil
247 }
248 return nt.Time, nil
249 }
250
251 // MarshalJSON ...
252 func (nt NullTime) MarshalJSON() ([]byte, error) {
253 if nt.Valid {
254 format := nt.Time.Format("2006-01-02 15:04:05")
255 return json.Marshal(format)
256 }
257 return json.Marshal(nil)
258 }
259
260 // UnmarshalJSON ...
261 func (nt *NullTime) UnmarshalJSON(b []byte) error {
262 var temp *time.Time
263 var t1 time.Time
264 var err error
265
266 s1 := string(b)
267 s2 := s1[1 : len(s1)-1]
268 if s1 == "null" {
269 temp = nil
270 } else {
271 t1, err = time.Parse("2006-01-02 15:04:05", s2)
272 if err != nil {
273 return err
274 }
275 temp = &t1
276 }
277
278 if temp != nil {
279 nt.Valid = true
280 nt.Time = *temp
281 } else {
282 nt.Valid = false
283 }
284 return nil
285 }
286
287 func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
288 base := "0000-00-00 00:00:00.0000000"
289 timeFormat := "2006-01-02 15:04:05.999999"
290 switch len(str) {
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)] {
293 return
294 }
295 t, err = time.Parse(timeFormat[:len(str)], str)
296 default:
297 err = fmt.Errorf("invalid time string: %s", str)
298 return
299 }
300
301 // Adjust location
302 if err == nil && loc != time.UTC {
303 y, mo, d := t.Date()
304 h, mi, s := t.Clock()
305 t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
306 }
307
308 return
309 }
310
File was created 1 package util
2
3 import (
4 "fmt"
5 "strings"
6 )
7
8 // IsWrappedWith ...
9 func IsWrappedWith(src, begin, end string) bool {
10 return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end)
11 }
12
13 // ParseInt64Arr ...
14 func ParseInt64Arr(s, sep string) (arr []int64) {
15 s = strings.TrimSpace(s)
16 if s != "" {
17 parts := strings.Split(s, sep)
18 arr = make([]int64, len(parts))
19 for i, p := range parts {
20 num := StringToInt64(p)
21 arr[i] = num
22 }
23 }
24
25 return arr
26 }
27
28 // Int64SliceToString ...
29 func Int64SliceToString(arr []int64) (s string) {
30 for i, num := range arr {
31 if i == 0 {
32 s += fmt.Sprintf("%d", num)
33 } else {
34 s += fmt.Sprintf(",%d", num)
35 }
36 }
37
38 return s
39 }
40
41 // CombineStrings ...
42 func CombineStrings(s1, s2, s3 string) string {
43 s1 = strings.TrimSpace(s1)
44 s2 = strings.TrimSpace(s2)
45
46 if s1 != "" && s2 != "" {
47 s1 += s3 + s2
48 } else {
49 s1 += s2
50 }
51
52 return s1
53 }
54
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) {
57 n = s
58 for _, c := range patern {
59 n = strings.Replace(n, string(c), r, -1)
60 }
61 return n
62 }
63
64 func StringToBool(s string) bool {
65 s = strings.ToLower(s)
66 if s == "true" {
67 return true
68 }
69 return false
70 }
71
72 func BoolToString(b bool) string {
73 return fmt.Sprintf("%b", b)
74 }
75
76 func StringSliceContains(slice []string, s string) bool {
77 for i := range slice {
78 if slice[i] == s {
79 return true
80 }
81 }
82 return false
83 }
84