- Store.WithTx runs fn on the writer, committing on nil and rolling back on error, panic or goroutine exit; panics propagate unchanged. - NewID returns a monotonic ULID string (oklog/ulid/v2, crypto/rand), strictly increasing within the process. - Timestamp stores UTC RFC 3339 TEXT at fixed millisecond precision. - LocalDate stores YYYY-MM-DD TEXT and rejects invalid or non-canonical dates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
28 lines
617 B
Go
28 lines
617 B
Go
package store
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/oklog/ulid/v2"
|
|
)
|
|
|
|
var (
|
|
idMu sync.Mutex
|
|
idEntropy = ulid.Monotonic(rand.Reader, 0)
|
|
idLastMS uint64
|
|
)
|
|
|
|
// NewID returns a new ULID as its canonical 26-character string. IDs from
|
|
// this process sort strictly in creation order, including within one
|
|
// millisecond and across a backwards wall-clock step. It panics if the
|
|
// monotonic entropy overflows within a millisecond.
|
|
func NewID() string {
|
|
idMu.Lock()
|
|
defer idMu.Unlock()
|
|
ms := max(ulid.Timestamp(time.Now()), idLastMS)
|
|
idLastMS = ms
|
|
return ulid.MustNew(ms, idEntropy).String()
|
|
}
|