refactor(store): align AX examples and terminology
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
a80e352b43
commit
4edd7dd0ca
8 changed files with 43 additions and 43 deletions
12
README.md
12
README.md
|
|
@ -30,19 +30,19 @@ func main() {
|
|||
}
|
||||
defer storeInstance.Close()
|
||||
|
||||
if err := storeInstance.Set("config", "theme", "dark"); err != nil {
|
||||
if err := storeInstance.Set("config", "colour", "blue"); err != nil {
|
||||
return
|
||||
}
|
||||
if err := storeInstance.SetWithTTL("session", "token", "abc123", 24*time.Hour); err != nil {
|
||||
return
|
||||
}
|
||||
themeValue, err := storeInstance.Get("config", "theme")
|
||||
colourValue, err := storeInstance.Get("config", "colour")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(themeValue)
|
||||
fmt.Println(colourValue)
|
||||
|
||||
// Watch "config" changes and print each event as it arrives.
|
||||
// Watch "config" mutations and print each event as it arrives.
|
||||
watcher := storeInstance.Watch("config", "*")
|
||||
defer storeInstance.Unwatch(watcher)
|
||||
go func() {
|
||||
|
|
@ -51,12 +51,12 @@ func main() {
|
|||
}
|
||||
}()
|
||||
|
||||
// Prefix tenant-42 preferences with "tenant-42:".
|
||||
// Store tenant-42 preferences under the "tenant-42:" prefix.
|
||||
scopedStore, err := store.NewScoped(storeInstance, "tenant-42")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := scopedStore.Set("prefs", "locale", "en-GB"); err != nil {
|
||||
if err := scopedStore.Set("preferences", "locale", "en-GB"); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
doc.go
10
doc.go
|
|
@ -10,20 +10,20 @@
|
|||
// }
|
||||
// defer storeInstance.Close()
|
||||
//
|
||||
// if err := storeInstance.Set("config", "theme", "dark"); err != nil {
|
||||
// if err := storeInstance.Set("config", "colour", "blue"); err != nil {
|
||||
// return
|
||||
// }
|
||||
// themeValue, err := storeInstance.Get("config", "theme")
|
||||
// colourValue, err := storeInstance.Get("config", "colour")
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// fmt.Println(themeValue)
|
||||
// fmt.Println(colourValue)
|
||||
//
|
||||
// scopedStore, err := store.NewScoped(storeInstance, "tenant-a")
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// if err := scopedStore.Set("config", "theme", "dark"); err != nil {
|
||||
// if err := scopedStore.Set("config", "colour", "blue"); err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// if err := quotaScopedStore.Set("prefs", "locale", "en-GB"); err != nil {
|
||||
// if err := quotaScopedStore.Set("preferences", "locale", "en-GB"); err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ func main() {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := scopedStore.Set("prefs", "locale", "en-GB"); err != nil {
|
||||
if err := scopedStore.Set("preferences", "locale", "en-GB"); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Keys are addressed by a two-level path: `(group, key)`. Groups act as logical na
|
|||
This model maps naturally to domain concepts:
|
||||
|
||||
```
|
||||
group: "user:42:config" key: "theme"
|
||||
group: "user:42:config" key: "colour"
|
||||
group: "user:42:config" key: "language"
|
||||
group: "session:abc" key: "token"
|
||||
```
|
||||
|
|
@ -198,10 +198,10 @@ scopedStore, err := store.NewScoped(storeInstance, "tenant-42")
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := scopedStore.Set("config", "theme", "dark"); err != nil {
|
||||
if err := scopedStore.Set("config", "colour", "blue"); err != nil {
|
||||
return
|
||||
}
|
||||
// Stored in underlying store as group="tenant-42:config", key="theme"
|
||||
// Stored in underlying store as group="tenant-42:config", key="colour"
|
||||
```
|
||||
|
||||
Namespace strings must match `^[a-zA-Z0-9-]+$`. Invalid namespaces are rejected at construction time.
|
||||
|
|
|
|||
|
|
@ -33,27 +33,27 @@ func main() {
|
|||
}
|
||||
defer storeInstance.Close()
|
||||
|
||||
// Store and read back a theme value.
|
||||
if err := storeInstance.Set("config", "theme", "dark"); err != nil {
|
||||
// Store "blue" under config/colour and read it back.
|
||||
if err := storeInstance.Set("config", "colour", "blue"); err != nil {
|
||||
return
|
||||
}
|
||||
themeValue, err := storeInstance.Get("config", "theme")
|
||||
colourValue, err := storeInstance.Get("config", "colour")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(themeValue) // "dark"
|
||||
fmt.Println(colourValue) // "blue"
|
||||
|
||||
// Store a session token that expires after 24 hours.
|
||||
if err := storeInstance.SetWithTTL("session", "token", "abc123", 24*time.Hour); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Read the config group into a map.
|
||||
// Read config/colour back into a map.
|
||||
configEntries, err := storeInstance.GetAll("config")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(configEntries) // map[theme:dark]
|
||||
fmt.Println(configEntries) // map[colour:blue]
|
||||
|
||||
// Render the mail host and port into smtp.example.com:587.
|
||||
if err := storeInstance.Set("mail", "host", "smtp.example.com"); err != nil {
|
||||
|
|
@ -68,15 +68,15 @@ func main() {
|
|||
}
|
||||
fmt.Println(renderedTemplate) // "smtp.example.com:587"
|
||||
|
||||
// Prefix tenant-42 preferences with tenant-42:.
|
||||
// Store tenant-42 preferences under the tenant-42: namespace prefix.
|
||||
scopedStore, err := store.NewScoped(storeInstance, "tenant-42")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := scopedStore.Set("prefs", "locale", "en-GB"); err != nil {
|
||||
if err := scopedStore.Set("preferences", "locale", "en-GB"); err != nil {
|
||||
return
|
||||
}
|
||||
// Stored internally as group "tenant-42:prefs", key "locale"
|
||||
// Stored internally as group "tenant-42:preferences", key "locale"
|
||||
|
||||
// Cap tenant-99 at 100 keys and 5 groups.
|
||||
quotaScopedStore, err := store.NewScopedWithQuota(storeInstance, "tenant-99", store.QuotaConfig{MaxKeys: 100, MaxGroups: 5})
|
||||
|
|
|
|||
12
events.go
12
events.go
|
|
@ -33,16 +33,16 @@ func (t EventType) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
// Usage example: `event := store.Event{Type: store.EventSet, Group: "config", Key: "theme", Value: "dark"}`
|
||||
// Usage example: `event := store.Event{Type: store.EventSet, Group: "config", Key: "colour", Value: "blue"}`
|
||||
// Usage example: `event := store.Event{Type: store.EventDeleteGroup, Group: "config"}`
|
||||
type Event struct {
|
||||
// Usage example: `if event.Type == store.EventDeleteGroup { return }`
|
||||
Type EventType
|
||||
// Usage example: `if event.Group == "config" { return }`
|
||||
Group string
|
||||
// Usage example: `if event.Key == "theme" { return }`
|
||||
// Usage example: `if event.Key == "colour" { return }`
|
||||
Key string
|
||||
// Usage example: `if event.Value == "dark" { return }`
|
||||
// Usage example: `if event.Value == "blue" { return }`
|
||||
Value string
|
||||
// Usage example: `if event.Timestamp.IsZero() { return }`
|
||||
Timestamp time.Time
|
||||
|
|
@ -50,7 +50,7 @@ type Event struct {
|
|||
|
||||
// Usage example: `watcher := storeInstance.Watch("config", "*"); defer storeInstance.Unwatch(watcher); for event := range watcher.Events { if event.Type == EventDeleteGroup { return } }`
|
||||
type Watcher struct {
|
||||
// Usage example: `for event := range watcher.Events { if event.Key == "theme" { return } }`
|
||||
// Usage example: `for event := range watcher.Events { if event.Key == "colour" { return } }`
|
||||
Events <-chan Event
|
||||
|
||||
// eventChannel is the internal write channel (same underlying channel as Events).
|
||||
|
|
@ -130,7 +130,7 @@ func (storeInstance *Store) OnChange(callback func(Event)) func() {
|
|||
}
|
||||
}
|
||||
|
||||
// notify(Event{Type: EventSet, Group: "config", Key: "theme", Value: "dark"})
|
||||
// notify(Event{Type: EventSet, Group: "config", Key: "colour", Value: "blue"})
|
||||
// dispatches matching watchers and callbacks after a successful write. If a
|
||||
// watcher buffer is full, the event is dropped instead of blocking the writer.
|
||||
// Callbacks are copied under a separate lock and invoked after the lock is
|
||||
|
|
@ -160,7 +160,7 @@ func (storeInstance *Store) notify(event Event) {
|
|||
}
|
||||
|
||||
// watcherMatches reports whether Watch("config", "*") should receive
|
||||
// Event{Group: "config", Key: "theme"}.
|
||||
// Event{Group: "config", Key: "colour"}.
|
||||
func watcherMatches(watcher *Watcher, event Event) bool {
|
||||
if watcher.group != "*" && watcher.group != event.Group {
|
||||
return false
|
||||
|
|
|
|||
12
scope.go
12
scope.go
|
|
@ -19,7 +19,7 @@ type QuotaConfig struct {
|
|||
MaxGroups int
|
||||
}
|
||||
|
||||
// Usage example: `scopedStore, err := store.NewScoped(storeInstance, "tenant-a"); if err != nil { return }; if err := scopedStore.Set("config", "theme", "dark"); err != nil { return }`
|
||||
// Usage example: `scopedStore, err := store.NewScoped(storeInstance, "tenant-a"); if err != nil { return }; if err := scopedStore.Set("config", "colour", "blue"); err != nil { return }`
|
||||
type ScopedStore struct {
|
||||
storeInstance *Store
|
||||
namespace string
|
||||
|
|
@ -54,12 +54,12 @@ func (scopedStore *ScopedStore) Namespace() string {
|
|||
return scopedStore.namespace
|
||||
}
|
||||
|
||||
// Usage example: `themeValue, err := scopedStore.Get("config", "theme")`
|
||||
// Usage example: `colourValue, err := scopedStore.Get("config", "colour")`
|
||||
func (scopedStore *ScopedStore) Get(group, key string) (string, error) {
|
||||
return scopedStore.storeInstance.Get(scopedStore.namespacedGroup(group), key)
|
||||
}
|
||||
|
||||
// Usage example: `if err := scopedStore.Set("config", "theme", "dark"); err != nil { return }`
|
||||
// Usage example: `if err := scopedStore.Set("config", "colour", "blue"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) Set(group, key, value string) error {
|
||||
if err := scopedStore.checkQuota("store.ScopedStore.Set", group, key); err != nil {
|
||||
return err
|
||||
|
|
@ -75,7 +75,7 @@ func (scopedStore *ScopedStore) SetWithTTL(group, key, value string, timeToLive
|
|||
return scopedStore.storeInstance.SetWithTTL(scopedStore.namespacedGroup(group), key, value, timeToLive)
|
||||
}
|
||||
|
||||
// Usage example: `if err := scopedStore.Delete("config", "theme"); err != nil { return }`
|
||||
// Usage example: `if err := scopedStore.Delete("config", "colour"); err != nil { return }`
|
||||
func (scopedStore *ScopedStore) Delete(group, key string) error {
|
||||
return scopedStore.storeInstance.Delete(scopedStore.namespacedGroup(group), key)
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ func (scopedStore *ScopedStore) DeleteGroup(group string) error {
|
|||
return scopedStore.storeInstance.DeleteGroup(scopedStore.namespacedGroup(group))
|
||||
}
|
||||
|
||||
// Usage example: `configEntries, err := scopedStore.GetAll("config")`
|
||||
// Usage example: `colourEntries, err := scopedStore.GetAll("config")`
|
||||
func (scopedStore *ScopedStore) GetAll(group string) (map[string]string, error) {
|
||||
return scopedStore.storeInstance.GetAll(scopedStore.namespacedGroup(group))
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ func (scopedStore *ScopedStore) Render(templateSource, group string) (string, er
|
|||
return scopedStore.storeInstance.Render(templateSource, scopedStore.namespacedGroup(group))
|
||||
}
|
||||
|
||||
// checkQuota("store.ScopedStore.Set", "config", "theme") returns nil when the
|
||||
// checkQuota("store.ScopedStore.Set", "config", "colour") returns nil when the
|
||||
// namespace still has quota available and QuotaExceededError when a new key or
|
||||
// group would exceed the configured limit. Existing keys are treated as
|
||||
// upserts and do not consume quota.
|
||||
|
|
|
|||
14
store.go
14
store.go
|
|
@ -27,7 +27,7 @@ const (
|
|||
entryValueColumn = "entry_value"
|
||||
)
|
||||
|
||||
// Usage example: `storeInstance, err := store.New(":memory:"); if err != nil { return }; if err := storeInstance.Set("config", "theme", "dark"); err != nil { return }`
|
||||
// Usage example: `storeInstance, err := store.New(":memory:"); if err != nil { return }; if err := storeInstance.Set("config", "colour", "blue"); err != nil { return }`
|
||||
type Store struct {
|
||||
database *sql.DB
|
||||
cancelPurge context.CancelFunc
|
||||
|
|
@ -83,7 +83,7 @@ func (storeInstance *Store) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Usage example: `themeValue, err := storeInstance.Get("config", "theme")`
|
||||
// Usage example: `colourValue, err := storeInstance.Get("config", "colour")`
|
||||
func (storeInstance *Store) Get(group, key string) (string, error) {
|
||||
var value string
|
||||
var expiresAt sql.NullInt64
|
||||
|
|
@ -106,7 +106,7 @@ func (storeInstance *Store) Get(group, key string) (string, error) {
|
|||
return value, nil
|
||||
}
|
||||
|
||||
// Usage example: `if err := storeInstance.Set("config", "theme", "dark"); err != nil { return }`
|
||||
// Usage example: `if err := storeInstance.Set("config", "colour", "blue"); err != nil { return }`
|
||||
func (storeInstance *Store) Set(group, key, value string) error {
|
||||
_, err := storeInstance.database.Exec(
|
||||
"INSERT INTO "+entriesTableName+" ("+entryGroupColumn+", "+entryKeyColumn+", "+entryValueColumn+", expires_at) VALUES (?, ?, ?, NULL) "+
|
||||
|
|
@ -135,7 +135,7 @@ func (storeInstance *Store) SetWithTTL(group, key, value string, timeToLive time
|
|||
return nil
|
||||
}
|
||||
|
||||
// Usage example: `if err := storeInstance.Delete("config", "theme"); err != nil { return }`
|
||||
// Usage example: `if err := storeInstance.Delete("config", "colour"); err != nil { return }`
|
||||
func (storeInstance *Store) Delete(group, key string) error {
|
||||
_, err := storeInstance.database.Exec("DELETE FROM "+entriesTableName+" WHERE "+entryGroupColumn+" = ? AND "+entryKeyColumn+" = ?", group, key)
|
||||
if err != nil {
|
||||
|
|
@ -170,13 +170,13 @@ func (storeInstance *Store) DeleteGroup(group string) error {
|
|||
|
||||
// Usage example: `for entry, err := range storeInstance.All("config") { if err != nil { break }; fmt.Println(entry.Key, entry.Value) }`
|
||||
type KeyValue struct {
|
||||
// Usage example: `if entry.Key == "theme" { return }`
|
||||
// Usage example: `if entry.Key == "colour" { return }`
|
||||
Key string
|
||||
// Usage example: `if entry.Value == "dark" { return }`
|
||||
// Usage example: `if entry.Value == "blue" { return }`
|
||||
Value string
|
||||
}
|
||||
|
||||
// Usage example: `configEntries, err := storeInstance.GetAll("config")`
|
||||
// Usage example: `colourEntries, err := storeInstance.GetAll("config")`
|
||||
func (storeInstance *Store) GetAll(group string) (map[string]string, error) {
|
||||
entriesByKey := make(map[string]string)
|
||||
for entry, err := range storeInstance.All(group) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue