-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen.go
141 lines (112 loc) · 2.7 KB
/
gen.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
141
package main
import (
"fmt"
"math/rand"
"strconv"
"time"
"github.com/garyburd/redigo/redis"
uuid "github.com/satori/go.uuid"
)
var (
// RandMinlen is the default alias length for random alias generators.
RandMinlen = 8
// RandChars is the default character set for random alias generators.
RandChars = "abcdefghijklmnopqrstuvwzyz0123456789"
// MinRandMinlen is the minimum alias length allowed for random alias generators.
MinRandMinlen = 4
// MinRandChars is the minimum number of characters allowed in a random alias
// generator character set.
MinRandChars = 8
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// Def is an alias generator definition.
type Def struct {
// Internal ID of the definition.
ID int `json:"id"`
// Name of the generator.
Name string `json:"name"`
// Type of generator.
Type string `json:"type"`
// Offset for seq generator.
// **NOT IMPLEMENTED**
Offset int64 `json:"offset"`
// Apply to rand generator.
Chars string `json:"chars"`
Minlen int `json:"minlen"`
Prefix string `json:"prefix"`
// Whether the definition is archived or not.
Deleted bool `json:"archived"`
}
// NewDef returns a new alias generator definition with the default settings.
func NewDef() *Def {
return &Def{
Chars: RandChars,
Minlen: RandMinlen,
}
}
// MakeGen makes an alias generator from the given definition given a redis connection.
func MakeGen(c redis.Conn, d *Def) Gen {
switch d.Type {
case "uuid":
return &UUIDGen{}
case "rand":
return &RandGen{
Prefix: d.Prefix,
Minlen: d.Minlen,
Chars: d.Chars,
charlen: len(d.Chars),
}
case "seq":
return &SeqGen{
Name: d.Name,
Offset: d.Offset,
conn: c,
}
}
return nil
}
// Gen is an alias generator interface.
type Gen interface {
New() (string, error)
}
// UUIDGen generates random UUIDs.
type UUIDGen struct{}
// New generates a new random UUID.
func (g *UUIDGen) New() (string, error) {
return uuid.NewV4().String(), nil
}
// RandGen is a random alias generator.
type RandGen struct {
Prefix string
Minlen int
Chars string
charlen int
}
// New generates a new random alias.
func (g *RandGen) New() (string, error) {
key := make([]byte, g.Minlen)
for i := range key {
key[i] = g.Chars[rand.Intn(g.charlen)]
}
alias := string(key)
if g.Prefix == "" {
return alias, nil
}
return fmt.Sprintf("%s%s", g.Prefix, alias), nil
}
// SeqGen is a sequential alias generator.
type SeqGen struct {
Name string
Offset int64
conn redis.Conn
}
// New generates a new sequential alias.
func (g *SeqGen) New() (string, error) {
id, err := redis.Int64(g.conn.Do("INCR", seqPrefix+g.Name))
if err != nil && err != redis.ErrNil {
return "", err
}
return strconv.FormatInt(id, 10), nil
}