forked from kdar/goqless
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgoqless.go
140 lines (123 loc) · 2.94 KB
/
goqless.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// reference: https://github.com/seomoz/qless-py
package goqless
import (
"bytes"
"crypto/rand"
"crypto/sha1"
"encoding/json"
"fmt"
"github.com/garyburd/redigo/redis"
mrand "math/rand"
"os"
"strconv"
"time"
"unicode"
"unicode/utf8"
)
// type Opts map[string]interface{}
// func (o Opts) Get(name string, dfault interface{}) interface{} {
// if v, ok := o[name]; ok {
// return v
// }
// return dfault
// }
// represents a string slice with special json unmarshalling
type StringSlice []string
func (s *StringSlice) UnmarshalJSON(data []byte) error {
// because tables and arrays are equal in LUA,
// an empty array would be presented as "{}".
if bytes.Equal(data, []byte("{}")) {
*s = []string{}
return nil
}
var str []string
err := json.Unmarshal(data, &str)
if err != nil {
return err
}
*s = str
return nil
}
// Generates a jid
func generateJID() string {
hasher := sha1.New()
uuid := make([]byte, 16)
n, err := rand.Read(uuid)
if err != nil || n != len(uuid) {
src := mrand.NewSource(time.Now().UnixNano())
r := mrand.New(src)
for n, _ := range uuid {
uuid[n] = byte(r.Int())
}
}
hasher.Write(uuid)
return fmt.Sprintf("%x", hasher.Sum(nil))
}
// returns a timestamp used in LUA calls
func timestamp() int64 {
return time.Now().UTC().Unix()
}
// returns a worker name for this machine/process
func workerName() string {
hn, err := os.Hostname()
if err != nil {
hn = os.Getenv("HOSTNAME")
}
if hn == "" {
hn = "localhost"
}
return fmt.Sprintf("%s-%d", hn, os.Getpid())
}
// makes the first character of a string upper case
func ucfirst(s string) string {
if s == "" {
return ""
}
r, n := utf8.DecodeRuneInString(s)
return string(unicode.ToUpper(r)) + s[n:]
}
// marshals a value. if the value happens to be
// a string or []byte, just return it.
func marshal(i interface{}) []byte {
//switch v := i.(type) {
//case []byte:
// return v
//case string:
// return []byte(v)
//}
byts, err := json.Marshal(i)
if err != nil {
return nil
}
return byts
}
// Bool is a helper that converts a command reply to a boolean. If err is not
// equal to nil, then Bool returns false, err. Otherwise Bool converts the
// reply to boolean as follows:
//
// Reply type Result
// integer value != 0, nil
// bulk strconv.ParseBool(reply) or r != "False", nil
// nil false, ErrNil
// other false, error
func Bool(reply interface{}, err error) (bool, error) {
if err != nil {
return false, err
}
switch reply := reply.(type) {
case int64:
return reply != 0, nil
case []byte:
r := string(reply)
b, err := strconv.ParseBool(r)
if err != nil {
return r != "False", nil
}
return b, err
case nil:
return false, redis.ErrNil
case redis.Error:
return false, reply
}
return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
}