Skip to content

Commit f0faef9

Browse files
committed
✨ switch from code gen to package
1 parent 8d3b50e commit f0faef9

File tree

9 files changed

+107
-259
lines changed

9 files changed

+107
-259
lines changed

.goreleaser.yaml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,7 @@ before:
33
- go mod tidy
44

55
builds:
6-
- env:
7-
- CGO_ENABLED=0
8-
ldflags:
9-
- -s -w -X github.com/jxlxx/geid.Version={{.Version}}
10-
goos:
11-
- linux
12-
- windows
13-
- darwin
6+
- skip: true
147

158
archives:
169
- format: tar.gz

README.md

Lines changed: 18 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Example: `ab-ce093c1`
88

99
- :sparkles: Optional prefixes: IDs will be of the form `prefix-*`
1010
- :sparkles: Safe to use with goroutines: New IDs require data from a counter which has a lock
11-
- :sparkles: Safe to use with multiple machines: Each ID requires a "machine ID" int coming from the environment
11+
- :sparkles: Safe to use with multiple machines: Can set a unique "Machine ID" for each instance
1212
- :sparkles: Optional custom epoch: Can override the default epoch of January 1st, 1970
1313

1414
## Install
@@ -17,122 +17,50 @@ Example: `ab-ce093c1`
1717
go install github.com/jxlxx/geid@latest
1818
```
1919

20-
## Configuration
21-
22-
Epoch is optional. The default epoch is January 1st, 1970.
23-
24-
```yaml
25-
package: animals
26-
epoch:
27-
year: 2024
28-
month: 6
29-
day: 14
30-
ids:
31-
- name: Cat
32-
prefix: cat-
33-
- name: Dog
34-
prefix: dog-
35-
- name: something # this id will not have a prefix
36-
```
37-
3820
## Getting Started
3921

40-
Generate code:
41-
42-
```sh
43-
geid -c config.yaml > ids.go
44-
```
22+
Epoch is optional. The default epoch is January 1st, 1970. Setting the epoch to a later date means short IDs.
4523

46-
Generated code:
24+
MachineID is optional. The default machine ID is "1". This is useful if you have many instances of identical
25+
ID generators running at the same time.
4726

4827
```go
49-
package animals
28+
package main
5029

5130
import (
5231
"fmt"
53-
"log"
54-
"os"
55-
"strconv"
56-
"sync"
5732
"time"
58-
)
5933

60-
const CatIDPrefix = "cat-"
61-
const DogIDPrefix = "dog-"
62-
const somethingIDPrefix = ""
63-
64-
func newCatID() string {
65-
return fmt.Sprintf("%s%s", CatIDPrefix, generateCode())
66-
}
67-
68-
func newDogID() string {
69-
return fmt.Sprintf("%s%s", DogIDPrefix, generateCode())
70-
}
71-
72-
func newsomethingID() string {
73-
return fmt.Sprintf("%s%s", somethingIDPrefix, generateCode())
74-
}
75-
76-
func generateCode() string {
77-
s := getSequenceNumber()
78-
t := getSecondsSinceEpoch()
79-
m := getMachineID()
80-
hex := fmt.Sprintf("%x%x%x", s, t, m)
81-
return hex
82-
}
83-
84-
type Counter struct {
85-
mu sync.Mutex
86-
x int
87-
}
34+
"github.com/jxlxx/geid"
35+
)
8836

89-
var counter = Counter{}
37+
type Cat struct{}
9038

