Commit cacf57bd4a044185604faf7d45dce09df11fc9cc
1 parent
d9855ed8cd
Exists in
master
merging with /utility package
Showing
7 changed files
with
611 additions
and
2 deletions
Show diff stats
default_values.go
... | ... | @@ -0,0 +1,65 @@ |
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 | +} | ... | ... |
diff.go
... | ... | @@ -0,0 +1,32 @@ |
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 | +} | ... | ... |
file_util.go
... | ... | @@ -0,0 +1,63 @@ |
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 | +} | ... | ... |
http.go
... | ... | @@ -58,12 +58,24 @@ func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { |
58 | 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 | 73 | // SetDefaultHeaders set's default headers for an HTTP response. |
62 | 74 | func SetDefaultHeaders(w http.ResponseWriter) { |
63 | 75 | w.Header().Set("Access-Control-Allow-Origin", "*") |
64 | 76 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") |
65 | 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 | 81 | // GetLocale ... |
... | ... | @@ -134,4 +146,3 @@ func Conflict(w http.ResponseWriter, r *http.Request, err string) { |
134 | 146 | func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { |
135 | 147 | Error(w, r, http.StatusInternalServerError, err) |
136 | 148 | } |
137 | - | ... | ... |
int_util.go
... | ... | @@ -0,0 +1,46 @@ |
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 | +} | ... | ... |
nullables.go
... | ... | @@ -0,0 +1,309 @@ |
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 | +} | ... | ... |
string_util.go
... | ... | @@ -0,0 +1,83 @@ |
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 | +} | ... | ... |