91-
func getSequenceNumber() int {
92-
counter.mu.Lock()
93-
defer counter.mu.Unlock()
94-
counter.x = (counter.x + 1) % 4096
95-
return counter.x + 170 // adding 170 so that the first few IDs are prettier
39+
func (c Cat) Prefix() string {
40+
return "cat-"
9641
}
9742

98-
var customEpoch = time.Date(2024, time.June, 14, 0, 0, 0, 0, time.UTC).Unix()
43+
func main() {
44+
c := Cat{}
45+
g := geid.New(c)
9946

100-
func getSecondsSinceEpoch() int64 {
101-
return time.Now().Unix() - customEpoch
102-
}
47+
t := time.Now()
48+
geid.SetCustomEpoch(time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC))
10349

104-
func getMachineID() int {
105-
machineID := mustGetEnv("MACHINE_ID")
106-
i, err := strconv.Atoi(machineID)
107-
if err != nil {
108-
log.Fatalf("cannot parse machine id into int. (MACHINE_ID = %s) ", machineID)
50+
for i := 0; i < 100; i++ {
51+
fmt.Println(g.NewID())
10952
}
110-
return i
111-
}
112-
113-
func mustGetEnv(key string) string {
114-
v, ok := os.LookupEnv(key)
115-
if !ok {
116-
log.Fatalf("%s environment key not found.\n", key)
117-
}
118-
return v
11953
}
12054
```
55+
12156
## Examples
12257

12358
```sh
12459
cat-ab-ce093c1
12560
cat-ac-ce093c1
12661
cat-ad-ce093c1
127-
dog-ae-ce093c1
128-
dog-af-ce093c1
129-
dog-b0-ce093c1
130-
b1-ce093c1
131-
b2-ce093c1
132-
b3-ce093c1
13362
```
13463

135-
13664
## Design
13765

13866
The implementation is loosely based on the following article: [Creating User-Facing, Short Unique IDs: What are the options? - Hwee Lin Yeo, Alexandra](https://medium.com/teamocard/creating-user-facing-short-unique-id-ids-what-are-the-options-464a19283d98)

Taskfile.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ vars:
88
VERSION: v0.0.{{ .VERSION_NUMBER }}
99

1010
tasks:
11-
build:
12-
description: build a local binary
13-
cmds:
14-
- go build -o bin/geid -ldflags="-s -w -X github.com/jxlxx/geid.Version={{.VERSION}}"
15-
1611
release:
1712
cmds:
1813
- goreleaser release --clean

example/main.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/jxlxx/geid"
8+
)
9+
10+
type Cat struct{}
11+
12+
func (c Cat) Prefix() string {
13+
return "cat-"
14+
}
15+
16+
func main() {
17+
c := Cat{}
18+
g := geid.New(c)
19+
20+
t := time.Now()
21+
geid.SetCustomEpoch(time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC))
22+
23+
for i := 0; i < 100; i++ {
24+
fmt.Println(g.NewID())
25+
}
26+
}

geid.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package geid
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
"time"
7+
)
8+
9+
type Prefix interface {
10+
Prefix() string
11+
}
12+
13+
type Generator struct {
14+
prefix string
15+
}
16+
17+
func New(p Prefix) *Generator {
18+
return &Generator{
19+
prefix: p.Prefix(),
20+
}
21+
}
22+
23+
func (i Generator) NewID() string {
24+
return fmt.Sprintf("%s%s", i.prefix, generateCode())
25+
}
26+
27+
var machineID = "1"
28+
29+
func SetMachineID(s string) {
30+
machineID = s
31+
}
32+
33+
var epoch = time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC).Unix()
34+
35+
func SetCustomEpoch(t time.Time) {
36+
epoch = t.Unix()
37+
}
38+
39+
func getSecondsSinceEpoch() int64 {
40+
return time.Now().Unix() - epoch
41+
}
42+
43+
func generateCode() string {
44+
s := getSequenceNumber()
45+
t := getSecondsSinceEpoch()
46+
hex := fmt.Sprintf("%x%x%x", s, t, machineID)
47+
return hex
48+
}
49+
50+
type Counter struct {
51+
mu sync.Mutex
52+
x int
53+
}
54+
55+
var counter = Counter{}
56+
57+
func getSequenceNumber() int {
58+
counter.mu.Lock()
59+
defer counter.mu.Unlock()
60+
counter.x = (counter.x + 1) % 4096
61+
return counter.x + 170
62+
}

go.mod

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
11
module github.com/jxlxx/geid
22

33
go 1.21.4
4-
5-
require (
6-
github.com/spf13/pflag v1.0.5
7-
gopkg.in/yaml.v3 v3.0.1
8-
)

go.sum

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +0,0 @@
1-
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
2-
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
3-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5-
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
6-
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

ids.gotmpl

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)